+++ /dev/null
-prefix = /tmp/ob
-exec_prefix = $(prefix)
-libdir = $(exec_prefix)/lib
-
-targets = libotk.so libotk.a
-sources = init.c display.c screeninfo.c rect.c gccache.c color.c font.c \
- timer.c timerqueue.c imagecontrol.c
-headers = init.h display.h screeninfo.h rect.h gccache.h color.h font.h \
- timer.h timerqueue.h imagecontrol.h
-
-CFLAGS += -g -W -Wall -I/usr/gwar/include/python2.2 `pkg-config --cflags xft`
-LDFLAGS += `pkg-config --libs xft`
-
-.PHONY: all install clean
-
-all: $(targets)
-
-install: $(targets)
- install -d $(libdir)
- install $^ $(libdir)
-
-clean:
- $(RM) $(targets) *.o core *\~ .\#*
-
-libotk.so: $(sources:.c=.o)
- $(CC) -shared -o $@ $^ $(LDFLAGS)
-
-libotk.a: $(sources:.c=.o)
- $(AR) -cr $@ $^
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "color.h"
-#include "display.h"
-#include "screeninfo.h"
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-static Bool cleancache = False;
-static PyObject *colorcache = NULL;
-
-static void parseColorName(OtkColor *self, const char *name) {
- XColor xcol;
-
- // get rgb values from colorname
- xcol.red = 0;
- xcol.green = 0;
- xcol.blue = 0;
- xcol.pixel = 0;
-
- if (!XParseColor(OBDisplay->display,
- OtkDisplay_ScreenInfo(OBDisplay, self->screen)->colormap,
- name, &xcol)) {
- fprintf(stderr, "OtkColor: color parse error: \"%s\"\n", name);
- self->red = self->green = self->blue = 0;
- } else {
- self->red = xcol.red >> 8;
- self->green = xcol.green >> 8;
- self->blue = xcol.blue >> 8;
- }
-}
-
-static void doCacheCleanup() {
- unsigned long *pixels;
- int i, ppos;
- unsigned int count;
- PyObject *key; // this is a color too, but i dont need to use it as such
- OtkColor *color;
-
- // ### TODO - support multiple displays!
- if (!PyDict_Size(colorcache)) return; // nothing to do
-
- pixels = malloc(sizeof(unsigned long) * PyDict_Size(colorcache));
-
- for (i = 0; i < ScreenCount(OBDisplay->display); i++) {
- count = 0;
- ppos = 0;
-
- while (PyDict_Next(colorcache, &ppos, &key, (PyObject**)&color)) {
- // get the screen from the hash
- if (color->screen != i) continue; // wrong screen
-
- // does someone other than the cache have a reference? (the cache gets 2)
- if (color->ob_refcnt > 2)
- continue;
-
- pixels[count++] = color->pixel;
- PyDict_DelItem(colorcache, key);
- --ppos; // back up one in the iteration
- }
-
- if (count > 0)
- XFreeColors(OBDisplay->display,
- OtkDisplay_ScreenInfo(OBDisplay, i)->colormap,
- pixels, count, 0);
- }
-
- free(pixels);
- cleancache = False;
-}
-
-static void allocate(OtkColor *self) {
- XColor xcol;
-
- // allocate color from rgb values
- xcol.red = self->red | self->red << 8;
- xcol.green = self->green | self->green << 8;
- xcol.blue = self->blue | self->blue << 8;
- xcol.pixel = 0;
-
- if (!XAllocColor(OBDisplay->display,
- OtkDisplay_ScreenInfo(OBDisplay, self->screen)->colormap,
- &xcol)) {
- fprintf(stderr, "OtkColor: color alloc error: rgb:%x/%x/%x\n",
- self->red, self->green, self->blue);
- xcol.pixel = 0;
- }
-
- self->pixel = xcol.pixel;
-
- if (cleancache)
- doCacheCleanup();
-}
-
-PyObject *OtkColor_FromRGB(int r, int g, int b, int screen)
-{
- OtkColor *self = PyObject_New(OtkColor, &OtkColor_Type);
- PyObject *cached;
-
- assert(screen >= 0); assert(r >= 0); assert(g >= 0); assert(b >= 0);
- assert(r <= 0xff); assert(g <= 0xff); assert(b <= 0xff);
-
- if (!colorcache) colorcache = PyDict_New();
-
- self->red = r;
- self->green = g;
- self->blue = b;
- self->screen = screen;
-
- // does this color already exist in the cache?
- cached = PyDict_GetItem(colorcache, (PyObject*)self);
- if (cached) {
- Py_INCREF(cached);
- return cached;
- }
-
- // add it to the cache
- PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
- allocate(self);
- return (PyObject*)self;
-}
-
-PyObject *OtkColor_FromName(const char *name, int screen)
-{
- OtkColor *self = PyObject_New(OtkColor, &OtkColor_Type);
- PyObject *cached;
-
- assert(screen >= 0); assert(name);
-
- if (!colorcache) colorcache = PyDict_New();
-
- self->red = -1;
- self->green = -1;
- self->blue = -1;
- self->screen = screen;
-
- parseColorName(self, name);
-
- // does this color already exist in the cache?
- cached = PyDict_GetItem(colorcache, (PyObject*)self);
- if (cached) {
- Py_INCREF(cached);
- return cached;
- }
-
- // add it to the cache
- PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
- allocate(self);
- return (PyObject*)self;
-}
-
-void OtkColor_CleanupColorCache()
-{
- cleancache = True;
-}
-
-
-
-static void otkcolor_dealloc(OtkColor* self)
-{
- // when this is called, the color has already been cleaned out of the cache
- PyObject_Del((PyObject*)self);
-}
-
-static int otkcolor_compare(OtkColor *c1, OtkColor *c2)
-{
- long result;
- unsigned long p1, p2;
-
- p1 = c1->red << 16 | c1->green << 8 | c1->blue;
- p2 = c2->red << 16 | c2->green << 8 | c2->blue;
-
- if (p1 < p2)
- result = -1;
- else if (p1 > p2)
- result = 1;
- else
- result = 0;
- return result;
-}
-
-static PyObject *otkcolor_repr(OtkColor *self)
-{
- return PyString_FromFormat("rgb:%x/%x/%x", self->red, self->green,
- self->blue);
-}
-
-static long otkcolor_hash(OtkColor *self)
-{
- return self->screen << 24 | self->red << 16 | self->green << 8 | self->blue;
-}
-
-PyTypeObject OtkColor_Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "OtkColor",
- sizeof(OtkColor),
- 0,
- (destructor)otkcolor_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- (cmpfunc)otkcolor_compare, /*tp_compare*/
- (reprfunc)otkcolor_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)otkcolor_hash, /*tp_hash */
-};
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __color_h
-#define __color_h
-
-#include <X11/Xlib.h>
-#include <Python.h>
-
-extern PyTypeObject OtkColor_Type;
-
-//! OtkColor objects are immutable. DONT CHANGE THEM.
-typedef struct OtkColor {
- PyObject_HEAD
- int red, green, blue;
- int screen;
- unsigned long pixel;
-} OtkColor;
-
-PyObject *OtkColor_FromRGB(int r, int g, int b, int screen);
-PyObject *OtkColor_FromName(const char *name, int screen);
-
-void OtkColor_CleanupColorCache();
-
-#endif // __color_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "display.h"
-#include "screeninfo.h"
-
-#include <X11/keysym.h>
-
-#ifdef SHAPE
-#include <X11/extensions/shape.h>
-#endif // SHAPE
-
-#ifdef HAVE_STDIO_H
-# include <stdio.h>
-#endif // HAVE_STDIO_H
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif // HAVE_STDLIB_H
-
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif // HAVE_FCNTL_H
-
-#ifdef HAVE_UNISTD_H
-# include <sys/types.h>
-# include <unistd.h>
-#endif // HAVE_UNISTD_H
-
-#include "../src/gettext.h"
-
-extern PyTypeObject OtkDisplay_Type;
-
-static int xerrorHandler(Display *d, XErrorEvent *e);
-
-struct OtkDisplay *OBDisplay = NULL;
-
-void OtkDisplay_Initialize(char *name)
-{
- OtkDisplay* self;
- PyObject *disp_env;
- XModifierKeymap *modmap;
- unsigned int NumLockMask = 0, ScrollLockMask = 0;
- size_t cnt;
- int i;
- int junk;
- (void) junk;
-
- self = PyObject_New(OtkDisplay, &OtkDisplay_Type);
-
- // Open the X display
- if (!(self->display = XOpenDisplay(name))) {
- printf(_("Unable to open connection to the X server. Please set the \n\
-DISPLAY environment variable approriately, or use the '-display' command \n\
-line argument.\n\n"));
- exit(1);
- }
- if (fcntl(ConnectionNumber(self->display), F_SETFD, 1) == -1) {
- printf(_("Couldn't mark display connection as close-on-exec.\n\n"));
- exit(1);
- }
-
- XSetErrorHandler(xerrorHandler);
-
- // set the DISPLAY environment variable for any lauched children, to the
- // display we're using, so they open in the right place.
- disp_env = PyString_FromFormat("DISPLAY=%s", DisplayString(self->display));
- if (putenv(PyString_AsString(disp_env))) {
- printf(_("warning: couldn't set environment variable 'DISPLAY'\n"));
- perror("putenv()");
- }
- Py_DECREF(disp_env);
-
- // find the availability of X extensions we like to use
-#ifdef SHAPE
- self->shape = XShapeQueryExtension(self->display,
- &self->shape_event_basep, &junk);
-#endif
-
-#ifdef XINERAMA
- self->xinerama = XineramaQueryExtension(self->display,
- &self->xinerama_event_basep, &junk);
-#endif // XINERAMA
-
- // get lock masks that are defined by the display (not constant)
- modmap = XGetModifierMapping(self->display);
- if (modmap && modmap->max_keypermod > 0) {
- const int mask_table[] = {
- ShiftMask, LockMask, ControlMask, Mod1Mask,
- Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
- };
- const size_t size = (sizeof(mask_table) / sizeof(mask_table[0])) *
- modmap->max_keypermod;
- // get the values of the keyboard lock modifiers
- // Note: Caps lock is not retrieved the same way as Scroll and Num lock
- // since it doesn't need to be.
- const KeyCode num_lock = XKeysymToKeycode(self->display, XK_Num_Lock);
- const KeyCode scroll_lock = XKeysymToKeycode(self->display,
- XK_Scroll_Lock);
-
- for (cnt = 0; cnt < size; ++cnt) {
- if (! modmap->modifiermap[cnt]) continue;
-
- if (num_lock == modmap->modifiermap[cnt])
- NumLockMask = mask_table[cnt / modmap->max_keypermod];
- if (scroll_lock == modmap->modifiermap[cnt])
- ScrollLockMask = mask_table[cnt / modmap->max_keypermod];
- }
- }
-
- if (modmap) XFreeModifiermap(modmap);
-
- self->mask_list[0] = 0;
- self->mask_list[1] = LockMask;
- self->mask_list[2] = NumLockMask;
- self->mask_list[3] = LockMask | NumLockMask;
- self->mask_list[4] = ScrollLockMask;
- self->mask_list[5] = ScrollLockMask | LockMask;
- self->mask_list[6] = ScrollLockMask | NumLockMask;
- self->mask_list[7] = ScrollLockMask | LockMask | NumLockMask;
-
- // set the global var, for the new screeninfo's
- OBDisplay = self;
-
- // Get information on all the screens which are available.
- self->screenInfoList = (PyListObject*)PyList_New(ScreenCount(self->display));
- for (i = 0; i < ScreenCount(self->display); ++i)
- PyList_SetItem((PyObject*)self->screenInfoList, i, OtkScreenInfo_New(i));
-
- Py_INCREF(OBDisplay); // make sure it stays around!!
-}
-
-void OtkDisplay_Grab(OtkDisplay *self)
-{
- assert(self);
- if (self->grab_count == 0)
- XGrabServer(self->display);
- self->grab_count++;
-}
-
-void OtkDisplay_Ungrab(OtkDisplay *self)
-{
- if (self->grab_count == 0) return;
- self->grab_count--;
- if (self->grab_count == 0)
- XUngrabServer(self->display);
-}
-
-OtkScreenInfo *OtkDisplay_ScreenInfo(OtkDisplay *self, int num)
-{
- assert(num >= 0);
- return (OtkScreenInfo*)PyList_GetItem((PyObject*)self->screenInfoList, num);
-}
-
-
-static PyObject *otkdisplay_grab(OtkDisplay* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":grab"))
- return NULL;
- OtkDisplay_Grab(self);
- return Py_None;
-}
-
-static PyObject *otkdisplay_ungrab(OtkDisplay* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":ungrab"))
- return NULL;
- OtkDisplay_Ungrab(self);
- return Py_None;
-}
-
-static PyMethodDef get_methods[] = {
- {"grab", (PyCFunction)otkdisplay_grab, METH_VARARGS,
- "Grab the X display."},
- {"ungrab", (PyCFunction)otkdisplay_ungrab, METH_VARARGS,
- "Ungrab/Release the X display."},
- {NULL, NULL, 0, NULL}
-};
-
-
-
-static void otkdisplay_dealloc(PyObject* self)
-{
- XCloseDisplay(((OtkDisplay*) self)->display);
- Py_DECREF(((OtkDisplay*) self)->screenInfoList);
- PyObject_Del(self);
-}
-
-static PyObject *otkdisplay_getattr(PyObject *obj, char *name)
-{
- return Py_FindMethod(get_methods, obj, name);
-}
-
-
-PyTypeObject OtkDisplay_Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "OtkDisplay",
- sizeof(OtkDisplay),
- 0,
- otkdisplay_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- otkdisplay_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 */
-};
-
-
-static int xerrorHandler(Display *d, XErrorEvent *e)
-{
-#ifdef DEBUG
- char errtxt[128];
-
- //if (e->error_code != BadWindow)
- {
- XGetErrorText(d, e->error_code, errtxt, 128);
- printf("X Error: %s\n", errtxt);
- }
-#else
- (void)d;
- (void)e;
-#endif
-
- return False;
-}
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __display_h
-#define __display_h
-
-#include <X11/Xlib.h>
-#include <Python.h>
-
-struct OtkScreenInfo;
-struct OtkDisplay;
-
-extern struct OtkDisplay *OBDisplay; // the global display XXX: move this to app.h and ob.h?
-
-extern PyTypeObject OtkDisplay_Type;
-
-typedef struct OtkDisplay {
- PyObject_HEAD
-
- //! The X display
- Display *display;
-
- //! Does the display have the Shape extention?
- Bool shape;
- //! Base for events for the Shape extention
- int shape_event_basep;
-
- //! Does the display have the Xinerama extention?
- Bool xinerama;
- //! Base for events for the Xinerama extention
- int xinerama_event_basep;
-
- //! A list of all possible combinations of keyboard lock masks
- unsigned int mask_list[8];
-
- //! The number of requested grabs on the display
- int grab_count;
-
- //! A list of information for all screens on the display
- PyListObject *screenInfoList;
-} OtkDisplay;
-
-//! Opens the X display, and sets the global OBDisplay variable
-/*!
- @see OBDisplay::display
- @param name The name of the X display to open. If it is null, the DISPLAY
- environment variable is used instead.
-*/
-void OtkDisplay_Initialize(char *name);
-
-//! Grabs the display
-void OtkDisplay_Grab(OtkDisplay *self);
-
-//! Ungrabs the display
-void OtkDisplay_Ungrab(OtkDisplay *self);
-
-//! Get the screen info for a specific screen
-struct OtkScreenInfo *OtkDisplay_ScreenInfo(OtkDisplay *self, int num);
-
-#endif // __display_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "font.h"
-#include "display.h"
-#include "color.h"
-
-#include "../src/gettext.h"
-
-static Bool xft_init = False;
-static const char *fallback = "fixed";
-
-void OtkFont_Initialize()
-{
- if (!XftInit(0)) {
- printf(_("Couldn't initialize Xft version %d.%d.%d.\n\n"),
- XFT_MAJOR, XFT_MINOR, XFT_REVISION);
- exit(3);
- }
- printf(_("Using Xft %d.%d.%d.\n"), XFT_MAJOR, XFT_MINOR, XFT_REVISION);
- xft_init = True;
-}
-
-PyObject *OtkFont_New(int screen, const char *fontstring, Bool shadow,
- unsigned char offset, unsigned char tint)
-{
- OtkFont *self = PyObject_New(OtkFont, &OtkFont_Type);
-
- assert(xft_init);
- assert(screen >= 0);
- assert(fontstring);
-
- self->screen = screen;
- self->shadow = shadow;
- self->offset = offset;
- self->tint = tint;
-
- if (!(self->xftfont = XftFontOpenName(OBDisplay->display, screen,
- fontstring))) {
- printf(_("Unable to load font: %s"), fontstring);
- printf(_("Trying fallback font: %s\n"), fallback);
- if (!(self->xftfont =
- XftFontOpenName(OBDisplay->display, screen, fallback))) {
- printf(_("Unable to load font: %s"), fallback);
- printf(_("Aborting!.\n"));
-
- exit(3); // can't continue without a font
- }
- }
-
- return (PyObject*)self;
-}
-
-int OtkFont_MeasureString(OtkFont *self, const char *string)//, Bool utf8)
-{
- XGlyphInfo info;
-
-/* if (utf8)*/
- XftTextExtentsUtf8(OBDisplay->display, self->xftfont,
- (const FcChar8*)string, strlen(string), &info);
-/* else
- XftTextExtents8(OBDisplay->display, self->xftfont,
- (const FcChar8*)string, strlen(string), &info);*/
-
- return info.xOff + (self->shadow ? self->offset : 0);
-}
-
-void OtkFont_DrawString(OtkFont *self, XftDraw *d, int x, int y,
- OtkColor *color, const char *string)//, Bool utf8)
-{
- assert(self);
- assert(d);
-
- if (self->shadow) {
- XftColor c;
- c.color.red = 0;
- c.color.green = 0;
- c.color.blue = 0;
- c.color.alpha = self->tint | self->tint << 8; // transparent shadow
- c.pixel = BlackPixel(OBDisplay->display, self->screen);
-
-/* if (utf8)*/
- XftDrawStringUtf8(d, &c, self->xftfont, x + self->offset,
- self->xftfont->ascent + y + self->offset,
- (const FcChar8*)string, strlen(string));
-/* else
- XftDrawString8(d, &c, self->xftfont, x + self->offset,
- self->xftfont->ascent + y + self->offset,
- (const FcChar8*)string, strlen(string));*/
- }
-
- XftColor c;
- c.color.red = color->red | color->red << 8;
- c.color.green = color->green | color->green << 8;
- c.color.blue = color->blue | color->blue << 8;
- c.pixel = color->pixel;
- c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet
-
-/* if (utf8)*/
- XftDrawStringUtf8(d, &c, self->xftfont, x, self->xftfont->ascent + y,
- (const FcChar8*)string, strlen(string));
-/* else
- XftDrawString8(d, &c, self->xftfont, x, self->xftfont->ascent + y,
- (const FcChar8*)string, strlen(string));*/
-}
-
-
-
-
-static PyObject *otkfont_measurestring(OtkFont* self, PyObject* args)
-{
- char *s;
-
- if (!PyArg_ParseTuple(args, "s", &s))
- return NULL;
- return PyInt_FromLong(OtkFont_MeasureString(self, s));
-}
-
-static PyMethodDef get_methods[] = {
- {"measureString", (PyCFunction)otkfont_measurestring, METH_VARARGS,
- "Measure the length of a string with a font."},
- {NULL, NULL, 0, NULL}
-};
-
-
-static void otkfont_dealloc(OtkFont* self)
-{
- // this is always set. cuz if it failed.. the app would exit!
- XftFontClose(OBDisplay->display, self->xftfont);
- PyObject_Del((PyObject*)self);
-}
-
-static PyObject *otkfont_getattr(PyObject *obj, char *name)
-{
- return Py_FindMethod(get_methods, obj, name);
-}
-
-PyTypeObject OtkFont_Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "OtkFont",
- sizeof(OtkFont),
- 0,
- (destructor)otkfont_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- otkfont_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 */
-};
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __font_h
-#define __font_h
-
-#include <X11/Xlib.h>
-#define _XFT_NO_COMPAT_ // no Xft 1 API
-#include <X11/Xft/Xft.h>
-#include <Python.h>
-
-extern PyTypeObject OtkFont_Type;
-
-struct OtkColor;
-struct ScreenInfo;
-
-#define OTKFONTHEIGHT(font) (font->xftfont->height + \
- (font->shadow ? font->offset : 0))
-#define OTKFONTMAXCHARWIDTH(font) (font->xftfont->max_advance_width)
-
-typedef struct OtkFont {
- PyObject_HEAD
- int screen;
- Bool shadow;
- unsigned char offset;
- unsigned char tint;
- XftFont *xftfont;
-} OtkFont;
-
-void OtkFont_Initialize();
-
-PyObject *OtkFont_New(int screen, const char *fontstring, Bool shadow,
- unsigned char offset, unsigned char tint);
-
-int OtkFont_MeasureString(OtkFont *self, const char *string);//, Bool utf8);
-
-//! Draws a string into an XftDraw object
-/*!
- Be Warned: If you use an XftDraw object and a color, or a font from
- different screens, you WILL have unpredictable results! :)
-*/
-void OtkFont_DrawString(OtkFont *self, XftDraw *d, int x, int y,
- struct OtkColor *color, const char *string);//, Bool utf8);
-
-/*
- bool createXftFont(void);
-
-public:
- // loads an Xft font
- BFont(int screen_num, const std::string &fontstring, bool shadow,
- unsigned char offset, unsigned char tint);
- virtual ~BFont();
-
- inline const std::string &fontstring() const { return _fontstring; }
-
- unsigned int height() const;
- unsigned int maxCharWidth() const;
-
- unsigned int measureString(const std::string &string,
- bool utf8 = false) const;
-
-};
-
-}
-*/
-#endif // __font_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "gccache.h"
-#include "screeninfo.h"
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-static OtkGCCache *gccache = NULL;
-
-OtkGCCacheContext *OtkGCCacheContext_New()
-{
- OtkGCCacheContext *self = malloc(sizeof(OtkGCCacheContext));
-
- self->gc = 0;
- self->pixel = 0ul;
- self->fontid = 0ul;
- self->function = 0;
- self->subwindow = 0;
- self->used = False;
- self->screen = ~0;
- self->linewidth = 0;
-
- return self;
-}
-
-void OtkGCCacheContext_Destroy(OtkGCCacheContext *self)
-{
- if (self->gc)
- XFreeGC(OBDisplay->display, self->gc);
- free(self);
-}
-
-void OtkGCCacheContext_Set(OtkGCCacheContext *self,
- OtkColor *color, XFontStruct *font,
- int function, int subwindow, int linewidth)
-{
- XGCValues gcv;
- unsigned long mask;
-
- self->pixel = gcv.foreground = color->pixel;
- self->function = gcv.function = function;
- self->subwindow = gcv.subwindow_mode = subwindow;
- self->linewidth = gcv.line_width = linewidth;
- gcv.cap_style = CapProjecting;
-
- mask = GCForeground | GCFunction | GCSubwindowMode | GCLineWidth |
- GCCapStyle;
-
- if (font) {
- self->fontid = gcv.font = font->fid;
- mask |= GCFont;
- } else {
- self->fontid = 0;
- }
-
- XChangeGC(OBDisplay->display, self->gc, mask, &gcv);
-}
-
-void OtkGCCacheContext_SetFont(OtkGCCacheContext *self,
- XFontStruct *font)
-{
- if (!font) {
- self->fontid = 0;
- return;
- }
-
- XGCValues gcv;
- self->fontid = gcv.font = font->fid;
- XChangeGC(OBDisplay->display, self->gc, GCFont, &gcv);
-}
-
-
-OtkGCCacheItem *OtkGCCacheItem_New()
-{
- OtkGCCacheItem *self = malloc(sizeof(OtkGCCacheItem));
-
- self->ctx = 0;
- self->count = 0;
- self->hits = 0;
- self->fault = False;
-
- return self;
-}
-
-
-void OtkGCCache_Initialize()
-{
- unsigned int i;
-
- gccache = malloc(sizeof(OtkGCCache));
-
- gccache->context_count = 128;
- gccache->cache_size = 16;
- gccache->cache_buckets = 8 * ScreenCount(OBDisplay->display);
- gccache->cache_total_size = gccache->cache_size * gccache->cache_buckets;
-
- gccache->contexts = malloc(sizeof(OtkGCCacheContext*) *
- gccache->context_count);
- for (i = 0; i < gccache->context_count; ++i)
- gccache->contexts[i] = OtkGCCacheContext_New();
-
- gccache->cache = malloc(sizeof(OtkGCCacheItem*) * gccache->cache_total_size);
- for (i = 0; i < gccache->cache_total_size; ++i)
- gccache->cache[i] = OtkGCCacheItem_New();
-}
-
-
-/*void OtkGCCache_Destroy()
-{
- unsigned int i;
-
- for (i = 0; i < gccache->context_count; ++i)
- OtkGCCacheContext_Destroy(gccache->contexts[i]);
-
- for (i = 0; i < gccache->cache_total_size; ++i)
- free(gccache->cache[i]);
-
- free(gccache->contexts);
- free(gccache->cache);
- free(gccache);
- gccache = NULL;
-}*/
-
-static OtkGCCacheContext *nextContext(int screen)
-{
- Window hd = OtkDisplay_ScreenInfo(OBDisplay, screen)->root_window;
- OtkGCCacheContext *c;
- unsigned int i;
-
- for (i = 0; i < gccache->context_count; ++i) {
- c = gccache->contexts[i];
-
- if (! c->gc) {
- c->gc = XCreateGC(OBDisplay->display, hd, 0, 0);
- c->used = False;
- c->screen = screen;
- }
- if (! c->used && c->screen == screen)
- return c;
- }
-
- fprintf(stderr, "OtkGCCache: context fault!\n");
- abort();
- return NULL; // shut gcc up
-}
-
-
-static void OtkGCCache_InternalRelease(OtkGCCacheContext *ctx)
-{
- ctx->used = False;
-}
-
-OtkGCCacheItem *OtkGCCache_Find(OtkColor *color, XFontStruct *font,
- int function, int subwindow, int linewidth)
-{
- const unsigned long pixel = color->pixel;
- const int screen = color->screen;
- const int key = color->red ^ color->green ^ color->blue;
- int k = (key % gccache->cache_size) * gccache->cache_buckets;
- unsigned int i = 0; // loop variable
- OtkGCCacheItem *c = gccache->cache[k], *prev = 0;
-
- /*
- this will either loop cache_buckets times then return/abort or
- it will stop matching
- */
- while (c->ctx &&
- (c->ctx->pixel != pixel || c->ctx->function != function ||
- c->ctx->subwindow != subwindow || c->ctx->screen != screen ||
- c->ctx->linewidth != linewidth)) {
- if (i < (gccache->cache_buckets - 1)) {
- prev = c;
- c = gccache->cache[++k];
- ++i;
- continue;
- }
- if (c->count == 0 && c->ctx->screen == screen) {
- // use this cache item
- OtkGCCacheContext_Set(c->ctx, color, font, function, subwindow,
- linewidth);
- c->ctx->used = True;
- c->count = 1;
- c->hits = 1;
- return c;
- }
- // cache fault!
- fprintf(stderr, "OtkGCCache: cache fault, count: %d, screen: %d, item screen: %d\n", c->count, screen, c->ctx->screen);
- abort();
- }
-
- if (c->ctx) {
- // reuse existing context
- if (font && font->fid && font->fid != c->ctx->fontid)
- OtkGCCacheContext_SetFont(c->ctx, font);
- c->count++;
- c->hits++;
- if (prev && c->hits > prev->hits) {
- gccache->cache[k] = prev;
- gccache->cache[k-1] = c;
- }
- } else {
- c->ctx = nextContext(screen);
- OtkGCCacheContext_Set(c->ctx, color, font, function, subwindow, linewidth);
- c->ctx->used = True;
- c->count = 1;
- c->hits = 1;
- }
-
- return c;
-}
-
-
-void OtkGCCache_Release(OtkGCCacheItem *item)
-{
- item->count--;
-}
-
-
-void OtkGCCache_Purge()
-{
- unsigned int i;
-
- for (i = 0; i < gccache->cache_total_size; ++i) {
- OtkGCCacheItem *d = gccache->cache[i];
-
- if (d->ctx && d->count == 0) {
- OtkGCCache_InternalRelease(d->ctx);
- d->ctx = 0;
- }
- }
-}
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __gccache_h
-#define __gccache_h
-
-#include <X11/Xlib.h>
-
-#include "display.h"
-#include "color.h"
-
-struct OtkGCCacheItem;
-
-typedef struct OtkGCCacheContext {
- GC gc;
- unsigned long pixel;
- unsigned long fontid;
- int function;
- int subwindow;
- Bool used;
- int screen;
- int linewidth;
-} OtkGCCacheContext;
-
-OtkGCCacheContext *OtkGCCacheContext_New();
-void OtkGCCacheContext_Destroy(OtkGCCacheContext *self);
-
-void OtkGCCacheContext_Set(OtkGCCacheContext *self,
- OtkColor *color, XFontStruct *font,
- int function, int subwindow, int linewidth);
-void OtkGCCacheContext_SetFont(OtkGCCacheContext *self,
- XFontStruct *font);
-
-
-typedef struct OtkGCCacheItem {
- OtkGCCacheContext *ctx;
- unsigned int count;
- unsigned int hits;
- Bool fault;
-} OtkGCCacheItem;
-
-OtkGCCacheItem *OtkGCCacheItem_New();
-
-
-typedef struct OtkGCCache {
- // this is closely modelled after the Qt GC cache, but with some of the
- // complexity stripped out
- unsigned int context_count;
- unsigned int cache_size;
- unsigned int cache_buckets;
- unsigned int cache_total_size;
- OtkGCCacheContext **contexts;
- OtkGCCacheItem **cache;
-} OtkGCCache;
-
-void OtkGCCache_Initialize();
-//void OtkGCCache_Destroy();
-
-// cleans up the cache
-void OtkGCCache_Purge();
-
-OtkGCCacheItem *OtkGCCache_Find(OtkColor *color,
- XFontStruct *font, int function,
- int subwindow, int linewidth);
-void OtkGCCache_Release(OtkGCCacheItem *item);
-
-
-/*
-
-
-class BPen {
-public:
- inline BPen(const BColor &_color, const XFontStruct * const _font = 0,
- int _linewidth = 0, int _function = GXcopy,
- int _subwindow = ClipByChildren)
- : color(_color), font(_font), linewidth(_linewidth), function(_function),
- subwindow(_subwindow), cache(OBDisplay::gcCache()), item(0) { }
-
- inline ~BPen(void) { if (item) cache->release(item); }
-
- inline const GC &gc(void) const {
- if (! item) item = cache->find(color, font, function, subwindow,
- linewidth);
- return item->gc();
- }
-
-private:
- const BColor &color;
- const XFontStruct *font;
- int linewidth;
- int function;
- int subwindow;
-
- mutable BGCCache *cache;
- mutable BGCCacheItem *item;
-};
-
-}*/
-
-#endif // __gccache_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "imagecontrol.h"
-#include "timer.h"
-#include "screeninfo.h"
-#include "display.h"
-
-typedef struct CachedImage {
- Pixmap pixmap;
-
- unsigned int count, width, height;
- unsigned long pixel1, pixel2, texture;
-} CachedImage;
-
-static void timeout(OtkImageControl *self);
-static void initColors(OtkImageControl *self, Visual *visual);
-
-PyObject *OtkImageControl_New(int screen)
-{
- OtkImageControl *self;
- int count, i;
- XPixmapFormatValues *pmv;
-
- self = PyObject_New(OtkImageControl, &OtkImageControl_Type);
-
- self->screen = OtkDisplay_ScreenInfo(OBDisplay, screen);
-
- self->timer = (OtkTimer*)OtkTimer_New((OtkTimeoutHandler)timeout, self);
- self->timer->timeout = 300000;
- OtkTimer_Start(self->timer);
- self->cache_max = 200;
-
- self->dither = True; // default value
- self->cpc = 4; // default value
-
- // get the BPP from the X server
- self->bpp = 0;
- if ((pmv = XListPixmapFormats(OBDisplay->display, &count))) {
- for (i = 0; i < count; i++)
- if (pmv[i].depth == self->screen->depth) {
- self->bpp = pmv[i].bits_per_pixel;
- break;
- }
- XFree(pmv);
- }
- if (!self->bpp) self->bpp = self->screen->depth;
- if (self->bpp >= 24) self->dither = False; // don't need dither at >= 24 bpp
-
- self->grad_xbuffer = self->grad_ybuffer = NULL;
- self->grad_buffer_width = self->grad_buffer_height = 0;
- self->sqrt_table = NULL;
-
- initColors(self, self->screen->visual);
-
- return (PyObject*)self;
-}
-
-static void initColors(OtkImageControl *self, Visual *visual)
-{
- // these are not used for !TrueColor
- self->red_offset = self->green_offset = self->blue_offset = 0;
- // these are not used for TrueColor
- self->colors = NULL;
- self->ncolors = 0;
-
- // figure out all our color settings based on the visual type
- switch (visual->class) {
- case TrueColor: {
- int i;
- unsigned long red_mask, green_mask, blue_mask;
-
- // find the offsets for each color in the visual's masks
- red_mask = visual->red_mask;
- green_mask = visual->green_mask;
- blue_mask = visual->blue_mask;
-
- while (! (red_mask & 1)) { self->red_offset++; red_mask >>= 1; }
- while (! (green_mask & 1)) { self->green_offset++; green_mask >>= 1; }
- while (! (blue_mask & 1)) { self->blue_offset++; blue_mask >>= 1; }
-
- // use the mask to determine the number of bits for each shade of color
- // so, best case, red_mask == 0xff (255), and so each bit is a different
- // shade!
- self->red_bits = 255 / red_mask;
- self->green_bits = 255 / green_mask;
- self->blue_bits = 255 / blue_mask;
-
- // compute color tables, based on the number of bits for each shade
- for (i = 0; i < 256; i++) {
- self->red_color_table[i] = i / self->red_bits;
- self->green_color_table[i] = i / self->green_bits;
- self->blue_color_table[i] = i / self->blue_bits;
- }
- break;
- }
-/*
- case PseudoColor:
- case StaticColor: {
- ncolors = self->cpc * self->cpc * self->cpc; // cpc ^ 3
-
- if (ncolors > (1 << self->screen->depth)) {
- self->cpc = (1 << self->screen->depth) / 3;
- ncolors = self->cpc * self->cpc * self->cpc; // cpc ^ 3
- }
-
- if (self->cpc < 2 || self->ncolors > (1 << self->screen->depth)) {
- fprintf(stderr,
- "OtkImageControl_New: invalid colormap size %d "
- "(%d/%d/%d) - reducing",
- self->ncolors, self->cpc, self->cpc, self->cpc);
-
- self->cpc = (1 << self->screen->depth) / 3;
- }
-
- self->colors = malloc(sizeof(XColor) * self->ncolors);
- if (! self->colors) {
- fprintf(stderr, "OtkImageControl_New: error allocating colormap\n");
- exit(1);
- }
-
- int i = 0, ii, p, r, g, b,
- bits = 255 / (colors_per_channel - 1);
-
- red_bits = green_bits = blue_bits = bits;
-
- for (i = 0; i < 256; i++)
- red_color_table[i] = green_color_table[i] = blue_color_table[i] =
- i / bits;
-
- for (r = 0, i = 0; r < colors_per_channel; r++)
- for (g = 0; g < colors_per_channel; g++)
- for (b = 0; b < colors_per_channel; b++, i++) {
- colors[i].red = (r * 0xffff) / (colors_per_channel - 1);
- colors[i].green = (g * 0xffff) / (colors_per_channel - 1);
- colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);;
- colors[i].flags = DoRed|DoGreen|DoBlue;
- }
-
- for (i = 0; i < ncolors; i++) {
- if (! XAllocColor(OBDisplay::display, colormap, &colors[i])) {
- fprintf(stderr, "couldn't alloc color %i %i %i\n",
- colors[i].red, colors[i].green, colors[i].blue);
- colors[i].flags = 0;
- } else {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- }
- }
-
- XColor icolors[256];
- int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth));
-
- for (i = 0; i < incolors; i++)
- icolors[i].pixel = i;
-
- XQueryColors(OBDisplay::display, colormap, icolors, incolors);
- for (i = 0; i < ncolors; i++) {
- if (! colors[i].flags) {
- unsigned long chk = 0xffffffff, pixel, close = 0;
-
- p = 2;
- while (p--) {
- for (ii = 0; ii < incolors; ii++) {
- r = (colors[i].red - icolors[i].red) >> 8;
- g = (colors[i].green - icolors[i].green) >> 8;
- b = (colors[i].blue - icolors[i].blue) >> 8;
- pixel = (r * r) + (g * g) + (b * b);
-
- if (pixel < chk) {
- chk = pixel;
- close = ii;
- }
-
- colors[i].red = icolors[close].red;
- colors[i].green = icolors[close].green;
- colors[i].blue = icolors[close].blue;
-
- if (XAllocColor(OBDisplay::display, colormap,
- &colors[i])) {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- break;
- }
- }
- }
- }
- }
-
- break;
- }
-
- case GrayScale:
- case StaticGray: {
- if (visual->c_class == StaticGray) {
- ncolors = 1 << screen_depth;
- } else {
- ncolors = colors_per_channel * colors_per_channel * colors_per_channel;
-
- if (ncolors > (1 << screen_depth)) {
- colors_per_channel = (1 << screen_depth) / 3;
- ncolors =
- colors_per_channel * colors_per_channel * colors_per_channel;
- }
- }
-
- if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) {
- fprintf(stderr,
- "BImageControl::BImageControl: invalid colormap size %d "
- "(%d/%d/%d) - reducing",
- ncolors, colors_per_channel, colors_per_channel,
- colors_per_channel);
-
- colors_per_channel = (1 << screen_depth) / 3;
- }
-
- colors = new XColor[ncolors];
- if (! colors) {
- fprintf(stderr,
- "BImageControl::BImageControl: error allocating colormap\n");
- exit(1);
- }
-
- int i = 0, ii, p, bits = 255 / (colors_per_channel - 1);
- red_bits = green_bits = blue_bits = bits;
-
- for (i = 0; i < 256; i++)
- red_color_table[i] = green_color_table[i] = blue_color_table[i] =
- i / bits;
-
- for (i = 0; i < ncolors; i++) {
- colors[i].red = (i * 0xffff) / (colors_per_channel - 1);
- colors[i].green = (i * 0xffff) / (colors_per_channel - 1);
- colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);;
- colors[i].flags = DoRed|DoGreen|DoBlue;
-
- if (! XAllocColor(OBDisplay::display, colormap,
- &colors[i])) {
- fprintf(stderr, "couldn't alloc color %i %i %i\n",
- colors[i].red, colors[i].green, colors[i].blue);
- colors[i].flags = 0;
- } else {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- }
- }
-
- XColor icolors[256];
- int incolors = (((1 << screen_depth) > 256) ? 256 :
- (1 << screen_depth));
-
- for (i = 0; i < incolors; i++)
- icolors[i].pixel = i;
-
- XQueryColors(OBDisplay::display, colormap, icolors, incolors);
- for (i = 0; i < ncolors; i++) {
- if (! colors[i].flags) {
- unsigned long chk = 0xffffffff, pixel, close = 0;
-
- p = 2;
- while (p--) {
- for (ii = 0; ii < incolors; ii++) {
- int r = (colors[i].red - icolors[i].red) >> 8;
- int g = (colors[i].green - icolors[i].green) >> 8;
- int b = (colors[i].blue - icolors[i].blue) >> 8;
- pixel = (r * r) + (g * g) + (b * b);
-
- if (pixel < chk) {
- chk = pixel;
- close = ii;
- }
-
- colors[i].red = icolors[close].red;
- colors[i].green = icolors[close].green;
- colors[i].blue = icolors[close].blue;
-
- if (XAllocColor(OBDisplay::display, colormap,
- &colors[i])) {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- break;
- }
- }
- }
- }
- }
-
- break;
- }
-*/
- default:
- fprintf(stderr, "OtkImageControl: unsupported visual class: %d\n",
- visual->class);
- exit(1);
- }
-}
-
-
-static void timeout(OtkImageControl *self)
-{
- (void)self;
-}
-
-
-
-static void otkimagecontrol_dealloc(OtkImageControl* self)
-{
- Py_DECREF(self->screen);
- Py_DECREF(self->timer);
- PyObject_Del((PyObject*)self);
-}
-
-PyTypeObject OtkImageControl_Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "OtkImageControl",
- sizeof(OtkImageControl),
- 0,
- (destructor)otkimagecontrol_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*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 */
-};
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __imagecontrol_h
-#define __imagecontrol_h
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <Python.h>
-
-struct OtkScreenInfo;
-struct OtkTimer;
-
-extern PyTypeObject OtkImageControl_Type;
-
-typedef struct OtkImageControl {
- struct OtkScreenInfo *screen;
-
- // for the pixmap cache
- struct OtkTimer *timer;
- unsigned long cache_max;
-
- Bool dither;
-
- int cpc; // colors-per-channel: must be a value between [2,6]
- int bpp; // bits-per-pixel
-
- unsigned int *grad_xbuffer;
- unsigned int *grad_ybuffer;
- unsigned int grad_buffer_width;
- unsigned int grad_buffer_height;
-
- unsigned long *sqrt_table;
-
- // These values are all determined based on a visual
-
- int red_bits; // the number of bits (1-255) that each shade of color
- int green_bits; // spans across. best case is 1, which gives 255 shades.
- int blue_bits;
- unsigned char red_color_table[256];
- unsigned char green_color_table[256];
- unsigned char blue_color_table[256];
-
- // These are only used for TrueColor visuals
- int red_offset; // the offset of each color in a color mask
- int green_offset;
- int blue_offset;
-
- // These are only used for !TrueColor visuals
- XColor *colors;
- int ncolors;
-
-} OtkImageControl;
-
-PyObject *OtkImageControl_New(int screen);
-
-
-/*
- inline bool doDither(void) { return dither; }
-
- inline const ScreenInfo* getScreenInfo() const { return screeninfo; }
-
- inline Window getDrawable(void) const { return window; }
-
- inline Visual *getVisual(void) { return screeninfo->visual(); }
-
- inline int getBitsPerPixel(void) const { return bits_per_pixel; }
- inline int getDepth(void) const { return screen_depth; }
- inline int getColorsPerChannel(void) const
- { return colors_per_channel; }
-
- unsigned long getSqrt(unsigned int x);
-
- Pixmap renderImage(unsigned int width, unsigned int height,
- const BTexture &texture);
-
- void installRootColormap(void);
- void removeImage(Pixmap pixmap);
- void getColorTables(unsigned char **rmt, unsigned char **gmt,
- unsigned char **bmt,
- int *roff, int *goff, int *boff,
- int *rbit, int *gbit, int *bbit);
- void getXColorTable(XColor **c, int *n);
- void getGradientBuffers(unsigned int w, unsigned int h,
- unsigned int **xbuf, unsigned int **ybuf);
- void setDither(bool d) { dither = d; }
-
- static void timeout(BImageControl *t);
-
-private:
- bool dither;
- const ScreenInfo *screeninfo;
- OBTimer *timer;
-
- Colormap colormap;
-
- Window window;
- XColor *colors;
- int colors_per_channel, ncolors, screen_number, screen_depth,
- bits_per_pixel, red_offset, green_offset, blue_offset,
- red_bits, green_bits, blue_bits;
- unsigned char red_color_table[256], green_color_table[256],
- blue_color_table[256];
- unsigned int *grad_xbuffer, *grad_ybuffer, grad_buffer_width,
- grad_buffer_height;
- unsigned long *sqrt_table, cache_max;
-
- typedef std::list<CachedImage> CacheContainer;
- CacheContainer cache;
-
- Pixmap searchCache(const unsigned int width, const unsigned int height,
- const unsigned long texture,
- const BColor &c1, const BColor &c2);
-};
-*/
-
-#endif // __imagecontrol_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "display.h"
-#include "screeninfo.h"
-#include "color.h"
-#include "gccache.h"
-#include "font.h"
-#include "rect.h"
-#include "timer.h"
-#include "timerqueue.h"
-#include "imagecontrol.h"
-
-#include <X11/Xlib.h>
-#include <Python.h>
-
-static PyMethodDef otk_methods[] = {
-// {"new_noddy", noddy_new_noddy, METH_VARARGS,
-// "Create a new Noddy object."},
-
- {NULL, NULL, 0, NULL}
-};
-
-void initotk(char *display)
-{
- OtkRect_Type.ob_type = &PyType_Type;
- OtkDisplay_Type.ob_type = &PyType_Type;
- OtkScreenInfo_Type.ob_type = &PyType_Type;
- OtkColor_Type.ob_type = &PyType_Type;
- OtkFont_Type.ob_type = &PyType_Type;
- OtkTimer_Type.ob_type = &PyType_Type;
- OtkImageControl_Type.ob_type = &PyType_Type;
-
- Py_InitModule("otk", otk_methods);
-
- OtkTimerQueue_Initialize();
- OtkDisplay_Initialize(display);
- assert(OBDisplay);
- OtkGCCache_Initialize();
- OtkFont_Initialize();
-}
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __init_h
-#define __init_h
-
-void initotk(char *display);
-
-#endif // __init_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "rect.h"
-
-PyObject *OtkRect_New(int x, int y, int width, int height)
-{
- OtkRect* self = PyObject_New(OtkRect, &OtkRect_Type);
-
- self->x = x;
- self->y = y;
- self->width = width;
- self->height = height;
-
- return (PyObject*)self;
-}
-
-
-
-static PyObject *otkrect_getx(OtkRect *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ":getX"))
- return NULL;
- return PyInt_FromLong(self->x);
-}
-
-static PyObject *otkrect_gety(OtkRect *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ":getY"))
- return NULL;
- return PyInt_FromLong(self->y);
-}
-
-static PyObject *otkrect_getwidth(OtkRect *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ":getWidth"))
- return NULL;
- return PyInt_FromLong(self->width);
-}
-
-static PyObject *otkrect_getheight(OtkRect *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ":getHeight"))
- return NULL;
- return PyInt_FromLong(self->height);
-}
-
-
-static PyMethodDef get_methods[] = {
- {"getX", (PyCFunction)otkrect_getx, METH_VARARGS,
- "Get the X coordinate."},
- {"getY", (PyCFunction)otkrect_gety, METH_VARARGS,
- "Get the Y coordinate."},
- {"getWidth", (PyCFunction)otkrect_getwidth, METH_VARARGS,
- "Get the width."},
- {"getHeight", (PyCFunction)otkrect_getheight, METH_VARARGS,
- "Get the height."},
- {NULL, NULL, 0, NULL}
-};
-
-
-
-static void otkrect_dealloc(PyObject *self)
-{
- PyObject_Del(self);
-}
-
-static PyObject *otkrect_getattr(PyObject *obj, char *name)
-{
- return Py_FindMethod(get_methods, obj, name);
-}
-
-
-PyTypeObject OtkRect_Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "OtkRect",
- sizeof(OtkRect),
- 0,
- otkrect_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- otkrect_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 */
-};
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __rect_h
-#define __rect_h
-
-#include <Python.h>
-
-extern PyTypeObject OtkRect_Type;
-
-typedef struct OtkRect {
- PyObject_HEAD
- int x, y, width, height;
-} OtkRect;
-
-PyObject *OtkRect_New(int x, int y, int width, int height);
-
-#endif // __rect_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#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*)
- 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 = (PyStringObject*)
- PyString_FromFormat("DISPLAY=%s",DisplayString(OBDisplay->display));
- dstr = PyString_AsString((PyObject*)self->display_string);
- dstr2 = strrchr(dstr, '.');
- if (dstr2) {
- PyObject *str;
-
- _PyString_Resize((PyObject**)&self->display_string, dstr2 - dstr);
- str = PyString_FromFormat(".%d", self->screen);
- PyString_Concat((PyObject**)&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 OtkRect *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(OtkScreenInfo* self)
-{
- Py_DECREF(self->display_string);
- Py_DECREF(self->rect);
-#ifdef XINERAMA
- Py_DECREF(self->xinerama_areas);
-#endif
- PyObject_Del((PyObject*)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,
- (destructor)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 */
-};
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __screeninfo_h
-#define __screeninfo_h
-
-#include <X11/Xlib.h>
-#include <Python.h>
-
-extern PyTypeObject OtkScreenInfo_Type;
-
-struct OtkRect;
-
-typedef struct OtkScreenInfo {
- PyObject_HEAD
- int screen;
- Window root_window;
-
- int depth;
- Visual *visual;
- Colormap colormap;
-
- PyStringObject *display_string;
- struct OtkRect *rect; // OtkRect
-#ifdef XINERAMA
- PyListObject *xinerama_areas; // holds OtkRect's
- 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
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "timer.h"
-#include "timerqueue.h"
-
-PyObject *OtkTimer_New(OtkTimeoutHandler handler, OtkTimeoutData data)
-{
- OtkTimer *self = PyObject_New(OtkTimer, &OtkTimer_Type);
-
- assert(handler); assert(data);
- self->handler = handler;
- self->data = data;
- self->recur = self->timing = False;
-
- return (PyObject*)self;
-}
-
-void OtkTimer_Start(OtkTimer *self)
-{
- gettimeofday(&(self->start), 0);
-
- self->end.tv_sec = self->start.tv_sec + self->timeout / 1000;
- self->end.tv_usec = self->start.tv_usec + self->timeout % 1000 * 1000;
-
- if (! self->timing) {
- self->timing = True;
- OtkTimerQueue_Add(self);
- }
-}
-
-void OtkTimer_Stop(OtkTimer *self)
-{
- if (self->timing) {
- self->timing = False;
- OtkTimerQueue_Remove(self);
- }
-}
-
-
-
-
-
-static void otktimer_dealloc(OtkTimer* self)
-{
- OtkTimer_Stop(self);
- // when this is called, the color has already been cleaned out of the cache
- PyObject_Del((PyObject*)self);
-}
-
-static int otktimer_compare(OtkTimer *t1, OtkTimer *t2)
-{
- if (t1->end.tv_sec == t2->end.tv_sec && t1->end.tv_usec == t2->end.tv_usec)
- return 0;
- else if ((t1->end.tv_sec < t2->end.tv_sec) ||
- (t1->end.tv_sec == t2->end.tv_sec &&
- t1->end.tv_usec < t2->end.tv_usec))
- return -1;
- else
- return 1;
-}
-
-PyTypeObject OtkTimer_Type = {
- PyObject_HEAD_INIT(NULL)
- 0,
- "OtkTimer",
- sizeof(OtkTimer),
- 0,
- (destructor)otktimer_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- (cmpfunc)otktimer_compare, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
-};
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __timer_h
-#define __timer_h
-
-#include <X11/Xlib.h>
-#include <Python.h>
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else // !TIME_WITH_SYS_TIME
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else // !HAVE_SYS_TIME_H
-# include <time.h>
-# endif // HAVE_SYS_TIME_H
-#endif // TIME_WITH_SYS_TIME
-
-extern PyTypeObject OtkTimer_Type;
-
-//! The data passed to the OtkTimeoutHandler function.
-/*!
- Note: this is a very useful place to put an object instance, and set the
- event handler to a static function in the same class.
-*/
-typedef void *OtkTimeoutData;
-//! The type of function which can be set as the callback for an OtkTimer
-//! firing
-typedef void (*OtkTimeoutHandler)(OtkTimeoutData);
-
-typedef struct OtkTimer {
- PyObject_HEAD
- OtkTimeoutHandler handler;
- OtkTimeoutData data;
- Bool recur;
- long timeout;
-
- // don't edit these
- Bool timing;
- struct timeval start;
- struct timeval end;
-} OtkTimer;
-
-PyObject *OtkTimer_New(OtkTimeoutHandler handler, OtkTimeoutData data);
-
-//! Causes the timer to begin
-void OtkTimer_Start(OtkTimer *self);
-
-//! Causes the timer to stop
-void OtkTimer_Stop(OtkTimer *self);
-
-#endif // __timer_h
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-
-#include "../config.h"
-#include "timerqueue.h"
-#include "display.h"
-
-#include <X11/Xlib.h>
-#include <Python.h>
-
-static PyObject *list = NULL; // PyListObject
-
-void OtkTimerQueue_Initialize()
-{
- list = PyList_New(0);
-}
-
-void OtkTimerQueue_Add(OtkTimer* timer)
-{
- PyList_Append(list, (PyObject*)timer);
- PyList_Sort(list);
-}
-
-void OtkTimerQueue_Remove(OtkTimer* timer)
-{
- int index;
-
- index = PySequence_Index(list, (PyObject*)timer);
- if (index >= 0)
- PySequence_DelItem(list, index);
-}
-
-static Bool shouldFire(OtkTimer *timer, const struct timeval *now)
-{
- return ! ((now->tv_sec < timer->end.tv_sec) ||
- (now->tv_sec == timer->end.tv_sec &&
- now->tv_usec < timer->end.tv_usec));
-}
-
-static void normalizeTimeval(struct timeval *time)
-{
- while (time->tv_usec < 0) {
- if (time->tv_sec > 0) {
- --time->tv_sec;
- time->tv_usec += 1000000;
- } else {
- time->tv_usec = 0;
- }
- }
-
- if (time->tv_usec >= 1000000) {
- time->tv_sec += time->tv_usec / 1000000;
- time->tv_usec %= 1000000;
- }
-
- if (time->tv_sec < 0) time->tv_sec = 0;
-}
-
-void OtkTimerQueue_Fire()
-{
- fd_set rfds;
- struct timeval now, tm, *timeout = NULL;
-
- const int xfd = ConnectionNumber(OBDisplay->display);
-
- FD_ZERO(&rfds);
- FD_SET(xfd, &rfds); // break on any x events
-
- // check for timer timeout
- gettimeofday(&now, 0);
-
- // there is a small chance for deadlock here:
- // *IF* the timer list keeps getting refreshed *AND* the time between
- // timer->start() and timer->shouldFire() is within the timer's period
- // then the timer will keep firing. This should be VERY near impossible.
- while (PyList_Size(list)) {
- OtkTimer *timer = (OtkTimer*)PyList_GetItem(list, 0);
-
- if (! shouldFire(timer, &now)) {
- tm.tv_sec = timer->end.tv_sec - now.tv_sec;
- tm.tv_usec = timer->end.tv_usec - now.tv_usec;
- normalizeTimeval(&tm);
- timeout = &tm; // set the timeout for the select
- break; // go on and wait
- }
-
- // stop and remove the timer from the queue
- PySequence_DelItem(list, 0);
- timer->timing = False;
-
- if (timer->handler)
- timer->handler(timer->data);
-
- if (timer->recur)
- OtkTimer_Start(timer);
- }
-
- select(xfd + 1, &rfds, 0, 0, timeout);
-}
+++ /dev/null
-// -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
-#ifndef __timerqueue_h
-#define __timerqueue_h
-
-#include "timer.h"
-
-void OtkTimerQueue_Initialize();
-
-//! Will wait for and fire the next timer in the queue.
-/*!
- The function will stop waiting if an event is received from the X server.
-*/
-void OtkTimerQueue_Fire();
-
-//! Adds a new timer to the queue
-/*!
- @param timer An OtkTimer to add to the queue
-*/
-void OtkTimerQueue_Add(OtkTimer* timer);
-
-//! Removes a timer from the queue
-/*!
- @param timer An OtkTimer already in the queue to remove
-*/
-void OtkTimerQueue_Remove(OtkTimer* timer);
-
-#endif // __timerqueue_h