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
17 15/08/2002 (Brad Jorsch, anomie@users.sourceforge.net)
18 * Pulled createXBMfromXPM into its own file, because it's the same in
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
32 #include "wmgeneral-gtk.h"
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 /******************************************************************************\
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
){
57 /******************************************************************************\
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 /******************************************************************************\
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 /******************************************************************************\
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 /******************************************************************************\
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
)){
99 /******************************************************************************\
101 \******************************************************************************/
103 static GdkWindow
*get_gdk_leader(GdkWindow
*win
){
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
);
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
){
137 GdkColor white
, black
;
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();
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
);
189 gtk_widget_show(iconwin
);
190 gtk_widget_show(dockwin
);
191 gdk_window_withdraw(dockwin
->window
);