1 // -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 #include "screeninfo.h"
14 #include "../src/gettext.h"
16 extern PyTypeObject OtkScreenInfo_Type
;
18 PyObject
*OtkScreenInfo_New(int num
)
24 self
= PyObject_New(OtkScreenInfo
, &OtkScreenInfo_Type
);
27 self
->root_window
= RootWindow(OBDisplay
->display
, self
->screen
);
28 self
->rect
= (OtkRect
*)
29 OtkRect_New(0, 0, WidthOfScreen(ScreenOfDisplay(OBDisplay
->display
,
31 HeightOfScreen(ScreenOfDisplay(OBDisplay
->display
,
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.
40 self
->depth
= DefaultDepth(OBDisplay
->display
, self
->screen
);
41 self
->visual
= DefaultVisual(OBDisplay
->display
, self
->screen
);
42 self
->colormap
= DefaultColormap(OBDisplay
->display
, self
->screen
);
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
;
51 vinfo_template
.screen
= self
->screen
;
52 vinfo_template
.class = TrueColor
;
54 vinfo_return
= XGetVisualInfo(OBDisplay
->display
,
55 VisualScreenMask
| VisualClassMask
,
56 &vinfo_template
, &vinfo_nitems
);
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
;
67 if (max_depth
< self
->depth
) 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
);
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
, '.');
88 _PyString_Resize((PyObject
**)&self
->display_string
, dstr2
- dstr
);
89 str
= PyString_FromFormat(".%d", self
->screen
);
90 PyString_Concat((PyObject
**)&self
->display_string
, str
);
94 self
->xinerama_active
= False
;
96 if (OtkDisplay
->hasXineramaExtensions()) {
97 if (OtkDisplay
->getXineramaMajorVersion() == 1) {
98 // we know the version 1(.1?) protocol
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.
105 if (XineramaIsActive(OBDisplay
->display
)) {
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.
113 XineramaScreenInfo
*info
= XineramaQueryScreens(OBDisplay
->display
,
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
));
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
;
133 return (PyObject
*)self
;
138 static PyObject
*otkscreeninfo_getscreen(OtkScreenInfo
* self
, PyObject
* args
)
140 if (!PyArg_ParseTuple(args
, ":getScreen"))
142 return PyInt_FromLong(self
->screen
);
145 static OtkRect
*otkscreeninfo_getrect(OtkScreenInfo
* self
, PyObject
* args
)
147 if (!PyArg_ParseTuple(args
, ":getRect"))
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
}
163 static void otkscreeninfo_dealloc(OtkScreenInfo
* self
)
165 Py_DECREF(self
->display_string
);
166 Py_DECREF(self
->rect
);
168 Py_DECREF(self
->xinerama_areas
);
170 PyObject_Del((PyObject
*)self
);
173 static PyObject
*otkscreeninfo_getattr(PyObject
*obj
, char *name
)
175 return Py_FindMethod(get_methods
, obj
, name
);
179 PyTypeObject OtkScreenInfo_Type
= {
180 PyObject_HEAD_INIT(NULL
)
183 sizeof(OtkScreenInfo
),
185 (destructor
)otkscreeninfo_dealloc
, /*tp_dealloc*/
187 otkscreeninfo_getattr
, /*tp_getattr*/
192 0, /*tp_as_sequence*/