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 10/10/2003 (Simon Law, sfllaw@debian.org)
16 * changed the parse_rcfile function to use getline instead of fgets.
17 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
18 * changed the read_rc_file to parse_rcfile, as suggester by Marcelo E. Magallon
19 * debugged the parse_rc file.
20 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
21 * Ripped similar code from all the wm* programs,
22 and put them in a single file.
36 #include <X11/extensions/shape.h>
38 #include "wmgeneral.h"
48 XSizeHints mysizehints
;
49 /* Deal with strange X11 function prototyping...
50 * If I don't do this, I will get warnings about the sign
51 * of the width/height variables - which are thrown away anyway. */
52 int dummy_int_width
, dummy_int_height
;
53 unsigned int uint_width
, uint_height
;
55 Pixel back_pix
, fore_pix
;
74 #define MAX_MOUSE_REGION (8)
75 MOUSE_REGION mouse_region
[MAX_MOUSE_REGION
];
77 /***********************/
78 /* Function Prototypes */
79 /***********************/
81 static void GetXPM(XpmIcon
*, char **);
82 static Pixel
GetColor(char *);
83 void RedrawWindow(void);
84 void AddMouseRegion(int, int, int, int, int);
85 int CheckMouseRegion(int, int);
87 /*******************************************************************************\
89 \*******************************************************************************/
91 void parse_rcfile(const char *filename
, rckeys
*keys
) {
96 char *tokens
= " :\t\n";
100 fp
= fopen(filename
, "r");
102 while (getline(&line
, &line_size
, fp
) >= 0) {
104 while (key
>= 0 && keys
[key
].label
) {
105 if ((p
= strstr(line
, keys
[key
].label
))) {
106 p
+= strlen(keys
[key
].label
);
107 p
+= strspn(p
, tokens
);
108 if ((i
= strcspn(p
, "#\n"))) p
[i
] = 0;
109 free(*keys
[key
].var
);
110 *keys
[key
].var
= strdup(p
);
120 /*******************************************************************************\
122 \*******************************************************************************/
124 static void GetXPM(XpmIcon
*wmgen
, char *pixmap_bytes
[]) {
126 XWindowAttributes attributes
;
129 /* For the colormap */
130 XGetWindowAttributes(display
, Root
, &attributes
);
132 wmgen
->attributes
.valuemask
|= (XpmReturnPixels
| XpmReturnExtensions
);
134 err
= XpmCreatePixmapFromData(display
, Root
, pixmap_bytes
, &(wmgen
->pixmap
),
135 &(wmgen
->mask
), &(wmgen
->attributes
));
137 if (err
!= XpmSuccess
) {
138 fprintf(stderr
, "Not enough free colorcells.\n");
143 /*******************************************************************************\
145 \*******************************************************************************/
147 static Pixel
GetColor(char *name
) {
150 XWindowAttributes attributes
;
152 XGetWindowAttributes(display
, Root
, &attributes
);
155 if (!XParseColor(display
, attributes
.colormap
, name
, &color
)) {
156 fprintf(stderr
, "wm.app: can't parse %s.\n", name
);
157 } else if (!XAllocColor(display
, attributes
.colormap
, &color
)) {
158 fprintf(stderr
, "wm.app: can't allocate %s.\n", name
);
163 /*******************************************************************************\
165 \*******************************************************************************/
167 static int flush_expose(Window w
) {
172 while (XCheckTypedWindowEvent(display
, w
, Expose
, &dummy
))
178 /*******************************************************************************\
180 \*******************************************************************************/
182 void RedrawWindow(void) {
184 flush_expose(iconwin
);
185 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
186 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
188 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
189 0,0, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
192 /*******************************************************************************\
194 \*******************************************************************************/
196 void RedrawWindowXY(int x
, int y
) {
198 flush_expose(iconwin
);
199 XCopyArea(display
, wmgen
.pixmap
, iconwin
, NormalGC
,
200 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
202 XCopyArea(display
, wmgen
.pixmap
, win
, NormalGC
,
203 x
,y
, wmgen
.attributes
.width
, wmgen
.attributes
.height
, 0,0);
206 /*******************************************************************************\
208 \*******************************************************************************/
210 void AddMouseRegion(int index
, int left
, int top
, int right
, int bottom
) {
212 if (index
< MAX_MOUSE_REGION
) {
213 mouse_region
[index
].enable
= 1;
214 mouse_region
[index
].top
= top
;
215 mouse_region
[index
].left
= left
;
216 mouse_region
[index
].bottom
= bottom
;
217 mouse_region
[index
].right
= right
;
221 /*******************************************************************************\
222 |* CheckMouseRegion *|
223 \*******************************************************************************/
225 int CheckMouseRegion(int x
, int y
) {
232 for (i
=0; i
<MAX_MOUSE_REGION
&& !found
; i
++) {
233 if (mouse_region
[i
].enable
&&
234 x
<= mouse_region
[i
].right
&&
235 x
>= mouse_region
[i
].left
&&
236 y
<= mouse_region
[i
].bottom
&&
237 y
>= mouse_region
[i
].top
)
240 if (!found
) return -1;
244 /*******************************************************************************\
246 \*******************************************************************************/
248 void copyXPMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
) {
250 XCopyArea(display
, wmgen
.pixmap
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
254 /*******************************************************************************\
256 \*******************************************************************************/
258 void copyXBMArea(int x
, int y
, int sx
, int sy
, int dx
, int dy
) {
260 XCopyArea(display
, wmgen
.mask
, wmgen
.pixmap
, NormalGC
, x
, y
, sx
, sy
, dx
, dy
);
264 /*******************************************************************************\
266 \*******************************************************************************/
268 void setMaskXY(int x
, int y
) {
270 XShapeCombineMask(display
, win
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
271 XShapeCombineMask(display
, iconwin
, ShapeBounding
, x
, y
, pixmask
, ShapeSet
);
274 /*******************************************************************************\
276 \*******************************************************************************/
277 void openXwindow(int argc
, char *argv
[], char *pixmap_bytes
[], char *pixmask_bits
, int pixmask_width
, int pixmask_height
) {
279 unsigned int borderwidth
= 1;
280 XClassHint classHint
;
281 char *display_name
= NULL
;
282 char *geometry
= NULL
;
283 char *wname
= argv
[0];
293 for (i
=1; argv
[i
]; i
++) {
294 if (!strcmp(argv
[i
], "-display"))
295 display_name
= argv
[++i
];
296 else if (!strcmp(argv
[i
], "-geometry"))
297 geometry
= argv
[++i
];
300 if (!(display
= XOpenDisplay(display_name
))) {
301 fprintf(stderr
, "%s: can't open display %s\n",
302 wname
, XDisplayName(display_name
));
305 screen
= DefaultScreen(display
);
306 Root
= RootWindow(display
, screen
);
307 d_depth
= DefaultDepth(display
, screen
);
308 x_fd
= XConnectionNumber(display
);
310 /* Convert XPM to XImage */
311 GetXPM(&wmgen
, pixmap_bytes
);
313 /* Create a window to hold the stuff */
314 mysizehints
.flags
= USSize
| USPosition
;
318 back_pix
= GetColor("white");
319 fore_pix
= GetColor("black");
321 XWMGeometry(display
, screen
, Geometry
, NULL
, borderwidth
, &mysizehints
,
322 &mysizehints
.x
, &mysizehints
.y
,
323 &dummy_int_width
, &dummy_int_height
, &dummy
);
325 XParseGeometry(geometry
, &mysizehints
.x
, &mysizehints
.y
,
326 &uint_width
, &uint_height
);
328 /* Override width/height anyway */
332 win
= XCreateSimpleWindow(display
, Root
, mysizehints
.x
, mysizehints
.y
,
333 uint_width
, uint_height
, borderwidth
, fore_pix
, back_pix
);
335 iconwin
= XCreateSimpleWindow(display
, win
, mysizehints
.x
, mysizehints
.y
,
336 uint_width
, uint_height
, borderwidth
, fore_pix
, back_pix
);
339 XSetWMNormalHints(display
, win
, &mysizehints
);
340 classHint
.res_name
= wname
;
341 classHint
.res_class
= wname
;
342 XSetClassHint(display
, win
, &classHint
);
344 XSelectInput(display
, win
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
);
345 XSelectInput(display
, iconwin
, ButtonPressMask
| ExposureMask
| ButtonReleaseMask
| PointerMotionMask
| StructureNotifyMask
);
347 if (XStringListToTextProperty(&wname
, 1, &name
) == 0) {
348 fprintf(stderr
, "%s: can't allocate window name\n", wname
);
352 XSetWMName(display
, win
, &name
);
354 /* Create GC for drawing */
356 gcm
= GCForeground
| GCBackground
| GCGraphicsExposures
;
357 gcv
.foreground
= fore_pix
;
358 gcv
.background
= back_pix
;
359 gcv
.graphics_exposures
= 0;
360 NormalGC
= XCreateGC(display
, Root
, gcm
, &gcv
);
364 pixmask
= XCreateBitmapFromData(display
, win
, pixmask_bits
, pixmask_width
, pixmask_height
);
366 XShapeCombineMask(display
, win
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
367 XShapeCombineMask(display
, iconwin
, ShapeBounding
, 0, 0, pixmask
, ShapeSet
);
371 mywmhints
.initial_state
= WithdrawnState
;
372 mywmhints
.icon_window
= iconwin
;
373 mywmhints
.icon_x
= mysizehints
.x
;
374 mywmhints
.icon_y
= mysizehints
.y
;
375 mywmhints
.window_group
= win
;
376 mywmhints
.flags
= StateHint
| IconWindowHint
| IconPositionHint
| WindowGroupHint
;
378 XSetWMHints(display
, win
, &mywmhints
);
380 XSetCommand(display
, win
, argv
, argc
);
381 XMapWindow(display
, win
);
385 /* vim: ts=4 columns=82