Hello, I am relatively new in python, but I am jumping in and trying some things.
I am working through how to write something like PyPanel, and am starting with PyPanel. The complicated part of that python is being extended by a custom c module, and the c module makes use of Xlib to draw onto a window. Further, the python code is also using the python Xlib modules.
My code - test.c (test.so)
#include <Python.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
/*---------------------------------------------------------*/
static PyObject * _testline(PyObject *self, PyObject *args) {
/*---------------------------------------------------------*/
Display *dsp = XOpenDisplay(NULL);
Window win;
GC gc;
XGCValues gcv;
if (!PyArg_ParseTuple(args, "l", &win))
return NULL;
int scr = DefaultScreen(dsp);
gc = XCreateGC(dsp, RootWindow(dsp, scr), GCGraphicsExposures, &gcv);
int whiteColor = WhitePixel(dsp, DefaultScreen(dsp));
XSetForeground(dsp, gc, whiteColor);
XDrawLine(dsp, win, gc, 10, 60, 180, 20);
//XFlush(dsp);
return Py_BuildValue("i", 1);
}
/*-------------------------------*/
static PyMethodDef TestMethods[] = {
/*-------------------------------*/
{"testline", _testline, METH_VARARGS, "Test Line"},
{NULL, NULL, 0, NULL}
};
/*----------------------*/
void inittest(void) {
/*----------------------*/
Py_InitModule("test", TestMethods);
}
My python code - test.py
#!/usr/local/bin/python -OO
"""
"""
#----------------------------------------------------------------------------
class Obj(object):
#----------------------------------------------------------------------------
""" Multi-purpose class """
#----------------------------
def __init__(self, **kwargs):
#----------------------------
self.__dict__.update(kwargs)
#----------------------------------------------------------------------------
# Main
#----------------------------------------------------------------------------
from distutils import sysconfig
from test import testline
from Xlib import X, display, error, Xatom, Xutil
import Xlib.protocol.event
import locale, os, pwd, select, sys, time
#----------------------------------------------------------------------------
class testPanel():
#----------------------------------------------------------------------------
#---------------------------
def __init__(self, display):
#---------------------------
self.display = display
self.screen = display.screen() # Screen obj
self.root = self.screen.root # Display root
self.error = error.CatchError() # Error Handler/Suppressor
self.colors = {} # Alloc'd colors
self.hidden = 0 # Panel hidden/minimized
self.focus = 0 # Currently focused window
self.rpm = None # Root pixmap ID
self.lgc = self.root.create_gc(foreground=self.getColor("0xece9e2"))
self.window = self.screen.root.create_window(0, 0,
300, 100, 0, self.screen.root_depth, window_class=X.InputOutput,
visual=X.CopyFromParent, colormap=X.CopyFromParent,
event_mask=(X.ExposureMask|X.ButtonPressMask|X.ButtonReleaseMask|X.EnterWindowMask))
self.root.change_attributes(event_mask=(X.PropertyChangeMask))
self.window.map()
win = self.window
break_all = False
while 1:
while self.display.pending_events():
e = self.display.next_event()
if e.type == X.Expose and e.count == 0:
break_all = True
break
if break_all:
break_all = False
break
self.display.flush()
while 1:
while self.display.pending_events():
e = self.display.next_event()
if e.type == X.ButtonRelease:
testline(self.window.id)
print("Draw")
self.display.flush()
#-------------------------
def getColor(self, color):
#-------------------------
""" Function to get/convert/alloc a color given a single hex str """
if color in self.colors:
return self.colors[color]
else:
r = int("0x"+color[2:4],0)*257
g = int("0x"+color[4:6],0)*257
b = int("0x"+color[6:8],0)*257
c = self.screen.default_colormap.alloc_color(r, g, b)
if not c:
sys.stderr.write("Error allocating color: %s\n" % color)
return self.screen.white_pixel
else:
self.colors[color] = c.pixel
return c.pixel
#-------------------------
if __name__ == "__main__":
#-------------------------
src = None
dst = None
# Version check
main = 2.4
config = globals().get("VERSION", None)
# Get the startup delay
delay = globals().get("STARTUP_DELAY", None)
# Set locale to user's default
locale.setlocale(locale.LC_ALL, "")
# If delay is set, pause, and let windowmanager load
if delay:
time.sleep(delay)
testPanel(display.Display())
Basically, the issue is that in my code, there has to be an XFlush(dsp); in the c module in order for it to draw, even if self.display.flush() is called in python right after. I assume this is because the Xlib included in my c module has parallel data to the one included by python's Xlib.
So if someone could give me advice on what's the proper way to have different modules draw onto the same window? Even if I restricted all drawing to c modules, I would still like the possibility of 'extensions' - extra c modules which do their own drawing onto the panel. Could create_resource_object be what I'm looking for? Or would it be better to use a subwindow somehow?
Thanks for any help.