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 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
16 * changed the read_rc_file to parse_rcfile, as suggester by Marcelo E. Magallon
17 * debugged the parse_rc file.
18 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
19 * Ripped similar code from all the wm* programs,
20 and put them in a single file.
33 #include <X11/extensions/shape.h>
35 #include "wmgeneral.h"
45 XSizeHints mysizehints
;
47 Pixel back_pix
, fore_pix
;
66 #define MAX_MOUSE_REGION (8)
67 MOUSE_REGION mouse_region
[MAX_MOUSE_REGION
];
69 /***********************/
70 /* Function Prototypes */
71 /***********************/
73 static void GetXPM(XpmIcon
*, char **);
74 static Pixel
GetColor(char *);
75 void RedrawWindow(void);
76 void AddMouseRegion(int, int, int, int, int);
77 int CheckMouseRegion(int, int);
79 /*******************************************************************************\
81 \*******************************************************************************/
83 void parse_rcfile(const char *filename
, rckeys
*keys
) {
87 char *tokens
= " :\t\n";
91 fp
= fopen(filename
, "r");
93 while (fgets(temp
, 128, fp
)) {
95 printf("read: %s\n",temp
);
96 while (key
>= 0 && keys
[key
].label
) {
97 printf("key: %s\n",keys
[key
].label
);
98 if ((p
= strstr(temp
, keys
[key
].label
))) {
99 p
+= strlen(keys
[key
].label
);
100 p
+= strspn(p
, tokens
);
101 if ((i
= strcspn(p
, "#\n"))) p
[i
] = 0;
102 free(*keys
[key
].var
);
103 *keys
[key
].var
= strdup(p
);
113 /*******************************************************************************\
115 \*******************************************************************************/
117 static void GetXPM(XpmIcon
*wmgen
, char *pixmap_bytes
[]) {
119 XWindowAttributes attributes
;
122 /* For the colormap */
123 XGetWindowAttributes(display
, Root
, &attributes
);
125 wmgen
->attributes
.valuemask
|= (XpmReturnPixels
| XpmReturnExtensions
);
127 err
= XpmCreatePixmapFromData(display
, Root
, pixmap_bytes
, &(wmgen
->pixmap
),
128 &(wmgen
->mask
), &(wmgen
->attributes
));
130 if (err
!= XpmSuccess
) {
131 fprintf(stderr
, "Not enough free colorcells.\n");
136 /*******************************************************************************\
138 \*******************************************************************************/
140 static Pixel
GetColor(char *name
) {
143 XWindowAttributes attributes
;
145 XGetWindowAttributes(display
, Root
, &attributes
);
148 if (!XParseColor(display
, attributes
.colormap
, name
, &color
)) {
149 fprintf(stderr
, "wm.app: can't parse %s.\n", name
);
150 } else if (!XAllocColor(display
, attributes
.colormap
, &color
)) {
151 fprintf(stderr
, "wm.app: can't allocate %s.\n", name
);
156 /*******************************************************************************\
158 \*******************************************************************************/
160 static int flush_expose(Window w
) {
165 while (XCheckTypedWindowEvent(display
, w
, Expose
, &dummy
))
171 /*******************************************************************************\
173 \*******************************************************************************/
175 void RedrawWindow(void) {
177 flush_expose(iconwin
);
178 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
179 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
181 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
182 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
185 /*******************************************************************************\
187 \*******************************************************************************/
189 void RedrawWindowXY(int x
, int y
) {
191 flush_expose(iconwin
);
192 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
193 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
195 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
196 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
199 /*******************************************************************************\
201 \*******************************************************************************/
203 void AddMouseRegion(int index
, int left
, int top
, int right
, int bottom
) {
205 if (index
< MAX_MOUSE_REGION
) {
206 mouse_region
[index
].enable
= 1;
207 mouse_region
[index
].top
= top
;
208 mouse_region
[index
].left
= left
;
209 mouse_region
[index
].bottom
= bottom
;
210 mouse_region
[index
].right
= right
;
214 /*******************************************************************************\
215 |* DelMouseRegion added for wmdonkeymon *|
216 \*******************************************************************************/
218 void DelMouseRegion(int index
) {
220 if (index
< MAX_MOUSE_REGION
) {
221 mouse_region
[index
].enable
= 0;
225 /*******************************************************************************\
226 |* CheckMouseRegion *|
227 \*******************************************************************************/
229 int CheckMouseRegion(int x
, int y
) {
236 for (i
=0; i
<MAX_MOUSE_REGION
&& !found
; i
++) {
237 if (mouse_region
[i
].enable
&&
238 x
<= mouse_region
[i
].right
&&
239 x
>= mouse_region
[i
].left
&&
240 y
<= mouse_region
[i
].bottom
&&
241 y
>= mouse_region
[i
].top
)
244 if (!found
) return -1;
248 /*******************************************************************************\
250 \*******************************************************************************/
252 void copyXPMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
) {
254 XCopyArea(display
, wmgen
.pixmap
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
258 /*******************************************************************************\
260 \*******************************************************************************/
262 void copyXBMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
) {
264 XCopyArea(display
, wmgen
.mask
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
268 /*******************************************************************************\
270 \*******************************************************************************/
272 void setMaskXY(int x
, int y
) {
274 XShapeCombineMask(display
, win
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
275 XShapeCombineMask(display
, iconwin
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
278 /*******************************************************************************\
280 \*******************************************************************************/
281 void openXwindow(int argc
, char *argv
[], char *pixmap_bytes
[], char *pixmask_bits
, int pixmask_width
, int pixmask_height
) {
283 unsigned int borderwidth
= 1;
284 XClassHint classHint
;
285 char *display_name
= NULL
;
286 char *wname
= argv
[0];
296 for (i
=1; argv
[i
]; i
++) {
297 if (!strcmp(argv
[i
], "-display"))
298 display_name
= argv
[i
+1];
301 if (!(display
= XOpenDisplay(display_name
))) {
302 fprintf(stderr
, "%s: can't open display %s\n",
303 wname
, XDisplayName(display_name
));
306 screen
= DefaultScreen(display
);
307 Root
= RootWindow(display
, screen
);
308 d_depth
= DefaultDepth(display
, screen
);
309 x_fd
= XConnectionNumber(display
);
311 /* Convert XPM to XImage */
312 GetXPM(&wmgen
, pixmap_bytes
);
314 /* Create a window to hold the stuff */
315 mysizehints
.flags
= USSize
| USPosition
;
319 back_pix
= GetColor("white");
320 fore_pix
= GetColor("black");
322 XWMGeometry(display
, screen
, Geometry
, NULL
, borderwidth
, &mysizehints
,
323 &mysizehints
.x
, &mysizehints
.y
,&mysizehints
.width
,&mysizehints
.height
, &dummy
);
325 mysizehints
.width
= 64;
326 mysizehints
.height
= 64;
328 win
= XCreateSimpleWindow(display
, Root
, mysizehints
.x
, mysizehints
.y
,
329 mysizehints
.width
, mysizehints
.height
, borderwidth
, fore_pix
, back_pix
);
331 iconwin
= XCreateSimpleWindow(display
, win
, mysizehints
.x
, mysizehints
.y
,
332 mysizehints
.width
, mysizehints
.height
, borderwidth
, fore_pix
, back_pix
);
335 XSetWMNormalHints(display
, win
, &mysizehints
);
336 classHint
.res_name
= wname
;
337 classHint
.res_class
= wname
;
338 XSetClassHint(display
, win
, &classHint
);
340 XSelectInput(display
, win
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
);
341 XSelectInput(display
, iconwin
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
);
343 if (XStringListToTextProperty(&wname
, 1, &name
) == 0) {
344 fprintf(stderr
, "%s: can't allocate window name\n", wname
);
348 XSetWMName(display
, win
, &name
);
350 /* Create GC for drawing */
352 gcm
= GCForeground
| GCBackground
| GCGraphicsExposures
;
353 gcv
.foreground
= fore_pix
;
354 gcv
.background
= back_pix
;
355 gcv
.graphics_exposures
= 0;
356 NormalGC
= XCreateGC(display
, Root
, gcm
, &gcv
);
360 pixmask
= XCreateBitmapFromData(display
, win
, pixmask_bits
, pixmask_width
, pixmask_height
);
362 XShapeCombineMask(display
, win
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
363 XShapeCombineMask(display
, iconwin
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
367 mywmhints
.initial_state
= WithdrawnState
;
368 mywmhints
.icon_window
= iconwin
;
369 mywmhints
.icon_x
= mysizehints
.x
;
370 mywmhints
.icon_y
= mysizehints
.y
;
371 mywmhints
.window_group
= win
;
372 mywmhints
.flags
= StateHint
| IconWindowHint
| IconPositionHint
| WindowGroupHint
;
374 XSetWMHints(display
, win
, &mywmhints
);
376 XSetCommand(display
, win
, argv
, argc
);
377 XMapWindow(display
, win
);