Fix two bugs related to command execution:
[dockapps.git] / wmweather+ / wmgeneral / wmgeneral-gtk.c
blob7fb1be3b295e8eb90f79a8e26d04b4945b6e440b
1 #include "../config.h"
3 /*
4 Best viewed with vim5, using ts=4
6 wmgeneral was taken from wmppp.
8 It has a lot of routines which most of the wm* programs use.
10 ------------------------------------------------------------
12 Author: Brad Jorsch, anomie@users.sourceforge.net
14 ---
15 CHANGES:
16 ---
17 15/08/2002 (Brad Jorsch, anomie@users.sourceforge.net)
18 * Pulled createXBMfromXPM into its own file, because it's the same in
19 both -gtk and -x11.
21 11/08/2002 (Brad Jorsch, anomie@users.sourceforge.net)
22 * This is based on wmgeneral-x11.c (formerly wmgeneral.c), it
23 implements a subset of the interface using Gtk+ 2.0
27 #include <stdio.h>
29 #include <gtk/gtk.h>
30 #include <gdk/gdkx.h>
32 #include "wmgeneral-gtk.h"
34 /******************/
35 /* Gtk+ Variables */
36 /******************/
38 static GtkWidget *dockwin, *iconwin;
39 static GdkPixmap *pixmap, *mask;
40 static GdkGC *pixmap_gc, *mask_gc;
41 static void (*click_func)(GdkEventButton *ev);
43 /******************************************************************************\
44 |* RedrawWindow *|
45 \******************************************************************************/
47 void RedrawWindow(void) {
48 gdk_draw_drawable(dockwin->window, pixmap_gc, pixmap, 0, 0, 0, 0, 64, 64);
49 gdk_draw_drawable(iconwin->window, pixmap_gc, pixmap, 0, 0, 0, 0, 64, 64);
52 static gint redraw_dock(gpointer d){
53 RedrawWindow();
54 return 0;
57 /******************************************************************************\
58 |* RedrawWindowXY *|
59 \******************************************************************************/
61 void RedrawWindowXY(int x, int y) {
62 gdk_draw_drawable(dockwin->window, pixmap_gc, pixmap, x, y, 0, 0, 64, 64);
63 gdk_draw_drawable(iconwin->window, pixmap_gc, pixmap, x, y, 0, 0, 64, 64);
66 /******************************************************************************\
67 |* copyXPMArea *|
68 \******************************************************************************/
70 void copyPixmapArea(int sx, int sy, int w, int h, int dx, int dy){
71 gdk_draw_drawable(pixmap, pixmap_gc, pixmap, sx, sy, dx, dy, w, h);
74 /******************************************************************************\
75 |* copyXBMArea *|
76 \******************************************************************************/
78 void copyMaskArea(int sx, int sy, int w, int h, int dx, int dy){
79 gdk_draw_drawable(mask, mask_gc, mask, sx, sy, dx, dy, w, h);
83 /******************************************************************************\
84 |* setMaskXY *|
85 \******************************************************************************/
87 void setMaskXY(int x, int y) {
88 gtk_widget_shape_combine_mask(dockwin, mask, x, y);
89 gtk_widget_shape_combine_mask(iconwin, mask, x, y);
92 /******************************************************************************\
93 |* setClickCallback *|
94 \******************************************************************************/
95 void setClickCallback(void (*func)(GdkEventButton *ev)){
96 click_func=func;
99 /******************************************************************************\
100 |* openXwindow *|
101 \******************************************************************************/
103 static GdkWindow *get_gdk_leader(GdkWindow *win){
104 GdkAtom atom, type;
105 gint len;
106 guchar *data;
107 GdkWindow *leader=NULL;
109 atom=gdk_atom_intern("WM_CLIENT_LEADER", TRUE);
110 type=gdk_atom_intern("WINDOW", TRUE);
111 if(atom==GDK_NONE || type==GDK_NONE) return NULL;
112 if(!gdk_property_get(win, atom, type, 0, 4, FALSE, NULL, NULL, &len, &data)) return NULL; if(len==4) leader=gdk_window_foreign_new(*(GdkNativeWindow *)data);
113 g_free(data);
114 return leader;
117 static GdkFilterReturn button_filter(XEvent *x, GdkEvent *ev, gpointer data){
118 /* Bleh, Gdk insists on trying to translate buttons 4-7 into Scroll events.
119 * Which would be ok, except for the part where it just _throws_ _away_ the
120 * releases! Damnit... So, we cheat and change any buttons >3 into
121 * button+4, and change it back in the click handler. */
122 if((x->type==ButtonPress || x->type==ButtonRelease) && x->xbutton.button>3){
123 x->xbutton.button+=4;
125 return GDK_FILTER_CONTINUE;
128 static void dock_click(GtkWidget *w, GdkEventButton *ev, gpointer d){
129 if(ev->button>7) ev->button-=4;
130 if(click_func!=NULL) click_func(ev);
133 #define die(args...) { fprintf(stderr, args); exit(1); }
135 void openDockWindow(int argc, char *argv[], char *pixmap_bytes[], char *pixmask_bits, int pixmask_width, int pixmask_height){
136 GdkColormap *cmap;
137 GdkColor white, black;
138 GdkWindow *leader;
139 XWMHints hints;
141 click_func=NULL;
142 if((dockwin=gtk_window_new(GTK_WINDOW_TOPLEVEL))==NULL) die("Couldn't create window");
143 if((iconwin=gtk_window_new(GTK_WINDOW_TOPLEVEL))==NULL) die("Couldn't create window");
144 gtk_widget_set_size_request(dockwin, 64, 64);
145 gtk_widget_set_size_request(iconwin, 64, 64);
146 gtk_widget_set_app_paintable(dockwin, TRUE);
147 gtk_widget_set_app_paintable(iconwin, TRUE);
148 gtk_widget_add_events(dockwin, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
149 gtk_widget_add_events(iconwin, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
150 g_signal_connect(G_OBJECT(dockwin), "expose-event", G_CALLBACK(redraw_dock), NULL);
151 g_signal_connect(G_OBJECT(iconwin), "expose-event", G_CALLBACK(redraw_dock), NULL);
152 g_signal_connect(G_OBJECT(dockwin), "button-press-event", G_CALLBACK(dock_click), NULL);
153 g_signal_connect(G_OBJECT(iconwin), "button-press-event", G_CALLBACK(dock_click), NULL);
154 g_signal_connect(G_OBJECT(dockwin), "button-release-event", G_CALLBACK(dock_click), NULL);
155 g_signal_connect(G_OBJECT(iconwin), "button-release-event", G_CALLBACK(dock_click), NULL);
156 g_signal_connect(G_OBJECT(dockwin), "destroy", G_CALLBACK(exit), NULL);
157 g_signal_connect(G_OBJECT(iconwin), "destroy", G_CALLBACK(exit), NULL);
158 gtk_widget_realize(dockwin);
159 gtk_widget_realize(iconwin);
160 gdk_window_add_filter(dockwin->window, (GdkFilterFunc)button_filter, NULL);
161 gdk_window_add_filter(iconwin->window, (GdkFilterFunc)button_filter, NULL);
162 if((leader=get_gdk_leader(dockwin->window))==NULL) die("Couldn't obtain Gdk leader window");
163 gdk_window_set_icon(leader, iconwin->window, NULL, NULL);
164 gdk_window_reparent(iconwin->window, leader, 0, 0);
165 gdk_window_unref(leader);
167 hints.initial_state = WithdrawnState;
168 hints.flags = StateHint;
169 XSetWMHints(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(dockwin->window), &hints);
171 cmap=gdk_colormap_get_system();
172 white.red=65535;
173 white.green=65535;
174 white.blue=65535;
175 black.red=0;
176 black.green=0;
177 black.blue=0;
178 gdk_color_alloc(cmap, &white);
179 gdk_color_alloc(cmap, &black);
180 mask=gdk_pixmap_create_from_data(NULL, pixmask_bits, pixmask_width, pixmask_height, 1, &white, &black);
181 pixmap=gdk_pixmap_colormap_create_from_xpm_d(NULL, cmap, NULL, NULL, pixmap_bytes);
183 pixmap_gc=gdk_gc_new(iconwin->window);
184 mask_gc=gdk_gc_new(mask);
186 setMaskXY(0, 0);
187 RedrawWindow();
189 gtk_widget_show(iconwin);
190 gtk_widget_show(dockwin);
191 gdk_window_withdraw(dockwin->window);