3
# examples/xrandr.py -- demonstrate the RandR extension
5
# Copyright (C) 2009 David H. Bronke <whitelynx@gmail.com>
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
import sys, os, pprint
24
# Change path so we find Xlib
25
sys.path.insert(1, os.path.join(sys.path[0], '..'))
27
from Xlib import X, display, Xutil
28
from Xlib.ext import randr
30
# Application window (only one)
32
def __init__(self, display):
36
if not self.d.has_extension('RANDR'):
37
sys.stderr.write('%s: server does not have the RANDR extension\n'
39
print self.d.query_extension('RANDR')
40
sys.stderr.write("\n".join(self.d.list_extensions()))
41
if self.d.query_extension('RANDR') is None:
45
r = self.d.xrandr_query_version()
46
print 'RANDR version %d.%d' % (r.major_version, r.minor_version)
49
# Grab the current screen
50
self.screen = self.d.screen()
52
self.window = self.screen.root.create_window(
54
self.screen.root_depth,
58
# special attribute values
59
background_pixel = self.screen.white_pixel,
60
event_mask = (X.ExposureMask |
61
X.StructureNotifyMask |
65
colormap = X.CopyFromParent,
68
self.gc = self.window.create_gc(
69
foreground = self.screen.black_pixel,
70
background = self.screen.white_pixel,
75
self.WM_DELETE_WINDOW = self.d.intern_atom('WM_DELETE_WINDOW')
76
self.WM_PROTOCOLS = self.d.intern_atom('WM_PROTOCOLS')
78
self.window.set_wm_name('Xlib example: xrandr.py')
79
self.window.set_wm_icon_name('xrandr.py')
80
self.window.set_wm_class('xrandr', 'XlibExample')
82
self.window.set_wm_protocols([self.WM_DELETE_WINDOW])
83
self.window.set_wm_hints(flags = Xutil.StateHint,
84
initial_state = Xutil.NormalState)
86
self.window.set_wm_normal_hints(flags = (Xutil.PPosition | Xutil.PSize
91
# Map the window, making it visible
94
# Enable all RandR events.
95
self.window.xrandr_select_input(
96
randr.RRScreenChangeNotifyMask
97
| randr.RRCrtcChangeNotifyMask
98
| randr.RROutputChangeNotifyMask
99
| randr.RROutputPropertyNotifyMask
102
self.pp = pprint.PrettyPrinter(indent=4)
105
self.pp.pprint(self.window.xrandr_get_screen_info()._data)
107
print "Screen size range:"
108
self.pp.pprint(self.window.xrandr_get_screen_size_range()._data)
110
print "Primary output:"
111
self.pp.pprint(self.window.xrandr_get_output_primary()._data)
113
resources = self.window.xrandr_get_screen_resources()._data
116
for mode_id, mode in self.parseModes(resources['mode_names'], resources['modes']).iteritems():
117
print " %d: %s" % (mode_id, mode['name'])
119
for output in resources['outputs']:
120
print "Output %d info:" % (output, )
121
self.pp.pprint(self.d.xrandr_get_output_info(output, resources['config_timestamp'])._data)
123
for crtc in resources['crtcs']:
124
print "CRTC %d info:" % (crtc, )
125
self.pp.pprint(self.d.xrandr_get_crtc_info(crtc, resources['config_timestamp'])._data)
127
print "Raw screen resources:"
128
self.pp.pprint(resources)
130
def parseModes(self, mode_names, modes):
134
modedata = dict(mode._data)
135
modedata['name'] = mode_names[lastIdx:lastIdx + modedata['name_length']]
136
modedatas[modedata['id']] = modedata
137
lastIdx += modedata['name_length']
140
# Main loop, handling events
144
e = self.d.next_event()
146
# Window has been destroyed, quit
147
if e.type == X.DestroyNotify:
150
# Screen information has changed
151
elif e.type == self.d.extension_event.ScreenChangeNotify:
152
print 'Screen change'
153
print self.pp.pprint(e._data)
155
# CRTC information has changed
156
elif e.type == self.d.extension_event.CrtcChangeNotify:
158
print self.pp.pprint(e._data)
160
# Output information has changed
161
elif e.type == self.d.extension_event.OutputChangeNotify:
162
print 'Output change'
163
print self.pp.pprint(e._data)
165
# Output property information has changed
166
elif e.type == self.d.extension_event.OutputPropertyNotify:
167
print 'Output property change'
168
print self.pp.pprint(e._data)
170
# Somebody wants to tell us something
171
elif e.type == X.ClientMessage:
172
if e.client_type == self.WM_PROTOCOLS:
174
if fmt == 32 and data[0] == self.WM_DELETE_WINDOW:
178
if __name__ == '__main__':
179
Window(display.Display()).loop()