@@ -1,13 +1,15 @@
from gi . repository import Gtk
import logging
from gi .repository import Gdk
from gi .repository import GObject
import pygame
import pygame .event
class _MockEvent (object ):
def __init__ (self , keyval ):
self .keyval = keyval
class Translator (object ):
key_trans = {
'Alt_L' : pygame .K_LALT ,
@@ -18,14 +20,14 @@ class Translator(object):
'Shift_R' : pygame .K_RSHIFT ,
'Super_L' : pygame .K_LSUPER ,
'Super_R' : pygame .K_RSUPER ,
'KP_Page_Up' : pygame .K_KP9 ,
'KP_Page_Down' : pygame .K_KP3 ,
'KP_End' : pygame .K_KP1 ,
'KP_Home' : pygame .K_KP7 ,
'KP_Up' : pygame .K_KP8 ,
'KP_Down' : pygame .K_KP2 ,
'KP_Left' : pygame .K_KP4 ,
'KP_Right' : pygame .K_KP6 ,
'KP_Page_Up' : pygame .K_KP9 ,
'KP_Page_Down' : pygame .K_KP3 ,
'KP_End' : pygame .K_KP1 ,
'KP_Home' : pygame .K_KP7 ,
'KP_Up' : pygame .K_KP8 ,
'KP_Down' : pygame .K_KP2 ,
'KP_Left' : pygame .K_KP4 ,
'KP_Right' : pygame .K_KP6 ,
}
@@ -38,47 +40,45 @@ class Translator(object):
pygame .K_RSHIFT : pygame .KMOD_RSHIFT ,
}
def __init__ (self , mainwindow , inner_evb ):
def __init__ (self , activity , inner_evb ):
"""Initialise the Translator with the windows to which to listen"""
self ._mainwindow = mainwindow
self ._activity = activity
self ._inner_evb = inner_evb
# Enable events
# (add instead of set here because the main window is already realized)
self ._mainwindow .add_events (
Gdk .EventMask .KEY_PRESS_MASK | \
Gdk .EventMask .KEY_RELEASE_MASK | \
self ._activity .add_events (
Gdk .EventMask .KEY_PRESS_MASK |
Gdk .EventMask .KEY_RELEASE_MASK |
Gdk .EventMask .VISIBILITY_NOTIFY_MASK
)
self ._inner_evb .set_events (
Gdk .EventMask .POINTER_MOTION_MASK | \
Gdk .EventMask .POINTER_MOTION_HINT_MASK | \
Gdk .EventMask .BUTTON_MOTION_MASK | \
Gdk .EventMask .BUTTON_PRESS_MASK | \
Gdk .EventMask .POINTER_MOTION_MASK |
Gdk .EventMask .POINTER_MOTION_HINT_MASK |
Gdk .EventMask .BUTTON_MOTION_MASK |
Gdk .EventMask .BUTTON_PRESS_MASK |
Gdk .EventMask .BUTTON_RELEASE_MASK
)
self ._mainwindow .set_can_focus (True )
self ._activity .set_can_focus (True )
self ._inner_evb .set_can_focus (True )
# Callback functions to link the event systems
self ._mainwindow .connect ('unrealize' , self ._quit_cb )
self ._mainwindow .connect ('visibility_notify_event' , self ._visibility_cb )
self ._activity .connect ('unrealize' , self ._quit_cb )
self ._activity .connect ('visibility_notify_event' , self ._visibility_cb )
self ._activity .connect ('configure-event' , self ._resize_cb )
self ._inner_evb .connect ('key_press_event' , self ._keydown_cb )
self ._inner_evb .connect ('key_release_event' , self ._keyup_cb )
self ._inner_evb .connect ('button_press_event' , self ._mousedown_cb )
self ._inner_evb .connect ('button_release_event' , self ._mouseup_cb )
self ._inner_evb .connect ('motion-notify-event' , self ._mousemove_cb )
self ._inner_evb .connect ('draw' , self ._draw_cb )
self ._inner_evb .connect ('configure-event' , self ._resize_cb )
self ._inner_evb .connect ('screen-changed' , self ._screen_changed_cb )
# Internal data
self .__stopped = False
self .__keystate = [0 ] * 323
self .__button_state = [0 ,0 , 0 ]
self .__mouse_pos = (0 ,0 )
self .__button_state = [0 , 0 , 0 ]
self .__mouse_pos = (0 , 0 )
self .__repeat = (None , None )
self .__held = set ()
self .__held_time_left = {}
@@ -92,30 +92,25 @@ def hook_pygame(self):
pygame .mouse .get_pos = self ._get_mouse_pos
def update_display (self ):
pygame .event .post (pygame .event .Event (pygame .VIDEOEXPOSE ))
def _draw_cb (self , widget , cr ):
if pygame .display .get_init ():
pygame .event .post (pygame .event .Event (pygame .VIDEOEXPOSE ))
return True
def _resize_cb (self , widget , event ):
evt = pygame .event .Event (pygame .VIDEORESIZE ,
size = (event .width ,event .height ), width = event .width , height = event .height )
pygame .event .post (evt )
return False # continue processing
if pygame .display .get_init ():
evt = pygame .event .Event (pygame .VIDEORESIZE ,
size = (event .width ,event .height ),
width = event .width , height = event .height )
pygame .event .post (evt )
return False # continue processing
def _screen_changed_cb (self , widget , previous_screen ):
if pygame .display .get_init ():
self .update_display ()
self .update_display ()
def _quit_cb (self , data = None ):
self .__stopped = True
pygame .event .post (pygame .event .Event (pygame .QUIT ))
def _visibility_cb (self , widget , event ):
if pygame .display .get_init ():
self .update_display ()
self .update_display ()
return False
def _keydown_cb (self , widget , event ):
@@ -134,7 +129,8 @@ def _keyup_cb(self, widget, event):
key = event .keyval
if self .__repeat [0 ] is not None :
if key in self .__held :
# This is possibly false if set_repeat() is called with a key held
# This is possibly false if set_repeat()
# is called with a key held
del self .__held_time_left [key ]
del self .__held_last_time [key ]
self .__held .discard (key )
@@ -151,20 +147,20 @@ def _keyevent(self, widget, event, type):
key = Gdk .keyval_name (event .keyval )
if key is None :
# No idea what this key is.
return False
return False
keycode = None
if key in self .key_trans :
keycode = self .key_trans [key ]
elif hasattr (pygame , 'K_' + key .upper ()):
keycode = getattr (pygame , 'K_' + key .upper ())
elif hasattr (pygame , 'K_' + key .lower ()):
keycode = getattr (pygame , 'K_' + key .lower ())
elif hasattr (pygame , 'K_' + key .upper ()):
keycode = getattr (pygame , 'K_' + key .upper ())
elif hasattr (pygame , 'K_' + key .lower ()):
keycode = getattr (pygame , 'K_' + key .lower ())
elif key == 'XF86Start' :
# view source request, specially handled...
self ._mainwindow .view_source ()
self ._activity .view_source ()
else :
print 'Key %s unrecognized' % key
logging . error ( 'Key %s unrecognized' % key )
if keycode is not None :
if type == pygame .KEYDOWN :
@@ -187,21 +183,22 @@ def _get_mouse_pressed(self):
return self .__button_state
def _mousedown_cb (self , widget , event ):
self .__button_state [event .button - 1 ] = 1
self .__button_state [event .button - 1 ] = 1
return self ._mouseevent (widget , event , pygame .MOUSEBUTTONDOWN )
def _mouseup_cb (self , widget , event ):
self .__button_state [event .button - 1 ] = 0
self .__button_state [event .button - 1 ] = 0
return self ._mouseevent (widget , event , pygame .MOUSEBUTTONUP )
def _mouseevent (self , widget , event , type ):
evt = pygame .event .Event (type , button = event .button , pos = (event .x , event .y ))
evt = pygame .event .Event (type , button = event .button , pos = (event .x ,
event .y ))
self ._post (evt )
return True
def _mousemove_cb (self , widget , event ):
# From http://www.learningpython.com/2006/07/25/writing-a-custom-widget-using-pygtk/
# if this is a hint, then let's get all the necessary
# if this is a hint, then let's get all the necessary
# information, if not it's all we need.
if event .is_hint :
win , x , y , state = event .window .get_device_position (event .device )
@@ -220,14 +217,15 @@ def _mousemove_cb(self, widget, event):
]
evt = pygame .event .Event (pygame .MOUSEMOTION ,
pos = self .__mouse_pos , rel = rel , buttons = self .__button_state )
pos = self .__mouse_pos , rel = rel ,
buttons = self .__button_state )
self ._post (evt )
return True
def _tick_cb (self ):
cur_time = pygame .time .get_ticks ()
for key in self .__held :
delta = cur_time - self .__held_last_time [key ]
delta = cur_time - self .__held_last_time [key ]
self .__held_last_time [key ] = cur_time
self .__held_time_left [key ] -= delta
@@ -251,8 +249,10 @@ def _post(self, evt):
try :
pygame .event .post (evt )
except pygame .error , e :
if str (e ) == 'Event queue full' :
print "Event queue full!"
if str (e ) == 'video system not initialized' :
pass
elif str (e ) == 'Event queue full' :
logging .error ("Event queue full!" )
pass
else :
raise e