1 /* -*-c-*- */
2 #include "config.h"
3
4 #include <stdio.h>
5
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #include <X11/Intrinsic.h>
9 #include <X11/Xatom.h>
10 #include <X11/Xproto.h>
11
12 #include "libs/FEvent.h"
13
14 Display *dpy;
15 Window Root, win;
16 int screen;
17
18 int has_focus_proto = 0;
19 int has_delete_proto = 1;
20 int input_mode = -1;
21
22 Atom ATOM_NET_WM_WINDOW_TYPE = None;
23 Atom ATOM_NET_WM_WINDOW_TYPE_DESKTOP = None;
24 Atom ATOM_NET_WM_WINDOW_TYPE_DOCK = None;
25 Atom ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = None;
26 Atom ATOM_NET_WM_WINDOW_TYPE_MENU = None;
27 Atom ATOM_NET_WM_WINDOW_TYPE_DIALOG = None;
28 Atom ATOM_NET_WM_WINDOW_TYPE_NORMAL = None;
29 Atom ATOM_NET_WM_WINDOW_TYPE_SPLASH = None;
30 Atom ATOM_NET_WM_WINDOW_TYPE_UTILITY = None;
31 Atom ATOM_KDE_NET_WM_WINDOW_TYPE_OVERRIDE = None;
32
33 Atom ATOM_NET_WM_STATE = None;
34 Atom ATOM_NET_WM_STATE_MODAL = None;
35 Atom ATOM_NET_WM_STATE_STICKY = None;
36 Atom ATOM_NET_WM_STATE_MAXIMIZED_VERT = None;
37 Atom ATOM_NET_WM_STATE_MAXIMIZED_HORIZ = None;
38 Atom ATOM_NET_WM_STATE_SHADED = None;
39 Atom ATOM_NET_WM_STATE_SKIP_TASKBAR = None;
40 Atom ATOM_NET_WM_STATE_SKIP_PAGER = None;
41 Atom ATOM_NET_WM_STATE_HIDDEN = None;
42 Atom ATOM_NET_WM_STATE_STAYS_ON_TOP = None;
43 Atom ATOM_NET_WM_STATE_FULLSCREEN = None;
44
45 Atom ATOM_NET_WM_DESKTOP = None;
46
47 /* wm protocol */
48 Atom ATOM_WM_DELETE_WINDOW = None;
49 Atom ATOM_WM_TAKE_FOCUS = None;
50
51 /* Motif window hints */
52 Atom ATOM_MOTIF_WM_HINTS = None;
53
54 #define MWM_HINTS_FUNCTIONS (1L << 0)
55 #define MWM_HINTS_DECORATIONS (1L << 1)
56 #define MWM_HINTS_INPUT_MODE (1L << 2)
57 #define MWM_HINTS_STATUS (1L << 3) /* ? */
58
59 /* bit definitions for MwmHints.functions */
60 #define MWM_FUNC_ALL (1L << 0)
61 #define MWM_FUNC_RESIZE (1L << 1)
62 #define MWM_FUNC_MOVE (1L << 2)
63 #define MWM_FUNC_MINIMIZE (1L << 3)
64 #define MWM_FUNC_MAXIMIZE (1L << 4)
65 #define MWM_FUNC_CLOSE (1L << 5)
66
67 /* values for MwmHints.input_mode */
68 #define MWM_INPUT_MODELESS 0
69 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
70 #define MWM_INPUT_SYSTEM_MODAL 2
71 #define MWM_INPUT_FULL_APPLICATION_MODAL 3
72
73 /* bit definitions for MwmHints.decorations */
74 #define MWM_DECOR_ALL (1L << 0)
75 #define MWM_DECOR_BORDER (1L << 1)
76 #define MWM_DECOR_RESIZEH (1L << 2)
77 #define MWM_DECOR_TITLE (1L << 3)
78 #define MWM_DECOR_MENU (1L << 4)
79 #define MWM_DECOR_MINIMIZE (1L << 5)
80 #define MWM_DECOR_MAXIMIZE (1L << 6)
81
82 /*
83 * _MWM_HINTS property
84 */
85 typedef struct
86 {
87 long props[4];
88 /* props[0]: flags */
89 /* props[1]: functions */
90 /* props[2]: decorations */
91 /* props[3]: inputMode */
92 } PropMotifWmHints;
93
94 typedef PropMotifWmHints PropMwmHints;
95
96 #define PROP_MOTIF_WM_HINTS_ELEMENTS 4
97 #define PROP_MWM_HINTS_ELEMENTS PROP_MOTIF_WM_HINTS_ELEMENTS
98
99 void
Xloop(void)100 Xloop(void)
101 {
102 while (1)
103 {
104 XEvent ev;
105 XWindowAttributes xatt;
106
107 /* Sit and wait for an event to happen */
108 FNextEvent(dpy,&ev);
109 switch(ev.type)
110 {
111 case ConfigureNotify:
112 break;
113 case ClientMessage:
114 if (has_delete_proto && ev.xclient.format == 32 &&
115 ev.xclient.data.l[0] == ATOM_WM_DELETE_WINDOW)
116 {
117 exit(0);
118 }
119 else if (has_focus_proto &&
120 ev.xclient.data.l[0] == ATOM_WM_TAKE_FOCUS)
121 {
122 printf("WM_TAKE_FOCUS message\n");
123 if (input_mode == 1)
124 {
125 printf ("\t...do nothing\n");
126 }
127 else if (input_mode == 0)
128 {
129 if (XGetWindowAttributes(dpy, win, &xatt)
130 && xatt.map_state == IsViewable)
131 {
132 printf ("\t...setting focus on our own: %lu\n",
133 ev.xclient.data.l[1]);
134 XSetInputFocus(
135 dpy, win, RevertToParent,
136 ev.xclient.data.l[1]);
137 }
138 else
139 {
140 printf ("\t...but we are not viewable\n");
141 }
142 }
143 }
144 break;
145 default:
146 break;
147 }
148 }
149 }
150
151 #define XIA(a) XInternAtom(dpy,a,False);
InitAtom(void)152 void InitAtom(void)
153 {
154 ATOM_NET_WM_WINDOW_TYPE = XIA("_NET_WM_WINDOW_TYPE");
155 ATOM_NET_WM_WINDOW_TYPE_DESKTOP = XIA("_NET_WM_WINDOW_TYPE_DESKTOP");
156 ATOM_NET_WM_WINDOW_TYPE_DOCK = XIA("_NET_WM_WINDOW_TYPE_DOCK");
157 ATOM_NET_WM_WINDOW_TYPE_TOOLBAR = XIA("_NET_WM_WINDOW_TYPE_TOOLBAR");
158 ATOM_NET_WM_WINDOW_TYPE_MENU = XIA("_NET_WM_WINDOW_TYPE_MENU");
159 ATOM_NET_WM_WINDOW_TYPE_DIALOG = XIA("_NET_WM_WINDOW_TYPE_DIALOG");
160 ATOM_NET_WM_WINDOW_TYPE_NORMAL = XIA("_NET_WM_WINDOW_TYPE_NORMAL");
161 ATOM_NET_WM_WINDOW_TYPE_SPLASH = XIA("_NET_WM_WINDOW_TYPE_SPLASH");
162 ATOM_NET_WM_WINDOW_TYPE_UTILITY = XIA("_NET_WM_WINDOW_TYPE_UTILITY");
163 ATOM_KDE_NET_WM_WINDOW_TYPE_OVERRIDE = XIA("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE");
164
165 ATOM_NET_WM_STATE = XIA("_NET_WM_STATE");
166 ATOM_NET_WM_STATE_MODAL = XIA("_NET_WM_STATE_MODAL");
167 ATOM_NET_WM_STATE_STICKY = XIA("_NET_WM_STATE_STICKY");
168 ATOM_NET_WM_STATE_MAXIMIZED_VERT = XIA("_NET_WM_STATE_MAXIMIZED_VERT");
169 ATOM_NET_WM_STATE_MAXIMIZED_HORIZ = XIA("_NET_WM_STATE_MAXIMIZED_HORIZ");
170 ATOM_NET_WM_STATE_SHADED = XIA("_NET_WM_STATE_SHADED");
171 ATOM_NET_WM_STATE_SKIP_TASKBAR = XIA("_NET_WM_STATE_SKIP_TASKBAR");
172 ATOM_NET_WM_STATE_SKIP_PAGER = XIA("_NET_WM_STATE_SKIP_PAGER");
173 ATOM_NET_WM_STATE_HIDDEN = XIA("_NET_WM_STATE_HIDDEN");
174 ATOM_NET_WM_STATE_FULLSCREEN = XIA("_NET_WM_STATE_FULLSCREEN");
175 ATOM_NET_WM_STATE_STAYS_ON_TOP = XIA("_NET_WM_STATE_STAYS_ON_TOP");
176
177 ATOM_NET_WM_DESKTOP = XIA("_NET_WM_DESKTOP");
178
179 ATOM_WM_DELETE_WINDOW = XIA("WM_DELETE_WINDOW");
180 ATOM_WM_TAKE_FOCUS = XIA("WM_TAKE_FOCUS");
181
182 ATOM_MOTIF_WM_HINTS = XIA("_MOTIF_WM_HINTS");
183 }
184
show_usage(void)185 void show_usage(void)
186 {
187 printf("Usage: hints_test OPTIONS\n");
188 printf("Options:\n");
189 printf(" --mwm-func <names>\n");
190 printf(" all, resize, move, minimize, maximize, close\n");
191 printf(" --mwm-decor <names>\n");
192 printf(" all, border, resizeh, title, menu, minimize, maximize\n");
193 printf(" --ewmh-state <names>\n");
194 printf(" hidden, shaded, sticky, skippager, skiptaskbar,\n");
195 printf(" maxhoriz, maxvert, modal, staysontop, fullscreen\n");
196 printf(" --ewmh-type <names>\n");
197 printf(" normal, dock, toolbar, desktop, menu, dialog, splash, utility\n");
198 printf(" --mwm-input { modless, app_modal, sys_modal, full_app_modal}\n");
199 printf(" --ewmh-desktop\n");
200 printf(" --wm-state { withdrawn, normal, iconic }\n");
201 printf(" --wm-urgency\n");
202 printf(" --wm-group { window, root, <win_id> }\n");
203 printf(" --min-size <width> <height>\n");
204 printf(" --max-size <width> <height>\n");
205 printf(" --inc-size <width> <height>\n");
206 printf(" --p-geometry <geometry>\n");
207 printf(" --us-geometry <geometry>\n");
208 printf(" --input { true, false }\n");
209 printf(" --delete-proto\n");
210 printf(" --no-delete-proto\n");
211 printf(" --transient\n");
212 }
213
main(int argc,char ** argv)214 int main(int argc, char **argv)
215 {
216 int state_count = 0;
217 Atom states[10];
218 Atom type = 0;
219 int i,x_r,y_r;
220 unsigned int h_r,w_r;
221 int ret;
222 int ewmh_state_arg = 0;
223 int ewmh_type_arg = 0;
224 int mwm_func_arg = 0;
225 int mwm_decor_arg = 0;
226 int has_ewmh_desktop = 0;
227 Atom ewmh_desktop = 0;
228 XSizeHints hints;
229 XClassHint classhints;
230 XWMHints wm_hints;
231 PropMwmHints mwm_hints;
232 Window trans_win = 0;
233
234 if (!(dpy = XOpenDisplay("")))
235 {
236 fprintf(stderr, "can't open display\n");
237 exit(1);
238 }
239
240 screen = DefaultScreen(dpy);
241 Root = RootWindow(dpy, screen);
242 InitAtom();
243
244 hints.width = 170;
245 hints.height = 100;
246 hints.x = 0;
247 hints.y = 0;
248
249 hints.flags = 0;
250
251 wm_hints.flags = 0;
252 mwm_hints.props[0] = 0;
253 mwm_hints.props[1] = 0;
254 mwm_hints.props[2] = 0;
255 mwm_hints.props[3] = 0;
256
257 win = XCreateSimpleWindow(
258 dpy, Root, 0, 0, hints.width, hints.height, 0, 0, 0);
259
260 for (i = 1; i < argc; i++)
261 {
262 char *error_arg = NULL;
263
264 if (strcasecmp(argv[i], "--help") == 0)
265 {
266 show_usage();
267 exit(0);
268 }
269 else if (strcasecmp(argv[i], "--ewmh-state") == 0)
270 {
271 ewmh_state_arg = 1;
272 ewmh_type_arg = 0;
273 mwm_func_arg = 0;
274 mwm_decor_arg = 0;
275 }
276 else if (strcasecmp(argv[i], "--ewmh-type") == 0)
277 {
278 ewmh_state_arg = 0;
279 ewmh_type_arg = 1;
280 mwm_func_arg = 0;
281 mwm_decor_arg = 0;
282 }
283 else if (strcasecmp(argv[i], "--mwm-func") == 0)
284 {
285 ewmh_state_arg = 0;
286 ewmh_type_arg = 0;
287 mwm_func_arg = 1;
288 mwm_decor_arg = 0;
289 }
290 else if (strcasecmp(argv[i], "--mwm-decor") == 0)
291 {
292 ewmh_state_arg = 0;
293 ewmh_type_arg = 0;
294 mwm_func_arg = 0;
295 mwm_decor_arg = 1;
296 }
297 else if (strcasecmp(argv[i], "--min-size") == 0)
298 {
299 i++;
300 hints.min_width = atoi(argv[i]);
301 i++;
302 hints.min_height = atoi(argv[i]);
303 hints.flags |= PMinSize;
304 }
305 else if (strcasecmp(argv[i], "--max-size") == 0)
306 {
307 i++;
308 hints.max_width = atoi(argv[i]);
309 i++;
310 hints.max_height = atoi(argv[i]);
311 hints.flags |= PMaxSize;
312 }
313 else if (strcasecmp(argv[i], "--inc-size") == 0)
314 {
315 i++;
316 hints.width_inc = atoi(argv[i]);
317 i++;
318 hints.height_inc = atoi(argv[i]);
319 hints.flags |= PResizeInc;
320 }
321 else if (strcasecmp(argv[i], "--p-geometry") == 0)
322 {
323 i++;
324 ret = XParseGeometry(argv[i], &x_r, &y_r, &w_r, &h_r);
325 if ((ret & WidthValue) && (ret & HeightValue))
326 {
327 hints.width = w_r;
328 hints.height = h_r;
329 hints.flags |= PSize;
330 }
331 if ((ret & XValue) && (ret & YValue))
332 {
333 hints.x = x_r;
334 hints.y = y_r;
335 hints.win_gravity = NorthWestGravity;
336 if (ret & XNegative)
337 {
338 hints.x += XDisplayWidth(dpy, screen) -
339 hints.width;
340 hints.win_gravity = NorthEastGravity;
341 }
342 if (ret & YNegative)
343 {
344 hints.y += XDisplayHeight(dpy, screen) -
345 hints.height;
346 if (ret & XNegative)
347 {
348 hints.win_gravity =
349 SouthEastGravity;
350 }
351 else
352 {
353 hints.win_gravity =
354 SouthWestGravity;
355 }
356 hints.flags |= PWinGravity;
357 }
358 hints.flags |= PPosition;
359 }
360 }
361 else if (strcasecmp(argv[i], "--us-geometry") == 0)
362 {
363 i++;
364 ret = XParseGeometry(argv[i], &x_r, &y_r, &w_r, &h_r);
365 if ((ret & WidthValue) && (ret & HeightValue))
366 {
367 hints.width = w_r;
368 hints.height = h_r;
369 hints.flags |= USSize;
370 }
371 if ((ret & XValue) && (ret & YValue))
372 {
373 hints.x = x_r;
374 hints.y = y_r;
375 hints.win_gravity=NorthWestGravity;
376 if (ret & XNegative)
377 {
378 hints.x += XDisplayWidth(dpy,screen) -
379 hints.width;
380 hints.win_gravity=NorthEastGravity;
381 }
382 if (ret & YNegative)
383 {
384 hints.y += XDisplayHeight(dpy,screen) -
385 hints.height;
386 if (ret & XNegative)
387 {
388 hints.win_gravity =
389 SouthEastGravity;
390 }
391 else
392 {
393 hints.win_gravity =
394 SouthWestGravity;
395 }
396 }
397 hints.flags |= USPosition | PWinGravity;
398 }
399 }
400 else if (strcasecmp(argv[i], "--input") == 0)
401 {
402 i++;
403 if (strcasecmp(argv[i], "true") == 0)
404 {
405 wm_hints.input = input_mode = True;
406 wm_hints.flags |= InputHint;
407 }
408 else if (strcasecmp(argv[i], "false") == 0)
409 {
410 wm_hints.input = input_mode = False;
411 wm_hints.flags |= InputHint;
412 }
413 else
414 {
415 error_arg = "--input";
416 }
417 }
418 else if (strcasecmp(argv[i], "--focus-proto") == 0)
419 {
420 has_focus_proto = 1;
421 }
422 else if (strcasecmp(argv[i], "--no-delete-proto") == 0)
423 {
424 has_delete_proto = 0;
425 }
426 else if (strcasecmp(argv[i], "--wm-state") == 0)
427 {
428 wm_hints.flags |= StateHint;
429 i++;
430 if (strcasecmp(argv[i], "withdrawn") == 0)
431 {
432 wm_hints.initial_state = WithdrawnState;
433 }
434 else if (strcasecmp(argv[i], "normal") == 0)
435 {
436 wm_hints.initial_state = NormalState;
437 }
438 else if (strcasecmp(argv[i], "iconic") == 0)
439 {
440 wm_hints.initial_state = IconicState;
441 }
442 else
443 {
444 error_arg = "--wm-state";
445 }
446 }
447 else if (strcasecmp(argv[i], "--wm-urgency") == 0)
448 {
449 wm_hints.flags |= XUrgencyHint;
450 }
451 else if (strcasecmp(argv[i], "--wm-group") == 0)
452 {
453 wm_hints.flags |= WindowGroupHint;
454 i++;
455 if (strcasecmp(argv[i], "window") == 0)
456 {
457 wm_hints.window_group = win;
458 }
459 else if (strcasecmp(argv[i], "root") == 0)
460 {
461 wm_hints.window_group = Root;
462 }
463 else
464 {
465 wm_hints.window_group =
466 strtoul(argv[i], NULL, 0);
467 }
468 }
469 else if (strcasecmp(argv[i], "--transient") == 0)
470 {
471 i++;
472 if (strcasecmp(argv[i],"root") == 0)
473 {
474 trans_win = Root;
475 }
476 else
477 {
478 trans_win = strtoul(argv[i], NULL, 0);
479 }
480 }
481 else if (strcasecmp(argv[i], "--mwm-input") == 0)
482 {
483 mwm_hints.props[0] |= MWM_HINTS_INPUT_MODE;
484 i++;
485 if (strcasecmp(argv[i], "modless") == 0)
486 {
487 mwm_hints.props[3] = MWM_INPUT_MODELESS;
488 }
489 else if (strcasecmp(argv[i], "app_modal") == 0)
490 {
491 mwm_hints.props[3] =
492 MWM_INPUT_PRIMARY_APPLICATION_MODAL;
493 }
494 else if (strcasecmp(argv[i], "sys_modal") == 0)
495 {
496 mwm_hints.props[3] =
497 MWM_INPUT_SYSTEM_MODAL;
498 }
499 else if (strcasecmp(argv[i], "full_app_modal") == 0)
500 {
501 mwm_hints.props[3] =
502 MWM_INPUT_FULL_APPLICATION_MODAL;
503 }
504 else
505 {
506 error_arg = "--mwm-input";
507 }
508 }
509 else if (strcasecmp(argv[i], "--ewmh-desktop") == 0)
510 {
511 has_ewmh_desktop = 1;
512 i++;
513 ewmh_desktop = atol(argv[i]);
514 }
515 else if (ewmh_state_arg && state_count < 10)
516 {
517 if (strcasecmp(argv[i], "hidden") == 0)
518 {
519 states[state_count++] =
520 ATOM_NET_WM_STATE_HIDDEN;
521 }
522 else if (strcasecmp(argv[i], "shaded") == 0)
523 {
524 states[state_count++] =
525 ATOM_NET_WM_STATE_SHADED;
526 }
527 else if (strcasecmp(argv[i], "sticky") == 0)
528 {
529 states[state_count++] =
530 ATOM_NET_WM_STATE_STICKY;
531 }
532 else if (strcasecmp(argv[i], "skippager") == 0)
533 {
534 states[state_count++] =
535 ATOM_NET_WM_STATE_SKIP_PAGER;
536 }
537 else if (strcasecmp(argv[i], "skiptaskbar") == 0)
538 {
539 states[state_count++] =
540 ATOM_NET_WM_STATE_SKIP_TASKBAR;
541 }
542 else if (strcasecmp(argv[i], "maxhoriz") == 0)
543 {
544 states[state_count++] =
545 ATOM_NET_WM_STATE_MAXIMIZED_HORIZ;
546 }
547 else if (strcasecmp(argv[i], "maxvert") == 0)
548 {
549 states[state_count++] =
550 ATOM_NET_WM_STATE_MAXIMIZED_VERT;
551 }
552 else if (strcasecmp(argv[i], "modal") == 0)
553 {
554 states[state_count++] =
555 ATOM_NET_WM_STATE_MODAL;
556 }
557 else if (strcasecmp(argv[i], "staysontop") == 0)
558 {
559 states[state_count++] =
560 ATOM_NET_WM_STATE_STAYS_ON_TOP;
561 }
562 else if (strcasecmp(argv[i], "fullscreen") == 0)
563 {
564 states[state_count++] =
565 ATOM_NET_WM_STATE_FULLSCREEN;
566 }
567 else
568 {
569 error_arg = "--ewmh-state";
570 }
571 }
572 else if (ewmh_type_arg)
573 {
574 if (strcasecmp(argv[i], "normal") == 0)
575 {
576 type = ATOM_NET_WM_WINDOW_TYPE_NORMAL;
577 }
578 else if (strcasecmp(argv[i], "dock") == 0)
579 {
580 type = ATOM_NET_WM_WINDOW_TYPE_DOCK;
581 }
582 else if (strcasecmp(argv[i], "toolbar") == 0)
583 {
584 type = ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
585 }
586 else if (strcasecmp(argv[i], "desktop") == 0)
587 {
588 type = ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
589 }
590 else if (strcasecmp(argv[i], "menu") == 0)
591 {
592 type = ATOM_NET_WM_WINDOW_TYPE_MENU;
593 }
594 else if (strcasecmp(argv[i], "dialog") == 0)
595 {
596 type = ATOM_NET_WM_WINDOW_TYPE_DIALOG;
597 }
598 else if (strcasecmp(argv[i], "splash") == 0)
599 {
600 type = ATOM_NET_WM_WINDOW_TYPE_SPLASH;
601 }
602 else if (strcasecmp(argv[i], "utility") == 0)
603 {
604 type = ATOM_NET_WM_WINDOW_TYPE_UTILITY;
605 }
606 else
607 {
608 error_arg = "--ewmh-type";
609 }
610 }
611 else if (mwm_func_arg)
612 {
613 mwm_hints.props[0] |= MWM_HINTS_FUNCTIONS;
614 if (strcasecmp(argv[i], "all") == 0)
615 {
616 mwm_hints.props[1] |= MWM_FUNC_ALL;
617 }
618 else if (strcasecmp(argv[i], "resize") == 0)
619 {
620 mwm_hints.props[1] |= MWM_FUNC_RESIZE;
621 }
622 else if (strcasecmp(argv[i], "move") == 0)
623 {
624 mwm_hints.props[1] |= MWM_FUNC_MOVE;
625 }
626 else if (strcasecmp(argv[i], "minimize") == 0)
627 {
628 mwm_hints.props[1] |= MWM_FUNC_MINIMIZE;
629 }
630 else if (strcasecmp(argv[i], "maximize") == 0)
631 {
632 mwm_hints.props[1] |= MWM_FUNC_MAXIMIZE;
633 }
634 else if (strcasecmp(argv[i], "close") == 0)
635 {
636 mwm_hints.props[1] |= MWM_FUNC_CLOSE;
637 }
638 else
639 {
640 error_arg = "--mwm-func";
641 }
642 }
643 else if (mwm_decor_arg)
644 {
645 mwm_hints.props[0] |= MWM_HINTS_DECORATIONS;
646 if (strcasecmp(argv[i], "all") == 0)
647 {
648 mwm_hints.props[2] |= MWM_DECOR_ALL;
649 }
650 else if (strcasecmp(argv[i], "border") == 0)
651 {
652 mwm_hints.props[2] |= MWM_DECOR_BORDER;
653 }
654 else if (strcasecmp(argv[i], "resizeh") == 0)
655 {
656 mwm_hints.props[2] |= MWM_DECOR_RESIZEH;
657 }
658 else if (strcasecmp(argv[i], "title") == 0)
659 {
660 mwm_hints.props[2] |= MWM_DECOR_TITLE;
661 }
662 else if (strcasecmp(argv[i], "menu") == 0)
663 {
664 mwm_hints.props[2] |= MWM_DECOR_MENU;
665 }
666 else if (strcasecmp(argv[i], "minimize") == 0)
667 {
668 mwm_hints.props[2] |= MWM_DECOR_MINIMIZE;
669 }
670 else if (strcasecmp(argv[i], "maximize") == 0)
671 {
672 mwm_hints.props[2] |= MWM_DECOR_MAXIMIZE;
673 }
674 else
675 {
676 error_arg = "--mwm-decor";
677 }
678 }
679 else
680 {
681 error_arg = "regular";
682 }
683 if (error_arg)
684 {
685 show_usage();
686 printf("Invalid %s argument: %s\n", error_arg, argv[i]);
687 exit(1);
688 }
689 }
690
691
692 XSelectInput(dpy, win, StructureNotifyMask);
693
694 if (wm_hints.flags)
695 {
696 XSetWMHints(dpy, win, &wm_hints);
697 }
698
699 if (state_count != 0)
700 {
701 XChangeProperty(
702 dpy, win, ATOM_NET_WM_STATE, XA_ATOM, 32,
703 PropModeReplace, (unsigned char *)states, state_count);
704 }
705
706 if (type != 0)
707 {
708 XChangeProperty(
709 dpy, win, ATOM_NET_WM_WINDOW_TYPE, XA_ATOM, 32,
710 PropModeReplace, (unsigned char *)&type, 1);
711 }
712
713 if (has_ewmh_desktop)
714 {
715 XChangeProperty(
716 dpy, win, ATOM_NET_WM_DESKTOP, XA_CARDINAL, 32,
717 PropModeReplace, (unsigned char *)&ewmh_desktop, 1);
718 }
719
720 if (has_delete_proto || has_focus_proto)
721 {
722 Atom proto[2];
723 int j = 0;
724
725 if (has_delete_proto)
726 proto[j++] = ATOM_WM_DELETE_WINDOW;
727 if (has_focus_proto)
728 proto[j++] = ATOM_WM_TAKE_FOCUS;
729
730 XSetWMProtocols(dpy, win, proto, j);
731 }
732
733 {
734 XTextProperty nametext;
735 char *list[] = { NULL, NULL };
736 list[0] = "Hints Test";
737
738 classhints.res_name = strdup("hints_test");
739 classhints.res_class = strdup("HintsTest");
740
741 if (!XStringListToTextProperty(list, 1, &nametext))
742 {
743 fprintf(stderr, "Failed to convert name to XText\n");
744 exit(1);
745 }
746 XSetWMProperties(
747 dpy, win, &nametext, &nametext, NULL, 0, &hints, NULL,
748 &classhints);
749 XFree(nametext.value);
750 }
751
752 if (mwm_hints.props[0] != 0)
753 {
754 XChangeProperty(
755 dpy, win, ATOM_MOTIF_WM_HINTS, ATOM_MOTIF_WM_HINTS, 32,
756 PropModeReplace,(unsigned char *)&mwm_hints,
757 PROP_MWM_HINTS_ELEMENTS);
758 }
759 if (trans_win !=0)
760 XSetTransientForHint(dpy, win, trans_win);
761
762 XMapWindow(dpy, win);
763 XSetWindowBackground(dpy, win, 0);
764
765 Xloop();
766 return 1;
767 }
768