2 Best viewed with GNU Emacs 19
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)
17 14/09/1998 (Dave Clark, clarkd@skyia.com)
18 * Updated createXBMfromXPM routine
19 * Now supports >256 colors
20 11/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
21 * Removed a bug from parse_rcfile. You could
22 not use "start" in a command if a label was
24 * Changed the needed geometry string.
25 We don't use window size, and don't support
27 03/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
29 02/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
30 * Added -geometry support (untested)
31 28/08/1998 (Martijn Pieterse, pieterse@xs4all.nl)
32 * Added createXBMfromXPM routine
33 * Saves a lot of work with changing xpm's.
34 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
35 * changed the read_rc_file to parse_rcfile, as suggested by Marcelo E. Magallon
36 * debugged the parse_rc file.
37 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
38 * Ripped similar code from all the wm* programs,
39 and put them in a single file.
52 #include <X11/extensions/shape.h>
54 #include "wmgeneral.h"
55 #include "charset.xpm"
64 XSizeHints mysizehints
;
66 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(unsigned, int, int, int, int);
93 int CheckMouseRegion(int, int);
94 void PutPixel(int, int, int);
95 int GetPixel(int, int);
97 /*******************************************************************************\
99 \*******************************************************************************/
101 void parse_rcfile(const char *filename
, rckeys
* keys
)
106 char *tokens
= " :\t\n";
110 fp
= fopen(filename
, "r");
112 while (fgets(temp
, 128, fp
)) {
115 q
= strtok(q
, tokens
);
116 while (key
>= 0 && keys
[key
].label
) {
117 if ((!strcmp(q
, keys
[key
].label
))) {
118 p
= strstr(temp
, keys
[key
].label
);
119 p
+= strlen(keys
[key
].label
);
120 p
+= strspn(p
, tokens
);
121 if ((i
= strcspn(p
, "#\n")))
123 free(*keys
[key
].var
);
124 *keys
[key
].var
= strdup(p
);
135 /*******************************************************************************\
137 \*******************************************************************************/
139 void parse_rcfile2(const char *filename
, rckeys2
* keys
)
144 char *tokens
= " :\t\n";
149 fp
= fopen(filename
, "r");
151 while (fgets(temp
, 128, fp
)) {
153 while (key
>= 0 && keys
[key
].label
) {
154 if ((p
= strstr(temp
, keys
[key
].label
))) {
155 p
+= strlen(keys
[key
].label
);
156 p
+= strspn(p
, tokens
);
157 if ((i
= strcspn(p
, "#\n")))
159 free(*keys
[key
].var
);
160 *keys
[key
].var
= strdup(p
);
172 /*******************************************************************************\
174 \*******************************************************************************/
176 static void GetXPM(XpmIcon
* wmgen
, char *pixmap_bytes
[])
179 XWindowAttributes attributes
;
182 /* For the colormap */
183 XGetWindowAttributes(display
, Root
, &attributes
);
185 wmgen
->attributes
.valuemask
|= (XpmReturnPixels
| XpmReturnExtensions
);
187 err
= XpmCreatePixmapFromData(display
, Root
, pixmap_bytes
, &(wmgen
->pixmap
),
188 &(wmgen
->mask
), &(wmgen
->attributes
));
190 if (err
!= XpmSuccess
) {
191 fprintf(stderr
, "Not enough free colorcells.\n");
196 /*******************************************************************************\
198 \*******************************************************************************/
200 static Pixel
GetColor(char *name
)
204 XWindowAttributes attributes
;
206 XGetWindowAttributes(display
, Root
, &attributes
);
209 if (!XParseColor(display
, attributes
.colormap
, name
, &color
)) {
210 fprintf(stderr
, "wm.app: can't parse %s.\n", name
);
211 } else if (!XAllocColor(display
, attributes
.colormap
, &color
)) {
212 fprintf(stderr
, "wm.app: can't allocate %s.\n", name
);
217 /*******************************************************************************\
219 \*******************************************************************************/
221 static int flush_expose(Window w
)
227 while (XCheckTypedWindowEvent(display
, w
, Expose
, &dummy
))
233 /*******************************************************************************\
235 \*******************************************************************************/
237 void RedrawWindow(void)
240 flush_expose(iconwin
);
241 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
242 0, 0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0, 0);
244 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
245 0, 0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0, 0);
248 /*******************************************************************************\
250 \*******************************************************************************/
252 void RedrawWindowXY(int x
, int y
)
255 flush_expose(iconwin
);
256 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
257 x
, y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0, 0);
259 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
260 x
, y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0, 0);
263 /*******************************************************************************\
265 \*******************************************************************************/
267 void AddMouseRegion(unsigned index
, int left
, int top
, int right
, int bottom
)
270 if (index
< MAX_MOUSE_REGION
) {
271 mouse_region
[index
].enable
= 1;
272 mouse_region
[index
].top
= top
;
273 mouse_region
[index
].left
= left
;
274 mouse_region
[index
].bottom
= bottom
;
275 mouse_region
[index
].right
= right
;
279 /*******************************************************************************\
280 |* CheckMouseRegion *|
281 \*******************************************************************************/
283 int CheckMouseRegion(int x
, int y
)
291 for (i
= 0; i
< MAX_MOUSE_REGION
&& !found
; i
++) {
292 if (mouse_region
[i
].enable
&&
293 x
<= mouse_region
[i
].right
&&
294 x
>= mouse_region
[i
].left
&&
295 y
<= mouse_region
[i
].bottom
&&
296 y
>= mouse_region
[i
].top
)
304 /***************************************************************************\
305 |* createXBMfromXPM *|
306 \***************************************************************************/
307 void createXBMfromXPM(char *xbm
, char **xpm
, int sx
, int sy
)
311 int width
, height
, numcol
, depth
;
313 unsigned char bwrite
;
317 sscanf(*xpm
, "%d %d %d %d", &width
, &height
, &numcol
, &depth
);
320 for (k
= 0; k
!= depth
; k
++) {
325 for (i
= numcol
+ 1; i
< numcol
+ sy
+ 1; i
++) {
328 for (j
= 0; j
< sx
* depth
; j
+= depth
) {
332 for (k
= 0; k
!= depth
; k
++) {
334 curpixel
|= xpm
[i
][j
+ k
];
337 if (curpixel
!= zero
) {
351 /*******************************************************************************\
353 \*******************************************************************************/
355 void copyXPMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
)
358 XCopyArea(display
, wmgen
.pixmap
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
362 /*******************************************************************************\
364 \*******************************************************************************/
366 void copyXBMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
)
369 XCopyArea(display
, wmgen
.mask
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
373 /*******************************************************************************\
375 \*******************************************************************************/
377 void setMaskXY(int x
, int y
)
380 XShapeCombineMask(display
, win
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
381 XShapeCombineMask(display
, iconwin
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
384 /*******************************************************************************\
386 \*******************************************************************************/
387 void openXwindow(int argc
, char *argv
[], char *pixmap_bytes
[], char *pixmask_bits
, int pixmask_width
, int pixmask_height
)
390 unsigned int borderwidth
= 1;
391 XClassHint classHint
;
392 char *display_name
= NULL
;
393 char *wname
= argv
[0];
399 char *geometry
= NULL
;
404 for (i
= 1; argv
[i
]; i
++) {
405 if (!strcmp(argv
[i
], "-display")) {
406 display_name
= argv
[i
+ 1];
409 if (!strcmp(argv
[i
], "-geometry")) {
410 geometry
= argv
[i
+ 1];
415 if (!(display
= XOpenDisplay(display_name
))) {
416 fprintf(stderr
, "%s: can't open display %s\n",
417 wname
, XDisplayName(display_name
));
420 screen
= DefaultScreen(display
);
421 Root
= RootWindow(display
, screen
);
422 d_depth
= DefaultDepth(display
, screen
);
423 x_fd
= XConnectionNumber(display
);
425 /* Convert XPM to XImage */
426 GetXPM(&wmgen
, pixmap_bytes
);
428 /* Create a window to hold the stuff */
429 mysizehints
.flags
= USSize
| USPosition
;
433 back_pix
= GetColor("white");
434 fore_pix
= GetColor("black");
436 XWMGeometry(display
, screen
, Geometry
, NULL
, borderwidth
, &mysizehints
,
437 &mysizehints
.x
, &mysizehints
.y
, &mysizehints
.width
, &mysizehints
.height
, &dummy
);
439 mysizehints
.width
= 64;
440 mysizehints
.height
= 64;
442 win
= XCreateSimpleWindow(display
, Root
, mysizehints
.x
, mysizehints
.y
,
443 mysizehints
.width
, mysizehints
.height
, borderwidth
, fore_pix
, back_pix
);
445 iconwin
= XCreateSimpleWindow(display
, win
, mysizehints
.x
, mysizehints
.y
,
446 mysizehints
.width
, mysizehints
.height
, borderwidth
, fore_pix
, back_pix
);
449 XSetWMNormalHints(display
, win
, &mysizehints
);
450 classHint
.res_name
= wname
;
451 classHint
.res_class
= wname
;
452 XSetClassHint(display
, win
, &classHint
);
454 XSelectInput(display
, win
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
);
455 XSelectInput(display
, iconwin
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
);
457 if (XStringListToTextProperty(&wname
, 1, &name
) == 0) {
458 fprintf(stderr
, "%s: can't allocate window name\n", wname
);
461 XSetWMName(display
, win
, &name
);
463 /* Create GC for drawing */
465 gcm
= GCForeground
| GCBackground
| GCGraphicsExposures
;
466 gcv
.foreground
= fore_pix
;
467 gcv
.background
= back_pix
;
468 gcv
.graphics_exposures
= 0;
469 NormalGC
= XCreateGC(display
, Root
, gcm
, &gcv
);
473 pixmask
= XCreateBitmapFromData(display
, win
, pixmask_bits
, pixmask_width
, pixmask_height
);
475 XShapeCombineMask(display
, win
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
476 XShapeCombineMask(display
, iconwin
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
480 mywmhints
.initial_state
= WithdrawnState
;
481 mywmhints
.icon_window
= iconwin
;
482 mywmhints
.icon_x
= mysizehints
.x
;
483 mywmhints
.icon_y
= mysizehints
.y
;
484 mywmhints
.window_group
= win
;
485 mywmhints
.flags
= StateHint
| IconWindowHint
| IconPositionHint
| WindowGroupHint
;
487 XSetWMHints(display
, win
, &mywmhints
);
489 XSetCommand(display
, win
, argv
, argc
);
490 XMapWindow(display
, win
);
494 if (sscanf(geometry
, "+%d+%d", &wx
, &wy
) != 2) {
495 fprintf(stderr
, "Bad geometry string.\n");
498 XMoveWindow(display
, win
, wx
, wy
);
508 GetXPM(&wmfont
, charset_xpm
);
511 void draw_char(char c
, int x
, int y
)
516 XCopyArea(display
, wmfont
.pixmap
, wmgen
.pixmap
, NormalGC
, sx
, sy
, 6, 7,
520 void draw_string(char *s
, int x
, int y
)
525 while (i
< strlen(s
)) {
526 if ((x
+ (x_space
* i
)) < 64) {
527 draw_char(s
[i
], x
+ (x_space
* i
), y
);