1- # $Id: display.py,v 1.4 2000-08-08 09:55:18 petli Exp $
1+ # $Id: display.py,v 1.5 2000-08-21 10:03:45 petli Exp $
22#
33# Xlib.display -- high level display object
44#
1818# along with this program; if not, write to the Free Software
1919# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2020
21+ # Python modules
22+ import new
2123
2224# Xlib modules
2325import error
26+ import ext
2427
2528# Xlib.protocol modules
2629import protocol .display
3336import xobject .colormap
3437import xobject .cursor
3538
39+ _resource_baseclasses = {
40+ 'resource' : xobject .resource .Resource ,
41+ 'drawable' : xobject .drawable .Drawable ,
42+ 'window' : xobject .drawable .Window ,
43+ 'pixmap' : xobject .drawable .Pixmap ,
44+ 'fontable' : xobject .fontable .Fontable ,
45+ 'font' : xobject .fontable .Font ,
46+ 'gc' : xobject .fontable .GC ,
47+ 'colormap' : xobject .colormap .Colormap ,
48+ 'cursor' : xobject .cursor .Cursor ,
49+ }
50+
51+ _resource_hierarchy = {
52+ 'resource' : ('drawable' , 'window' , 'pixmap' ,
53+ 'fontable' , 'font' , 'gc' ,
54+ 'colormap' , 'cursor' ),
55+ 'drawable' : ('window' , 'pixmap' ),
56+ 'fontable' : ('font' , 'gc' )
57+ }
58+
3659class _BaseDisplay (protocol .display .Display ):
37- resource_classes = {
38- 'resource' : xobject .resource .Resource ,
39- 'drawable' : xobject .drawable .Drawable ,
40- 'window' : xobject .drawable .Window ,
41- 'pixmap' : xobject .drawable .Pixmap ,
42- 'font' : xobject .fontable .Font ,
43- 'gc' : xobject .fontable .GC ,
44- 'colormap' : xobject .colormap .Colormap ,
45- 'cursor' : xobject .cursor .Cursor ,
46- }
47-
60+ resource_classes = _resource_baseclasses .copy ()
61+
4862class Display :
4963 def __init__ (self , display = None ):
5064 self .display = _BaseDisplay (display )
5165
66+ # Find all supported extensions
67+ self .extensions = self .list_extensions ()
68+ self .class_extension_dicts = {}
69+
70+ # Go through all extension modules
71+ for extname , modname in ext .__extensions__ :
72+ if extname in self .extensions :
73+
74+ # Import the module and fetch it
75+ __import__ ('Xlib.ext.' + modname )
76+ mod = getattr (ext , modname )
77+
78+ info = self .query_extension (extname )
79+ self .display .set_extension_major (extname , info .major_opcode )
80+
81+ # Call initialiasation function
82+ mod .init (self , info )
83+
84+ # Finalize extensions by creating new classes
85+ for type , dict in self .class_extension_dicts .items ():
86+ origcls = self .display .resource_classes [type ]
87+ self .display .resource_classes [type ] = new .classobj (origcls .__name__ ,
88+ (origcls ,),
89+ dict )
90+
91+ # Problem: we have already created some objects without the
92+ # extensions: the screen roots and default colormaps.
93+ # Fix that by reinstantiating them.
94+ for screen in self .display .info .roots :
95+ screen .root = self .display .resource_classes ['window' ](self .display , screen .root .id )
96+ screen .default_colormap = self .display .resource_classes ['colormap' ](self .display , screen .default_colormap .id )
97+
98+
5299 def fileno (self ):
53100 return self .display .fileno ()
54101
@@ -58,6 +105,11 @@ def close(self):
58105 def flush (self ):
59106 self .display .flush ()
60107
108+ def sync (self ):
109+ # Do a light-weight replyrequest to sync. There must
110+ # be a better way to do it...
111+ self .get_pointer_control ()
112+
61113 def next_event (self ):
62114 return self .display .next_event ()
63115
@@ -73,7 +125,72 @@ def screen(self, sno = None):
73125 return self .display .info .roots [self .display .default_screen ]
74126 else :
75127 return self .display .info .roots [sno ]
76-
128+
129+ ###
130+ ### Extension module interface
131+ ###
132+
133+ def extension_add_method (self , object , name , function ):
134+ """extension_add_method(object, name, function)
135+
136+ Add an X extension module method. OBJECT is the type of
137+ object to add the function to, a string from this list:
138+
139+ display
140+ resource
141+ drawable
142+ window
143+ pixmap
144+ fontable
145+ font
146+ gc
147+ colormap
148+ cursor
149+
150+ NAME is the name of the method, a string. FUNCTION is a
151+ normal function whose first argument is a 'self'.
152+ """
153+
154+ if object == 'display' :
155+ if hasattr (self , name ):
156+ raise error .MethodOverrideError ('attempting to replace display method: %s' % name )
157+
158+ setattr (self , name , new .instancemethod (function , self , self .__class__ ))
159+
160+ else :
161+ types = (object , ) + _resource_hierarchy .get (object , ())
162+ for type in types :
163+ cls = _resource_baseclasses [type ]
164+ if hasattr (cls , name ):
165+ raise error .MethodOverrideError ('attempting to replace %s method: %s' % (type , name ))
166+
167+ method = new .instancemethod (function , None , cls )
168+
169+ # Maybe should check extension overrides too
170+ try :
171+ self .class_extension_dicts [type ][name ] = method
172+ except KeyError :
173+ self .class_extension_dicts [type ] = { name : method }
174+
175+ def add_extension_event (self , code , evt ):
176+ """add_extension_event(code, evt)
177+
178+ Add an extension event. CODE is the numeric code, and EVT is
179+ the event class.
180+ """
181+
182+ self .display .add_extension_event (code , evt )
183+
184+ def add_extension_error (self , code , err ):
185+ """add_extension_error(code, err)
186+
187+ Add an extension error. CODE is the numeric code, and ERR is
188+ the error class.
189+ """
190+
191+ self .display .add_extension_error (code , err )
192+
193+
77194 ###
78195 ### X requests
79196 ###
@@ -94,42 +211,52 @@ def get_selection_owner(self, selection):
94211 selection = selection )
95212 return r .owner
96213
97- def send_event (self , destination , event , propagate = 0 , event_mask = 0 ):
214+ def send_event (self , destination , event , propagate = 0 , event_mask = 0 ,
215+ onerror = None ):
216+
98217 request .SendEvent (display = self .display ,
218+ onerror = onerror ,
99219 propagate = propagate ,
100220 destination = destination ,
101221 event_mask = event_mask ,
102222 event = event )
103223
104- def ungrab_pointer (self , time ):
224+ def ungrab_pointer (self , time , onerror = None ):
105225 request .UngrabPointer (display = self .display ,
226+ onerror = onerror ,
106227 time = time )
107228
108- def change_active_pointer_grab (self , event_mask , cursor , time ):
229+ def change_active_pointer_grab (self , event_mask , cursor , time , onerror = None ):
109230 request .ChangeActivePointerGrab (display = self .display ,
231+ onerror = onerror ,
110232 cursor = cursor ,
111233 time = time ,
112234 event_mask = event_mask )
113235
114- def ungrab_keyboard (self , time ):
236+ def ungrab_keyboard (self , time , onerror = None ):
115237 request .UngrabKeyboard (display = self .display ,
238+ onerror = onerror ,
116239 time = time )
117240
118- def allow_events (self , mode , time ):
241+ def allow_events (self , mode , time , onerror = None ):
119242 request .AllowEvents (display = self .display ,
243+ onerror = onerror ,
120244 mode = mode ,
121245 time = time )
122246
123- def grab_server (self ):
247+ def grab_server (self , onerror = None ):
124248 request .GrabServer (display = self .display )
249+ onerror = onerror ,
125250
126- def ungrab_server (self ):
251+ def ungrab_server (self , onerror = None ):
127252 request .UngrabServer (display = self .display )
253+ onerror = onerror ,
128254
129255 def warp_pointer (self , x , y , src_window = 0 , src_x = 0 , src_y = 0 ,
130- src_width = 0 , src_height = 0 ):
256+ src_width = 0 , src_height = 0 , onerror = None ):
131257
132258 request .WarpPointer (display = self .display ,
259+ onerror = onerror ,
133260 src_window = src_window ,
134261 dst_window = X .NONE ,
135262 src_x = src_x ,
@@ -139,8 +266,9 @@ def warp_pointer(self, x, y, src_window = 0, src_x = 0, src_y = 0,
139266 dst_x = x ,
140267 dst_y = y )
141268
142- def set_input_focus (self , focus , revert_to , time ):
269+ def set_input_focus (self , focus , revert_to , time , onerror = None ):
143270 request .SetInputFocus (display = self .display ,
271+ onerror = onerror ,
144272 revert_to = revert_to ,
145273 focus = focus ,
146274 time = time )
@@ -154,11 +282,19 @@ def query_keymap(self):
154282
155283 def open_font (self , name ):
156284 fid = self .display .allocate_resource_id ()
285+ ec = error .CatchError (error .BadName )
286+
157287 request .OpenFont (display = self .display ,
288+ onerror = ec ,
158289 fid = fid ,
159290 name = name )
291+ self .sync ()
160292
161- return fontable .Font (self .display , fid , owner = 1 )
293+ if ec .get_error ():
294+ self .display .free_resource_id (fid )
295+ return None
296+ else :
297+ return fontable .Font (self .display , fid , owner = 1 )
162298
163299 def list_fonts (self , pattern , max_names ):
164300 r = request .ListFonts (display = self .display ,
@@ -171,8 +307,9 @@ def list_fonts_with_info(self, pattern, max_names):
171307 max_names = max_names ,
172308 pattern = pattern )
173309
174- def set_font_path (self , path ):
310+ def set_font_path (self , path , onerror = None ):
175311 request .SetFontPath (display = self .display ,
312+ onerror = onerror ,
176313 path = path )
177314
178315 def get_font_path (self ):
@@ -191,8 +328,9 @@ def list_extensions(self):
191328 r = request .ListExtensions (display = self .display )
192329 return r .names
193330
194- def change_keyboard_mapping (self , first_keycode , keysyms ):
331+ def change_keyboard_mapping (self , first_keycode , keysyms , onerror = None ):
195332 request .ChangeKeyboardMapping (display = self .display ,
333+ onerror = onerror ,
196334 first_keycode = first_keycode ,
197335 keysyms = keysyms )
198336
@@ -202,18 +340,20 @@ def get_keyboard_mapping(self, first_keycode, count):
202340 count = count )
203341 return r .keysyms
204342
205- def change_keyboard_control (self , ** keys ):
343+ def change_keyboard_control (self , onerror = None , ** keys ):
206344 request .ChangeKeyboardControl (display = self .display ,
345+ onerror = onerror ,
207346 attrs = keys )
208347
209348 def get_keyboard_control (self ):
210349 return request .GetKeyboardControl (display = self .display )
211350
212- def bell (self , percent = 0 ):
351+ def bell (self , percent = 0 , onerror = None ):
213352 request .Bell (display = self .display ,
353+ onerror = onerror ,
214354 percent = percent )
215355
216- def change_pointer_control (self , accel = None , threshold = None ):
356+ def change_pointer_control (self , accel = None , threshold = None , onerror = None ):
217357
218358 if accel is None :
219359 do_accel = 0
@@ -229,6 +369,7 @@ def change_pointer_control(self, accel = None, threshold = None):
229369 do_threshold = 1
230370
231371 request .ChangePointerControl (display = self .display ,
372+ onerror = onerror ,
232373 do_accel = do_accel ,
233374 do_thres = do_threshold ,
234375 accel_num = accel_num ,
@@ -238,8 +379,9 @@ def change_pointer_control(self, accel = None, threshold = None):
238379 def get_pointer_control (self ):
239380 return request .GetPointerControl (display = self .display )
240381
241- def set_screen_saver (self , timeout , interval , prefer_blank , allow_exposures ):
382+ def set_screen_saver (self , timeout , interval , prefer_blank , allow_exposures , onerror = None ):
242383 request .SetScreenSaver (display = self .display ,
384+ onerror = onerror ,
243385 timeout = timeout ,
244386 interval = interval ,
245387 prefer_blank = prefer_blank ,
@@ -248,25 +390,29 @@ def set_screen_saver(self, timeout, interval, prefer_blank, allow_exposures):
248390 def get_screen_saver (self ):
249391 return request .GetScreenSaver (display = self .display )
250392
251- def change_hosts (self , mode , host_family , host ):
393+ def change_hosts (self , mode , host_family , host , onerror = None ):
252394 request .ChangeHosts (display = self .display ,
395+ onerror = onerror ,
253396 mode = mode ,
254397 host_family = host_family ,
255398 host = host )
256399
257400 def list_hosts (self ):
258401 return request .ListHosts (display = self .display )
259402
260- def set_access_control (self , mode ):
403+ def set_access_control (self , mode , onerror = None ):
261404 request .SetAccessControl (display = self .display ,
405+ onerror = onerror ,
262406 mode = mode )
263407
264- def set_close_down_mode (self , mode ):
408+ def set_close_down_mode (self , mode , onerror = None ):
265409 request .SetCloseDownMode (display = self .display ,
410+ onerror = onerror ,
266411 mode = mode )
267412
268- def force_screen_saver (self , mode ):
413+ def force_screen_saver (self , mode , onerror = None ):
269414 request .ForceScreenSaver (display = self .display ,
415+ onerror = onerror ,
270416 mode = mode )
271417
272418 def set_pointer_mapping (self , map ):
@@ -287,6 +433,7 @@ def get_modifier_mapping(self):
287433 r = request .GetModifierMapping (display = self .display )
288434 return r .keycodes
289435
290- def no_operation (self ):
291- request .NoOperation (self )
436+ def no_operation (self , onerror = None ):
437+ request .NoOperation (display = self .display ,
438+ onerror = onerror )
292439
0 commit comments