Subject: wmbubble: Patch to actually fix things by removing dependency on gdk Package: wmbubble Version: 1.46-2.1 Severity: normal
*** Please type your report below this line *** The fix patched into -2.1 caused bug reports numbers #602122 and #602137 -- to wit, the application no longer behaves like a dockapp in windowmaker or openbox. The attached patch fixes this by removing the dependency on gdk altogether, replacing it with bare xlib calls. I've tested it on the two machines I have access to right now (ia32/sid on a 16bpp display and x86-64/sid on a 24bpp display) under both windowmanagers; it seems to work. The patch does explicitly desupport PsuedoColor (8bpp) displays; if this is a deal breaker tell me and I'll figure out how to work around that. Thanks- - Robert Jacobs -- System Information: Debian Release: squeeze/sid APT prefers unstable APT policy: (500, 'unstable'), (500, 'stable') Architecture: i386 (i686) Kernel: Linux 2.6.32-5-686 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages wmbubble depends on: ii libatk1.0-0 1.30.0-1 The ATK accessibility toolkit ii libc6 2.11.2-7 Embedded GNU C Library: Shared lib ii libcairo2 1.8.10-6 The Cairo 2D vector graphics libra ii libfontconfig1 2.8.0-2.1 generic font configuration library ii libfreetype6 2.4.2-2.1 FreeType 2 font engine, shared lib ii libglib2.0-0 2.24.2-1 The GLib library of C routines ii libgtk2.0-0 2.20.1-2 The GTK+ graphical user interface ii libpango1.0-0 1.28.3-1 Layout and rendering of internatio ii libx11-6 2:1.3.3-3 X11 client-side library wmbubble recommends no packages. Versions of packages wmbubble suggests: ii lxterminal [x-terminal-emulat 0.1.8-2 desktop independent vte-based term ii rxvt-unicode [x-terminal-emul 9.09-1 RXVT-like terminal emulator with U ii sox 14.3.1-1 Swiss army knife of sound processi ii xterm [x-terminal-emulator] 266-1 X terminal emulator ii xvt [x-terminal-emulator] 2.1-20 X terminal-emulator similar to xte -- no debconf information
diff -Nuar wmbubble-1.46-2.orig//bubblemon.c wmbubble-1.46/bubblemon.c --- wmbubble-1.46-2.orig//bubblemon.c 2010-11-22 00:37:46.087971694 -0800 +++ wmbubble-1.46/bubblemon.c 2010-11-22 00:47:27.619973208 -0800 @@ -55,11 +55,10 @@ #include <string.h> /* x11 includes */ -#include <gdk/gdk.h> -#include <gdk/gdkx.h> +#include <X11/Xutil.h> #include <X11/Xresource.h> -#include "include/master.xpm" +#include "include/frame.xbm" #include "include/bubblemon.h" #include "include/sys_include.h" @@ -85,9 +84,11 @@ static void bubblemon_setup_colors(void); static void bubblemon_allocate_buffers(void); static void bubblemon_update(int proximity); -static void make_new_bubblemon_dockapp(void); +static void make_new_bubblemon_dockapp(int argc, char * argv[]); static void get_memory_load_percentage(void); static void bubblemon_session_defaults(void); +static void RedrawWindow(void); +static void wmPutPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b); static int get_screen_selection(void); #if defined(ENABLE_CPU) || defined(ENABLE_MEMSCREEN) /* draw functions for load average / memory screens */ @@ -291,20 +292,12 @@ #ifdef PRO int cnt = 25000; #endif - GdkEvent *event; + XEvent event; #ifdef FPS o = f = y = 0; #endif - /* initialize GDK */ - if (!gdk_init_check(&argc, &argv)) { - fprintf(stderr, - "GDK init failed, bye bye. Check \"DISPLAY\" variable.\n"); - exit(-1); - } - gdk_rgb_init(); - /* dynamically generate getopt string depending on compile options * we are going to borrow 256 char string from exec function, and * also build up the "compiled features" string */ @@ -407,34 +400,29 @@ bubblemon_session_defaults(); /* create dockapp window. creates windows, allocates memory, etc */ - make_new_bubblemon_dockapp(); + make_new_bubblemon_dockapp(argc,argv); #ifdef PRO while (cnt--) { #else while (1) { #endif - while (gdk_events_pending()) { - event = gdk_event_get(); - if (event) { - switch (event->type) { - case GDK_DESTROY: - gdk_exit(0); - exit(0); - break; - case GDK_BUTTON_PRESS: - if (event->button.button == 3) { + while (XPending(bm.display)) { + XNextEvent(bm.display,&event); + switch (event.type) { + case ButtonPress: + if (event.xbutton.button == 3) { bm.picture_lock = bm.picture_lock ? 0 : 1; break; } - if (event->button.button <= argc) { + if (event.xbutton.button <= argc) { snprintf(execute, 250, "%s &", - argv[event->button.button - 1]); + argv[event.xbutton.button - 1]); system(execute); } break; #if defined(ENABLE_CPU) || defined(ENABLE_MEMSCREEN) - case GDK_ENTER_NOTIFY: + case EnterNotify: /* mouse in: make it darker, and eventually bring up * meminfo */ proximity = 1; @@ -442,7 +430,7 @@ if (!bm.picture_lock) bm.screen_type = get_screen_selection(); break; - case GDK_LEAVE_NOTIFY: + case LeaveNotify: /* mouse out: back to light */ proximity = 0; break; @@ -451,7 +439,6 @@ break; } } - } #ifndef PRO usleep(15000); #else @@ -478,12 +465,13 @@ /* *INDENT-ON* */ /* actually draw the screen */ -#ifndef BLACKBOX - gdk_draw_rgb_image(bm.win, bm.gc, 4, 4, 56, 56, - GDK_RGB_DITHER_NONE, bm.rgb_buf, 56 * 3); -#endif - gdk_draw_rgb_image(bm.iconwin, bm.gc, 4, 4, 56, 56, - GDK_RGB_DITHER_NONE, bm.rgb_buf, 56 * 3); + int xx,yy; + unsigned char * from=bm.rgb_buf; + for (yy=0;yy<56;yy++) + for (xx=0;xx<56;xx++,from+=3) + wmPutPixel(xx,yy,from[0],from[1],from[2]); + + RedrawWindow(); #ifdef ENABLE_MEMSCREEN /* update graph histories */ if (memscreen_enabled) @@ -504,13 +492,13 @@ if (first_time) { first_time = 0; - lshift_code = XKeysymToKeycode(GDK_WINDOW_XDISPLAY(bm.win), + lshift_code = XKeysymToKeycode(bm.display, XStringToKeysym("Shift_L")); - rshift_code = XKeysymToKeycode(GDK_WINDOW_XDISPLAY(bm.win), + rshift_code = XKeysymToKeycode(bm.display, XStringToKeysym("Shift_R")); } - XQueryKeymap(GDK_WINDOW_XDISPLAY(bm.win), keys); + XQueryKeymap(bm.display, keys); #if 0 if (0) { /* debug */ @@ -537,86 +525,132 @@ } } +/* flush_expose + removes all expose events off the event stack */ +static int flush_expose(Window w) { + XEvent dummy; + int i=0; + + while (XCheckTypedWindowEvent(bm.display, w, Expose, &dummy)) + i++; + + return i; +} + +/* RedrawWindow + copies the contents of the Ximage -> Xpixmap -> both windows */ +void RedrawWindow(void) { + XPutImage(bm.display, bm.pixmap, bm.gc, bm.xim, 0,0, 1,1, 56,56); + flush_expose(bm.iconwin); + XCopyArea(bm.display, bm.pixmap, bm.iconwin, bm.gc, 0,0, 58,58, 0,0); + flush_expose(bm.win); + XCopyArea(bm.display, bm.pixmap, bm.win, bm.gc, 0,0, 58,58, 0,0); +} + +void wmPutPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b) { + unsigned long pxl; + + pxl = ((r*bm.xim->red_mask/255)&bm.xim->red_mask) | + ((g*bm.xim->green_mask/255)&bm.xim->green_mask) | + ((b*bm.xim->blue_mask/255)&bm.xim->blue_mask); + + XPutPixel(bm.xim, x, y, pxl); +}; + /* This is the function that actually creates the display widgets */ -static void make_new_bubblemon_dockapp(void) +static void make_new_bubblemon_dockapp(int argc, char * argv[]) { -#define MASK GDK_BUTTON_PRESS_MASK | \ - GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK - - GdkWindowAttr attr; - GdkWindowAttr attri; - Window win; - Window iconwin; + unsigned long gcm; + XTextProperty name; + XClassHint classHint; + XGCValues gcv; + Window Root; + Visual * visual; + char *wname = argv[0]; + long InterestingEvents = NoEventMask; + int screen; + unsigned int depth; XSizeHints sizehints; XWMHints wmhints; - attr.width = 64; - attr.height = 64; - attr.title = NAME; - attr.event_mask = MASK; - attr.wclass = GDK_INPUT_OUTPUT; - attr.visual = gdk_visual_get_system(); - attr.colormap = gdk_colormap_get_system(); - attr.wmclass_name = NAME; - attr.wmclass_class = NAME; - attr.window_type = GDK_WINDOW_TOPLEVEL; - - sizehints.flags = USSize; - sizehints.width = 64; - sizehints.height = 64; - - bm.win = gdk_window_new(NULL, &attr, - GDK_WA_TITLE | GDK_WA_WMCLASS | - GDK_WA_VISUAL | GDK_WA_COLORMAP); + if (!(bm.display = XOpenDisplay(NULL))) { + fprintf(stderr, "%s: can't open display %s\n", wname, XDisplayName(NULL)); + exit(1); + } + screen = DefaultScreen(bm.display); + Root = RootWindow(bm.display, screen); + visual = DefaultVisual(bm.display, screen); + depth = DefaultDepth(bm.display, screen); + + if (visual->red_mask == 0 || + visual->green_mask == 0 || + visual->blue_mask == 0 || + (visual->class != TrueColor && visual->class != DirectColor)) { + fprintf(stderr, "We require a true- or direct- color display, and yours isn't.\n"); + exit(2); + } + + bm.win = XCreateSimpleWindow + (bm.display, Root, 0,0, 58,58, 0, + BlackPixel(bm.display,screen), WhitePixel(bm.display,screen)); if (!bm.win) fprintf(stderr, "Cannot make toplevel window\n"); - attri.width = 64; - attri.height = 64; - attri.title = NAME; - attri.event_mask = MASK; - attri.wclass = GDK_INPUT_OUTPUT; - attri.visual = gdk_visual_get_system(); - attri.colormap = gdk_colormap_get_system(); - attri.wmclass_name = NAME; - attri.wmclass_class = NAME; - attri.window_type = GDK_WINDOW_CHILD; - - bm.iconwin = gdk_window_new(bm.win, &attri, - GDK_WA_TITLE | GDK_WA_WMCLASS); + bm.iconwin = XCreateSimpleWindow + (bm.display, bm.win, 0,0, 58,58, 0, + BlackPixel(bm.display,screen), WhitePixel(bm.display,screen)); if (!bm.iconwin) fprintf(stderr, "Cannot make icon window\n"); - win = GDK_WINDOW_XWINDOW(bm.win); - iconwin = GDK_WINDOW_XWINDOW(bm.iconwin); - XSetWMNormalHints(GDK_WINDOW_XDISPLAY(bm.win), win, &sizehints); + XSetWMNormalHints(bm.display, bm.win, &sizehints); + + /* Activate hints */ + classHint.res_name = wname; + classHint.res_class = wname; + XSetClassHint(bm.display, bm.win, &classHint); + + /* Select acceptable input events */ + InterestingEvents |= KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | ExposureMask; + + XSelectInput(bm.display, bm.win, InterestingEvents); + XSelectInput(bm.display, bm.iconwin, InterestingEvents); + + if (XStringListToTextProperty(&wname, 1, &name) == 0) { + fprintf(stderr, "%s: can't allocate window name\n", wname); + exit(3); + } + + XSetWMName(bm.display, bm.win, &name); + XSetCommand(bm.display, bm.win, argv, argc); wmhints.initial_state = WithdrawnState; - wmhints.icon_window = iconwin; + wmhints.icon_window = bm.iconwin; wmhints.icon_x = 0; wmhints.icon_y = 0; - wmhints.window_group = win; + wmhints.window_group = bm.win; wmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint; + XSetWMHints(bm.display, bm.win, &wmhints); - bm.gc = gdk_gc_new(bm.win); + gcm = GCGraphicsExposures; + gcv.graphics_exposures = 0; + bm.gc = XCreateGC(bm.display, Root, gcm, &gcv); - bm.pixmap = - gdk_pixmap_create_from_xpm_d(bm.win, &(bm.mask), NULL, master_xpm); - gdk_window_shape_combine_mask(bm.win, bm.mask, 0, 0); - gdk_window_shape_combine_mask(bm.iconwin, bm.mask, 0, 0); + bm.pixmap = XCreatePixmapFromBitmapData(bm.display,Root,master_bits,58,58,BlackPixel(bm.display,screen),WhitePixel(bm.display,screen),depth); - gdk_window_set_back_pixmap(bm.win, bm.pixmap, False); - gdk_window_set_back_pixmap(bm.iconwin, bm.pixmap, False); + /* Create an XImage without data. Then allocate space for same. */ + bm.xim = XCreateImage(bm.display, visual, depth, ZPixmap, 0, NULL, 56,56, 32, 0); + bm.xim->data = (char *)malloc(bm.xim->bytes_per_line * 56 ); - gdk_window_show(bm.win); + XMapWindow(bm.display, bm.win); #ifdef KDE_DOCKAPP /* makes the dockapp visible inside KDE wm */ - gdk_window_show(bm.iconwin); + XMapWindow(bm.display, bm.iconwin); #endif - XSetWMHints(GDK_WINDOW_XDISPLAY(bm.win), win, &wmhints); /* We begin with zero bubbles */ bm.n_bubbles = 0; diff -Nuar wmbubble-1.46-2.orig//include/bubblemon.h wmbubble-1.46/include/bubblemon.h --- wmbubble-1.46-2.orig//include/bubblemon.h 2001-02-17 01:03:01.000000000 -0800 +++ wmbubble-1.46/include/bubblemon.h 2010-11-22 00:44:03.231974644 -0800 @@ -19,8 +19,7 @@ #ifndef _BUBBLEMON_H_ #define _BUBBLEMON_H_ -#include <gdk/gdk.h> -#include <gdk/gdkx.h> +#include <X11/Xlib.h> /* CPU load alpha-blending: smaller values = ligher text * minblend = mouseout @@ -66,11 +65,11 @@ typedef struct { /* X11 stuff */ Display *display; - GdkWindow *win; /* main window */ - GdkWindow *iconwin; /* icon window */ - GdkGC *gc; /* drawing GC */ - GdkPixmap *pixmap; /* main dockapp pixmap */ - GdkBitmap *mask; /* dockapp mask */ + Window win; + Window iconwin; + GC gc; + Pixmap pixmap; + XImage * xim; /* main image buffer */ unsigned char rgb_buf[56 * 56 * 3 + 1]; @@ -90,7 +89,7 @@ /* bubble stuff */ int samples; unsigned char *bubblebuf; - int *colors; + unsigned int *colors; int *waterlevels; int *waterlevels_dy; Bubble *bubbles; diff -Nuar wmbubble-1.46-2.orig//include/frame.xbm wmbubble-1.46/include/frame.xbm --- wmbubble-1.46-2.orig//include/frame.xbm 1969-12-31 16:00:00.000000000 -0800 +++ wmbubble-1.46/include/frame.xbm 2010-11-22 00:44:03.255963735 -0800 @@ -0,0 +1,42 @@ +#define master_width 58 +#define master_height 58 +static unsigned char master_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff -Nuar wmbubble-1.46-2.orig//Makefile wmbubble-1.46/Makefile --- wmbubble-1.46-2.orig//Makefile 2010-11-22 00:37:46.087971694 -0800 +++ wmbubble-1.46/Makefile 2010-11-22 00:48:09.471965002 -0800 @@ -16,7 +16,7 @@ # USER_CFLAGS = -ansi -Wall -pg -O3 -DPRO # test coverage cflags # USER_CFLAGS = -fprofile-arcs -ftest-coverage -Wall -ansi -g -DPRO -BUILD_CFLAGS = `pkg-config gtk+-2.0 --cflags` +BUILD_CFLAGS = CFLAGS = $(USER_CFLAGS) $(BUILD_CFLAGS) ${EXTRA} BINARY=bubblemon @@ -28,21 +28,21 @@ # special things for Linux ifeq ($(OS), Linux) OBJS += sys_linux.o - LIBS = `pkg-config gtk+-2.0 --libs | sed "s/-lgtk//g"` + LIBS = -lX11 INSTALL = -m 755 endif # special things for FreeBSD ifeq ($(OS), FreeBSD) OBJS += sys_freebsd.o - LIBS = `pkg-config gtk+-2.0 --libs | sed "s/-lgtk//g"` -lkvm + LIBS = -lX11 -lkvm INSTALL = -c -g kmem -m 2755 -o root endif # special things for OpenBSD ifeq ($(OS), OpenBSD) OBJS += sys_openbsd.o - LIBS = `pkg-config gtk+-2.0 --libs | sed "s/-lgtk//g"` + LIBS = -lX11 endif #special things for SunOS @@ -65,7 +65,7 @@ endif CFLAGS = $(USER_CFLAGS) $(BUILD_CFLAGS) ${EXTRA} OBJS += sys_sunos.o - LIBS = `pkg-config gtk+-2.0 --libs` -lkstat -lm + LIBS = -lX11 -lkstat -lm INSTALL = -m 755 endif