]> Dogcows Code - chaz/openbox/commitdiff
add screeninfo
authorDana Jansens <danakj@orodu.net>
Fri, 20 Dec 2002 23:19:07 +0000 (23:19 +0000)
committerDana Jansens <danakj@orodu.net>
Fri, 20 Dec 2002 23:19:07 +0000 (23:19 +0000)
otk_c/Makefile
otk_c/display.c
otk_c/display.h
otk_c/rect.h [new file with mode: 0644]
otk_c/screeninfo.c [new file with mode: 0644]
otk_c/screeninfo.h [new file with mode: 0644]

index f84be3107bbbcb48d11124c452d84a5fc51e7760..28c1488a6e0defb9a5c984622833cfd428a76382 100644 (file)
@@ -3,8 +3,8 @@ exec_prefix=$(prefix)
 libdir=$(exec_prefix)/lib
 
 targets = libotk.so libotk.a
-sources = display.c
-headers = display.h
+sources = display.c screeninfo.c
+headers = display.h screeninfo.h
 
 CFLAGS+=-I/usr/gwar/include/python2.2
 
index ab193437875acc075f747901e785fc6bce4c4c10..85965210e4fe9a6196f0b6bf855af889a837ad7e 100644 (file)
@@ -1,6 +1,8 @@
 // -*- mode: C; indent-tabs-mode: nil; -*-
 
+#include "../config.h"
 #include "display.h"
+#include "screeninfo.h"
 
 #include <X11/keysym.h>
 
@@ -118,7 +120,7 @@ line argument.\n\n"));
   // Get information on all the screens which are available.
   self->screenInfoList = PyList_New(ScreenCount(self->display));
   for (i = 0; i < ScreenCount(self->display); ++i)
-    PyList_Append(self->screenInfoList, OtkScreenInfo_New(i));
+    PyList_SetItem(self->screenInfoList, i, OtkScreenInfo_New(i));
 
   self->gccache = OtkGCCache_New(PyList_Size(self->screenInfoList));
   
index fd9b706fb76349aa143e4729d6450774d421a6bd..87574b761d147f5d9aea136565a790d8a62b0dde 100644 (file)
@@ -5,10 +5,13 @@
 #include <X11/Xlib.h>
 #include <Python.h>
 
-typedef OtkScreenInfo;
-typedef OtkGCCache;
+struct OtkScreenInfo;
+struct OtkGCCache;
+struct OtkDisplay;
 
-typedef struct {
+struct OtkDisplay *OBDisplay; // the global display XXX: move this to app.h and ob.h?
+
+typedef struct OtkDisplay {
   PyObject_HEAD
   
   //! The X display
@@ -41,7 +44,7 @@ typedef struct {
     @see BImageControl
     @see BTexture
   */
-  OtkGCCache *gccache;
+  struct OtkGCCache *gccache;
 } OtkDisplay;
 
 //! Creates a struct, opens the X display
diff --git a/otk_c/rect.h b/otk_c/rect.h
new file mode 100644 (file)
index 0000000..4d08828
--- /dev/null
@@ -0,0 +1,5 @@
+typedef struct {
+  int x, y, width, height;
+} OtkRect;
+
+PyObject *OtkRect_New(int x, int y, int width, int height);
diff --git a/otk_c/screeninfo.c b/otk_c/screeninfo.c
new file mode 100644 (file)
index 0000000..0153d7f
--- /dev/null
@@ -0,0 +1,195 @@
+// -*- mode: C; indent-tabs-mode: nil; -*-
+
+#include "../config.h"
+#include "screeninfo.h"
+#include "display.h"
+#include "rect.h"
+
+#include <X11/Xutil.h>
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#include "../src/gettext.h"
+
+extern PyTypeObject OtkScreenInfo_Type;
+
+PyObject *OtkScreenInfo_New(int num)
+{
+  OtkScreenInfo* self;
+  char *dstr, *dstr2;
+  int i;
+
+  self = PyObject_New(OtkScreenInfo, &OtkScreenInfo_Type);
+
+  self->screen = num;
+  self->root_window = RootWindow(OBDisplay->display, self->screen);
+  self->rect = OtkRect_New(0, 0,
+                          WidthOfScreen(ScreenOfDisplay(OBDisplay->display,
+                                                        self->screen)),
+                          HeightOfScreen(ScreenOfDisplay(OBDisplay->display,
+                                                         self->screen)));
+  
+  /*
+    If the default depth is at least 8 we will use that,
+    otherwise we try to find the largest TrueColor visual.
+    Preference is given to 24 bit over larger depths if 24 bit is an option.
+  */
+
+  self->depth = DefaultDepth(OBDisplay->display, self->screen);
+  self->visual = DefaultVisual(OBDisplay->display, self->screen);
+  self->colormap = DefaultColormap(OBDisplay->display, self->screen);
+  
+  if (self->depth < 8) {
+    // search for a TrueColor Visual... if we can't find one...
+    // we will use the default visual for the screen
+    XVisualInfo vinfo_template, *vinfo_return;
+    int vinfo_nitems;
+    int best = -1;
+
+    vinfo_template.screen = self->screen;
+    vinfo_template.class = TrueColor;
+
+    vinfo_return = XGetVisualInfo(OBDisplay->display,
+                                  VisualScreenMask | VisualClassMask,
+                                  &vinfo_template, &vinfo_nitems);
+    if (vinfo_return) {
+      int max_depth = 1;
+      for (i = 0; i < vinfo_nitems; ++i) {
+        if (vinfo_return[i].depth > max_depth) {
+          if (max_depth == 24 && vinfo_return[i].depth > 24)
+            break;          // prefer 24 bit over 32
+          max_depth = vinfo_return[i].depth;
+          best = i;
+        }
+      }
+      if (max_depth < self->depth) best = -1;
+    }
+
+    if (best != -1) {
+      self->depth = vinfo_return[best].depth;
+      self->visual = vinfo_return[best].visual;
+      self->colormap = XCreateColormap(OBDisplay->display, self->root_window,
+                                      self->visual, AllocNone);
+    }
+
+    XFree(vinfo_return);
+  }
+
+  // get the default display string and strip the screen number
+  self->display_string =
+    PyString_FromFormat("DISPLAY=%s",DisplayString(OBDisplay->display));
+  dstr = PyString_AsString(self->display_string);
+  dstr2 = strrchr(dstr, '.');
+  if (dstr2) {
+    PyObject *str;
+    
+    PyString_Resize(self->display_string, dstr2 - dstr);
+    str = PyString_FromFormat(".%d", self->screen);
+    PyString_Concat(&self->display_string, str);
+  }
+
+#ifdef    XINERAMA
+  self->xinerama_active = False;
+
+  if (OtkDisplay->hasXineramaExtensions()) {
+    if (OtkDisplay->getXineramaMajorVersion() == 1) {
+      // we know the version 1(.1?) protocol
+
+      /*
+        in this version of Xinerama, we can't query on a per-screen basis, but
+        in future versions we should be able, so the 'activeness' is checked
+        on a pre-screen basis anyways.
+      */
+      if (XineramaIsActive(OBDisplay->display)) {
+        /*
+          If Xinerama is being used, there there is only going to be one screen
+          present. We still, of course, want to use the screen class, but that
+          is why no screen number is used in this function call. There should
+          never be more than one screen present with Xinerama active.
+        */
+        int num;
+        XineramaScreenInfo *info = XineramaQueryScreens(OBDisplay->display,
+                                                        &num);
+        if (num > 0 && info) {
+         self->xinerama_areas = PyList_New(num);
+          for (i = 0; i < num; ++i) {
+           PyList_SetItem(self->xinerama_areas, i,
+                          OtkRect_New(info[i].x_org, info[i].y_org,
+                                      info[i].width, info[i].height));
+          }
+          XFree(info);
+
+          // if we can't find any xinerama regions, then we act as if it is not
+          // active, even though it said it was
+          self->xinerama_active = True;
+        }
+      }
+    }
+  }
+#endif // XINERAMA
+    
+  return (PyObject*)self;
+}
+
+
+
+static PyObject *otkscreeninfo_getscreen(OtkScreenInfo* self, PyObject* args)
+{
+  if (!PyArg_ParseTuple(args, ":getScreen"))
+    return NULL;
+  return PyInt_FromLong(self->screen);
+}
+
+static PyObject *otkscreeninfo_getrect(OtkScreenInfo* self, PyObject* args)
+{
+  if (!PyArg_ParseTuple(args, ":getRect"))
+    return NULL;
+  return self->rect;
+}
+
+
+static PyMethodDef get_methods[] = {
+  {"getScreen", (PyCFunction)otkscreeninfo_getscreen, METH_VARARGS,
+   "Get the screen number."},
+  {"getRect", (PyCFunction)otkscreeninfo_getrect, METH_VARARGS,
+   "Get the area taken up by the screen."},
+  {NULL, NULL, 0, NULL}
+};
+
+
+
+static void otkscreeninfo_dealloc(PyObject* self)
+{
+  PyObject_Del(((OtkScreenInfo*) self)->display_string);
+  PyObject_Del(((OtkScreenInfo*) self)->rect);
+#ifdef XINERAMA
+  PyObject_Del(((OtkScreenInfo*) self)->xinerama_areas);
+#endif
+  PyObject_Del(self);
+}
+
+static PyObject *otkscreeninfo_getattr(PyObject *obj, char *name)
+{
+  return Py_FindMethod(get_methods, obj, name);
+}
+
+
+PyTypeObject OtkScreenInfo_Type = {
+  PyObject_HEAD_INIT(NULL)
+  0,
+  "OtkScreenInfo",
+  sizeof(OtkScreenInfo),
+  0,
+  otkscreeninfo_dealloc, /*tp_dealloc*/
+  0,          /*tp_print*/
+  otkscreeninfo_getattr, /*tp_getattr*/
+  0,          /*tp_setattr*/
+  0,          /*tp_compare*/
+  0,          /*tp_repr*/
+  0,          /*tp_as_number*/
+  0,          /*tp_as_sequence*/
+  0,          /*tp_as_mapping*/
+  0,          /*tp_hash */
+};
diff --git a/otk_c/screeninfo.h b/otk_c/screeninfo.h
new file mode 100644 (file)
index 0000000..5114a37
--- /dev/null
@@ -0,0 +1,31 @@
+// -*- mode: C; indent-tabs-mode: nil; -*-
+#ifndef   __screeninfo_h
+#define   __screeninfo_h
+
+#include <X11/Xlib.h>
+#include <Python.h>
+
+typedef struct OtkScreenInfo {
+  int screen;
+  Window root_window;
+
+  int depth;
+  Visual *visual;
+  Colormap colormap;
+
+  PyObject *display_string; // PyStringObject
+  PyObject *rect; // OtkRect
+#ifdef XINERAMA
+  PyObject *xinerama_areas; // PyListObject[OtkRect]
+  Bool xinerama_active;
+#endif
+} OtkScreenInfo;
+
+//! Creates an OtkScreenInfo for a screen
+/*!
+  @param num The number of the screen on the display for which to fill the
+             struct with information. Must be a value >= 0.
+*/
+PyObject *OtkScreenInfo_New(int num);
+
+#endif // __screeninfo_h
This page took 0.031771 seconds and 4 git commands to generate.