wmshutdown: Add support for suspend and hibernate.
[dockapps.git] / wmmemfree / dockapp.c
blob9c3ff16f343cdc1b566c549547a2d0dda7248122
1 /*
2 * dockapp.c - dockapp part
4 * Copyright (C) 2003 Draghicioiu Mihai <misuceldestept@go.ro>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <signal.h>
24 #include <X11/X.h>
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <X11/xpm.h>
28 #include <X11/extensions/shape.h>
29 #include <X11/extensions/shapeconst.h>
30 #include <X11/cursorfont.h>
32 #include "wmmemfree.h"
33 #include "options.h"
35 #include "xpm/bg.xpm"
36 #include "xpm/on.xpm"
37 #include "xpm/off.xpm"
38 #include "xpm/numbers.xpm"
39 #include "xpm/panel.xpm"
41 #define WINDOW_WIDTH 64
42 #define WINDOW_HEIGHT 64
44 Display *display;
45 int screen;
46 Window iconwindow, window, mapwindow;
47 Colormap colormap;
48 GC gc;
49 Pixmap background, backgroundmask, on, off, numbers, buffer, panel;
50 Atom wm_delete_window;
51 Atom _motif_wm_hints;
52 int moving, oldx, oldy;
53 int screenwidth, screenheight;
54 Cursor fleur;
56 void free_stuff()
58 XUnmapWindow(display, mapwindow);
59 XFreeGC(display, gc);
60 XDestroyWindow(display, iconwindow);
61 XDestroyWindow(display, window);
62 XFreePixmap(display, buffer);
63 XFreePixmap(display, numbers);
64 XFreePixmap(display, off);
65 XFreePixmap(display, on);
66 XFreePixmap(display, backgroundmask);
67 XFreePixmap(display, background);
68 XCloseDisplay(display);
71 void handle_signal(int sig)
73 switch(sig)
75 case SIGINT:
76 fprintf(stderr, "Interrupt received\n");
77 break;
78 case SIGQUIT:
79 fprintf(stderr, "Quit signal received\n");
80 break;
81 case SIGTERM:
82 fprintf(stderr, "Terminate signal received\n");
83 default:
84 fprintf(stderr, "Got signal %d\n", sig);
86 stop_timer();
87 free_stuff();
88 exit(0);
91 void make_window()
93 Window rootwindow;
94 XpmAttributes xpmattributes;
95 XSetWindowAttributes windowattributes;
96 int shapeevent, shapeerror;
97 XWMHints *wmhints;
98 XClassHint *classhint;
99 XSizeHints *sizehints;
100 XGCValues gcvalues;
101 unsigned int depth;
102 struct
104 long flags;
105 long functions;
106 long decorations;
107 long input_mode;
108 long unknown;
109 } mwmhints;
112 display = XOpenDisplay(opt_display);
113 if(!display)
115 fprintf(stderr, "Could not open display %s\n", opt_display);
116 exit(1);
118 screen = DefaultScreen(display);
119 screenwidth = DisplayWidth(display, screen);
120 screenheight = DisplayHeight(display, screen);
121 rootwindow = RootWindow(display, screen);
122 colormap = DefaultColormap(display, screen);
123 depth = DefaultDepth(display, screen);
124 xpmattributes.valuemask = XpmColormap | XpmCloseness;
125 xpmattributes.colormap = colormap;
126 xpmattributes.closeness = 40000;
127 XpmCreatePixmapFromData(display, rootwindow, bg_xpm,
128 &background, &backgroundmask, &xpmattributes);
129 XpmCreatePixmapFromData(display, rootwindow, on_xpm,
130 &on, None, &xpmattributes);
131 XpmCreatePixmapFromData(display, rootwindow, off_xpm,
132 &off, None, &xpmattributes);
133 XpmCreatePixmapFromData(display, rootwindow, numbers_xpm,
134 &numbers, None, &xpmattributes);
135 buffer = XCreatePixmap(display, rootwindow,
136 WINDOW_WIDTH, WINDOW_HEIGHT, depth);
137 windowattributes.background_pixmap = background;
138 windowattributes.event_mask = ExposureMask |
139 ButtonPressMask |
140 ButtonReleaseMask |
141 PointerMotionMask |
142 PropertyChangeMask;
143 windowattributes.colormap = colormap;
144 window = XCreateWindow(display, rootwindow,
145 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
146 CopyFromParent,
147 InputOutput,
148 CopyFromParent,
149 CWBackPixmap | CWEventMask | CWColormap,
150 &windowattributes);
151 iconwindow = XCreateWindow(display, rootwindow,
152 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0,
153 CopyFromParent,
154 InputOutput,
155 CopyFromParent,
156 CWBackPixmap | CWEventMask,
157 &windowattributes);
158 fleur = XCreateFontCursor(display, XC_fleur);
159 if(XShapeQueryExtension(display, &shapeevent, &shapeerror) && opt_shape)
161 XShapeCombineMask(display, window, ShapeBounding,
162 0, 0, backgroundmask, ShapeSet);
163 XShapeCombineMask(display, iconwindow, ShapeBounding,
164 0, 0, backgroundmask, ShapeSet);
166 else
168 XpmCreatePixmapFromData(display, rootwindow, panel_xpm,
169 &panel, None, &xpmattributes);
170 gcvalues.function = GXcopy;
171 gcvalues.graphics_exposures = False;
172 gcvalues.clip_mask = backgroundmask;
173 gcvalues.clip_x_origin = 0;
174 gcvalues.clip_y_origin = 0;
175 gc = XCreateGC(display, rootwindow,
176 GCFunction |
177 GCGraphicsExposures |
178 GCClipMask |
179 GCClipXOrigin |
180 GCClipYOrigin,
181 &gcvalues);
182 XCopyArea(display, background, panel, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
183 gcvalues.clip_mask = None;
184 XChangeGC(display, gc, GCClipMask, &gcvalues);
185 XCopyArea(display, panel, background, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
186 XFreeGC(display, gc);
187 XFreePixmap(display, panel);
190 mapwindow = opt_window ? iconwindow : window;
191 wmhints = XAllocWMHints();
192 wmhints -> flags = InputHint | WindowGroupHint | IconWindowHint | StateHint;
193 wmhints -> input = True;
194 wmhints -> window_group = window;
195 wmhints -> icon_window = iconwindow;
196 wmhints -> initial_state = WithdrawnState;
197 XSetWMHints(display, window, wmhints);
198 XFree(wmhints);
200 classhint = XAllocClassHint();
201 classhint -> res_name = OPT_CLASS_NAME;
202 classhint -> res_class = OPT_CLASS_CLASS;
203 XSetClassHint(display, mapwindow, classhint);
204 XFree(classhint);
206 sizehints = XAllocSizeHints();
207 sizehints -> flags = USSize | PSize | PMinSize | PMaxSize | PBaseSize;
208 sizehints -> width = WINDOW_WIDTH;
209 sizehints -> height = WINDOW_HEIGHT;
210 sizehints -> min_width = WINDOW_WIDTH;
211 sizehints -> min_height = WINDOW_HEIGHT;
212 sizehints -> max_width = WINDOW_WIDTH;
213 sizehints -> max_height = WINDOW_HEIGHT;
214 sizehints -> base_width = WINDOW_WIDTH;
215 sizehints -> base_height = WINDOW_HEIGHT;
216 XSetWMNormalHints(display, mapwindow, sizehints);
217 XFree(sizehints);
219 XStoreName(display, window, OPT_WINDOW_NAME);
220 XStoreName(display, iconwindow, OPT_WINDOW_NAME); /* For other wms */
222 gcvalues.graphics_exposures = False;
223 gcvalues.function = GXcopy;
224 gc = XCreateGC(display, rootwindow,
225 GCGraphicsExposures | GCFunction,
226 &gcvalues);
227 XCopyArea(display, background, buffer, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
228 XSetCommand(display, window, argv, argc);
229 wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0);
230 XSetWMProtocols(display, mapwindow, &wm_delete_window, 1);
231 if(opt_window)
233 _motif_wm_hints = XInternAtom(display, "_MOTIF_WM_HINTS", 0);
234 mwmhints.flags = 2;
235 mwmhints.functions = 0x71; /* WTF IS THIS ? */
236 mwmhints.decorations = 0;
237 XChangeProperty(display, mapwindow,
238 _motif_wm_hints, _motif_wm_hints,
239 32, PropModeReplace, (unsigned char *)&mwmhints, 5);
241 XMapWindow(display, mapwindow);
242 signal(SIGINT, handle_signal);
243 signal(SIGQUIT, handle_signal);
244 signal(SIGTERM, handle_signal);
247 void update_window()
249 XCopyArea(display, buffer, iconwindow, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
250 XCopyArea(display, buffer, window, gc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
253 void process_events()
255 XEvent event;
256 int winx, winy;
258 XNextEvent(display, &event);
259 switch(event.type)
261 case Expose:
262 update_window();
263 break;
264 case ButtonPress:
265 if(opt_window && (event.xbutton.button == 1))
267 XDefineCursor(display, mapwindow, fleur);
268 moving = 1;
269 oldx = event.xbutton.x;
270 oldy = event.xbutton.y;
272 break;
273 case MotionNotify:
274 winx = event.xmotion.x_root - oldx;
275 winy = event.xmotion.y_root - oldy;
276 if(winx < 0) winx = 0;
277 if(winy < 0) winy = 0;
278 if(winx > (screenwidth - WINDOW_WIDTH))
279 winx = screenwidth - WINDOW_WIDTH;
280 if(winy > (screenheight - WINDOW_HEIGHT))
281 winy = screenheight - WINDOW_HEIGHT;
282 if(moving)
283 XMoveWindow(display, mapwindow, winx, winy);
284 break;
285 case ButtonRelease:
286 if(opt_window)
288 moving = 0;
289 XUndefineCursor(display, mapwindow);
291 break;
292 case ClientMessage:
293 if(event.xclient.data.l[0] == wm_delete_window)
294 exitloop = 1;
295 break;