1# Xlib.ext.randr -- RandR extension module
2#
3#    Copyright (C) 2006 Mike Meyer <mwm@mired.org>
4#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public License
7# as published by the Free Software Foundation; either version 2.1
8# of the License, or (at your option) any later version.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13# See the GNU Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this library; if not, write to the
17#    Free Software Foundation, Inc.,
18#    59 Temple Place,
19#    Suite 330,
20#    Boston, MA 02111-1307 USA
21
22
23"""RandR - provide access to the RandR extension information.
24
25This implementation is based off version 1.3 of the XRandR protocol, and may
26not be compatible with other versions.
27
28Version 1.2 of the protocol is documented at:
29http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt
30
31Version 1.3.1 here:
32http://www.x.org/releases/X11R7.5/doc/randrproto/randrproto.txt
33
34"""
35
36
37from Xlib import X
38from Xlib.protocol import rq, structs
39
40extname = 'RANDR'
41
42
43# Event codes #
44RRScreenChangeNotify        = 0
45
46# V1.2 additions
47RRNotify                    = 1
48
49# RRNotify Subcodes
50RRNotify_CrtcChange         = 0
51RRNotify_OutputChange       = 1
52RRNotify_OutputProperty     = 2
53
54
55# Event selection bits #
56RRScreenChangeNotifyMask    = (1 << 0)
57
58# V1.2 additions
59RRCrtcChangeNotifyMask      = (1 << 1)
60RROutputChangeNotifyMask    = (1 << 2)
61RROutputPropertyNotifyMask  = (1 << 3)
62
63
64# Constants #
65SetConfigSuccess            = 0
66SetConfigInvalidConfigTime  = 1
67SetConfigInvalidTime        = 2
68SetConfigFailed             = 3
69
70# used in the rotation field; rotation and reflection in 0.1 proto.
71Rotate_0                    = 1
72Rotate_90                   = 2
73Rotate_180                  = 4
74Rotate_270                  = 8
75
76# new in 1.0 protocol, to allow reflection of screen
77Reflect_X                   = 16
78Reflect_Y                   = 32
79
80# new in 1.2 protocol
81HSyncPositive               = 0x00000001
82HSyncNegative               = 0x00000002
83VSyncPositive               = 0x00000004
84VSyncNegative               = 0x00000008
85Interlace                   = 0x00000010
86DoubleScan                  = 0x00000020
87CSync                       = 0x00000040
88CSyncPositive               = 0x00000080
89CSyncNegative               = 0x00000100
90HSkewPresent                = 0x00000200
91BCast                       = 0x00000400
92PixelMultiplex              = 0x00000800
93DoubleClock                 = 0x00001000
94ClockDivideBy2              = 0x00002000
95
96# event types?
97Connected                   = 0
98Disconnected                = 1
99UnknownConnection           = 2
100
101# Conventional RandR output properties
102PROPERTY_RANDR_EDID         = "EDID"
103PROPERTY_SIGNAL_FORMAT      = "SignalFormat"
104PROPERTY_SIGNAL_PROPERTIES  = "SignalProperties"
105PROPERTY_CONNECTOR_TYPE     = "ConnectorType"
106PROPERTY_CONNECTOR_NUMBER   = "ConnectorNumber"
107PROPERTY_COMPATIBILITY_LIST = "CompatibilityList"
108PROPERTY_CLONE_LIST         = "CloneList"
109
110# subpixel order - TODO: These constants are part of the RENDER extension and
111# should be moved there if/when that extension is added to python-xlib.
112SubPixelUnknown             = 0
113SubPixelHorizontalRGB       = 1
114SubPixelHorizontalBGR       = 2
115SubPixelVerticalRGB         = 3
116SubPixelVerticalBGR         = 4
117SubPixelNone                = 5
118
119
120# Error Codes #
121BadRROutput                 = 0
122BadRRCrtc                   = 1
123BadRRMode                   = 2
124
125
126# Data Structures #
127
128RandR_ScreenSizes = rq.Struct(
129        rq.Card16('width_in_pixels'),
130        rq.Card16('height_in_pixels'),
131        rq.Card16('width_in_millimeters'),
132        rq.Card16('height_in_millimeters'),
133        )
134
135
136RandR_ModeInfo = rq.Struct(
137        rq.Card32('id'),
138        rq.Card16('width'),
139        rq.Card16('height'),
140        rq.Card32('dot_clock'),
141        rq.Card16('h_sync_start'),
142        rq.Card16('h_sync_end'),
143        rq.Card16('h_total'),
144        rq.Card16('h_skew'),
145        rq.Card16('v_sync_start'),
146        rq.Card16('v_sync_end'),
147        rq.Card16('v_total'),
148        rq.Card16('name_length'),
149        rq.Card32('flags'),
150        )
151
152RandR_Rates = rq.Struct(
153        rq.LengthOf('rates', 2),
154        rq.List('rates', rq.Card16Obj)
155        )
156
157# TODO: This struct is part of the RENDER extension and should be moved there
158# if/when that extension is added to python-xlib.
159Render_Transform = rq.Struct(
160        rq.Card32('matrix11'), #FIXME: All of these are listed as FIXED in the protocol header.
161        rq.Card32('matrix12'),
162        rq.Card32('matrix13'),
163        rq.Card32('matrix21'),
164        rq.Card32('matrix22'),
165        rq.Card32('matrix23'),
166        rq.Card32('matrix31'),
167        rq.Card32('matrix32'),
168        rq.Card32('matrix33'),
169        )
170
171
172# Requests #
173
174class QueryVersion(rq.ReplyRequest):
175    _request = rq.Struct(
176        rq.Card8('opcode'),
177        rq.Opcode(0),
178        rq.RequestLength(),
179        rq.Card32('major_version'),
180        rq.Card32('minor_version'),
181        )
182    _reply = rq.Struct(
183        rq.ReplyCode(),
184        rq.Pad(1),
185        rq.Card16('sequence_number'),
186        rq.ReplyLength(),
187        rq.Card32('major_version'),
188        rq.Card32('minor_version'),
189        rq.Pad(16),
190        )
191
192def query_version(self):
193    """Get the current version of the RandR extension.
194
195    """
196    return QueryVersion(
197        display=self.display,
198        opcode=self.display.get_extension_major(extname),
199        major_version=1,
200        minor_version=3,
201        )
202
203
204class _1_0SetScreenConfig(rq.ReplyRequest):
205    _request = rq.Struct(
206        rq.Card8('opcode'),
207        rq.Opcode(2),
208        rq.RequestLength(),
209        rq.Drawable('drawable'),
210        rq.Card32('timestamp'),
211        rq.Card32('config_timestamp'),
212        rq.Card16('size_id'),
213        rq.Card16('rotation'),
214        )
215    _reply = rq.Struct(
216        rq.ReplyCode(),
217        rq.Card8('status'),
218        rq.Card16('sequence_number'),
219        rq.ReplyLength(),
220        rq.Card32('new_timestamp'),
221        rq.Card32('new_config_timestamp'),
222        rq.Window('root'),
223        rq.Card16('subpixel_order'),
224        rq.Pad(10),
225        )
226
227def _1_0set_screen_config(self, size_id, rotation, config_timestamp, timestamp=X.CurrentTime):
228    """Sets the screen to the specified size and rotation.
229
230    """
231    return _1_0SetScreenConfig(
232        display=self.display,
233        opcode=self.display.get_extension_major(extname),
234        drawable=self,
235        timestamp=timestamp,
236        config_timestamp=config_timestamp,
237        size_id=size_id,
238        rotation=rotation,
239        )
240
241
242class SetScreenConfig(rq.ReplyRequest):
243    _request = rq.Struct(
244        rq.Card8('opcode'),
245        rq.Opcode(2),
246        rq.RequestLength(),
247        rq.Drawable('drawable'),
248        rq.Card32('timestamp'),
249        rq.Card32('config_timestamp'),
250        rq.Card16('size_id'),
251        rq.Card16('rotation'),
252        rq.Card16('rate'), # added in version 1.1
253        rq.Pad(2),
254        )
255    _reply = rq.Struct(
256        rq.ReplyCode(),
257        rq.Card8('status'),
258        rq.Card16('sequence_number'),
259        rq.ReplyLength(),
260        rq.Card32('new_timestamp'),
261        rq.Card32('new_config_timestamp'),
262        rq.Window('root'),
263        rq.Card16('subpixel_order'),
264        rq.Pad(10),
265        )
266
267def set_screen_config(self, size_id, rotation, config_timestamp, rate=0, timestamp=X.CurrentTime):
268    """Sets the screen to the specified size, rate, rotation and reflection.
269
270    rate can be 0 to have the server select an appropriate rate.
271
272    """
273    return SetScreenConfig(
274        display=self.display,
275        opcode=self.display.get_extension_major(extname),
276        drawable=self,
277        timestamp=timestamp,
278        config_timestamp=config_timestamp,
279        size_id=size_id,
280        rotation=rotation,
281        rate=rate,
282        )
283
284
285class SelectInput(rq.Request):
286    _request = rq.Struct(
287        rq.Card8('opcode'),
288        rq.Opcode(4),
289        rq.RequestLength(),
290        rq.Window('window'),
291        rq.Card16('mask'),
292        rq.Pad(2),
293        )
294
295def select_input(self, mask):
296    return SelectInput(
297        display=self.display,
298        opcode=self.display.get_extension_major(extname),
299        window=self,
300        mask=mask,
301        )
302
303
304class GetScreenInfo(rq.ReplyRequest):
305    _request = rq.Struct(
306        rq.Card8('opcode'),
307        rq.Opcode(5),
308        rq.RequestLength(),
309        rq.Window('window'),
310        )
311    _reply = rq.Struct(
312        rq.ReplyCode(),
313        rq.Card8('set_of_rotations'),
314        rq.Card16('sequence_number'),
315        rq.ReplyLength(),
316        rq.Window('root'),
317        rq.Card32('timestamp'),
318        rq.Card32('config_timestamp'),
319        rq.LengthOf('sizes', 2),
320        rq.Card16('size_id'),
321        rq.Card16('rotation'),
322        rq.Card16('rate'), # added in version 1.1
323        rq.Card16('n_rate_ents'), # XCB's protocol description disagrees with the X headers on this; ignoring.
324        rq.Pad(2),
325        rq.List('sizes', RandR_ScreenSizes),
326        #rq.List('rates', RandR_Rates) #FIXME: Why does uncommenting this cause an error?
327        )
328
329def get_screen_info(self):
330    """Retrieve information about the current and available configurations for
331    the screen associated with this window.
332
333    """
334    return GetScreenInfo(
335        display=self.display,
336        opcode=self.display.get_extension_major(extname),
337        window=self,
338        )
339
340
341# version 1.2
342
343class GetScreenSizeRange(rq.ReplyRequest):
344    _request = rq.Struct(
345        rq.Card8('opcode'),
346        rq.Opcode(6),
347        rq.RequestLength(),
348        rq.Window('window'),
349        )
350    _reply = rq.Struct(
351        rq.ReplyCode(),
352        rq.Pad(1),
353        rq.Card16('sequence_number'),
354        rq.ReplyLength(),
355        rq.Card16('min_width'),
356        rq.Card16('min_height'),
357        rq.Card16('max_width'),
358        rq.Card16('max_height'),
359        rq.Pad(16),
360        )
361
362def get_screen_size_range(self):
363    """Retrieve the range of possible screen sizes. The screen may be set to
364	any size within this range.
365
366    """
367    return GetScreenSizeRange(
368        display=self.display,
369        opcode=self.display.get_extension_major(extname),
370        window=self,
371        )
372
373
374class SetScreenSize(rq.Request):
375    _request = rq.Struct(
376        rq.Card8('opcode'),
377        rq.Opcode(7),
378        rq.RequestLength(),
379        rq.Window('window'),
380        rq.Card16('width'),
381        rq.Card16('height'),
382        rq.Card32('width_in_millimeters'),
383        rq.Card32('height_in_millimeters'),
384        )
385
386def set_screen_size(self, width, height, width_in_millimeters=None, height_in_millimeters=None):
387    return SetScreenSize(
388        display=self.display,
389        opcode=self.display.get_extension_major(extname),
390        window=self,
391        width=width,
392        height=height,
393        width_in_millimeters=width_in_millimeters,
394        height_in_millimeters=height_in_millimeters,
395        )
396
397
398class GetScreenResources(rq.ReplyRequest):
399    _request = rq.Struct(
400        rq.Card8('opcode'),
401        rq.Opcode(8),
402        rq.RequestLength(),
403        rq.Window('window'),
404        )
405    _reply = rq.Struct(
406        rq.ReplyCode(),
407        rq.Pad(1),
408        rq.Card16('sequence_number'),
409        rq.ReplyLength(),
410        rq.Card32('timestamp'),
411        rq.Card32('config_timestamp'),
412        rq.LengthOf('crtcs', 2),
413        rq.LengthOf('outputs', 2),
414        rq.LengthOf('modes', 2),
415        rq.LengthOf('mode_names', 2),
416        rq.Pad(8),
417        rq.List('crtcs', rq.Card32Obj),
418        rq.List('outputs', rq.Card32Obj),
419        rq.List('modes', RandR_ModeInfo),
420        rq.String8('mode_names'),
421        )
422
423def get_screen_resources(self):
424    return GetScreenResources(
425        display=self.display,
426        opcode=self.display.get_extension_major(extname),
427        window=self,
428        )
429
430
431class GetOutputInfo(rq.ReplyRequest):
432    _request = rq.Struct(
433        rq.Card8('opcode'),
434        rq.Opcode(9),
435        rq.RequestLength(),
436        rq.Card32('output'),
437        rq.Card32('config_timestamp'),
438        )
439    _reply = rq.Struct(
440        rq.ReplyCode(),
441        rq.Card8('status'),
442        rq.Card16('sequence_number'),
443        rq.ReplyLength(),
444        rq.Card32('timestamp'),
445        rq.Card32('crtc'),
446        rq.Card32('mm_width'),
447        rq.Card32('mm_height'),
448        rq.Card8('connection'),
449        rq.Card8('subpixel_order'),
450        rq.LengthOf('crtcs', 2),
451        rq.LengthOf('modes', 2),
452        rq.Card16('num_preferred'),
453        rq.LengthOf('clones', 2),
454        rq.LengthOf('name', 2),
455        rq.List('crtcs', rq.Card32Obj),
456        rq.List('modes', rq.Card32Obj),
457        rq.List('clones', rq.Card32Obj),
458        rq.String8('name'),
459        )
460
461def get_output_info(self, output, config_timestamp):
462    return GetOutputInfo(
463        display=self.display,
464        opcode=self.display.get_extension_major(extname),
465        output=output,
466        config_timestamp=config_timestamp,
467        )
468
469
470class ListOutputProperties(rq.ReplyRequest):
471    _request = rq.Struct(
472        rq.Card8('opcode'),
473        rq.Opcode(10),
474        rq.RequestLength(),
475        rq.Card32('output'),
476        )
477    _reply = rq.Struct(
478        rq.ReplyCode(),
479        rq.Pad(1),
480        rq.Card16('sequence_number'),
481        rq.ReplyLength(),
482        rq.LengthOf('atoms', 2),
483        rq.Pad(22),
484        rq.List('atoms', rq.Card32Obj),
485        )
486
487def list_output_properties(self, output):
488    return ListOutputProperties (
489        display=self.display,
490        opcode=self.display.get_extension_major(extname),
491        output=output,
492        )
493
494
495class QueryOutputProperty(rq.ReplyRequest):
496    _request = rq.Struct(
497        rq.Card8('opcode'),
498        rq.Opcode(11),
499        rq.RequestLength(),
500        rq.Card32('output'),
501        rq.Card32('property'),
502        )
503    _reply = rq.Struct(
504        rq.ReplyCode(),
505        rq.Pad(1),
506        rq.Card16('sequence_number'),
507        rq.ReplyLength(),
508        rq.Bool('pending'),
509        rq.Bool('range'),
510        rq.Bool('immutable'),
511        rq.Pad(21),
512        rq.List('valid_values', rq.Card32Obj),
513        )
514
515def query_output_property(self, output, property):
516    return QueryOutputProperty (
517        display=self.display,
518        opcode=self.display.get_extension_major(extname),
519        output=output,
520        property=property,
521        )
522
523
524class ConfigureOutputProperty (rq.Request):
525    _request = rq.Struct(
526        rq.Card8('opcode'),
527        rq.Opcode(12),
528        rq.RequestLength(),
529        rq.Card32('output'),
530        rq.Card32('property'),
531        rq.Bool('pending'),
532        rq.Bool('range'),
533        rq.Pad(2),
534        rq.List('valid_values', rq.Card32Obj),
535        )
536
537def configure_output_property (self, output, property):
538    return ConfigureOutputProperty (
539        display=self.display,
540        opcode=self.display.get_extension_major(extname),
541        output=output,
542        property=property,
543        )
544
545
546class ChangeOutputProperty(rq.Request):
547    _request = rq.Struct(
548        rq.Card8('opcode'),
549        rq.Opcode(13),
550        rq.RequestLength(),
551        rq.Card32('output'),
552        rq.Card32('property'),
553        rq.Card32('type'),
554        rq.Format('value', 1),
555        rq.Card8('mode'),
556        rq.Pad(2),
557        rq.LengthOf('value', 4),
558        rq.PropertyData('value'),
559        )
560
561def change_output_property(self, output, property, type, mode, value):
562    return ChangeOutputProperty(
563        display=self.display,
564        opcode=self.display.get_extension_major(extname),
565        output=output,
566        property=property,
567        type=type,
568        mode=mode,
569        value=value,
570        )
571
572
573class DeleteOutputProperty(rq.Request):
574    _request = rq.Struct(
575        rq.Card8('opcode'),
576        rq.Opcode(14),
577        rq.RequestLength(),
578        rq.Card32('output'),
579        rq.Card32('property'),
580        )
581
582def delete_output_property(self, output, property):
583    return DeleteOutputProperty(
584        display=self.display,
585        opcode=self.display.get_extension_major(extname),
586        output=output,
587        property=property,
588        )
589
590
591class GetOutputProperty(rq.ReplyRequest):
592    _request = rq.Struct(
593        rq.Card8('opcode'),
594        rq.Opcode(15),
595        rq.RequestLength(),
596        rq.Card32('output'),
597        rq.Card32('property'),
598        rq.Card32('type'),
599        rq.Card32('long_offset'),
600        rq.Card32('long_length'),
601        rq.Bool('delete'),
602        rq.Bool('pending'),
603        rq.Pad(2),
604        )
605    _reply = rq.Struct(
606        rq.ReplyCode(),
607        rq.Format('value', 1),
608        rq.Card16('sequence_number'),
609        rq.ReplyLength(),
610        rq.Card32('property_type'),
611        rq.Card32('bytes_after'),
612        rq.LengthOf('value', 4),
613        rq.Pad(12),
614        rq.List('value', rq.Card8Obj),
615        )
616
617def get_output_property(self, output, property, type, long_offset, long_length, delete=False, pending=False):
618    return GetOutputProperty(
619        display=self.display,
620        opcode=self.display.get_extension_major(extname),
621        output=output,
622        property=property,
623        type=type,
624        long_offset=long_offset,
625        long_length=long_length,
626        delete=delete,
627        pending=pending,
628        )
629
630
631class CreateMode(rq.ReplyRequest):
632    _request = rq.Struct(
633        rq.Card8('opcode'),
634        rq.Opcode(16),
635        rq.RequestLength(),
636        rq.Window('window'),
637        rq.Object('mode', RandR_ModeInfo),
638        rq.String8('name'),
639        )
640    _reply = rq.Struct(
641        rq.ReplyCode(),
642        rq.Pad(1),
643        rq.Card16('sequence_number'),
644        rq.ReplyLength(),
645        rq.Card32('mode'),
646        rq.Pad(20),
647        )
648
649def create_mode(self, mode, name):
650    return CreateMode (
651        display=self.display,
652        opcode=self.display.get_extension_major(extname),
653        window=self,
654        mode=mode,
655        name=name,
656        )
657
658
659class DestroyMode(rq.Request):
660    _request = rq.Struct(
661        rq.Card8('opcode'),
662        rq.Opcode(17),
663        rq.RequestLength(),
664        rq.Card32('mode'),
665        )
666
667def destroy_mode(self, mode):
668    return DestroyMode(
669        display=self.display,
670        opcode=self.display.get_extension_major(extname),
671        mode=mode,
672        )
673
674
675class AddOutputMode(rq.Request):
676    _request = rq.Struct(
677        rq.Card8('opcode'),
678        rq.Opcode(18),
679        rq.RequestLength(),
680        rq.Card32('output'),
681        rq.Card32('mode'),
682        )
683
684def add_output_mode(self, output, mode):
685    return AddOutputMode(
686        display=self.display,
687        opcode=self.display.get_extension_major(extname),
688        output=output,
689        mode=mode,
690        )
691
692
693class DeleteOutputMode(rq.Request):
694    _request = rq.Struct(
695        rq.Card8('opcode'),
696        rq.Opcode(19),
697        rq.RequestLength(),
698        rq.Card32('output'),
699        rq.Card32('mode'),
700        )
701
702def delete_output_mode(self):
703    return DeleteOutputMode(
704        display=self.display,
705        opcode=self.display.get_extension_major(extname),
706        output=output,
707        mode=mode,
708        )
709
710
711class GetCrtcInfo(rq.ReplyRequest):
712    _request = rq.Struct(
713        rq.Card8('opcode'),
714        rq.Opcode(20),
715        rq.RequestLength(),
716        rq.Card32('crtc'),
717        rq.Card32('config_timestamp'),
718        )
719    _reply = rq.Struct(
720        rq.ReplyCode(),
721        rq.Card8('status'),
722        rq.Card16('sequence_number'),
723        rq.ReplyLength(),
724        rq.Card32('timestamp'),
725        rq.Int16('x'),
726        rq.Int16('y'),
727        rq.Card16('width'),
728        rq.Card16('height'),
729        rq.Card32('mode'),
730        rq.Card16('rotation'),
731        rq.Card16('possible_rotations'),
732        rq.LengthOf('outputs', 2),
733        rq.LengthOf('possible_outputs', 2),
734        rq.List('outputs', rq.Card32Obj),
735        rq.List('possible_outputs', rq.Card32Obj),
736        )
737
738def get_crtc_info(self, crtc, config_timestamp):
739    return GetCrtcInfo (
740        display=self.display,
741        opcode=self.display.get_extension_major(extname),
742        crtc=crtc,
743        config_timestamp=config_timestamp,
744        )
745
746
747class SetCrtcConfig(rq.ReplyRequest):
748    _request = rq.Struct(
749        rq.Card8('opcode'),
750        rq.Opcode(21),
751        rq.RequestLength(),
752        rq.Card32('crtc'),
753        rq.Card32('timestamp'),
754        rq.Card32('config_timestamp'),
755        rq.Int16('x'),
756        rq.Int16('y'),
757        rq.Card32('mode'),
758        rq.Card16('rotation'),
759        rq.Pad(2),
760        rq.List('outputs', rq.Card32Obj),
761        )
762    _reply = rq.Struct(
763        rq.ReplyCode(),
764        rq.Card8('status'),
765        rq.Card16('sequence_number'),
766        rq.ReplyLength(),
767        rq.Card32('new_timestamp'),
768        rq.Pad(20),
769        )
770
771def set_crtc_config(self, crtc, config_timestamp, x, y, mode, rotation, outputs, timestamp=X.CurrentTime):
772    return SetCrtcConfig (
773        display=self.display,
774        opcode=self.display.get_extension_major(extname),
775        crtc=crtc,
776        config_timestamp=config_timestamp,
777        x=x,
778        y=y,
779        mode=mode,
780        rotation=rotation,
781        outputs=outputs,
782        timestamp=timestamp,
783        )
784
785
786class GetCrtcGammaSize(rq.ReplyRequest):
787    _request = rq.Struct(
788        rq.Card8('opcode'),
789        rq.Opcode(22),
790        rq.RequestLength(),
791        rq.Card32('crtc'),
792        )
793    _reply = rq.Struct(
794        rq.ReplyCode(),
795        rq.Card8('status'),
796        rq.Card16('sequence_number'),
797        rq.ReplyLength(),
798        rq.Card16('size'),
799        rq.Pad(22),
800        )
801
802def get_crtc_gamma_size(self, crtc):
803    return GetCrtcGammaSize (
804        display=self.display,
805        opcode=self.display.get_extension_major(extname),
806        crtc=crtc,
807        )
808
809
810class GetCrtcGamma(rq.ReplyRequest):
811    _request = rq.Struct(
812        rq.Card8('opcode'),
813        rq.Opcode(23),
814        rq.RequestLength(),
815        rq.Card32('crtc'),
816        )
817    _reply = rq.Struct(
818        rq.ReplyCode(),
819        rq.Card8('status'),
820        rq.Card16('sequence_number'),
821        rq.ReplyLength(),
822        rq.LengthOf(('red', 'green', 'blue'), 2),
823        rq.Pad(22),
824        rq.List('red', rq.Card16Obj),
825        rq.List('green', rq.Card16Obj),
826        rq.List('blue', rq.Card16Obj),
827        )
828
829def get_crtc_gamma(self, crtc):
830    return GetCrtcGamma (
831        display=self.display,
832        opcode=self.display.get_extension_major(extname),
833        crtc=crtc,
834        )
835
836
837class SetCrtcGamma(rq.Request):
838    _request = rq.Struct(
839        rq.Card8('opcode'),
840        rq.Opcode(24),
841        rq.RequestLength(),
842        rq.Card32('crtc'),
843        rq.Card16('size'),
844        rq.Pad(2),
845        rq.List('red', rq.Card16Obj),
846        rq.List('green', rq.Card16Obj),
847        rq.List('blue', rq.Card16Obj),
848        )
849
850def set_crtc_gamma(self, crtc, size, red, green, blue):
851    return SetCrtcGamma(
852        display=self.display,
853        opcode=self.display.get_extension_major(extname),
854        crtc=crtc,
855        size=size,
856        red=red,
857        green=green,
858        blue=blue,
859        )
860
861
862# version 1.3
863
864class GetScreenResourcesCurrent(rq.ReplyRequest):
865    _request = rq.Struct(
866        rq.Card8('opcode'),
867        rq.Opcode(25),
868        rq.RequestLength(),
869        rq.Window('window'),
870        )
871    _reply = rq.Struct(
872        rq.ReplyCode(),
873        rq.Pad(1),
874        rq.Card16('sequence_number'),
875        rq.ReplyLength(),
876        rq.Card32('timestamp'),
877        rq.Card32('config_timestamp'),
878        rq.LengthOf('crtcs', 2),
879        rq.LengthOf('outputs', 2),
880        rq.LengthOf('modes', 2),
881        rq.LengthOf('names', 2),
882        rq.Pad(8),
883        rq.List('crtcs', rq.Card32Obj),
884        rq.List('outputs', rq.Card32Obj),
885        rq.List('modes', RandR_ModeInfo),
886        rq.String8('names'),
887        )
888
889def get_screen_resources_current(self):
890    return GetScreenResourcesCurrent(
891        display=self.display,
892        opcode=self.display.get_extension_major(extname),
893        window=self,
894        )
895
896
897class SetCrtcTransform(rq.Request):
898    _request = rq.Struct(
899        rq.Card8('opcode'),
900        rq.Opcode(26),
901        rq.RequestLength(),
902        rq.Card32('crtc'),
903        rq.Object('transform', Render_Transform),
904        rq.LengthOf('filter_name', 2),
905        rq.Pad(2),
906        rq.String8('filter_name'),
907        rq.List('filter_params', rq.Card32Obj), #FIXME: The protocol says FIXED? http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt#n2161
908        )
909
910def set_crtc_transform(self, crtc, n_bytes_filter):
911    return SetCrtcTransform(
912        display=self.display,
913        opcode=self.display.get_extension_major(extname),
914        crtc=crtc,
915        n_bytes_filter=n_bytes_filter,
916        )
917
918
919class GetCrtcTransform(rq.ReplyRequest):
920    _request = rq.Struct(
921        rq.Card8('opcode'),
922        rq.Opcode(27),
923        rq.RequestLength(),
924        rq.Card32('crtc'),
925        )
926    _reply = rq.Struct(
927        rq.ReplyCode(),
928        rq.Card8('status'),
929        rq.Card16('sequence_number'),
930        rq.ReplyLength(),
931        rq.Object('pending_transform', Render_Transform),
932        rq.Bool('has_transforms'),
933        rq.Pad(3),
934        rq.Object('current_transform', Render_Transform),
935        rq.Pad(4),
936        rq.LengthOf('pending_filter_name', 2),
937        rq.LengthOf('pending_filter_params', 2),
938        rq.LengthOf('current_filter_name', 2),
939        rq.LengthOf('current_filter_params', 2),
940        rq.String8('pending_filter_name'),
941        rq.List('pending_filter_params', rq.Card32Obj), #FIXME: The protocol says FIXED? http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt#n2161
942        rq.String8('current_filter_name'),
943        rq.List('current_filter_params', rq.Card32Obj), #FIXME: The protocol says FIXED? http://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt#n2161
944        )
945
946def get_crtc_transform(self, crtc):
947    return GetCrtcTransform(
948        display=self.display,
949        opcode=self.display.get_extension_major(extname),
950        crtc=crtc,
951        )
952
953
954class GetPanning(rq.ReplyRequest):
955    _request = rq.Struct(
956        rq.Card8('opcode'),
957        rq.Opcode(28),
958        rq.RequestLength(),
959        rq.Card32('crtc'),
960        )
961    _reply = rq.Struct(
962        rq.ReplyCode(),
963        rq.Card8('status'),
964        rq.Card16('sequence_number'),
965        rq.ReplyLength(),
966        rq.Card32('timestamp'),
967        rq.Card16('left'),
968        rq.Card16('top'),
969        rq.Card16('width'),
970        rq.Card16('height'),
971        rq.Card16('track_left'),
972        rq.Card16('track_top'),
973        rq.Card16('track_width'),
974        rq.Card16('track_height'),
975        rq.Int16('border_left'),
976        rq.Int16('border_top'),
977        rq.Int16('border_right'),
978        rq.Int16('border_bottom'),
979        )
980
981def get_panning(self, crtc):
982    return GetPanning (
983        display=self.display,
984        opcode=self.display.get_extension_major(extname),
985        crtc=crtc,
986        )
987
988
989class SetPanning(rq.ReplyRequest):
990    _request = rq.Struct(
991        rq.Card8('opcode'),
992        rq.Opcode(29),
993        rq.RequestLength(),
994        rq.Card32('crtc'),
995        rq.Card32('timestamp'),
996        rq.Card16('left'),
997        rq.Card16('top'),
998        rq.Card16('width'),
999        rq.Card16('height'),
1000        rq.Card16('track_left'),
1001        rq.Card16('track_top'),
1002        rq.Card16('track_width'),
1003        rq.Card16('track_height'),
1004        rq.Int16('border_left'),
1005        rq.Int16('border_top'),
1006        rq.Int16('border_right'),
1007        rq.Int16('border_bottom'),
1008        )
1009    _reply = rq.Struct(
1010        rq.ReplyCode(),
1011        rq.Card8('status'),
1012        rq.Card16('sequence_number'),
1013        rq.ReplyLength(),
1014        rq.Card32('new_timestamp'),
1015        rq.Pad(20),
1016        )
1017
1018def set_panning(self, crtc, left, top, width, height, track_left, track_top, track_width, track_height, border_left, border_top, border_width, border_height, timestamp=X.CurrentTime):
1019    return SetPanning (
1020        display=self.display,
1021        opcode=self.display.get_extension_major(extname),
1022        crtc=crtc,
1023        left=left,
1024        top=top,
1025        width=width,
1026        height=height,
1027        track_left=track_left,
1028        track_top=track_top,
1029        track_width=track_width,
1030        track_height=track_height,
1031        border_left=border_left,
1032        border_top=border_top,
1033        border_width=border_width,
1034        border_height=border_height,
1035        timestamp=timestamp,
1036        )
1037
1038
1039class SetOutputPrimary(rq.Request):
1040    _request = rq.Struct(
1041        rq.Card8('opcode'),
1042        rq.Opcode(30),
1043        rq.RequestLength(),
1044        rq.Window('window'),
1045        rq.Card32('output'),
1046        )
1047
1048def set_output_primary(self, output):
1049    return SetOutputPrimary(
1050        display=self.display,
1051        opcode=self.display.get_extension_major(extname),
1052        window=self,
1053        output=output,
1054        )
1055
1056
1057class GetOutputPrimary(rq.ReplyRequest):
1058    _request = rq.Struct(
1059        rq.Card8('opcode'),
1060        rq.Opcode(31),
1061        rq.RequestLength(),
1062        rq.Window('window'),
1063        )
1064    _reply = rq.Struct(
1065        rq.ReplyCode(),
1066        rq.Pad(1),
1067        rq.Card16('sequence_number'),
1068        rq.ReplyLength(),
1069        rq.Card32('output'),
1070        rq.Pad(20),
1071        )
1072
1073def get_output_primary(self):
1074    return GetOutputPrimary(
1075        display=self.display,
1076        opcode=self.display.get_extension_major(extname),
1077        window=self,
1078        )
1079
1080
1081# Events #
1082
1083class ScreenChangeNotify(rq.Event):
1084    _code = None
1085    _fields = rq.Struct(
1086        rq.Card8('type'),
1087        rq.Card8('rotation'),
1088        rq.Card16('sequence_number'),
1089        rq.Card32('timestamp'),
1090        rq.Card32('config_timestamp'),
1091        rq.Window('root'),
1092        rq.Window('window'),
1093        rq.Card16('size_id'),
1094        rq.Card16('subpixel_order'),
1095        rq.Card16('width_in_pixels'),
1096        rq.Card16('height_in_pixels'),
1097        rq.Card16('width_in_millimeters'),
1098        rq.Card16('height_in_millimeters'),
1099        )
1100
1101
1102class CrtcChangeNotify(rq.Event):
1103    _code = None
1104    _fields = rq.Struct(
1105        rq.Card8('type'),
1106        rq.Card8('sub_code'),
1107        rq.Card16('sequence_number'),
1108        rq.Card32('timestamp'),
1109        rq.Window('window'),
1110        rq.Card32('crtc'),
1111        rq.Card32('mode'),
1112        rq.Card16('rotation'),
1113        rq.Pad(2),
1114        rq.Int16('x'),
1115        rq.Int16('y'),
1116        rq.Card16('width'),
1117        rq.Card16('height'),
1118        )
1119
1120
1121class OutputChangeNotify(rq.Event):
1122    _code = None
1123    _fields = rq.Struct(
1124        rq.Card8('type'),
1125        rq.Card8('sub_code'),
1126        rq.Card16('sequence_number'),
1127        rq.Card32('timestamp'),
1128        rq.Card32('config_timestamp'),
1129        rq.Window('window'),
1130        rq.Card32('output'),
1131        rq.Card32('crtc'),
1132        rq.Card32('mode'),
1133        rq.Card16('rotation'),
1134        rq.Card8('connection'),
1135        rq.Card8('subpixel_order'),
1136        )
1137
1138
1139class OutputPropertyNotify(rq.Event):
1140    _code = None
1141    _fields = rq.Struct(
1142        rq.Card8('type'),
1143        rq.Card8('sub_code'),
1144        rq.Card16('sequence_number'),
1145        rq.Window('window'),
1146        rq.Card32('output'),
1147        rq.Card32('atom'),
1148        rq.Card32('timestamp'),
1149        rq.Card8('state'),
1150        rq.Pad(11),
1151        )
1152
1153
1154# Initialization #
1155
1156def init(disp, info):
1157    disp.extension_add_method('display', 'xrandr_query_version', query_version)
1158    disp.extension_add_method('window', 'xrandr_select_input', select_input)
1159    disp.extension_add_method('window', 'xrandr_get_screen_info', get_screen_info)
1160    disp.extension_add_method('drawable', 'xrandr_1_0set_screen_config', _1_0set_screen_config)
1161    disp.extension_add_method('drawable', 'xrandr_set_screen_config', set_screen_config)
1162    disp.extension_add_method('window', 'xrandr_get_screen_size_range', get_screen_size_range)
1163    disp.extension_add_method('window', 'xrandr_set_screen_size', set_screen_size)
1164    disp.extension_add_method('window', 'xrandr_get_screen_resources', get_screen_resources)
1165    disp.extension_add_method('display', 'xrandr_get_output_info', get_output_info)
1166    disp.extension_add_method('display', 'xrandr_list_output_properties', list_output_properties)
1167    disp.extension_add_method('display', 'xrandr_query_output_property', query_output_property)
1168    disp.extension_add_method('display', 'xrandr_configure_output_property ', configure_output_property )
1169    disp.extension_add_method('display', 'xrandr_change_output_property', change_output_property)
1170    disp.extension_add_method('display', 'xrandr_delete_output_property', delete_output_property)
1171    disp.extension_add_method('display', 'xrandr_get_output_property', get_output_property)
1172    disp.extension_add_method('window', 'xrandr_create_mode', create_mode)
1173    disp.extension_add_method('display', 'xrandr_destroy_mode', destroy_mode)
1174    disp.extension_add_method('display', 'xrandr_add_output_mode', add_output_mode)
1175    disp.extension_add_method('display', 'xrandr_delete_output_mode', delete_output_mode)
1176    disp.extension_add_method('display', 'xrandr_get_crtc_info', get_crtc_info)
1177    disp.extension_add_method('display', 'xrandr_set_crtc_config', set_crtc_config)
1178    disp.extension_add_method('display', 'xrandr_get_crtc_gamma_size', get_crtc_gamma_size)
1179    disp.extension_add_method('display', 'xrandr_get_crtc_gamma', get_crtc_gamma)
1180    disp.extension_add_method('display', 'xrandr_set_crtc_gamma', set_crtc_gamma)
1181    disp.extension_add_method('window', 'xrandr_get_screen_resources_current', get_screen_resources_current)
1182    disp.extension_add_method('display', 'xrandr_set_crtc_transform', set_crtc_transform)
1183    disp.extension_add_method('display', 'xrandr_get_crtc_transform', get_crtc_transform)
1184    disp.extension_add_method('window', 'xrandr_set_output_primary', set_output_primary)
1185    disp.extension_add_method('window', 'xrandr_get_output_primary', get_output_primary)
1186    disp.extension_add_method('display', 'xrandr_get_panning', get_panning)
1187    disp.extension_add_method('display', 'xrandr_set_panning', set_panning)
1188
1189    disp.extension_add_event(info.first_event + RRScreenChangeNotify, ScreenChangeNotify)
1190     # add RRNotify events (1 event code with 3 subcodes)
1191    disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_CrtcChange, CrtcChangeNotify)
1192    disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputChange, OutputChangeNotify)
1193    disp.extension_add_subevent(info.first_event + RRNotify, RRNotify_OutputProperty, OutputPropertyNotify)
1194
1195    #disp.extension_add_error(BadRROutput, BadRROutputError)
1196    #disp.extension_add_error(BadRRCrtc, BadRRCrtcError)
1197    #disp.extension_add_error(BadRRMode, BadRRModeError)
1198