#!/usr/bin/python
#
# Bluetooth PIN helper
# Written by Maxim Krasnyansky <maxk@qualcomm.com>
#
import sys, os, string, popen2

# X Display initialization.
# Find running X Server and parse it's arguments.
# Set enviroment variables DISPLAY and XAUTHORITY
# using info extracted from X Server args.
#
def set_display():
	disp = ":0"
	auth = ""
	proc = "-C X -C XFree86"
	ps   = "/bin/ps " + proc + " --format args --no-headers"

	r,w = popen2.popen2(ps)
	arg = string.split(r.read())
	for i in range(1, len(arg)):
		if arg[i][0] != '-' and i==1:
			disp = arg[i]
		elif arg[i] == "-auth":
			auth = arg[i+1]
			break

	os.environ['DISPLAY']    = disp 
	os.environ['XAUTHORITY'] = auth

# Set X display before initializing GTK
set_display()

from gtk import *

# Dialog Class
DLG_OK = 1
DLG_CANCEL = 2
class Dialog(GtkDialog):
	result = DLG_CANCEL 
	args = {}
	def __init__(self, modal=FALSE, mesg=None, args = {}):
		GtkDialog.__init__(self)
		self.args = args
		self.set_modal(modal)
		self.set_usize(400, 0)
		self.set_uposition(300,300)
		
		self.connect("destroy", self.quit)
		self.connect("delete_event", self.quit)

		self.action_area.set_border_width(2)

		ok = GtkButton("Accept")
		ok.connect("clicked", self.ok)
		self.action_area.pack_start(ok, padding = 20)
		ok.show()

		cl = GtkButton("Reject")
		cl.connect("clicked", self.cancel)
		self.action_area.pack_start(cl, padding = 20)
		cl.show()

		if mesg:
			msg = GtkLabel()
			msg.set_text(mesg)
			self.vbox.pack_start(msg, padding = 10)
			msg.show()

		self.ents = []
		for k in self.args.keys():
			hbox = GtkHBox()
			hbox.set_border_width(5)
			self.vbox.pack_start(hbox)
			hbox.show()

			l = GtkLabel()
			e = GtkEntry()
			l.set_text( k )
			e.set_text( self.args[k] )
			e.connect("key_press_event", self.key_press)
			hbox.pack_start(l, padding = 10, expand = FALSE)
			hbox.pack_start(e)
			l.show()
			e.show()

			self.ents.append( (k, e) )

		self.ents[0][1].grab_focus()

	def key_press(self, entry, event):
		if event.keyval == GDK.Return:
			entry.emit_stop_by_name("key_press_event")
			self.ok()
		elif event.keyval == GDK.Escape:
			entry.emit_stop_by_name("key_press_event")
			self.cancel()

	def ok(self, *args):
		self.result = DLG_OK 
		for e in self.ents:
			k = e[0]
			self.args[k] = e[1].get_text() 
		self.quit()

	def cancel(self, *args):
		self.result = DLG_CANCEL 
		self.quit()

	def quit(self, *args):
		self.hide()
		self.destroy()
		mainquit()

def dialog(title, mesg, args, modal = FALSE):
	dlg = Dialog(args = args, mesg = mesg, modal = modal)
	dlg.set_title(title)
	dlg.show()
	mainloop()
	return dlg.result

def main(*args):
	if len(sys.argv) < 2:
		print "ERR"
		sys.exit()
	
	dir    = sys.argv[1]
	bdaddr = sys.argv[2]

	if len(sys.argv) > 3:
		name = sys.argv[3]
	else:
		name = ""

	title = "Bluetooth PIN Code"

	# Bluetooth spec recommends automatic strong random PIN generation.
	# So eventually we should implement that. 
	pin = { "PIN": "" }

	if dir == "out":
		mesg = "Outgoing connection to "
	else:
		mesg = "Incomming connection from "
	
	mesg = mesg + name + "[" + bdaddr + "]"

	if dialog(title, mesg, pin) == DLG_OK:
		pin["PIN"] = string.strip(pin["PIN"])

		if len(pin["PIN"]) >= 4 and len(pin["PIN"]) <=16:
			print "PIN:" + pin["PIN"]
		else:
			print "ERR"
	else:
		print "ERR"

#
main()
