2 * FreeRDP: A Remote Desktop Protocol Client
5 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 #include <X11/Xutil.h>
22 #include "xf_window.h"
24 /* Extended Window Manager Hints: http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html */
26 #define MWM_HINTS_DECORATIONS (1L << 1)
27 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
29 struct _PropMotifWmHints
32 unsigned long functions;
33 unsigned long decorations;
37 typedef struct _PropMotifWmHints PropMotifWmHints;
39 void window_fullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen)
43 if (window->decorations)
44 window_show_decorations(xfi, window, False);
46 XSetInputFocus(xfi->display, window->handle, RevertToParent, CurrentTime);
47 window->fullscreen = True;
51 /* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
53 boolean window_GetProperty(xfInfo* xfi, Window window, char* name, int length,
54 unsigned long* nitems, unsigned long* bytes, uint8** prop)
61 property = XInternAtom(xfi->display, name, True);
66 status = XGetWindowProperty(xfi->display, window,
67 property, 0, length, False, AnyPropertyType,
68 &actual_type, &actual_format, nitems, bytes, prop);
70 if (status != Success)
76 boolean window_GetCurrentDesktop(xfInfo* xfi)
83 status = window_GetProperty(xfi, DefaultRootWindow(xfi->display),
84 "_NET_CURRENT_DESKTOP", 1, &nitems, &bytes, &prop);
89 xfi->current_desktop = (int) *prop;
95 boolean window_GetWorkArea(xfInfo* xfi)
103 status = window_GetProperty(xfi, DefaultRootWindow(xfi->display),
104 "_NET_WORKAREA", 32 * 4, &nitems, &bytes, &prop);
109 window_GetCurrentDesktop(xfi);
111 plong = (long*) prop;
113 xfi->workArea.x = plong[xfi->current_desktop * 4 + 0];
114 xfi->workArea.y = plong[xfi->current_desktop * 4 + 1];
115 xfi->workArea.width = plong[xfi->current_desktop * 4 + 2];
116 xfi->workArea.height = plong[xfi->current_desktop * 4 + 3];
122 void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show)
125 PropMotifWmHints hints;
127 hints.decorations = 0;
128 hints.flags = MWM_HINTS_DECORATIONS;
130 atom = XInternAtom(xfi->display, "_MOTIF_WM_HINTS", True);
134 printf("window_show_decorations: failed to obtain atom _MOTIF_WM_HINTS\n");
141 XChangeProperty(xfi->display, window->handle, atom, atom, 32,
142 PropModeReplace, (uint8*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
146 window->decorations = show;
149 xfWindow* desktop_create(xfInfo* xfi, char* name)
153 window = (xfWindow*) xzalloc(sizeof(xfWindow));
158 XSizeHints* size_hints;
159 XClassHint* class_hints;
161 window->decorations = True;
162 window->fullscreen = False;
164 window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
165 xfi->workArea.x, xfi->workArea.y, xfi->width, xfi->height, 0, xfi->depth, InputOutput, xfi->visual,
166 CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
167 CWBorderPixel, &xfi->attribs);
169 class_hints = XAllocClassHint();
171 if (class_hints != NULL)
174 class_hints->res_name = name;
176 class_hints->res_class = "freerdp";
177 XSetClassHint(xfi->display, window->handle, class_hints);
181 size_hints = XAllocSizeHints();
185 size_hints->flags = PMinSize | PMaxSize;
186 size_hints->min_width = size_hints->max_width = xfi->width;
187 size_hints->min_height = size_hints->max_height = xfi->height;
188 XSetWMNormalHints(xfi->display, window->handle, size_hints);
193 KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
194 VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
195 PointerMotionMask | ExposureMask;
197 XSelectInput(xfi->display, window->handle, input_mask);
198 XMapWindow(xfi->display, window->handle);
204 xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, char* name)
208 window = (xfWindow*) xzalloc(sizeof(xfWindow));
210 window->width = width;
211 window->height = height;
217 XSizeHints* size_hints;
218 XClassHint* class_hints;
220 window->decorations = False;
221 window->fullscreen = False;
223 window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
224 x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
225 CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
226 CWBorderPixel, &xfi->attribs);
228 window_show_decorations(xfi, window, window->decorations);
230 class_hints = XAllocClassHint();
232 if (class_hints != NULL)
234 class_hints->res_name = "rail";
235 class_hints->res_class = "freerdp";
236 XSetClassHint(xfi->display, window->handle, class_hints);
240 size_hints = XAllocSizeHints();
244 size_hints->flags = PMinSize | PMaxSize;
245 size_hints->min_width = size_hints->max_width = window->width;
246 size_hints->min_height = size_hints->max_height = window->height;
247 XSetWMNormalHints(xfi->display, window->handle, size_hints);
252 KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
253 VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
254 PointerMotionMask | ExposureMask;
256 XSelectInput(xfi->display, window->handle, input_mask);
257 XMapWindow(xfi->display, window->handle);
259 memset(&gcv, 0, sizeof(gcv));
260 window->gc = XCreateGC(xfi->display, window->handle, GCGraphicsExposures, &gcv);
261 window->surface = XCreatePixmap(xfi->display, window->handle, window->width, window->height, xfi->depth);
263 XStoreName(xfi->display, window->handle, name);
265 xf_MoveWindow(xfi, window, x, y, width, height);
271 void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
273 XSizeHints* size_hints;
274 XWindowChanges changes;
278 changes.width = width;
279 changes.height = height;
281 XConfigureWindow(xfi->display, window->handle, CWX | CWY | CWWidth | CWHeight, &changes);
283 window->width = width;
284 window->height = height;
285 XFreePixmap(xfi->display, window->surface);
286 window->surface = XCreatePixmap(xfi->display, window->handle, window->width, window->height, xfi->depth);
288 size_hints = XAllocSizeHints();
292 size_hints->flags = PMinSize | PMaxSize;
293 size_hints->min_width = size_hints->max_width = window->width;
294 size_hints->min_height = size_hints->max_height = window->height;
295 XSetWMNormalHints(xfi->display, window->handle, size_hints);
300 void xf_DestroyWindow(xfInfo* xfi, xfWindow* window)
302 XFreeGC(xfi->display, window->gc);
303 XFreePixmap(xfi->display, window->surface);
304 XUnmapWindow(xfi->display, window->handle);
305 XDestroyWindow(xfi->display, window->handle);