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

pygtk.require('2.0')

# X Display initialization.
# Find running X Server and parse its arguments.
# Set environment 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()

# Some versions of fontconfig will segfault if HOME isn't set.
os.environ['HOME'] = ""

import gtk

# Dialog Class
DLG_OK = 1
DLG_CANCEL = 2
class Dialog(gtk.Dialog):
	result = DLG_CANCEL 
	args = {}
	def __init__(self, modal=gtk.FALSE, mesg=None, args = {}):
		gtk.Dialog.__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 = gtk.Button("Accept")
		ok.connect("clicked", self.ok)
		self.action_area.pack_start(ok, padding = 20)
		ok.show()

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

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

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

			l = gtk.Label("")
			e = gtk.Entry()
			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 = gtk.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 == gtk.keysyms.Return:
			entry.emit_stop_by_name("key_press_event")
			self.ok()
		elif event.keyval == gtk.keysyms.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()
		gtk.mainquit()

def dialog(title, mesg, args, modal = gtk.FALSE):
	dlg = Dialog(args = args, mesg = mesg, modal = modal)
	dlg.set_title(title)
	dlg.show()
	gtk.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 = "Incoming connection from "
	
	mesg = mesg + name + "[" + bdaddr + "]"

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

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

#
main()
