compositor-x11: Rename the output make to "weston-X11"
[platform/upstream/weston.git] / clients / wscreensaver-glue.c
1 /*
2  * Copyright © 2011 Collabora, Ltd.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #include "wscreensaver-glue.h"
24
25 double frand(double f)
26 {
27         double r = random();
28         return r * f / (double)RAND_MAX;
29 }
30
31 void clear_gl_error(void)
32 {
33         while (glGetError() != GL_NO_ERROR)
34                 ;
35 }
36
37 void check_gl_error(const char *msg)
38 {
39         const char *emsg;
40         int err = glGetError();
41
42         switch (err)
43         {
44         case GL_NO_ERROR:
45                 return;
46
47         #define ERR(tok) case tok: emsg = #tok; break;
48         ERR(GL_INVALID_ENUM)
49         ERR(GL_INVALID_VALUE)
50         ERR(GL_INVALID_OPERATION)
51         ERR(GL_STACK_OVERFLOW)
52         ERR(GL_STACK_UNDERFLOW)
53         ERR(GL_OUT_OF_MEMORY)
54         #undef ERR
55
56         default:
57                 fprintf(stderr, "%s: %s: unknown GL error 0x%04x\n",
58                         progname, msg, err);
59                 exit(1);
60         }
61
62         fprintf(stderr, "%s: %s: GL error %s\n", progname, msg, emsg);
63         exit(1);
64 }
65
66 static void
67 read_xpm_color(uint32_t *ctable, const char *line)
68 {
69         unsigned char key;
70         char cstr[10];
71         char *end;
72         uint32_t value;
73
74         if (sscanf(line, "%1c c %9s", &key, cstr) < 2) {
75                 fprintf(stderr, "%s: error in XPM color definition '%s'\n",
76                         progname, line);
77                 return;
78         }
79
80         value = strtol(&cstr[1], &end, 16);
81
82         if (strcmp(cstr, "None") == 0)
83                 ctable[key] = 0x00000000;
84         else if (cstr[0] != '#' || !(cstr[1] != '\0' && *end == '\0')) {
85                 fprintf(stderr, "%s: error interpreting XPM color '%s'\n",
86                         progname, cstr);
87                 return;
88         } else {
89                 ctable[key] = value | 0xff000000;
90         }
91 }
92
93 static void
94 read_xpm_row(char *data, const char *line, uint32_t *ctable, int width)
95 {
96         uint32_t *pixel = (uint32_t *)data;
97         uint8_t *p = (uint8_t *)line;
98         int i;
99
100         for (i = 0; i < width; ++i)
101                 pixel[i] = ctable[p[i]];
102 }
103
104 XImage *xpm_to_ximage(char **xpm_data)
105 {
106         XImage *xi;
107         int colors;
108         int cpp;
109         int i;
110         uint32_t ctable[256] = { 0 };
111
112         xi = malloc(sizeof *xi);
113         if (!xi)
114                 return NULL;
115         xi->data = NULL;
116
117         if (sscanf(xpm_data[0], "%d %d %d %d", &xi->width,
118                                         &xi->height, &colors, &cpp) < 4)
119                 goto errout;
120
121         if (xi->width < 1 || xi->height < 1 || cpp != 1)
122                 goto errout;
123
124         xi->bytes_per_line = xi->width * sizeof(uint32_t);
125         xi->data = malloc(xi->height * xi->bytes_per_line);
126         if (!xi->data)
127                 goto errout;
128
129         for (i = 0; i < colors; ++i)
130                 read_xpm_color(ctable, xpm_data[i + 1]);
131
132         for (i = 0; i < xi->height; ++i)
133                 read_xpm_row(xi->data + i * xi->bytes_per_line,
134                              xpm_data[i + colors + 1], ctable, xi->width);
135
136         return xi;
137
138 errout:
139         fprintf(stderr, "%s: error processing XPM data.\n", progname);
140         XDestroyImage(xi);
141         return NULL;
142 }
143
144 void XDestroyImage(XImage *xi)
145 {
146         free(xi->data);
147         free(xi);
148 }