2 Best viewed with vim5, using ts=4
4 wmgeneral was taken from wmppp.
6 It has a lot of routines which most of the wm* programs use.
8 ------------------------------------------------------------
10 Author: Martijn Pieterse (pieterse@xs4all.nl)
15 25/08/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
16 * Fixed --display handling.
17 23/08/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
18 * Fixed --geometry handling.
19 05/07/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
20 * Fixed --geometry handling.
21 23/05/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
22 * Added missing prototype for parse_rcfile2.
23 18/04/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
24 * Improved bugfix in createXBMfromXPM from 17/04/2002.
25 17/04/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
26 * Fixed a bug in createXBMfromXPM, introduced on 10/03/2002.
27 31/03/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
28 * Some changes to make this file work with wmweather v1.31 and v2.0:
29 + extracted initXwindow from openXwindow,
30 + added XpmColorSymbols to valuemask in GetXPM,
31 + added colorspec to colorsymbols in openXwindow.
32 10/03/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
33 * Added > 1 char/pixel support in createXBMfromXPM.
34 09/03/2002 (Martin A. Godisch, godisch@tcs.inf.tu-dresden.de)
35 * Added EnterWindowMask, LeaveWindowMask, KeyPressMask,
36 KeyReleaseMask in XSelectInput
37 11/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
38 * Removed a bug from parse_rcfile. You could
39 not use "start" in a command if a label was
41 * Changed the needed geometry string.
42 We don't use window size, and don't support
44 03/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
46 02/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
47 * Added -geometry support (untested)
48 28/08/1998 (Martijn Pieterse, pieterse@xs4all.nl)
49 * Added createXBMfromXPM routine
50 * Saves a lot of work with changing xpm's.
51 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
52 * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
53 * debugged the parse_rc file.
54 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
55 * Ripped similar code from all the wm* programs,
56 and put them in a single file.
69 #include <X11/extensions/shape.h>
71 #include "wmgeneral.h"
81 XSizeHints mysizehints
;
83 Pixel back_pix
, fore_pix
;
101 MOUSE_REGION mouse_region
[MAX_MOUSE_REGION
];
103 /***********************/
104 /* Function Prototypes */
105 /***********************/
107 static void GetXPM(XpmIcon
*, char **);
108 static Pixel
GetColor(char *);
109 void RedrawWindow(void);
110 void AddMouseRegion(unsigned, int, int, int, int);
111 int CheckMouseRegion(int, int);
113 /*******************************************************************************\
115 \*******************************************************************************/
117 void parse_rcfile(const char *filename
, rckeys
*keys
) {
121 char *tokens
= " :\t\n";
125 fp
= fopen(filename
, "r");
127 while (fgets(temp
, 128, fp
)) {
130 q
= strtok(q
, tokens
);
131 while (key
>= 0 && keys
[key
].label
) {
132 if ((!strcmp(q
, keys
[key
].label
))) {
133 p
= strstr(temp
, keys
[key
].label
);
134 p
+= strlen(keys
[key
].label
);
135 p
+= strspn(p
, tokens
);
136 if ((i
= strcspn(p
, "#\n"))) p
[i
] = 0;
137 free(*keys
[key
].var
);
138 *keys
[key
].var
= strdup(p
);
148 /*******************************************************************************\
150 \*******************************************************************************/
152 void parse_rcfile2(const char *filename
, rckeys2
*keys
) {
156 char *tokens
= " :\t\n";
161 fp
= fopen(filename
, "r");
163 while (fgets(temp
, 128, fp
)) {
165 while (key
>= 0 && keys
[key
].label
) {
166 if ((p
= strstr(temp
, keys
[key
].label
))) {
167 p
+= strlen(keys
[key
].label
);
168 p
+= strspn(p
, tokens
);
169 if ((i
= strcspn(p
, "#\n"))) p
[i
] = 0;
170 free(*keys
[key
].var
);
171 *keys
[key
].var
= strdup(p
);
182 /*******************************************************************************\
184 \*******************************************************************************/
186 static void GetXPM(XpmIcon
*wmgen
, char *pixmap_bytes
[]) {
188 XWindowAttributes attributes
;
191 /* For the colormap */
192 XGetWindowAttributes(display
, Root
, &attributes
);
194 wmgen
->attributes
.valuemask
|= (XpmReturnPixels
| XpmReturnExtensions
| XpmColorSymbols
);
196 err
= XpmCreatePixmapFromData(display
, Root
, pixmap_bytes
, &(wmgen
->pixmap
),
197 &(wmgen
->mask
), &(wmgen
->attributes
));
199 if (err
!= XpmSuccess
) {
200 fprintf(stderr
, "wm.app: not enough free colorcells.\n");
205 /*******************************************************************************\
207 \*******************************************************************************/
209 static Pixel
GetColor(char *name
) {
212 XWindowAttributes attributes
;
214 XGetWindowAttributes(display
, Root
, &attributes
);
217 if (!XParseColor(display
, attributes
.colormap
, name
, &color
)) {
218 fprintf(stderr
, "wm.app: can't parse %s.\n", name
);
219 } else if (!XAllocColor(display
, attributes
.colormap
, &color
)) {
220 fprintf(stderr
, "wm.app: can't allocate %s.\n", name
);
225 /*******************************************************************************\
227 \*******************************************************************************/
229 static int flush_expose(Window w
) {
234 while (XCheckTypedWindowEvent(display
, w
, Expose
, &dummy
))
240 /*******************************************************************************\
242 \*******************************************************************************/
244 void RedrawWindow(void) {
246 flush_expose(iconwin
);
247 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
248 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
250 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
251 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
254 /*******************************************************************************\
256 \*******************************************************************************/
258 void RedrawWindowXY(int x
, int y
) {
260 flush_expose(iconwin
);
261 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
262 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
264 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
265 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
268 /*******************************************************************************\
270 \*******************************************************************************/
272 void AddMouseRegion(unsigned index
, int left
, int top
, int right
, int bottom
) {
274 if (index
< MAX_MOUSE_REGION
) {
275 mouse_region
[index
].enable
= 1;
276 mouse_region
[index
].top
= top
;
277 mouse_region
[index
].left
= left
;
278 mouse_region
[index
].bottom
= bottom
;
279 mouse_region
[index
].right
= right
;
283 /*******************************************************************************\
284 |* CheckMouseRegion *|
285 \*******************************************************************************/
287 int CheckMouseRegion(int x
, int y
) {
294 for (i
=0; i
<MAX_MOUSE_REGION
&& !found
; i
++) {
295 if (mouse_region
[i
].enable
&&
296 x
<= mouse_region
[i
].right
&&
297 x
>= mouse_region
[i
].left
&&
298 y
<= mouse_region
[i
].bottom
&&
299 y
>= mouse_region
[i
].top
)
302 if (!found
) return -1;
306 /*******************************************************************************\
307 |* createXBMfromXPM *|
308 \*******************************************************************************/
310 void createXBMfromXPM(char *xbm
, char **xpm
, int sx
, int sy
) {
313 int width
, height
, numcol
, chars
;
314 char *zero
, *color
, *pos
;
315 unsigned char bwrite
;
319 sscanf(*xpm
, "%d %d %d %d", &width
, &height
, &numcol
, &chars
);
321 zero
= malloc(chars
* sizeof(char));
322 color
= malloc(chars
* sizeof(char));
323 memcpy(zero
, xpm
[1], chars
);
324 for (i
= numcol
+1; i
< numcol
+sy
+1; i
++) {
328 for (j
= 0; j
< sx
; j
++) {
330 memcpy(color
, pos
, chars
);
331 if (memcmp(color
, zero
, chars
)) {
341 pos
+= chars
* sizeof(char);
348 /*******************************************************************************\
350 \*******************************************************************************/
352 void copyXPMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
) {
354 XCopyArea(display
, wmgen
.pixmap
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
358 /*******************************************************************************\
360 \*******************************************************************************/
362 void copyXBMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
) {
364 XCopyArea(display
, wmgen
.mask
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
367 /*******************************************************************************\
369 \*******************************************************************************/
371 void setMaskXY(int x
, int y
) {
373 XShapeCombineMask(display
, win
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
374 XShapeCombineMask(display
, iconwin
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
377 /*******************************************************************************\
379 \*******************************************************************************/
381 void initXwindow(char *display_name
) {
383 if (!(display
= XOpenDisplay(display_name
))) {
384 fprintf(stderr
, "wm.app: can't open display %s\n",
385 XDisplayName(display_name
));
388 screen
= DefaultScreen(display
);
389 Root
= RootWindow(display
, screen
);
390 d_depth
= DefaultDepth(display
, screen
);
391 x_fd
= XConnectionNumber(display
);
395 /*******************************************************************************\
397 \*******************************************************************************/
399 void openXwindow(int argc
, char *argv
[], char *pixmap_bytes
[], char *pixmask_bits
, int pixmask_width
, int pixmask_height
, char *geometry
, XpmColorSymbol
*colorspec
) {
401 unsigned int borderwidth
= 1;
402 XClassHint classHint
;
403 char *wname
= argv
[0];
412 /* Convert XPM to XImage */
414 for (i
= 0; colorspec
[i
].name
; i
++)
415 colorspec
[i
].pixel
= GetColor(colorspec
[i
].value
);
416 wmgen
.attributes
.numsymbols
= i
;
417 wmgen
.attributes
.colorsymbols
= colorspec
;
419 GetXPM(&wmgen
, pixmap_bytes
);
421 /* Create a window to hold the stuff */
422 mysizehints
.flags
= USSize
| USPosition
;
426 back_pix
= GetColor("white");
427 fore_pix
= GetColor("black");
429 XWMGeometry(display
, screen
, geometry
, NULL
, borderwidth
, &mysizehints
,
430 &mysizehints
.x
, &mysizehints
.y
,&mysizehints
.width
,&mysizehints
.height
, &dummy
);
432 mysizehints
.width
= 64;
433 mysizehints
.height
= 64;
435 win
= XCreateSimpleWindow(display
, Root
, mysizehints
.x
, mysizehints
.y
,
436 mysizehints
.width
, mysizehints
.height
, borderwidth
, fore_pix
, back_pix
);
438 iconwin
= XCreateSimpleWindow(display
, win
, mysizehints
.x
, mysizehints
.y
,
439 mysizehints
.width
, mysizehints
.height
, borderwidth
, fore_pix
, back_pix
);
442 XSetWMNormalHints(display
, win
, &mysizehints
);
443 classHint
.res_name
= wname
;
444 classHint
.res_class
= wname
;
445 XSetClassHint(display
, win
, &classHint
);
447 XSelectInput(display
, win
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
| EnterWindowMask
| LeaveWindowMask
| KeyPressMask
| KeyReleaseMask
);
448 XSelectInput(display
, iconwin
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
| EnterWindowMask
| LeaveWindowMask
| KeyPressMask
| KeyReleaseMask
);
450 if (XStringListToTextProperty(&wname
, 1, &name
) == 0) {
451 fprintf(stderr
, "%s: can't allocate window name\n", wname
);
455 XSetWMName(display
, win
, &name
);
457 /* Create GC for drawing */
459 gcm
= GCForeground
| GCBackground
| GCGraphicsExposures
;
460 gcv
.foreground
= fore_pix
;
461 gcv
.background
= back_pix
;
462 gcv
.graphics_exposures
= 0;
463 NormalGC
= XCreateGC(display
, Root
, gcm
, &gcv
);
467 pixmask
= XCreateBitmapFromData(display
, win
, pixmask_bits
, pixmask_width
, pixmask_height
);
469 XShapeCombineMask(display
, win
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
470 XShapeCombineMask(display
, iconwin
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
474 mywmhints
.initial_state
= WithdrawnState
;
475 mywmhints
.icon_window
= iconwin
;
476 mywmhints
.icon_x
= mysizehints
.x
;
477 mywmhints
.icon_y
= mysizehints
.y
;
478 mywmhints
.window_group
= win
;
479 mywmhints
.flags
= StateHint
| IconWindowHint
| IconPositionHint
| WindowGroupHint
;
481 XSetWMHints(display
, win
, &mywmhints
);
483 XSetCommand(display
, win
, argv
, argc
);
484 XMapWindow(display
, win
);