Build in Maemo/scratchbox
[neverball] / share / syswm.c
1 /*
2  * Copyright (C) 2003-2010 Neverball authors
3  *
4  * NEVERBALL is  free software; you can redistribute  it and/or modify
5  * it under the  terms of the GNU General  Public License as published
6  * by the Free  Software Foundation; either version 2  of the License,
7  * or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
11  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
12  * General Public License for more details.
13  */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17
18 #include <SDL_video.h>
19 #include <SDL_syswm.h>
20
21 #include "syswm.h"
22 #include "base_config.h"
23 #include "image.h"
24 #include "lang.h"
25
26 /*---------------------------------------------------------------------------*/
27
28 void set_SDL_icon(const char *filename)
29 {
30 #if !defined(__APPLE__) && !defined(_WIN32)
31     SDL_Surface *icon;
32
33     if ((icon = load_surface(filename)))
34     {
35         SDL_WM_SetIcon(icon, NULL);
36         free(icon->pixels);
37         SDL_FreeSurface(icon);
38     }
39 #endif
40     return;
41 }
42
43 void set_EWMH_icon(const char *filename)
44 {
45 #if SDL_VIDEO_DRIVER_X11 && !SDL_VIDEO_DRIVER_QUARTZ && !ENABLE_OPENGLES
46     SDL_SysWMinfo info;
47
48     Display *dpy;
49     Window   window;
50
51     unsigned char *p;
52     int w, h, b;
53
54     SDL_VERSION(&info.version);
55
56     if (SDL_GetWMInfo(&info) != 1)
57     {
58         fprintf(stderr, L_("Failed to get WM info: %s\n"), SDL_GetError());
59         return;
60     }
61
62     if (info.subsystem != SDL_SYSWM_X11)
63         return;
64
65     dpy    = info.info.x11.display;
66     window = info.info.x11.wmwindow;
67
68     /*
69      * This code loads an image and sets it as the _NET_WM_ICON window
70      * property, as described in the Extended Window Manager Hints
71      * specification[*].  From the spec: "This is an array of 32-bit packed
72      * CARDINAL ARGB with high byte being A, low byte being B.  The first two
73      * cardinals are width, height.  Data is in rows, left to right and top to
74      * bottom."
75      *
76      * [*] http://standards.freedesktop.org/wm-spec/latest/
77      */
78
79     if ((p = image_load(filename, &w, &h, &b)))
80     {
81         long *data = NULL;
82
83         if ((data = calloc(2 + w * h, sizeof (long))))
84         {
85             int r, c;
86
87             data[0] = w;
88             data[1] = h;
89
90             for (r = 0; r < h; r++)
91                 for (c = 0; c < w; c++)
92                 {
93                     long          *dp = &data[2 + r * w + c];
94                     unsigned char *pp = &p[(h - r - 1) * w * b + c * b];
95
96                     if (b < 3)
97                     {
98                         if (b == 2)
99                             *dp |= *(pp + 1) << 24;
100
101                         *dp |= *(pp + 0) << 16;
102                         *dp |= *(pp + 0) << 8;
103                         *dp |= *(pp + 0) << 0;
104                     }
105                     else
106                     {
107                         if (b == 4)
108                             *dp |= *(pp + 3) << 24;
109
110                         *dp |= *(pp + 0) << 16;
111                         *dp |= *(pp + 1) << 8;
112                         *dp |= *(pp + 2) << 0;
113                     }
114                 }
115
116             info.info.x11.lock_func();
117             {
118                 Atom icon = XInternAtom(dpy, "_NET_WM_ICON", False);
119
120                 XChangeProperty(dpy, window, icon, XA_CARDINAL, 32,
121                                 PropModeReplace, (unsigned char *) data,
122                                 2 + w * h);
123             }
124             info.info.x11.unlock_func();
125
126             free(data);
127         }
128         else
129             fputs(L_("Failed to allocate memory for EWMH icon data.\n"), stderr);
130
131         free(p);
132     }
133 #endif
134
135     return;
136 }
137
138 /*---------------------------------------------------------------------------*/
139