1/*
2 * Copyright 2014 Olaf Seibert
3 */
4
5/*
6 * Code to look at a few Motif Window Manager hints.
7 *
8 * Only the bits marked [v] are actually looked at.
9 * For the rest, ctwm has no concept, really.
10 *
11 * For some information about the meaning of the flags, see
12 * the manual page VendorShell(3) from the Motif library.
13 */
14
15#include "ctwm.h"
16
17#include <stdio.h>
18
19#include "ctwm_atoms.h"
20#include "list.h"
21#include "mwmhints.h"
22#include "screen.h"
23
24bool
25GetMWMHints(Window w, MotifWmHints *mwmHints)
26{
27	int success;
28	Atom actual_type;
29	int actual_format;
30	unsigned long nitems;
31	unsigned long bytes_after;
32	unsigned long *prop = NULL;
33
34	/* Defaults for when not found */
35	mwmHints->flags = 0;
36	mwmHints->functions = 0;
37	mwmHints->decorations = 0;
38#ifdef FULL_MWM_DATA
39	mwmHints->input_mode = 0;
40	mwmHints->status = 0;
41#endif
42
43	success = XGetWindowProperty(
44	                  dpy, w, XA__MOTIF_WM_HINTS,
45	                  0, 5,           /* long_offset, long long_length, */
46	                  False,          /* Bool delete, */
47	                  AnyPropertyType,/* Atom req_type */
48	                  &actual_type,   /* Atom *actual_type_return, */
49	                  &actual_format, /* int *actual_format_return, */
50	                  &nitems,        /* unsigned long *nitems_return,  */
51	                  &bytes_after,   /* unsigned long * */
52	                  (unsigned char **)&prop);       /* unsigned char ** */
53
54	if(success == Success &&
55	                actual_type == XA__MOTIF_WM_HINTS &&
56	                actual_format == 32 &&
57	                nitems >= 3) {
58		mwmHints->flags = (int)prop[0];
59		mwmHints->functions = (int)prop[1];
60		mwmHints->decorations = (int)prop[2];
61#ifdef FULL_MWM_DATA
62		mwmHints->input_mode = (int)prop[3];
63		mwmHints->status = (int)prop[4];
64#endif
65
66		if(mwmHints->flags & MWM_HINTS_FUNCTIONS) {
67			if(mwmHints->functions & MWM_FUNC_ALL) {
68				mwmHints->functions ^= ~0;
69			}
70		}
71		if(mwmHints->flags & MWM_HINTS_DECORATIONS) {
72			if(mwmHints->decorations & MWM_DECOR_ALL) {
73				mwmHints->decorations ^= ~0;
74			}
75		}
76
77		success = true;
78	}
79	else {
80		success = false;
81	}
82
83	if(prop != NULL) {
84		XFree(prop);
85	}
86
87	return success;
88}
89
90
91
92/*
93 * Simple test wrappers
94 */
95static bool
96mwm_sets_decorations(MotifWmHints *hints)
97{
98	return (hints->flags & MWM_HINTS_DECORATIONS) ? true : false;
99}
100
101
102/* 1 = yes   0 = no   -1 = no opinion */
103int
104mwm_has_border(MotifWmHints *hints)
105{
106	/* No opinion if hints don't set decoration info */
107	if(!mwm_sets_decorations(hints)) {
108		return -1;
109	}
110
111	/* No opinion if the user told us to ignore it */
112	if(LookInNameList(Scr->MWMIgnore, "DECOR_BORDER")) {
113		return -1;
114	}
115
116	/* No border if hints said so */
117	if((hints->decorations & MWM_DECOR_BORDER) == 0) {
118		return 0;
119	}
120
121	/* Else border */
122	return 1;
123}
124
125
126bool
127mwm_sets_title(MotifWmHints *hints)
128{
129	/* Not if we don't have decoration info */
130	if(!mwm_sets_decorations(hints)) {
131		return false;
132	}
133
134	/* Not if the user wants to ignore title frobbing */
135	if(LookInNameList(Scr->MWMIgnore, "DECOR_TITLE")) {
136		return false;
137	}
138
139	/* Else we do have info to use */
140	return true;
141}
142
143
144bool
145mwm_has_title(MotifWmHints *hints)
146{
147	if(mwm_sets_decorations(hints)
148	                && ((hints->decorations & MWM_DECOR_TITLE) == 0)) {
149		return false;
150	}
151	return true;
152}
153