From http://www.jwz.org/xscreensaver/xscreensaver-5.34.tar.gz
[xscreensaver] / android / jwxyz.c
1 /* xscreensaver, Copyright (c) 1991-2015 Jamie Zawinski <jwz@jwz.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  */
11
12 /* JWXYZ Is Not Xlib.
13
14    But it's a bunch of function definitions that bear some resemblance to
15    Xlib and that do things that bear some resemblance to the
16    things that Xlib might have done.
17  */
18
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <wchar.h>
22 #include <android/log.h>
23
24 #include "jwxyz.h"
25 #include "jwxyz-timers.h"
26 #include "yarandom.h"
27 #include "screenhackI.h"
28
29 typedef signed char BOOL;
30 #define YES             (BOOL)1
31 #define NO              (BOOL)0
32
33 struct CGPoint {
34     float x;
35     float y;
36 };
37 typedef struct CGPoint CGPoint;
38
39 struct CGSize {
40     float width;
41     float height;
42 };
43 typedef struct CGSize CGSize;
44
45 struct CGRect {
46     CGPoint origin;
47     CGSize size;
48 };
49 typedef struct CGRect CGRect;
50
51 struct jwxyz_Drawable {
52     enum { WINDOW, PIXMAP } type;
53     CGRect frame;
54     union {
55         struct {
56             unsigned long background;
57             int last_mouse_x, last_mouse_y;
58         } window;
59         struct {
60             int depth;
61             void *cgc_buffer;   
62         } pixmap;
63     };
64 };
65
66 struct jwxyz_Display {
67     Window main_window;
68     Screen *screen;
69     int screen_count;
70     struct jwxyz_sources_data *timers_data;
71 };
72
73 struct jwxyz_Screen {
74     Display *dpy;
75     Visual *visual;
76     unsigned long black, white;
77     int screen_number;
78 };
79
80
81 Screen *
82 XDefaultScreenOfDisplay (Display *dpy)
83 {
84   return dpy->screen;
85 }
86
87 unsigned long
88 XBlackPixelOfScreen(Screen *screen)
89 {
90   return screen->black;
91 }
92
93 unsigned long
94 XWhitePixelOfScreen(Screen *screen)
95 {
96   return screen->white;
97 }
98
99
100 static void draw_rect(Display *, Drawable, GC,
101                       int x, int y, unsigned int width,
102                       unsigned int height, BOOL foreground_p, BOOL fill_p);
103
104 Status
105 XParseColor(Display * dpy, Colormap cmap, const char *spec, XColor * ret)
106 {
107     unsigned char r = 0, g = 0, b = 0;
108     if (*spec == '#' && strlen(spec) == 7) {
109         static unsigned const char hex[] = {    // yeah yeah, shoot me.
110             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
113                 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
114             0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116             0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
121                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
122             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
123                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
124             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
125                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
126         };
127         r = (hex[spec[1]] << 4) | hex[spec[2]];
128         g = (hex[spec[3]] << 4) | hex[spec[4]];
129         b = (hex[spec[5]] << 4) | hex[spec[6]];
130     } else if (!strcasecmp(spec, "black")) {
131 //  r = g = b = 0;
132     } else if (!strcasecmp(spec, "white")) {
133         r = g = b = 255;
134     } else if (!strcasecmp(spec, "red")) {
135         r = 255;
136     } else if (!strcasecmp(spec, "green")) {
137         g = 255;
138     } else if (!strcasecmp(spec, "blue")) {
139         b = 255;
140     } else if (!strcasecmp(spec, "cyan")) {
141         g = b = 255;
142     } else if (!strcasecmp(spec, "magenta")) {
143         r = b = 255;
144     } else if (!strcasecmp(spec, "yellow")) {
145         r = g = 255;
146     } else {
147         return 0;
148     }
149
150     ret->red = (r << 8) | r;
151     ret->green = (g << 8) | g;
152     ret->blue = (b << 8) | b;
153     ret->flags = DoRed | DoGreen | DoBlue;
154     return 1;
155 }
156
157 Status XAllocColor(Display * dpy, Colormap cmap, XColor * color)
158 {
159     // store 32 bit ARGB in the pixel field.
160     // (The uint32_t is so that 0xFF000000 doesn't become 0xFFFFFFFFFF000000)
161     color->pixel = (uint32_t)
162         ((0xFF << 24) |
163          (((color->red >> 8) & 0xFF) << 16) |
164          (((color->green >> 8) & 0xFF) << 8) |
165          (((color->blue >> 8) & 0xFF)));
166     return 1;
167 }
168
169 //  needs to be implemented in Android...
170 int
171 XFillRectangle(Display * dpy, Drawable d, GC gc, int x, int y,
172                unsigned int width, unsigned int height)
173 {
174     return 0;
175 }
176
177 //  needs to be implemented in Android...
178 int
179 XDrawString(Display * dpy, Drawable d, GC gc, int x, int y,
180             const char *str, int len)
181 {
182     return 0;                   // try this for now...
183 }
184
185
186 //  needs to be implemented in Android...
187 int XFreeGC(Display * dpy, GC gc)
188 {
189     return 0;
190 }
191
192
193
194 int XFreeFont(Display * dpy, XFontStruct * f)
195 {
196     return 0;
197 }
198
199 int XFreeFontInfo(char **names, XFontStruct * info, int n)
200 {
201     int i;
202     if (names) {
203         for (i = 0; i < n; i++)
204             if (names[i])
205                 free(names[i]);
206         free(names);
207     }
208     if (info) {
209         for (i = 0; i < n; i++)
210             if (info[i].per_char)
211                 free(info[i].per_char);
212         free(info);
213     }
214     return 0;
215 }
216
217
218 //  needs to be implemented in Android...
219 int XUnloadFont(Display * dpy, Font fid)
220 {
221     return 0;
222 }
223
224
225 //  needs to be implemented in Android...
226 GC
227 XCreateGC(Display * dpy, Drawable d, unsigned long mask, XGCValues * xgcv)
228 {
229 }
230
231
232 //  needs to be implemented in Android...
233 XFontStruct *XLoadQueryFont(Display * dpy, const char *name)
234 {
235 }
236
237
238 Status
239 XGetWindowAttributes(Display * dpy, Window w, XWindowAttributes * xgwa)
240 {
241
242 //  Assert (w && w->type == WINDOW, "not a window");
243
244     memset(xgwa, 0, sizeof(*xgwa));
245     xgwa->x = w->frame.origin.x;
246     xgwa->y = w->frame.origin.y;
247     xgwa->width = w->frame.size.width;
248     xgwa->height = w->frame.size.height;
249     xgwa->depth = 32;
250     xgwa->screen = dpy->screen;
251     xgwa->visual = dpy->screen->visual;
252
253     return 0;
254 }
255
256 //  needs to be implemented in Android...
257 int XSetFont(Display * dpy, GC gc, Font fid)
258 {
259     return 0;
260 }
261
262
263 //  needs to be implemented in Android...
264 int XClearWindow(Display * dpy, Window win)
265 {
266 }
267
268 // declared in utils/visual.h
269 int has_writable_cells(Screen * s, Visual * v)
270 {
271     return 0;
272 }
273
274 Status
275 XAllocColorCells(Display * dpy, Colormap cmap, Bool contig,
276                  unsigned long *pmret, unsigned int npl,
277                  unsigned long *pxret, unsigned int npx)
278 {
279     return 0;
280 }
281
282 int XStoreColors(Display * dpy, Colormap cmap, XColor * colors, int n)
283 {
284     //Assert(0, "XStoreColors called");
285     return 0;
286 }
287
288 int
289 XFreeColors(Display * dpy, Colormap cmap, unsigned long *px, int npixels,
290             unsigned long planes)
291 {
292     return 0;
293 }
294
295 int XFlush(Display * dpy)
296 {
297     return 0;
298 }
299
300 Display *XDisplayOfScreen(Screen * s)
301 {
302     return s->dpy;
303 }
304
305 //  needs to be implemented in Android...
306 int
307 XLookupString(XKeyEvent * e, char *buf, int size, KeySym * k_ret,
308               XComposeStatus * xc)
309 {
310     return 0;
311 }
312
313 int XScreenNumberOfScreen(Screen * s)
314 {
315     return s->screen_number;
316 }
317
318 int jwxyz_ScreenCount(Display * dpy)
319 {
320     return dpy->screen_count;
321 }
322
323
324 /*
325 // should this be defined?
326 static Display *jwxyz_live_displays[20] = { 0, };
327 */
328
329 Display * jwxyz_make_display (void *nsview_arg, void *cgc_arg)
330 {
331     Display *d = (Display *) calloc(1, sizeof(*d));
332     d->screen = (Screen *) calloc(1, sizeof(Screen));
333     d->screen->dpy = d;
334
335     d->screen_count = 1;
336     d->screen->screen_number = 0;
337     d->screen->black = 0xFF000000;
338     d->screen->white = 0xFFFFFFFF;
339
340     Visual *v = (Visual *) calloc(1, sizeof(Visual));
341     v->class = TrueColor;
342     v->red_mask = 0x00FF0000;
343     v->green_mask = 0x0000FF00;
344     v->blue_mask = 0x000000FF;
345     v->bits_per_rgb = 8;
346     d->screen->visual = v;
347
348     Window w = (Window) calloc(1, sizeof(*w));
349     w->type = WINDOW;
350     w->window.background = BlackPixelOfScreen(d->screen);
351
352     d->main_window = w;
353
354     return d;
355 }
356
357 void
358 jwxyz_free_display (Display *dpy)
359 {
360   free (dpy->screen->visual);
361   free (dpy->screen);
362   free (dpy->main_window);
363   free (dpy);
364 }
365
366
367 /* Call this when the Renderer calls onSurfaceChanged
368  */
369 void
370 jwxyz_window_resized (Display *dpy, Window w, 
371                       int new_x, int new_y, int new_width, int new_height,
372                       void *cgc_arg)
373 {
374     w->frame.origin.x = new_x;
375     w->frame.origin.y = new_y;
376     w->frame.size.width = new_width;
377     w->frame.size.height = new_height;
378 }
379
380 Window XRootWindow(Display * dpy, int screen)
381 {
382     return dpy->main_window;
383 }
384
385 /* Handle an abort on Android
386    TODO: Test that Android handles aborts properly
387  */
388 void
389 jwxyz_abort (const char *fmt, ...)
390 {
391   char s[10240];
392   if (!fmt || !*fmt)
393     strcpy (s, "abort");
394   else
395     {
396       va_list args;
397       va_start (args, fmt);
398       vsprintf (s, fmt, args);
399       va_end (args);
400     }
401   /* Send error to Android device log */
402   __android_log_write(ANDROID_LOG_ERROR, "xscreensaver", s);
403
404   abort();  
405 }
406
407 Pixmap
408 XCreatePixmap (Display *dpy, Drawable d,
409                unsigned int width, unsigned int height, unsigned int depth)
410 {
411 }
412
413 int
414 XDestroyImage (XImage *ximage)
415 {
416   if (ximage->data) free (ximage->data);
417   free (ximage);
418   return 0;
419 }
420
421 int
422 XDrawString16 (Display *dpy, Drawable d, GC gc, int x, int y,
423              const XChar2b *str, int len)
424 {
425 }
426
427 int
428 XFreePixmap (Display *d, Pixmap p)
429 {
430 }
431
432 XImage *
433 XGetImage (Display *dpy, Drawable d, int x, int y,
434            unsigned int width, unsigned int height,
435            unsigned long plane_mask, int format)
436 {
437 }
438
439 unsigned long
440 XGetPixel (XImage *ximage, int x, int y)
441 {
442 }
443
444 int
445 XSetForeground (Display *dpy, GC gc, unsigned long fg)
446 {
447 }
448
449 int
450 XTextExtents16 (XFontStruct *f, const XChar2b *s, int length,
451                 int *dir_ret, int *ascent_ret, int *descent_ret,
452                 XCharStruct *cs)
453 {
454 }
455
456 int
457 XPutPixel (XImage *ximage, int x, int y, unsigned long pixel)
458 {
459 }
460
461 XImage *
462 XCreateImage (Display *dpy, Visual *visual, unsigned int depth,
463               int format, int offset, char *data,
464               unsigned int width, unsigned int height,
465               int bitmap_pad, int bytes_per_line)
466 {
467 }