1 /*
2  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3  *
4  *Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  *"Software"), to deal in the Software without restriction, including
7  *without limitation the rights to use, copy, modify, merge, publish,
8  *distribute, sublicense, and/or sell copies of the Software, and to
9  *permit persons to whom the Software is furnished to do so, subject to
10  *the following conditions:
11  *
12  *The above copyright notice and this permission notice shall be
13  *included in all copies or substantial portions of the Software.
14  *
15  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  *Except as contained in this notice, the name of the XFree86 Project
24  *shall not be used in advertising or otherwise to promote the sale, use
25  *or other dealings in this Software without prior written authorization
26  *from the XFree86 Project.
27  *
28  * Authors:     Earle F. Philhower, III
29  */
30 
31 #ifdef HAVE_XWIN_CONFIG_H
32 #include <xwin-config.h>
33 #endif
34 #include <X11/Xatom.h>
35 #include "propertyst.h"
36 #include "windowstr.h"
37 #include "winmultiwindowclass.h"
38 #include "win.h"
39 
40 /*
41  * Local function
42  */
43 
44 DEFINE_ATOM_HELPER(AtmWmWindowRole, "WM_WINDOW_ROLE")
45 
46 int
winMultiWindowGetClassHint(WindowPtr pWin,char ** res_name,char ** res_class)47 winMultiWindowGetClassHint(WindowPtr pWin, char **res_name, char **res_class)
48 {
49     struct _Window *pwin;
50     struct _Property *prop;
51     int len_name, len_class;
52 
53     if (!pWin || !res_name || !res_class) {
54         ErrorF("winMultiWindowGetClassHint - pWin, res_name, or res_class was "
55                "NULL\n");
56         return 0;
57     }
58 
59     pwin = (struct _Window *) pWin;
60 
61     if (pwin->optional)
62         prop = (struct _Property *) pwin->optional->userProps;
63     else
64         prop = NULL;
65 
66     *res_name = *res_class = NULL;
67 
68     while (prop) {
69         if (prop->propertyName == XA_WM_CLASS
70             && prop->type == XA_STRING && prop->format == 8 && prop->data) {
71             /*
72               WM_CLASS property should consist of 2 null terminated strings, but we
73               must handle the cases when one or both is absent or not null terminated
74             */
75             len_name = strlen((char *) prop->data);
76             if (len_name > prop->size) len_name = prop->size;
77 
78             (*res_name) = malloc(len_name + 1);
79 
80             if (!*res_name) {
81                 ErrorF("winMultiWindowGetClassHint - *res_name was NULL\n");
82                 return 0;
83             }
84 
85             /* Copy name and ensure null terminated */
86             strncpy((*res_name), prop->data, len_name);
87             (*res_name)[len_name] = '\0';
88 
89             /* Compute length of class name, it could be that it is absent or not null terminated */
90             len_class = (len_name >= prop->size) ? 0 : (strlen(((char *) prop->data) + 1 + len_name));
91             if (len_class > prop->size - 1 - len_name) len_class = prop->size - 1 - len_name;
92 
93             (*res_class) = malloc(len_class + 1);
94 
95             if (!*res_class) {
96                 ErrorF("winMultiWindowGetClassHint - *res_class was NULL\n");
97 
98                 /* Free the previously allocated res_name */
99                 free(*res_name);
100                 return 0;
101             }
102 
103             /* Copy class name and ensure null terminated */
104             strncpy((*res_class), ((char *) prop->data) + 1 + len_name, len_class);
105             (*res_class)[len_class] = '\0';
106 
107             return 1;
108         }
109         else
110             prop = prop->next;
111     }
112 
113     return 0;
114 }
115 
116 int
winMultiWindowGetWMHints(WindowPtr pWin,WinXWMHints * hints)117 winMultiWindowGetWMHints(WindowPtr pWin, WinXWMHints * hints)
118 {
119     struct _Window *pwin;
120     struct _Property *prop;
121 
122     if (!pWin || !hints) {
123         ErrorF("winMultiWindowGetWMHints - pWin or hints was NULL\n");
124         return 0;
125     }
126 
127     pwin = (struct _Window *) pWin;
128 
129     if (pwin->optional)
130         prop = (struct _Property *) pwin->optional->userProps;
131     else
132         prop = NULL;
133 
134     memset(hints, 0, sizeof(WinXWMHints));
135 
136     while (prop) {
137         if (prop->propertyName == XA_WM_HINTS && prop->data) {
138             memcpy(hints, prop->data, sizeof(WinXWMHints));
139             return 1;
140         }
141         else
142             prop = prop->next;
143     }
144 
145     return 0;
146 }
147 
148 int
winMultiWindowGetWindowRole(WindowPtr pWin,char ** res_role)149 winMultiWindowGetWindowRole(WindowPtr pWin, char **res_role)
150 {
151     struct _Window *pwin;
152     struct _Property *prop;
153     int len_role;
154 
155     if (!pWin || !res_role)
156         return 0;
157 
158     pwin = (struct _Window *) pWin;
159 
160     if (pwin->optional)
161         prop = (struct _Property *) pwin->optional->userProps;
162     else
163         prop = NULL;
164 
165     *res_role = NULL;
166     while (prop) {
167         if (prop->propertyName == AtmWmWindowRole()
168             && prop->type == XA_STRING && prop->format == 8 && prop->data) {
169             len_role = prop->size;
170 
171             (*res_role) = malloc(len_role + 1);
172 
173             if (!*res_role) {
174                 ErrorF("winMultiWindowGetWindowRole - *res_role was NULL\n");
175                 return 0;
176             }
177 
178             strncpy((*res_role), prop->data, len_role);
179             (*res_role)[len_role] = 0;
180 
181             return 1;
182         }
183         else
184             prop = prop->next;
185     }
186 
187     return 0;
188 }
189 
190 int
winMultiWindowGetWMNormalHints(WindowPtr pWin,WinXSizeHints * hints)191 winMultiWindowGetWMNormalHints(WindowPtr pWin, WinXSizeHints * hints)
192 {
193     struct _Window *pwin;
194     struct _Property *prop;
195 
196     if (!pWin || !hints) {
197         ErrorF("winMultiWindowGetWMNormalHints - pWin or hints was NULL\n");
198         return 0;
199     }
200 
201     pwin = (struct _Window *) pWin;
202 
203     if (pwin->optional)
204         prop = (struct _Property *) pwin->optional->userProps;
205     else
206         prop = NULL;
207 
208     memset(hints, 0, sizeof(WinXSizeHints));
209 
210     while (prop) {
211         if (prop->propertyName == XA_WM_NORMAL_HINTS && prop->data) {
212             memcpy(hints, prop->data, sizeof(WinXSizeHints));
213             return 1;
214         }
215         else
216             prop = prop->next;
217     }
218 
219     return 0;
220 }
221 
222 int
winMultiWindowGetTransientFor(WindowPtr pWin,Window * pDaddyId)223 winMultiWindowGetTransientFor(WindowPtr pWin, Window *pDaddyId)
224 {
225     struct _Window *pwin;
226     struct _Property *prop;
227 
228     if (!pWin) {
229         ErrorF("winMultiWindowGetTransientFor - pWin was NULL\n");
230         return 0;
231     }
232 
233     pwin = (struct _Window *) pWin;
234 
235     if (pwin->optional)
236         prop = (struct _Property *) pwin->optional->userProps;
237     else
238         prop = NULL;
239 
240     if (pDaddyId)
241         *pDaddyId = 0;
242 
243     while (prop) {
244         if (prop->propertyName == XA_WM_TRANSIENT_FOR) {
245             if (pDaddyId)
246                 memcpy(pDaddyId, prop->data, sizeof(Window));
247             return 1;
248         }
249         else
250             prop = prop->next;
251     }
252 
253     return 0;
254 }
255 
256 int
winMultiWindowGetWMName(WindowPtr pWin,char ** wmName)257 winMultiWindowGetWMName(WindowPtr pWin, char **wmName)
258 {
259     struct _Window *pwin;
260     struct _Property *prop;
261     int len_name;
262 
263     if (!pWin || !wmName) {
264         ErrorF("winMultiWindowGetClassHint - pWin, res_name, or res_class was "
265                "NULL\n");
266         return 0;
267     }
268 
269     pwin = (struct _Window *) pWin;
270 
271     if (pwin->optional)
272         prop = (struct _Property *) pwin->optional->userProps;
273     else
274         prop = NULL;
275 
276     *wmName = NULL;
277 
278     while (prop) {
279         if (prop->propertyName == XA_WM_NAME
280             && prop->type == XA_STRING && prop->data) {
281             len_name = prop->size;
282 
283             (*wmName) = malloc(len_name + 1);
284 
285             if (!*wmName) {
286                 ErrorF("winMultiWindowGetWMName - *wmName was NULL\n");
287                 return 0;
288             }
289 
290             strncpy((*wmName), prop->data, len_name);
291             (*wmName)[len_name] = 0;
292 
293             return 1;
294         }
295         else
296             prop = prop->next;
297     }
298 
299     return 0;
300 }
301