]> Dogcows Code - chaz/openbox/blob - otk_c/screeninfo.c
2f11cfd9661e0f5f2114ad8868bd7ab1b3983b9b
[chaz/openbox] / otk_c / screeninfo.c
1 // -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #include "../config.h"
4 #include "screeninfo.h"
5 #include "display.h"
6 #include "rect.h"
7
8 #include <X11/Xutil.h>
9
10 #ifdef HAVE_STRING_H
11 # include <string.h>
12 #endif
13
14 #include "../src/gettext.h"
15
16 extern PyTypeObject OtkScreenInfo_Type;
17
18 PyObject *OtkScreenInfo_New(int num)
19 {
20 OtkScreenInfo* self;
21 char *dstr, *dstr2;
22 int i;
23
24 self = PyObject_New(OtkScreenInfo, &OtkScreenInfo_Type);
25
26 self->screen = num;
27 self->root_window = RootWindow(OBDisplay->display, self->screen);
28 self->rect = (OtkRect*)
29 OtkRect_New(0, 0, WidthOfScreen(ScreenOfDisplay(OBDisplay->display,
30 self->screen)),
31 HeightOfScreen(ScreenOfDisplay(OBDisplay->display,
32 self->screen)));
33
34 /*
35 If the default depth is at least 8 we will use that,
36 otherwise we try to find the largest TrueColor visual.
37 Preference is given to 24 bit over larger depths if 24 bit is an option.
38 */
39
40 self->depth = DefaultDepth(OBDisplay->display, self->screen);
41 self->visual = DefaultVisual(OBDisplay->display, self->screen);
42 self->colormap = DefaultColormap(OBDisplay->display, self->screen);
43
44 if (self->depth < 8) {
45 // search for a TrueColor Visual... if we can't find one...
46 // we will use the default visual for the screen
47 XVisualInfo vinfo_template, *vinfo_return;
48 int vinfo_nitems;
49 int best = -1;
50
51 vinfo_template.screen = self->screen;
52 vinfo_template.class = TrueColor;
53
54 vinfo_return = XGetVisualInfo(OBDisplay->display,
55 VisualScreenMask | VisualClassMask,
56 &vinfo_template, &vinfo_nitems);
57 if (vinfo_return) {
58 int max_depth = 1;
59 for (i = 0; i < vinfo_nitems; ++i) {
60 if (vinfo_return[i].depth > max_depth) {
61 if (max_depth == 24 && vinfo_return[i].depth > 24)
62 break; // prefer 24 bit over 32
63 max_depth = vinfo_return[i].depth;
64 best = i;
65 }
66 }
67 if (max_depth < self->depth) best = -1;
68 }
69
70 if (best != -1) {
71 self->depth = vinfo_return[best].depth;
72 self->visual = vinfo_return[best].visual;
73 self->colormap = XCreateColormap(OBDisplay->display, self->root_window,
74 self->visual, AllocNone);
75 }
76
77 XFree(vinfo_return);
78 }
79
80 // get the default display string and strip the screen number
81 self->display_string = (PyStringObject*)
82 PyString_FromFormat("DISPLAY=%s",DisplayString(OBDisplay->display));
83 dstr = PyString_AsString((PyObject*)self->display_string);
84 dstr2 = strrchr(dstr, '.');
85 if (dstr2) {
86 PyObject *str;
87
88 _PyString_Resize((PyObject**)&self->display_string, dstr2 - dstr);
89 str = PyString_FromFormat(".%d", self->screen);
90 PyString_Concat((PyObject**)&self->display_string, str);
91 }
92
93 #ifdef XINERAMA
94 self->xinerama_active = False;
95
96 if (OtkDisplay->hasXineramaExtensions()) {
97 if (OtkDisplay->getXineramaMajorVersion() == 1) {
98 // we know the version 1(.1?) protocol
99
100 /*
101 in this version of Xinerama, we can't query on a per-screen basis, but
102 in future versions we should be able, so the 'activeness' is checked
103 on a pre-screen basis anyways.
104 */
105 if (XineramaIsActive(OBDisplay->display)) {
106 /*
107 If Xinerama is being used, there there is only going to be one screen
108 present. We still, of course, want to use the screen class, but that
109 is why no screen number is used in this function call. There should
110 never be more than one screen present with Xinerama active.
111 */
112 int num;
113 XineramaScreenInfo *info = XineramaQueryScreens(OBDisplay->display,
114 &num);
115 if (num > 0 && info) {
116 self->xinerama_areas = PyList_New(num);
117 for (i = 0; i < num; ++i) {
118 PyList_SetItem(self->xinerama_areas, i,
119 OtkRect_New(info[i].x_org, info[i].y_org,
120 info[i].width, info[i].height));
121 }
122 XFree(info);
123
124 // if we can't find any xinerama regions, then we act as if it is not
125 // active, even though it said it was
126 self->xinerama_active = True;
127 }
128 }
129 }
130 }
131 #endif // XINERAMA
132
133 return (PyObject*)self;
134 }
135
136
137
138 static PyObject *otkscreeninfo_getscreen(OtkScreenInfo* self, PyObject* args)
139 {
140 if (!PyArg_ParseTuple(args, ":getScreen"))
141 return NULL;
142 return PyInt_FromLong(self->screen);
143 }
144
145 static OtkRect *otkscreeninfo_getrect(OtkScreenInfo* self, PyObject* args)
146 {
147 if (!PyArg_ParseTuple(args, ":getRect"))
148 return NULL;
149 return self->rect;
150 }
151
152
153 static PyMethodDef get_methods[] = {
154 {"getScreen", (PyCFunction)otkscreeninfo_getscreen, METH_VARARGS,
155 "Get the screen number."},
156 {"getRect", (PyCFunction)otkscreeninfo_getrect, METH_VARARGS,
157 "Get the area taken up by the screen."},
158 {NULL, NULL, 0, NULL}
159 };
160
161
162
163 static void otkscreeninfo_dealloc(OtkScreenInfo* self)
164 {
165 Py_DECREF(self->display_string);
166 Py_DECREF(self->rect);
167 #ifdef XINERAMA
168 Py_DECREF(self->xinerama_areas);
169 #endif
170 PyObject_Del((PyObject*)self);
171 }
172
173 static PyObject *otkscreeninfo_getattr(PyObject *obj, char *name)
174 {
175 return Py_FindMethod(get_methods, obj, name);
176 }
177
178
179 PyTypeObject OtkScreenInfo_Type = {
180 PyObject_HEAD_INIT(NULL)
181 0,
182 "OtkScreenInfo",
183 sizeof(OtkScreenInfo),
184 0,
185 (destructor)otkscreeninfo_dealloc, /*tp_dealloc*/
186 0, /*tp_print*/
187 otkscreeninfo_getattr, /*tp_getattr*/
188 0, /*tp_setattr*/
189 0, /*tp_compare*/
190 0, /*tp_repr*/
191 0, /*tp_as_number*/
192 0, /*tp_as_sequence*/
193 0, /*tp_as_mapping*/
194 0, /*tp_hash */
195 };
This page took 0.040697 seconds and 3 git commands to generate.