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 14/09/1998 (Dave Clark, clarkd@skyia.com)
16 * Updated createXBMfromXPM routine
17 * Now supports >256 colors
18 11/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
19 * Removed a bug from parse_rcfile. You could
20 not use "start" in a command if a label was
22 * Changed the needed geometry string.
23 We don't use window size, and don't support
25 03/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
27 02/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
28 * Added -geometry support (untested)
29 28/08/1998 (Martijn Pieterse, pieterse@xs4all.nl)
30 * Added createXBMfromXPM routine
31 * Saves a lot of work with changing xpm's.
32 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
33 * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
34 * debugged the parse_rc file.
35 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
36 * Ripped similar code from all the wm* programs,
37 and put them in a single file.
50 #include <X11/extensions/shape.h>
52 #include "wmgeneral.h"
62 XSizeHints mysizehints
;
64 Pixel back_pix
, fore_pix
;
83 MOUSE_REGION mouse_region
[MAX_MOUSE_REGION
];
85 /***********************/
86 /* Function Prototypes */
87 /***********************/
89 static void GetXPM(XpmIcon
*, char **);
90 static Pixel
GetColor(char *);
91 void RedrawWindow(void);
92 void AddMouseRegion(int, int, int, int, int);
93 int CheckMouseRegion(int, int);
95 /*****************************************************************************\
97 \*****************************************************************************/
99 void parse_rcfile(const char *filename
, rckeys
*keys
) {
103 char *tokens
= " :\t\n";
107 fp
= fopen(filename
, "r");
109 while (fgets(temp
, 128, fp
)) {
112 q
= strtok(q
, tokens
);
113 while (key
>= 0 && keys
[key
].label
) {
114 if ((!strcmp(q
, keys
[key
].label
))) {
115 p
= strstr(temp
, keys
[key
].label
);
116 p
+= strlen(keys
[key
].label
);
117 p
+= strspn(p
, tokens
);
118 if ((i
= strcspn(p
, "#\n"))) p
[i
] = 0;
119 free(*keys
[key
].var
);
120 *keys
[key
].var
= strdup(p
);
130 /***************************************************************************\
132 \***************************************************************************/
134 void parse_rcfile2(const char *filename
, rckeys2
*keys
) {
138 char *tokens
= " :\t\n";
143 fp
= fopen(filename
, "r");
145 while (fgets(temp
, 128, fp
)) {
147 while (key
>= 0 && keys
[key
].label
) {
148 if ((p
= strstr(temp
, keys
[key
].label
))) {
149 p
+= strlen(keys
[key
].label
);
150 p
+= strspn(p
, tokens
);
151 if ((i
= strcspn(p
, "#\n"))) p
[i
] = 0;
152 free(*keys
[key
].var
);
153 *keys
[key
].var
= strdup(p
);
164 /***************************************************************************\
166 \***************************************************************************/
168 static void GetXPM(XpmIcon
*wmgen
, char *pixmap_bytes
[]) {
170 XWindowAttributes attributes
;
173 /* For the colormap */
174 XGetWindowAttributes(display
, Root
, &attributes
);
176 wmgen
->attributes
.valuemask
|= (XpmReturnPixels
| XpmReturnExtensions
);
178 err
= XpmCreatePixmapFromData(display
, Root
, pixmap_bytes
, &(wmgen
->pixmap
),
179 &(wmgen
->mask
), &(wmgen
->attributes
));
181 if (err
!= XpmSuccess
) {
182 fprintf(stderr
, "Not enough free colorcells.\n");
187 /***************************************************************************\
189 \***************************************************************************/
191 static Pixel
GetColor(char *name
) {
194 XWindowAttributes attributes
;
196 XGetWindowAttributes(display
, Root
, &attributes
);
199 if (!XParseColor(display
, attributes
.colormap
, name
, &color
)) {
200 fprintf(stderr
, "wm.app: can't parse %s.\n", name
);
201 } else if (!XAllocColor(display
, attributes
.colormap
, &color
)) {
202 fprintf(stderr
, "wm.app: can't allocate %s.\n", name
);
207 /***************************************************************************\
209 \***************************************************************************/
211 static int flush_expose(Window w
) {
216 while (XCheckTypedWindowEvent(display
, w
, Expose
, &dummy
))
222 /***************************************************************************\
224 \***************************************************************************/
226 void RedrawWindow(void) {
228 flush_expose(iconwin
);
229 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
230 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
232 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
233 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
236 /***************************************************************************\
238 \***************************************************************************/
240 void RedrawWindowXY(int x
, int y
) {
242 flush_expose(iconwin
);
243 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
244 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
246 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
247 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
250 /***************************************************************************\
252 \***************************************************************************/
254 void AddMouseRegion(int index
, int left
, int top
, int right
, int bottom
) {
256 if (index
< MAX_MOUSE_REGION
) {
257 mouse_region
[index
].enable
= 1;
258 mouse_region
[index
].top
= top
;
259 mouse_region
[index
].left
= left
;
260 mouse_region
[index
].bottom
= bottom
;
261 mouse_region
[index
].right
= right
;
265 /***************************************************************************\
266 |* CheckMouseRegion *|
267 \***************************************************************************/
269 int CheckMouseRegion(int x
, int y
) {
276 for (i
=0; i
<MAX_MOUSE_REGION
&& !found
; i
++) {
277 if (mouse_region
[i
].enable
&&
278 x
<= mouse_region
[i
].right
&&
279 x
>= mouse_region
[i
].left
&&
280 y
<= mouse_region
[i
].bottom
&&
281 y
>= mouse_region
[i
].top
)
284 if (!found
) return -1;
288 /***************************************************************************\
289 |* createXBMfromXPM *|
290 \***************************************************************************/
291 void createXBMfromXPM(char *xbm
, char **xpm
, int sx
, int sy
) {
294 int width
, height
, numcol
, depth
;
296 unsigned char bwrite
;
300 sscanf(*xpm
, "%d %d %d %d", &width
, &height
, &numcol
, &depth
);
303 for (k
=0; k
!=depth
; k
++)
309 for (i
=numcol
+1; i
< numcol
+sy
+1; i
++) {
312 for (j
=0; j
<sx
*depth
; j
+=depth
) {
316 for (k
=0; k
!=depth
; k
++)
319 curpixel
|= xpm
[i
][j
+k
];
322 if ( curpixel
!= zero
) {
336 /***************************************************************************\
339 |* copies pixel area from master XPM to application window *|
341 |* x,y: first corner of area to be copied from master XPM *|
342 |* sx,sy: second corner of area to be copied from master XPM *|
343 |* dx,dy: first corner of target area *|
344 \***************************************************************************/
346 void copyXPMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
) {
348 XCopyArea(display
, wmgen
.pixmap
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
352 /***************************************************************************\
355 |* copies pixel area from XBM to master XPM?!?!? *|
357 |* x,y: first corner of area to be copied from XBM *|
358 |* sx,sy: width and height of area to be copied from XBM *|
359 |* dx,dy: first corner of target area *|
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
);
368 /***************************************************************************\
370 \***************************************************************************/
372 void setMaskXY(int x
, int y
) {
374 XShapeCombineMask(display
, win
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
375 XShapeCombineMask(display
, iconwin
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
378 /***************************************************************************\
380 \***************************************************************************/
381 void openXwindow(int argc
, char *argv
[], char *pixmap_bytes
[], char *pixmask_bits
, int pixmask_width
, int pixmask_height
) {
383 unsigned int borderwidth
= 1;
384 XClassHint classHint
;
385 char *display_name
= NULL
;
386 char *wname
= argv
[0];
392 char *geometry
= NULL
;
397 for (i
=1; argv
[i
]; i
++) {
398 if (!strcmp(argv
[i
], "-display")) {
399 display_name
= argv
[i
+1];
402 if (!strcmp(argv
[i
], "-geometry")) {
403 geometry
= argv
[i
+1];
408 if (!(display
= XOpenDisplay(display_name
))) {
409 fprintf(stderr
, "%s: can't open display %s\n",
410 wname
, XDisplayName(display_name
));
413 screen
= DefaultScreen(display
);
414 Root
= RootWindow(display
, screen
);
415 d_depth
= DefaultDepth(display
, screen
);
416 x_fd
= XConnectionNumber(display
);
418 /* Convert XPM to XImage */
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
);
448 XSelectInput(display
, iconwin
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
);
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
);
487 if (sscanf(geometry
, "+%d+%d", &wx
, &wy
) != 2) {
488 fprintf(stderr
, "Bad geometry string.\n");
491 XMoveWindow(display
, win
, wx
, wy
);