Make sure EWMH code isn't used when SDL supports Quartz (OS X)
[neverball] / share / syswm.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <SDL_video.h>
5 #include <SDL_syswm.h>
6
7 #include "syswm.h"
8 #include "base_config.h"
9 #include "image.h"
10 #include "lang.h"
11
12 /*---------------------------------------------------------------------------*/
13
14 void set_SDL_icon(const char *filename)
15 {
16 #if !defined(__APPLE__) && !defined(_WIN32)
17     SDL_Surface *icon;
18
19     if ((icon = load_surface(filename)))
20     {
21         SDL_WM_SetIcon(icon, NULL);
22         free(icon->pixels);
23         SDL_FreeSurface(icon);
24     }
25 #endif
26     return;
27 }
28
29 void set_EWMH_icon(const char *filename)
30 {
31 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ
32     SDL_SysWMinfo info;
33
34     Display *dpy;
35     Window   window;
36
37     unsigned char *p;
38     int w, h, b;
39
40     SDL_VERSION(&info.version);
41
42     if (SDL_GetWMInfo(&info) != 1)
43     {
44         fprintf(stderr, L_("Failed to get WM info: %s\n"), SDL_GetError());
45         return;
46     }
47
48     if (info.subsystem != SDL_SYSWM_X11)
49         return;
50
51     dpy    = info.info.x11.display;
52     window = info.info.x11.wmwindow;
53
54     /*
55      * This code loads an image and sets it as the _NET_WM_ICON window
56      * property, as described in the Extended Window Manager Hints
57      * specification[*].  From the spec: "This is an array of 32-bit packed
58      * CARDINAL ARGB with high byte being A, low byte being B.  The first two
59      * cardinals are width, height.  Data is in rows, left to right and top to
60      * bottom."
61      *
62      * [*] http://standards.freedesktop.org/wm-spec/latest/
63      */
64
65     if ((p = image_load(config_data(filename), &w, &h, &b)))
66     {
67         long *data = NULL;
68
69         if ((data = calloc(2 + w * h, sizeof (long))))
70         {
71             int r, c;
72
73             data[0] = w;
74             data[1] = h;
75
76             for (r = 0; r < h; r++)
77                 for (c = 0; c < w; c++)
78                 {
79                     long          *dp = &data[2 + r * w + c];
80                     unsigned char *pp = &p[(h - r - 1) * w * b + c * b];
81
82                     if (b < 3)
83                     {
84                         if (b == 2)
85                             *dp |= *(pp + 1) << 24;
86
87                         *dp |= *(pp + 0) << 16;
88                         *dp |= *(pp + 0) << 8;
89                         *dp |= *(pp + 0) << 0;
90                     }
91                     else
92                     {
93                         if (b == 4)
94                             *dp |= *(pp + 3) << 24;
95
96                         *dp |= *(pp + 0) << 16;
97                         *dp |= *(pp + 1) << 8;
98                         *dp |= *(pp + 2) << 0;
99                     }
100                 }
101
102             info.info.x11.lock_func();
103             {
104                 Atom icon = XInternAtom(dpy, "_NET_WM_ICON", False);
105
106                 XChangeProperty(dpy, window, icon, XA_CARDINAL, 32,
107                                 PropModeReplace, (unsigned char *) data,
108                                 2 + w * h);
109             }
110             info.info.x11.unlock_func();
111
112             free(data);
113         }
114         else
115             fputs(L_("Failed to allocate memory for EWMH icon data.\n"), stderr);
116
117         free(p);
118     }
119 #endif
120
121     return;
122 }
123
124 /*---------------------------------------------------------------------------*/
125