11 #include <SDL_syswm.h>
16 #define DIE(format, ...) do { \
17 fprintf(stderr, "Died at %s:%d: ", __FILE__, __LINE__ ); \
18 fprintf(stderr, format "\n", ## __VA_ARGS__); \
22 static const char * hdAtomNames[] = {
23 "_HILDON_NON_COMPOSITED_WINDOW",
24 "_HILDON_STACKABLE_WINDOW",
26 "_NET_WM_STATE_FULLSCREEN",
27 "_NET_WM_WINDOW_TYPE",
28 "_NET_WM_WINDOW_TYPE_NORMAL",
29 "_NET_WM_WINDOW_TYPE_DIALOG",
30 "_HILDON_WM_WINDOW_TYPE_ANIMATION_ACTOR",
31 "_HILDON_ANIMATION_CLIENT_READY",
32 "_HILDON_ANIMATION_CLIENT_MESSAGE_SHOW",
33 "_HILDON_ANIMATION_CLIENT_MESSAGE_POSITION",
34 "_HILDON_ANIMATION_CLIENT_MESSAGE_ROTATION",
35 "_HILDON_ANIMATION_CLIENT_MESSAGE_SCALE",
36 "_HILDON_ANIMATION_CLIENT_MESSAGE_ANCHOR",
37 "_HILDON_ANIMATION_CLIENT_MESSAGE_PARENT",
38 "_HILDON_WM_WINDOW_TYPE_REMOTE_TEXTURE",
39 "_HILDON_TEXTURE_CLIENT_MESSAGE_SHM",
40 "_HILDON_TEXTURE_CLIENT_MESSAGE_DAMAGE",
41 "_HILDON_TEXTURE_CLIENT_MESSAGE_SHOW",
42 "_HILDON_TEXTURE_CLIENT_MESSAGE_POSITION",
43 "_HILDON_TEXTURE_CLIENT_MESSAGE_OFFSET",
44 "_HILDON_TEXTURE_CLIENT_MESSAGE_SCALE",
45 "_HILDON_TEXTURE_CLIENT_MESSAGE_PARENT",
46 "_HILDON_TEXTURE_CLIENT_READY",
50 static bool hd_ok = false;
52 Atom hdAtomsValues[ATOM_COUNT];
56 static void hd_setup_stackable_window();
60 SDL_VERSION(&WMinfo.version);
61 if (!SDL_GetWMInfo(&WMinfo)) {
62 DIE("Bad SDL version");
65 Display * display = WMinfo.info.x11.display;
68 XInternAtoms(display, (char**)hdAtomNames, ATOM_COUNT, True, hdAtomsValues);
70 if (HDATOM(_HILDON_NON_COMPOSITED_WINDOW) == None) {
71 printf("Hildon Desktop seems not be loaded, since %s is not defined",
72 "_HILDON_NON_COMPOSITED_WINDOW");
76 if (hgwLaunched || true) {
77 hd_setup_stackable_window();
84 /** Enables or disables the Hildon NonCompositedWindow property */
85 void hdSetNonCompositing(bool enable)
91 WMinfo.info.x11.lock_func();
92 display = WMinfo.info.x11.display;
93 window = WMinfo.info.x11.fswindow;
96 XUnmapWindow(display, window);
97 XChangeProperty(display, window, HDATOM(_HILDON_NON_COMPOSITED_WINDOW),
98 XA_INTEGER, 32, PropModeReplace,
99 (unsigned char *) &one, 1);
100 XMapWindow(display, window);
102 XDeleteProperty(display, window,
103 HDATOM(_HILDON_NON_COMPOSITED_WINDOW));
106 WMinfo.info.x11.unlock_func();
109 static Atom get_window_type(Display *dpy, Window win)
111 Atom window_type = None;
114 unsigned long nitems, bytes_after;
115 unsigned char *prop_return = NULL;
117 if(Success == XGetWindowProperty(dpy, win, HDATOM(_NET_WM_WINDOW_TYPE),
119 False, XA_ATOM, &actual_type,
120 &actual_format, &nitems, &bytes_after,
121 &prop_return) && prop_return) {
122 window_type = *(Atom *)prop_return;
129 static Window find_launcher_window(Display *display, Window start)
131 Window root, parent, *children;
132 unsigned int count, i;
134 if (XQueryTree(display, start, &root, &parent, &children, &count)) {
135 XClassHint class_hints;
136 for (i = 0; i < count; i++) {
137 Window cur = children[i];
138 Window sub = find_launcher_window(display, cur);
141 if (XGetClassHint(display, cur, &class_hints)) {
142 if (strcasecmp(class_hints.res_class, "drnoksnes_startup") == 0) {
143 XFree(class_hints.res_name);
144 XFree(class_hints.res_class);
146 if (get_window_type(display, cur) !=
147 HDATOM(_NET_WM_WINDOW_TYPE_NORMAL)) {
155 XFree(class_hints.res_name);
156 XFree(class_hints.res_class);
165 /** Finds the drnoksnes_startup window. */
166 static Window find_launcher_window(Display *display)
168 return find_launcher_window(display,
169 RootWindow(display, DefaultScreen(display)));
172 /** Converts the aux SDL windows into tops of the HildonWindowStack */
173 static void hd_setup_stackable_window()
180 XSetWindowAttributes xattr;
184 WMinfo.info.x11.lock_func();
185 display = WMinfo.info.x11.display;
187 Window launcher = find_launcher_window(display);
190 printf("HD: Games startup window was not found\n");
194 hints = XGetWMHints(display, launcher);
195 //hints->input = True;
196 hints->flags = (hints->flags & WindowGroupHint)/* | InputHint*/;
198 chint = XAllocClassHint();
199 chint->res_name = chint->res_class = strdup("drnoksnes");
201 window = WMinfo.info.x11.fswindow;
202 XSetTransientForHint(display, window, launcher);
203 XSetWMHints(display, window, hints);
204 XSetClassHint(display, window, chint);
205 atom = HDATOM(_NET_WM_WINDOW_TYPE_NORMAL);
206 XChangeProperty(display, window, HDATOM(_NET_WM_WINDOW_TYPE),
207 XA_ATOM, 32, PropModeReplace,
208 (unsigned char *) &atom, 1);
209 xattr.override_redirect = False;
210 XChangeWindowAttributes(display, window, CWOverrideRedirect, &xattr);
211 atom = HDATOM(_NET_WM_STATE_FULLSCREEN);
212 XChangeProperty(display, window, HDATOM(_NET_WM_STATE),
213 XA_ATOM, 32, PropModeReplace,
214 (unsigned char *) &atom, 1);
215 XChangeProperty(display, window, HDATOM(_HILDON_STACKABLE_WINDOW),
216 XA_INTEGER, 32, PropModeReplace,
217 (unsigned char *) &one, 1);
219 free(chint->res_name);
223 WMinfo.info.x11.unlock_func();
227 void hdSetupFullscreen(bool enable)
229 Display *display = WMinfo.info.x11.display;
230 Window window = WMinfo.info.x11.wmwindow;
233 WMinfo.info.x11.lock_func();
235 /* So we hide the SDL nonfullscreen window when in fullscreen mode. */
237 XUnmapWindow(display, window);
239 XMapWindow(display, window);
242 WMinfo.info.x11.unlock_func();