mirror of
https://github.com/gryf/wmdocklib.git
synced 2025-12-18 20:10:23 +01:00
1569327 release 1.1 is broken
cleaning up more things. MANIFEST.in includes ll readmes, wmdocklib correctly populated.
This commit is contained in:
8
MANIFEST
8
MANIFEST
@@ -1,6 +1,8 @@
|
|||||||
README.txt
|
README.txt
|
||||||
setup.py
|
setup.py
|
||||||
|
examples/README
|
||||||
examples/pywmdatetime.py
|
examples/pywmdatetime.py
|
||||||
|
examples/pywmgeneric.py
|
||||||
examples/pywmhdmon.py
|
examples/pywmhdmon.py
|
||||||
examples/pywmseti.py
|
examples/pywmseti.py
|
||||||
examples/pywmsysmon.py
|
examples/pywmsysmon.py
|
||||||
@@ -8,12 +10,8 @@ examples/sample.pywmdatetimerc
|
|||||||
examples/sample.pywmgenericrc
|
examples/sample.pywmgenericrc
|
||||||
examples/sample.pywmhdmonrc
|
examples/sample.pywmhdmonrc
|
||||||
examples/sample.pywmsetirc
|
examples/sample.pywmsetirc
|
||||||
examples/setup.py
|
wmdocklib/README
|
||||||
pywmgeneral/__init__.py
|
|
||||||
pywmgeneral/pywmhelpers.py
|
|
||||||
pywmgeneral/setup.py
|
|
||||||
wmdocklib/__init__.py
|
wmdocklib/__init__.py
|
||||||
wmdocklib/pywmgeneral.c
|
wmdocklib/pywmgeneral.c
|
||||||
wmdocklib/pywmgeneral.h
|
wmdocklib/pywmgeneral.h
|
||||||
wmdocklib/pywmgeneric.py
|
|
||||||
wmdocklib/pywmhelpers.py
|
wmdocklib/pywmhelpers.py
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
include *.txt
|
include *.txt
|
||||||
include */*.py */*.c */*.h */sample.pywm*rc
|
include */*.py */*.c */*.h */sample.pywm*rc */README
|
||||||
|
|||||||
97
examples/README
Normal file
97
examples/README
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
[Pywmdatetime]
|
||||||
|
Pywmdatetime is a WindowMaker dockapp for displaying time, date and
|
||||||
|
some other information. The colors and formats are easy to configure
|
||||||
|
through the configuration file or as command line arguments. Invoke
|
||||||
|
the program with --help or see the sample rc-file for more information.
|
||||||
|
|
||||||
|
[Pywmgeneric]
|
||||||
|
Pywmgeneric is a dockapp with five entrys that display the first line of
|
||||||
|
output from an external program, the returned string from an python
|
||||||
|
method or an static string. Three mouse actions can be associated with
|
||||||
|
each displayed entry.
|
||||||
|
|
||||||
|
[Pywmgeneric -- DETAILED]
|
||||||
|
Five different entries can be defined in pywmgeneric. Every entry can
|
||||||
|
have an action, an update_delay and up to three mouse actions associated
|
||||||
|
with it. Some additional options are also available.
|
||||||
|
|
||||||
|
The associated action of an entry is executed with update_delay time
|
||||||
|
between executions. The output from the action is stored. If no special
|
||||||
|
display options are defined, the application will display the first line
|
||||||
|
of output from the action. If it does not fit in the window, it will
|
||||||
|
slowly scroll in the window. Clicking with the mouse on the text invokes
|
||||||
|
one of the mouse actions, depending on which button was pressed. The
|
||||||
|
action can be to execute an external program, to run a python method or
|
||||||
|
to update the text through performing the action associated with the
|
||||||
|
entry. The mouse actions can retreive the text genererated by the timed
|
||||||
|
action.
|
||||||
|
|
||||||
|
Python methods that should be executed as actions should be defined in
|
||||||
|
the class UserMethods. Look in pywmgeneric.py, near the top, for this
|
||||||
|
class and the documentation of how these methods should be defined.
|
||||||
|
Note that the methods allready there only are samples and will probably
|
||||||
|
not work on your system.
|
||||||
|
|
||||||
|
Other options in the configuration file include:
|
||||||
|
scroll = yes|no - en-/disable scrolling of the text when it doesn't fit
|
||||||
|
display = <text> - display a static string instead of the first line of
|
||||||
|
the action-generated output.
|
||||||
|
|
||||||
|
See the sample configuration file for examples and more information.
|
||||||
|
Note that this file is only for reference, it is the one I use. Things
|
||||||
|
will probably not work on your system if you do not change it.
|
||||||
|
|
||||||
|
[Pywmgeneric -- USES]
|
||||||
|
This program is very generic (hence the name ;) ), the uses are many
|
||||||
|
since it is highly configurable.
|
||||||
|
|
||||||
|
I use it for displaying my cpu and system temperatures. I just defined
|
||||||
|
methods for reading two files in the /proc filesystem on my system.
|
||||||
|
|
||||||
|
I also use it for fetching headlines from a newspaper, displaying the
|
||||||
|
first headline fetched. If I click with my left button, all headlines
|
||||||
|
will appear in an xmessage. If I rightclick the headlines along with
|
||||||
|
summaries are displayed, and if I click with my middle button mozilla
|
||||||
|
will fire up showing the newspaper's website.
|
||||||
|
|
||||||
|
I have an external program which displays what's currently on tv,
|
||||||
|
ideal for use with this program I thought! I modified it a bit so
|
||||||
|
it printed a summary line at the top, and voila I have all
|
||||||
|
currently running tv programs scrolling by in an dockapp. And clicking
|
||||||
|
on it shows me the details.
|
||||||
|
|
||||||
|
You could use it as an application launcher, just display the name of
|
||||||
|
the applications and associate mouse actions to lauch them. The
|
||||||
|
xterm-entry in the sample shows this.
|
||||||
|
|
||||||
|
You could probably come up with much more than this!
|
||||||
|
|
||||||
|
[pywmhdmon]
|
||||||
|
pywmhdmon is a WindowMaker dockapp that displays the available space on
|
||||||
|
up to four of your filesystems. It also contains a bar showing the
|
||||||
|
current HD activity. It currently only works on system which has a
|
||||||
|
/proc/stat like file. The application is easy to configure, invoke it
|
||||||
|
with --help or see the sample rc-file for more information.
|
||||||
|
|
||||||
|
[pywmhdmon -- BUGS]
|
||||||
|
The activity bar does not work with the proc filesystem that comes with
|
||||||
|
the 2.6 kernels. It is just a matter of rewriting the app to parse the
|
||||||
|
new format, but I'm low on time personally.
|
||||||
|
|
||||||
|
[Pywmseti]
|
||||||
|
Pywmseti is an WindowMaker dockapp for monitoring your seti@home progress.
|
||||||
|
The application displays how many workunits you have done and the progress
|
||||||
|
on the current one. You start/stop the seti@home process by simply clicking
|
||||||
|
anywhere in the application. It also displays the time spent on the workunit
|
||||||
|
(or since you started the program if you restart it in the middle of a
|
||||||
|
workunit). Invoke the program with --help or see the sample rc-file for
|
||||||
|
more information about customization.
|
||||||
|
|
||||||
|
[pywmsysmon]
|
||||||
|
pywmsysmon is a WindowMaker dockapp that displays your cpu and memory
|
||||||
|
usages. The upper graph shows your cpu usage history and the lower
|
||||||
|
"progress bar" shows your current memory usage excluding cached and
|
||||||
|
buffered data. This program currently only works on systems which got
|
||||||
|
the /proc/stat and /proc/meminfo files available. Invoke the program
|
||||||
|
with --help for information about customization.
|
||||||
|
|
||||||
596
pywmgeneric/pywmgeneral.c
Normal file
596
pywmgeneric/pywmgeneral.c
Normal file
@@ -0,0 +1,596 @@
|
|||||||
|
/* pywmgeneral.c
|
||||||
|
*
|
||||||
|
* Python bindings to some of the most important functions in the widely used
|
||||||
|
* wmgeneral.c. Also some added functions. The rc file parser is removed since
|
||||||
|
* Python provide better facilities for this.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003 Kristoffer Erlandsson
|
||||||
|
*
|
||||||
|
* Licensed under the GNU General Public License.
|
||||||
|
*
|
||||||
|
* History:
|
||||||
|
*
|
||||||
|
* 2003-06-24 Kristoffer Erlandsson
|
||||||
|
* Added some additional event handling.
|
||||||
|
*
|
||||||
|
* 2003-06-16 Kristoffer Erlandsson
|
||||||
|
* Added checkForMouseClick to make catching of mouse clicks available from
|
||||||
|
* Python.
|
||||||
|
*
|
||||||
|
* 2003-06-14 Kristoffer Erlandsson
|
||||||
|
* Finished support for "everything" included in wmgeneral by default.
|
||||||
|
*
|
||||||
|
* 2003-06-13 Kristoffer Erlandsson
|
||||||
|
* File created made most of the pure wrapper functions and xpm inclusion.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Thanks to Martijn Pieterse for createing the original wmgeneral.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/xpm.h>
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
|
||||||
|
#include "pywmgeneral.h"
|
||||||
|
|
||||||
|
/*****************/
|
||||||
|
/* X11 Variables */
|
||||||
|
/*****************/
|
||||||
|
|
||||||
|
Window Root;
|
||||||
|
int screen;
|
||||||
|
int x_fd;
|
||||||
|
int d_depth;
|
||||||
|
XSizeHints mysizehints;
|
||||||
|
XWMHints mywmhints;
|
||||||
|
Pixel back_pix, fore_pix;
|
||||||
|
char *Geometry = "";
|
||||||
|
Window iconwin, win;
|
||||||
|
GC NormalGC;
|
||||||
|
XpmIcon wmgen;
|
||||||
|
Pixmap pixmask;
|
||||||
|
Atom deleteAtom; /* Added 2003-06-24 for graceful shutdown. */
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* The Python stuff */
|
||||||
|
/*****************************************************************************/
|
||||||
|
static char **pixmap; /* Global pixmap, we only support one of these */
|
||||||
|
static char *maskBits; /* Global maskbits, also only 1 supported */
|
||||||
|
|
||||||
|
char **pyListToStrs(PyObject *l) {
|
||||||
|
/* Convert a python list of strings to a char **. */
|
||||||
|
int size, i;
|
||||||
|
char **target;
|
||||||
|
PyObject *s;
|
||||||
|
if (!PyList_Check(l)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "List expected.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size = PyList_Size(l);
|
||||||
|
target = (char **)malloc(size * sizeof(char *));
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
s = PySequence_GetItem(l, i);
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL; /* Shouldn't happen. */
|
||||||
|
if (!PyString_Check(s)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "String expected.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
target[i] = PyString_AsString(s);
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_includePixmap(PyObject *self, PyObject *args) {
|
||||||
|
/* Set the global pixmap. */
|
||||||
|
PyObject *arg;
|
||||||
|
if (!PyArg_ParseTuple(args, "O", &arg))
|
||||||
|
return NULL;
|
||||||
|
if(!(pixmap = pyListToStrs(arg)))
|
||||||
|
return NULL;
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_openXwindow(PyObject *self, PyObject *args) {
|
||||||
|
/* This function now uses the global variable pixmap as xpm and creates the
|
||||||
|
* xbm mask of the given height and width from this one. IOW no other xbm
|
||||||
|
* masks are supported at the moment. This shouldn't be needed except in
|
||||||
|
* special cases (I think...)
|
||||||
|
*/
|
||||||
|
int argc, width, height;
|
||||||
|
PyObject *argvTmp;
|
||||||
|
char **argv;
|
||||||
|
if (!PyArg_ParseTuple(args, "iOii", &argc, &argvTmp, &width, &height))
|
||||||
|
return NULL;
|
||||||
|
if (!(argv = pyListToStrs(argvTmp)))
|
||||||
|
return NULL;
|
||||||
|
maskBits = (char *)malloc(width * height * sizeof(char));
|
||||||
|
createXBMfromXPM(maskBits, pixmap, width, height);
|
||||||
|
openXwindow(argc, argv, pixmap, maskBits, width, height);
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_redrawWindow(PyObject *self, PyObject *args) {
|
||||||
|
if (!PyArg_ParseTuple(args, ""))
|
||||||
|
return NULL;
|
||||||
|
RedrawWindow();
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_redrawWindowXY(PyObject *self, PyObject *args) {
|
||||||
|
int x, y;
|
||||||
|
if (!PyArg_ParseTuple(args, "ii", &x, &y))
|
||||||
|
return NULL;
|
||||||
|
RedrawWindowXY(x, y);
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_addMouseRegion(PyObject *self, PyObject *args) {
|
||||||
|
int index, left, top, right, bottom;
|
||||||
|
if (!PyArg_ParseTuple(args, "iiiii", &index, &left, &top, &right, &bottom))
|
||||||
|
return NULL;
|
||||||
|
AddMouseRegion(index, left, top, right, bottom);
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_checkMouseRegion(PyObject *self, PyObject *args) {
|
||||||
|
int x, y;
|
||||||
|
if (!PyArg_ParseTuple(args, "ii", &x, &y))
|
||||||
|
return NULL;
|
||||||
|
return Py_BuildValue("i", CheckMouseRegion(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_copyXPMArea(PyObject *self, PyObject *args) {
|
||||||
|
/* x - source x, y - source y
|
||||||
|
* sx - width, sy - height
|
||||||
|
* dx - destination x, dy - destination y
|
||||||
|
*
|
||||||
|
* Variables named as in the original wmgeneral.c, don't blame me for it :)
|
||||||
|
*/
|
||||||
|
int x, y, sx, sy, dx, dy;
|
||||||
|
if (!PyArg_ParseTuple(args, "iiiiii", &x, &y, &sx, &sy, &dx, &dy))
|
||||||
|
return NULL;
|
||||||
|
copyXPMArea(x, y, sx, sy, dx, dy);
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pywmgeneral_checkForEvents(PyObject *self, PyObject *args) {
|
||||||
|
/* If we find an event we handle, return a dicitionary containing some
|
||||||
|
* information about it. Return None if there are no events we handle.
|
||||||
|
* Ignore events we don't handle. Also we provide a handler for when the
|
||||||
|
* window is exposed, redraw it.
|
||||||
|
*/
|
||||||
|
XEvent event;
|
||||||
|
if (!PyArg_ParseTuple(args, ""))
|
||||||
|
return NULL;
|
||||||
|
while (XPending(display)) {
|
||||||
|
XNextEvent(display, &event);
|
||||||
|
if (event.type == Expose) {
|
||||||
|
RedrawWindow();
|
||||||
|
}
|
||||||
|
else if (event.type == ClientMessage) {
|
||||||
|
if((Atom)event.xclient.data.l[0] == deleteAtom) {
|
||||||
|
XCloseDisplay(display);
|
||||||
|
return Py_BuildValue("{s:s}", "type", "destroynotify");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.type == DestroyNotify) {
|
||||||
|
/* This seems to never happen, why? */
|
||||||
|
XCloseDisplay(display);
|
||||||
|
return Py_BuildValue("{s:s}", "type", "destroynotify");
|
||||||
|
}
|
||||||
|
else if (event.type == ButtonRelease) {
|
||||||
|
return Py_BuildValue("{s:s,s:i,s:i,s:i}", "type", "buttonrelease",
|
||||||
|
"button", event.xbutton.button, "x",
|
||||||
|
event.xbutton.x, "y", event.xbutton.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef PyWmgeneralMethods[] = {
|
||||||
|
{"openXwindow", pywmgeneral_openXwindow, METH_VARARGS,
|
||||||
|
"Open the X window containing everything."},
|
||||||
|
{"includePixmap", pywmgeneral_includePixmap, METH_VARARGS,
|
||||||
|
"Set the global pixmap that will be used as a mask and for everything else."},
|
||||||
|
{"redrawWindow", pywmgeneral_redrawWindow, METH_VARARGS,
|
||||||
|
"Redraw the window."},
|
||||||
|
{"redrawWindowXY", pywmgeneral_redrawWindowXY, METH_VARARGS,
|
||||||
|
"Redraw a give region of the window."},
|
||||||
|
{"addMouseRegion", pywmgeneral_addMouseRegion, METH_VARARGS,
|
||||||
|
"Add a mouse region with a given index."},
|
||||||
|
{"checkMouseRegion", pywmgeneral_checkMouseRegion, METH_VARARGS,
|
||||||
|
"Check if the given coordinates are in any mouse region."},
|
||||||
|
{"copyXPMArea", pywmgeneral_copyXPMArea, METH_VARARGS,
|
||||||
|
"Copy an area of the global XPM."},
|
||||||
|
{"checkForEvents", pywmgeneral_checkForEvents, METH_VARARGS,
|
||||||
|
"Check for some Xevents"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
void initpywmgeneral(void) {
|
||||||
|
Py_InitModule("pywmgeneral", PyWmgeneralMethods);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Original C sources (With some modifications) */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************/
|
||||||
|
/* Mouse Regions */
|
||||||
|
/*****************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int enable;
|
||||||
|
int top;
|
||||||
|
int bottom;
|
||||||
|
int left;
|
||||||
|
int right;
|
||||||
|
} MOUSE_REGION;
|
||||||
|
|
||||||
|
MOUSE_REGION mouse_region[MAX_MOUSE_REGION];
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* Function Prototypes */
|
||||||
|
/***********************/
|
||||||
|
|
||||||
|
static void GetXPM(XpmIcon *, char **);
|
||||||
|
static Pixel GetColor(char *);
|
||||||
|
void RedrawWindow(void);
|
||||||
|
void AddMouseRegion(int, int, int, int, int);
|
||||||
|
int CheckMouseRegion(int, int);
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* GetXPM *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
static void GetXPM(XpmIcon *wmgen, char *pixmap_bytes[]) {
|
||||||
|
|
||||||
|
XWindowAttributes attributes;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* For the colormap */
|
||||||
|
XGetWindowAttributes(display, Root, &attributes);
|
||||||
|
|
||||||
|
wmgen->attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
|
||||||
|
|
||||||
|
err = XpmCreatePixmapFromData(display, Root, pixmap_bytes, &(wmgen->pixmap),
|
||||||
|
&(wmgen->mask), &(wmgen->attributes));
|
||||||
|
|
||||||
|
if (err != XpmSuccess) {
|
||||||
|
fprintf(stderr, "Not enough free colorcells.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* GetColor *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
static Pixel GetColor(char *name) {
|
||||||
|
|
||||||
|
XColor color;
|
||||||
|
XWindowAttributes attributes;
|
||||||
|
|
||||||
|
XGetWindowAttributes(display, Root, &attributes);
|
||||||
|
|
||||||
|
color.pixel = 0;
|
||||||
|
if (!XParseColor(display, attributes.colormap, name, &color)) {
|
||||||
|
fprintf(stderr, "wm.app: can't parse %s.\n", name);
|
||||||
|
} else if (!XAllocColor(display, attributes.colormap, &color)) {
|
||||||
|
fprintf(stderr, "wm.app: can't allocate %s.\n", name);
|
||||||
|
}
|
||||||
|
return color.pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* flush_expose *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
static int flush_expose(Window w) {
|
||||||
|
|
||||||
|
XEvent dummy;
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
while (XCheckTypedWindowEvent(display, w, Expose, &dummy))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* RedrawWindow *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
void RedrawWindow(void) {
|
||||||
|
|
||||||
|
flush_expose(iconwin);
|
||||||
|
XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
|
||||||
|
0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
|
||||||
|
flush_expose(win);
|
||||||
|
XCopyArea(display, wmgen.pixmap, win, NormalGC,
|
||||||
|
0,0, wmgen.attributes.width, wmgen.attributes.height, 0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* RedrawWindowXY *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
void RedrawWindowXY(int x, int y) {
|
||||||
|
|
||||||
|
flush_expose(iconwin);
|
||||||
|
XCopyArea(display, wmgen.pixmap, iconwin, NormalGC,
|
||||||
|
x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
|
||||||
|
flush_expose(win);
|
||||||
|
XCopyArea(display, wmgen.pixmap, win, NormalGC,
|
||||||
|
x,y, wmgen.attributes.width, wmgen.attributes.height, 0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* AddMouseRegion *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
void AddMouseRegion(int index, int left, int top, int right, int bottom) {
|
||||||
|
|
||||||
|
if (index < MAX_MOUSE_REGION) {
|
||||||
|
mouse_region[index].enable = 1;
|
||||||
|
mouse_region[index].top = top;
|
||||||
|
mouse_region[index].left = left;
|
||||||
|
mouse_region[index].bottom = bottom;
|
||||||
|
mouse_region[index].right = right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* CheckMouseRegion *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
int CheckMouseRegion(int x, int y) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
|
||||||
|
for (i=0; i<MAX_MOUSE_REGION && !found; i++) {
|
||||||
|
if (mouse_region[i].enable &&
|
||||||
|
x <= mouse_region[i].right &&
|
||||||
|
x >= mouse_region[i].left &&
|
||||||
|
y <= mouse_region[i].bottom &&
|
||||||
|
y >= mouse_region[i].top)
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
if (!found) return -1;
|
||||||
|
return (i-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* createXBMfromXPM *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
void createXBMfromXPM(char *xbm, char **xpm, int sx, int sy) {
|
||||||
|
|
||||||
|
int i,j,k;
|
||||||
|
int width, height, numcol, depth;
|
||||||
|
int zero=0;
|
||||||
|
unsigned char bwrite;
|
||||||
|
int bcount;
|
||||||
|
int curpixel;
|
||||||
|
|
||||||
|
sscanf(*xpm, "%d %d %d %d", &width, &height, &numcol, &depth);
|
||||||
|
|
||||||
|
|
||||||
|
for (k=0; k!=depth; k++)
|
||||||
|
{
|
||||||
|
zero <<=8;
|
||||||
|
zero |= xpm[1][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=numcol+1; i < numcol+sy+1; i++) {
|
||||||
|
bcount = 0;
|
||||||
|
bwrite = 0;
|
||||||
|
for (j=0; j<sx*depth; j+=depth) {
|
||||||
|
bwrite >>= 1;
|
||||||
|
|
||||||
|
curpixel=0;
|
||||||
|
for (k=0; k!=depth; k++)
|
||||||
|
{
|
||||||
|
curpixel <<=8;
|
||||||
|
curpixel |= xpm[i][j+k];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( curpixel != zero ) {
|
||||||
|
bwrite += 128;
|
||||||
|
}
|
||||||
|
bcount++;
|
||||||
|
if (bcount == 8) {
|
||||||
|
*xbm = bwrite;
|
||||||
|
xbm++;
|
||||||
|
bcount = 0;
|
||||||
|
bwrite = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* copyXPMArea *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy) {
|
||||||
|
|
||||||
|
XCopyArea(display, wmgen.pixmap, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* copyXBMArea *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
void copyXBMArea(int x, int y, int sx, int sy, int dx, int dy) {
|
||||||
|
|
||||||
|
XCopyArea(display, wmgen.mask, wmgen.pixmap, NormalGC, x, y, sx, sy, dx, dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* setMaskXY *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
|
||||||
|
void setMaskXY(int x, int y) {
|
||||||
|
|
||||||
|
XShapeCombineMask(display, win, ShapeBounding, x, y, pixmask, ShapeSet);
|
||||||
|
XShapeCombineMask(display, iconwin, ShapeBounding, x, y, pixmask, ShapeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************\
|
||||||
|
|* openXwindow *|
|
||||||
|
\*******************************************************************************/
|
||||||
|
void openXwindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height) {
|
||||||
|
|
||||||
|
unsigned int borderwidth = 1;
|
||||||
|
XClassHint classHint;
|
||||||
|
char *display_name = NULL;
|
||||||
|
char *wname = argv[0];
|
||||||
|
XTextProperty name;
|
||||||
|
|
||||||
|
XGCValues gcv;
|
||||||
|
unsigned long gcm;
|
||||||
|
|
||||||
|
char *geometry = NULL;
|
||||||
|
|
||||||
|
int dummy=0;
|
||||||
|
int i, wx, wy;
|
||||||
|
|
||||||
|
/* Changed to work better with Python. Changed check in for loop to control
|
||||||
|
* argc instead of argv.
|
||||||
|
*/
|
||||||
|
for (i=1; i < argc; i++) {
|
||||||
|
if (!strcmp(argv[i], "-display")) {
|
||||||
|
display_name = argv[i+1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (!strcmp(argv[i], "-geometry")) {
|
||||||
|
geometry = argv[i+1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(display = XOpenDisplay(display_name))) {
|
||||||
|
fprintf(stderr, "%s: can't open display %s\n",
|
||||||
|
wname, XDisplayName(display_name));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
screen = DefaultScreen(display);
|
||||||
|
Root = RootWindow(display, screen);
|
||||||
|
d_depth = DefaultDepth(display, screen);
|
||||||
|
x_fd = XConnectionNumber(display);
|
||||||
|
|
||||||
|
/* Convert XPM to XImage */
|
||||||
|
GetXPM(&wmgen, pixmap_bytes);
|
||||||
|
|
||||||
|
/* Create a window to hold the stuff */
|
||||||
|
mysizehints.flags = USSize | USPosition;
|
||||||
|
mysizehints.x = 0;
|
||||||
|
mysizehints.y = 0;
|
||||||
|
|
||||||
|
back_pix = GetColor("white");
|
||||||
|
fore_pix = GetColor("black");
|
||||||
|
|
||||||
|
XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
|
||||||
|
&mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
|
||||||
|
|
||||||
|
mysizehints.width = 64;
|
||||||
|
mysizehints.height = 64;
|
||||||
|
|
||||||
|
win = XCreateSimpleWindow(display, Root, mysizehints.x, mysizehints.y,
|
||||||
|
mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
|
||||||
|
|
||||||
|
iconwin = XCreateSimpleWindow(display, win, mysizehints.x, mysizehints.y,
|
||||||
|
mysizehints.width, mysizehints.height, borderwidth, fore_pix, back_pix);
|
||||||
|
|
||||||
|
|
||||||
|
/* Added 2003-06-24 for graceful shutdown. */
|
||||||
|
deleteAtom = XInternAtom(display, "WM_DELETE_WINDOW", 0);
|
||||||
|
XSetWMProtocols(display, win, &deleteAtom, 1);
|
||||||
|
|
||||||
|
|
||||||
|
/* Activate hints */
|
||||||
|
XSetWMNormalHints(display, win, &mysizehints);
|
||||||
|
classHint.res_name = wname;
|
||||||
|
classHint.res_class = wname;
|
||||||
|
XSetClassHint(display, win, &classHint);
|
||||||
|
|
||||||
|
XSelectInput(display, win, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
|
||||||
|
XSelectInput(display, iconwin, ButtonPressMask | ExposureMask | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask);
|
||||||
|
|
||||||
|
if (XStringListToTextProperty(&wname, 1, &name) == 0) {
|
||||||
|
fprintf(stderr, "%s: can't allocate window name\n", wname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
XSetWMName(display, win, &name);
|
||||||
|
|
||||||
|
/* Create GC for drawing */
|
||||||
|
|
||||||
|
gcm = GCForeground | GCBackground | GCGraphicsExposures;
|
||||||
|
gcv.foreground = fore_pix;
|
||||||
|
gcv.background = back_pix;
|
||||||
|
gcv.graphics_exposures = 0;
|
||||||
|
NormalGC = XCreateGC(display, Root, gcm, &gcv);
|
||||||
|
|
||||||
|
/* ONLYSHAPE ON */
|
||||||
|
|
||||||
|
pixmask = XCreateBitmapFromData(display, win, pixmask_bits, pixmask_width, pixmask_height);
|
||||||
|
|
||||||
|
XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet);
|
||||||
|
XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
|
||||||
|
|
||||||
|
/* ONLYSHAPE OFF */
|
||||||
|
|
||||||
|
mywmhints.initial_state = WithdrawnState;
|
||||||
|
mywmhints.icon_window = iconwin;
|
||||||
|
mywmhints.icon_x = mysizehints.x;
|
||||||
|
mywmhints.icon_y = mysizehints.y;
|
||||||
|
mywmhints.window_group = win;
|
||||||
|
mywmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
|
||||||
|
|
||||||
|
XSetWMHints(display, win, &mywmhints);
|
||||||
|
|
||||||
|
XSetCommand(display, win, argv, argc);
|
||||||
|
XMapWindow(display, win);
|
||||||
|
|
||||||
|
if (geometry) {
|
||||||
|
if (sscanf(geometry, "+%d+%d", &wx, &wy) != 2) {
|
||||||
|
fprintf(stderr, "Bad geometry string.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
XMoveWindow(display, win, wx, wy);
|
||||||
|
}
|
||||||
|
}
|
||||||
66
pywmgeneric/pywmgeneral.h
Normal file
66
pywmgeneric/pywmgeneral.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2003 Kristoffer Erlandsson
|
||||||
|
*
|
||||||
|
* Licensed under the GNU General Public License.
|
||||||
|
* Copyright (C) 2003 Kristoffer Erlandsson
|
||||||
|
*
|
||||||
|
* Licensed under the GNU General Public License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WMGENERAL_H_INCLUDED
|
||||||
|
#define WMGENERAL_H_INCLUDED
|
||||||
|
|
||||||
|
/***********/
|
||||||
|
/* Defines */
|
||||||
|
/***********/
|
||||||
|
|
||||||
|
#define MAX_MOUSE_REGION (16)
|
||||||
|
|
||||||
|
/************/
|
||||||
|
/* Typedefs */
|
||||||
|
/************/
|
||||||
|
|
||||||
|
typedef struct _rckeys rckeys;
|
||||||
|
|
||||||
|
struct _rckeys {
|
||||||
|
const char *label;
|
||||||
|
char **var;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _rckeys2 rckeys2;
|
||||||
|
|
||||||
|
struct _rckeys2 {
|
||||||
|
const char *family;
|
||||||
|
const char *label;
|
||||||
|
char **var;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Pixmap pixmap;
|
||||||
|
Pixmap mask;
|
||||||
|
XpmAttributes attributes;
|
||||||
|
} XpmIcon;
|
||||||
|
|
||||||
|
/*******************/
|
||||||
|
/* Global variable */
|
||||||
|
/*******************/
|
||||||
|
|
||||||
|
Display *display;
|
||||||
|
|
||||||
|
/***********************/
|
||||||
|
/* Function Prototypes */
|
||||||
|
/***********************/
|
||||||
|
|
||||||
|
void AddMouseRegion(int index, int left, int top, int right, int bottom);
|
||||||
|
int CheckMouseRegion(int x, int y);
|
||||||
|
|
||||||
|
void openXwindow(int argc, char *argv[], char **, char *, int, int);
|
||||||
|
void RedrawWindow(void);
|
||||||
|
void RedrawWindowXY(int x, int y);
|
||||||
|
|
||||||
|
void createXBMfromXPM(char *, char **, int, int);
|
||||||
|
void copyXPMArea(int, int, int, int, int, int);
|
||||||
|
void copyXBMArea(int, int, int, int, int, int);
|
||||||
|
void setMaskXY(int, int);
|
||||||
|
|
||||||
|
#endif
|
||||||
253
pywmgeneric/pywmhelpers.py
Normal file
253
pywmgeneric/pywmhelpers.py
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
"""pywmhelpers.py
|
||||||
|
|
||||||
|
Various helper functions when writing wm dockapps in Python. This module
|
||||||
|
is way better commented than the pywmgeneral one. This is the one
|
||||||
|
intented for use in applications. Many functions are just wrappers
|
||||||
|
around the ones in pywmgeneral but with nicer interfaces and better
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
Copyright (C) 2003 Kristoffer Erlandsson
|
||||||
|
|
||||||
|
Licensed under the GNU General Public License
|
||||||
|
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
2003-06-25 Kristoffer Erlandsson
|
||||||
|
Updated documentation
|
||||||
|
|
||||||
|
2003-06-24 Kristoffer Erlandsson
|
||||||
|
Some changes to handle the additional event handling in pywmgeneral
|
||||||
|
|
||||||
|
2003-06-16 Kristoffer Erlandsson
|
||||||
|
First workingish version
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import ConfigParser
|
||||||
|
|
||||||
|
import pywmgeneral
|
||||||
|
|
||||||
|
def readConfigFile(fileName, errOut):
|
||||||
|
"""Read the config file fileName.
|
||||||
|
|
||||||
|
Return a dictionary with the options and values in the DEFAULT
|
||||||
|
section. Ignore everything else. The configuration file should not
|
||||||
|
get so complicated so that sections are needed. errOut is the
|
||||||
|
file-like object to which error messages will be printed.
|
||||||
|
"""
|
||||||
|
if not os.access(fileName, os.R_OK):
|
||||||
|
if errOut:
|
||||||
|
errOut.write(
|
||||||
|
'Configuration file is not readable. Using defaults.\n')
|
||||||
|
return {}
|
||||||
|
cp = ConfigParser.ConfigParser()
|
||||||
|
try:
|
||||||
|
cp.read(fileName)
|
||||||
|
except ConfigParser.Error, e:
|
||||||
|
if errOut:
|
||||||
|
errOut.write('Error in configuration file:\n')
|
||||||
|
errOut.write(str(e) + '\nUsing defaults.')
|
||||||
|
return {}
|
||||||
|
defaults = cp.defaults()
|
||||||
|
if defaults == {}:
|
||||||
|
if errOut:
|
||||||
|
errOut.write(
|
||||||
|
'Missing or empty DEFAULT section in the config file.\n')
|
||||||
|
errOut.write('Using defaults.\n')
|
||||||
|
return defaults
|
||||||
|
|
||||||
|
def getCenterStartPos(s, letterWidth, areaWidth, offset):
|
||||||
|
"""Get the x starting position if we want to paint s centred."""
|
||||||
|
w = len(s) * letterWidth
|
||||||
|
textArea = areaWidth - offset * 2 - 1
|
||||||
|
return (textArea - w) / 2
|
||||||
|
|
||||||
|
def addChar(ch, x, y, letterWidth, letterHeight, lettersStartX, lettersStartY,
|
||||||
|
letters, digitWidth, digitHeight, digitsStartX, digitsStartY,
|
||||||
|
digits, xOffset, yOffset, width, height):
|
||||||
|
"""Paint the character ch at position x, y in the window.
|
||||||
|
|
||||||
|
Return the (width, height) of the character painted. Raise
|
||||||
|
ValueError if we try to paint a char not in letters or digits
|
||||||
|
or if we get out of bounds during painting. digits is really
|
||||||
|
just another line of chars, it's unlucky called digits everywhere
|
||||||
|
I used it since it contained only digits in the start. However,
|
||||||
|
now it contains various special chars too everywhere I use it. But
|
||||||
|
the name remains in too many places so I haven't gotten to change
|
||||||
|
it.
|
||||||
|
"""
|
||||||
|
chIndex = letters.find(ch.lower())
|
||||||
|
if chIndex != -1:
|
||||||
|
chX = lettersStartX + chIndex * letterWidth
|
||||||
|
chY = lettersStartY
|
||||||
|
w = letterWidth
|
||||||
|
h = letterHeight
|
||||||
|
else:
|
||||||
|
chIndex = digits.find(ch)
|
||||||
|
if chIndex != -1:
|
||||||
|
chX = digitsStartX + chIndex * digitWidth
|
||||||
|
chY = digitsStartY
|
||||||
|
w = digitWidth
|
||||||
|
h = digitHeight
|
||||||
|
else:
|
||||||
|
raise ValueError, "Unsupported char: '%s'" % ch
|
||||||
|
targX = x + xOffset
|
||||||
|
targY = y + yOffset
|
||||||
|
if targX + w > width - xOffset or targY + h > height - yOffset\
|
||||||
|
or targX < 0 or targY < 0:
|
||||||
|
raise ValueError, "Out of bounds."
|
||||||
|
pywmgeneral.copyXPMArea(chX, chY, w, h, targX, targY)
|
||||||
|
return (w, h)
|
||||||
|
|
||||||
|
def addString(s, x, y, letterWidth, letterHeight, lettersStartX, lettersStartY,
|
||||||
|
letters, digitWidth, digitHeight, digitsStartX, digitsStartY,
|
||||||
|
digits, xOffset, yOffset, width, height):
|
||||||
|
"""Add a string at the given x and y positions.
|
||||||
|
|
||||||
|
Call addChar repeatedely, so the same exception rules apply."""
|
||||||
|
lastW = 0
|
||||||
|
for letter in s:
|
||||||
|
w, h = addChar(letter, x + lastW, y, letterWidth, letterHeight,
|
||||||
|
lettersStartX, lettersStartY, letters, digitWidth,
|
||||||
|
digitHeight, digitsStartX, digitsStartY, digits,
|
||||||
|
xOffset, yOffset, width, height)
|
||||||
|
lastW += w
|
||||||
|
|
||||||
|
def getVertSpacing(numLines, margin, height, letterHeight, yOffset):
|
||||||
|
"""Return the optimal spacing between a number of lines.
|
||||||
|
|
||||||
|
margin is the space we want between the first line and the top."""
|
||||||
|
h = height - numLines * letterHeight - yOffset * 2 - margin
|
||||||
|
return h / (numLines - 1)
|
||||||
|
|
||||||
|
|
||||||
|
def readXPM(fileName):
|
||||||
|
"""Read the xpm in filename.
|
||||||
|
|
||||||
|
Return a list of strings containing the xpm. Raise IOError if we run
|
||||||
|
into trouble when trying to read the file. This function surely
|
||||||
|
doesn't handle all XPMs, but it handles the ones I use, so that'll
|
||||||
|
do.
|
||||||
|
"""
|
||||||
|
f = file(fileName, 'r')
|
||||||
|
lines = [l.rstrip('\n') for l in f.readlines()]
|
||||||
|
s = ''.join(lines)
|
||||||
|
res = []
|
||||||
|
while 1:
|
||||||
|
nextStrStart = s.find('"')
|
||||||
|
if nextStrStart != -1:
|
||||||
|
nextStrEnd = s.find('"', nextStrStart + 1)
|
||||||
|
if nextStrEnd != -1:
|
||||||
|
res.append(s[nextStrStart+1:nextStrEnd])
|
||||||
|
s = s[nextStrEnd+1:]
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
return res
|
||||||
|
|
||||||
|
def setColor(xpm, name, newColor):
|
||||||
|
"""Find the color with comment name and set this color to newColor.
|
||||||
|
|
||||||
|
Change the source code of an XPM represented as a list of strings.
|
||||||
|
I'm certain that this will fail on many XPMs too, but it'll do for
|
||||||
|
the ones I use. No check is done that the color is valid, this has
|
||||||
|
to be done elsewhere.
|
||||||
|
"""
|
||||||
|
colorRE = re.compile(
|
||||||
|
r"^(?P<letter>.).*?c (?P<color>#.*?) s (?P<comment>.*)")
|
||||||
|
index = 1
|
||||||
|
for line in xpm[1:]:
|
||||||
|
m = colorRE.match(line)
|
||||||
|
if not m is None:
|
||||||
|
comment = m.group('comment')
|
||||||
|
if comment == name:
|
||||||
|
letter = m.group('letter')
|
||||||
|
color = newColor
|
||||||
|
xpm[index] = '%s\tc %s s %s' % (letter, color, comment)
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
def setDefaultPixmap(xpm):
|
||||||
|
"""Set the pixmap of the program.
|
||||||
|
|
||||||
|
xpm is an XPM represented as a list of strings, possible gotten
|
||||||
|
from readXPM(). This is what we use all the time later. The XBM
|
||||||
|
mask is created out of the XPM. If I understand correctly how it
|
||||||
|
works we use the upper left rectangle as mask. This is the
|
||||||
|
simplest way to do it and is the desired behaviour in most cases.
|
||||||
|
"""
|
||||||
|
pywmgeneral.includePixmap(xpm)
|
||||||
|
|
||||||
|
def openXwindow(argv, w, h):
|
||||||
|
"""Open the X window of given width and height.
|
||||||
|
|
||||||
|
The XBM mask is here created from the upper left rectangle of the
|
||||||
|
XPM using the given width and height."""
|
||||||
|
pywmgeneral.openXwindow(len(argv), argv, w, h)
|
||||||
|
|
||||||
|
def redraw():
|
||||||
|
"""Redraw the window."""
|
||||||
|
pywmgeneral.redrawWindow()
|
||||||
|
|
||||||
|
def redrawXY(x, y):
|
||||||
|
"""Redraw a given region of the window."""
|
||||||
|
pywmgeneral.redrawWindowXY(x, y)
|
||||||
|
|
||||||
|
def copyXPMArea(sourceX, sourceY, width, height, targetX, targetY):
|
||||||
|
"""Copy an area of the global XPM."""
|
||||||
|
if width > 0 or height > 0:
|
||||||
|
pywmgeneral.copyXPMArea(sourceX, sourceY, width, height,
|
||||||
|
targetX, targetY)
|
||||||
|
|
||||||
|
def addMouseRegion(index, left, top, right, bottom):
|
||||||
|
"""Add a mouse region in the window."""
|
||||||
|
pywmgeneral.addMouseRegion(index, left, top, right, bottom)
|
||||||
|
|
||||||
|
def checkMouseRegion(x, y):
|
||||||
|
"""Check if x,y is in any mouse region. Return that region, otherwise -1.
|
||||||
|
"""
|
||||||
|
return pywmgeneral.checkMouseRegion(x, y)
|
||||||
|
|
||||||
|
def getEvent():
|
||||||
|
"""Check for XEvents and return one if found.
|
||||||
|
|
||||||
|
Return None if we find no events. There may be events pending still
|
||||||
|
after this function is called. If an event which we handle is found,
|
||||||
|
return a dictionary with information about it. All dictionaries
|
||||||
|
contain a 'type' field identifying the event. Now existing events
|
||||||
|
with dictionary keys are:
|
||||||
|
'buttonrelease':
|
||||||
|
x, y, button
|
||||||
|
'destroynotify':
|
||||||
|
"""
|
||||||
|
return pywmgeneral.checkForEvents()
|
||||||
|
|
||||||
|
def getColorCode(colorName, rgbFileName):
|
||||||
|
"""Convert a color to rgb code usable in an xpm.
|
||||||
|
|
||||||
|
We use the file rgbFileName for looking up the colors. Return None
|
||||||
|
if we find no match. The rgbFileName should be like the one found in
|
||||||
|
/usr/lib/X11R6/rgb.txt on most sytems.
|
||||||
|
"""
|
||||||
|
f = file(rgbFileName, 'r')
|
||||||
|
lines = f.readlines()
|
||||||
|
f.close()
|
||||||
|
for l in lines:
|
||||||
|
if l[0] != '!':
|
||||||
|
words = l.split()
|
||||||
|
if len(words) > 3:
|
||||||
|
name = ' '.join(words[3:])
|
||||||
|
if colorName.lower() == name.lower():
|
||||||
|
# Found the right color, get it's code
|
||||||
|
try:
|
||||||
|
r = int(words[0])
|
||||||
|
g = int(words[1])
|
||||||
|
b = int(words[2])
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
rgbstr = '#' + str(hex(r))[2:].zfill(2) + \
|
||||||
|
str(hex(g))[2:].zfill(2) + \
|
||||||
|
str(hex(b))[2:].zfill(2)
|
||||||
|
return rgbstr
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
3
setup.py
3
setup.py
@@ -28,6 +28,5 @@ setup(name="pywmdockapps",
|
|||||||
scripts=['examples/pywmdatetime.py',
|
scripts=['examples/pywmdatetime.py',
|
||||||
'examples/pywmhdmon.py',
|
'examples/pywmhdmon.py',
|
||||||
'examples/pywmseti.py',
|
'examples/pywmseti.py',
|
||||||
'examples/pywmsysmon.py',
|
'examples/pywmsysmon.py'],
|
||||||
'examples/setup.py'],
|
|
||||||
ext_modules = [module1])
|
ext_modules = [module1])
|
||||||
|
|||||||
Reference in New Issue
Block a user