1 /* testx11.c, Copyright (c) 2015-2017 Dave Odell <dmo2118@gmail.com>
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
11 * This is a test for X11 drawing primitives for the non-X11 ports of
12 * XScreenSaver. It shouldn't normally be installed with the other screenhacks.
14 * Almost no error checking in here. This is intentional.
17 #include "screenhack.h"
18 #include "glx/rotator.h"
19 #include "colorbars.h"
22 #include "ximage-loader.h"
23 #include "images/gen/logo-180_png.h"
29 # define jwxyz_XSetAntiAliasing(dpy, gc, p)
32 #ifndef jwxyz_assert_display
33 # define jwxyz_assert_display(dpy)
36 #define countof(a) (sizeof(a) / sizeof(*(a)))
38 static const char *testx11_defaults [] = {
39 ".background: #a020f0", /* purple */
42 "*ignoreRotation: True",
47 static XrmOptionDescRec testx11_options [] = {
67 XWindowAttributes xgwa;
75 /* Pixels from XAllocPixel. */
76 unsigned long rgb[3], salmon, magenta, gray50, dark_slate_gray1, cyan;
82 /* These X11 objects aren't altered after creation, except for:
83 - copy_gc and thick_line_gc get anti-aliasing toggled.
84 - xor_gc's clip mask (if it's turned on) always covers the entire window.
86 GC copy_gc, mono_gc, thick_line_gc, xor_gc, graph_gc;
87 Pixmap clip_mask_tile;
89 /* Backdrop stuff, naturally. */
91 Pixmap backdrop_tile, backdrop_scratch;
92 XColor backdrop_colors[64];
95 /* The following items may be modified by various test modes. */
96 Pixmap primitives_mini_pix;
113 fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM));
118 check_no_mem (void *ptr)
126 alloc_color (struct testx11 *st,
127 unsigned short r, unsigned short g, unsigned short b)
133 color.flags = DoRed | DoGreen | DoBlue;
134 XAllocColor (st->dpy, st->xgwa.colormap, &color);
139 create_backbuffer(struct testx11 *st)
142 st->backbuffer = XCreatePixmap (st->dpy, st->win,
143 st->xgwa.width, st->xgwa.height,
149 toggle_antialiasing (struct testx11 *st)
151 st->anti_alias_p ^= True;
152 jwxyz_XSetAntiAliasing (st->dpy, st->copy_gc, st->anti_alias_p);
153 jwxyz_XSetAntiAliasing (st->dpy, st->thick_line_gc, st->anti_alias_p);
159 primitives_mini_rect(struct testx11 *st, Drawable t, int x, int y)
161 XFillRectangle(st->dpy, t, st->copy_gc, x, y, 2, 2);
165 images_copy_test (Display *dpy, Drawable src, Drawable dst, GC gc,
166 int src_y, int dst_x, int dst_y, unsigned long cells)
168 XCopyArea(dpy, src, dst, gc, 0, src_y, 3, 2, dst_x, dst_y);
171 XImage *image = XGetImage(dpy, src, 0, src_y, 3, 2, cells, ZPixmap);
172 XPutImage(dpy, dst, gc, image, 0, 0, dst_x, dst_y + 2, 3, 2);
173 XDestroyImage(image);
178 images_pattern (struct testx11 *st, Drawable d, unsigned y)
181 for (x = 0; x != 3; ++x) {
182 XSetForeground(st->dpy, st->images_point_gc, st->rgb[x]);
183 XDrawPoint(st->dpy, d, st->images_point_gc, x, y);
184 XSetForeground(st->dpy, st->images_point_gc, st->rgb[2 - x]);
185 XFillRectangle(st->dpy, d, st->images_point_gc, x, y + 1, 1, 1);
188 images_copy_test (st->dpy, d, d, st->images_point_gc, y, 0, y + 2,
189 st->rgb[0] | st->rgb[1] | st->rgb[2]);
192 static const unsigned tile_size = 16;
193 static const unsigned tile_count = 8;
195 static const unsigned preserve_size = 128;
198 make_clip_mask (struct testx11 *st)
200 /* Activate this for extra Fun! */
202 /* This is kind of slow, but that's OK, because this only happens on int
205 unsigned w = st->xgwa.width, h = st->xgwa.height;
207 Pixmap mask = XCreatePixmap (st->dpy, st->clip_mask_tile, w, h, 1);
209 for (y = 0; y < h; y += 8) {
210 for (x = 0; x < w; x += 8) {
211 XCopyArea (st->dpy, st->clip_mask_tile, mask, st->mono_gc,
216 XSetClipMask (st->dpy, st->xor_gc, mask);
217 XFreePixmap (st->dpy, mask);
223 colorbars (struct testx11 *st)
225 Pixmap logo_mask = 0;
226 Pixmap logo = image_data_to_pixmap (st->dpy, st->win,
227 logo_180_png, sizeof(logo_180_png),
229 draw_colorbars (st->xgwa.screen, st->xgwa.visual, st->win,
230 st->xgwa.colormap, 0, 0, st->xgwa.width, st->xgwa.height,
232 XFreePixmap (st->dpy, logo);
233 XFreePixmap (st->dpy, logo_mask);
238 testx11_init (Display *dpy, Window win)
240 static const char backdrop_pattern[] = {
241 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07', /* Zig */
242 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01', /* Zag */
243 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07', /* etc. */
244 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01',
245 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07',
246 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01',
247 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07',
248 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01',
251 static const char clip_bits[] = {
252 '\x33', '\x33', '\xcc', '\xcc', '\x33', '\x33', '\xcc', '\xcc'
255 struct testx11 *st = (struct testx11 *) malloc (sizeof(*st));
263 XGetWindowAttributes (dpy, win, &st->xgwa);
265 create_backbuffer (st);
267 st->rgb[0] = alloc_color (st, 0xffff, 0x0000, 0x0000);
268 st->rgb[1] = alloc_color (st, 0x0000, 0xffff, 0x0000);
269 st->rgb[2] = alloc_color (st, 0x0000, 0x0000, 0xffff);
270 st->salmon = alloc_color (st, 0xffff, 0x7fff, 0x7fff);
271 st->magenta = alloc_color (st, 0xffff, 0x0000, 0xffff);
272 st->gray50 = alloc_color (st, 0x8000, 0x8000, 0x8000);
273 st->dark_slate_gray1 = alloc_color (st, 0x8000, 0xffff, 0xffff);
274 st->cyan = alloc_color (st, 0x0000, 0xffff, 0xffff);
276 st->backdrop_tile = XCreatePixmapFromBitmapData (dpy, win,
277 (char *) backdrop_pattern,
278 tile_size, tile_size * 2,
281 st->clip_mask_tile = XCreatePixmapFromBitmapData (dpy, win,
282 (char *) clip_bits, 8, 8,
286 unsigned s = tile_size * tile_count;
287 st->backdrop_scratch = XCreatePixmap (dpy, win, s, s, st->xgwa.depth);
290 st->backdrop_ncolors = countof (st->backdrop_colors);
291 make_color_loop (st->xgwa.screen, st->xgwa.visual, st->xgwa.colormap,
292 180, 1, 0.5, 210, 1, 0.5, 240, 1, 0.5,
293 st->backdrop_colors, &st->backdrop_ncolors, True, NULL);
298 st->mode = mode_primitives;
300 st->mode = mode_welcome;
303 st->anti_alias_p = False;
305 gcv.function = GXcopy;
306 gcv.foreground = st->cyan;
307 gcv.background = st->magenta;
309 gcv.cap_style = CapRound;
310 /* TODO: Real X11 uses fixed by default. */
311 gcv.font = XLoadFont (dpy, "fixed");
312 st->copy_gc = XCreateGC (dpy, win,
313 GCFunction | GCForeground | GCBackground
314 | GCLineWidth | GCCapStyle | GCFont, &gcv);
316 gcv.foreground = BlackPixelOfScreen (st->xgwa.screen);
317 st->backdrop_black_gc = XCreateGC (dpy, win, GCForeground, &gcv);
319 gcv.foreground = alloc_color (st, 0x8000, 0x4000, 0xffff);
321 gcv.cap_style = CapProjecting;
322 st->thick_line_gc = XCreateGC (dpy, win,
323 GCForeground | GCLineWidth | GCCapStyle,
326 gcv.function = GXxor;
327 st->xor_gc = XCreateGC (dpy, win, GCFunction, &gcv);
329 st->images_point_gc = XCreateGC (dpy, win, 0, NULL);
331 st->graph_gc = XCreateGC (dpy, win, 0, &gcv);
333 st->mono_gc = XCreateGC (dpy, st->clip_mask_tile, 0, &gcv);
335 st->copy_pix64 = XCreatePixmap(dpy, win, 64, 64, st->xgwa.depth);
337 st->primitives_mini_pix = XCreatePixmap (dpy, win, 16, 24, st->xgwa.depth);
340 static const char text[] = "Welcome from testx11_init().";
342 XDrawString (dpy, win, st->copy_gc, 16, 16, text, countof (text) - 1);
348 XCreatePixmap(dpy, win, preserve_size, preserve_size, st->xgwa.depth);
350 XCreatePixmap(dpy, win, preserve_size, preserve_size, st->xgwa.depth);
352 toggle_antialiasing (st);
356 jwxyz_assert_display (dpy);
358 st->rot = make_rotator (2, 2, 2, 2, 0.01, False);
364 backdrop (struct testx11 *st, Drawable t)
366 unsigned w = st->xgwa.width, h = st->xgwa.height;
369 for (y = 0; y != tile_count; ++y) {
370 const float s0 = 2 * M_PI / tile_count;
371 float y_fac = sin ((y + st->frame / 16.0) * s0);
372 for (x = 0; x != tile_count; ++x) {
373 int c = ((sin ((x + st->frame / 8.0) * s0) * y_fac) - 1) / 2 *
374 st->backdrop_ncolors / 2;
375 c = (c + st->frame) % st->backdrop_ncolors;
376 XSetBackground (st->dpy, st->backdrop_black_gc,
377 st->backdrop_colors[c].pixel);
378 XCopyPlane (st->dpy, st->backdrop_tile, st->backdrop_scratch,
379 st->backdrop_black_gc, 0, st->frame % tile_size,
380 tile_size, tile_size, x * tile_size, y * tile_size, 1);
384 /* XFillRectangle (st->dpy, t, st->backdrop_black_gc, 0, 0, w, h); */
386 for (y = 0; y < h; y += tile_count * tile_size) {
387 for (x = 0; x < w; x += tile_count * tile_size) {
388 XCopyArea (st->dpy, st->backdrop_scratch, t, st->copy_gc, 0, 0,
389 tile_count * tile_size, tile_count * tile_size, x, y);
394 static const unsigned button_pad = 16;
395 static const unsigned button_size = 64;
399 testx11_graph_rotator (struct testx11 *st)
403 int boxw = st->xgwa.width / 3;
404 int boxh = (st->xgwa.height - (22 * 5)) / 4;
405 int boxx = st->xgwa.width - boxw - 20;
406 int boxy = st->xgwa.height - boxh - 20;
410 get_position (st->rot, &x, &y, &z, True);
411 if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
414 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
415 XDrawRectangle (st->dpy, st->win, st->graph_gc,
416 boxx-1, boxy-1, boxw+2, boxh+2);
418 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
419 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
421 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
422 XDrawLine (st->dpy, st->win, st->graph_gc,
423 boxx + boxw - 1, boxy,
424 boxx + boxw - 1, boxy + boxh);
426 XSetForeground (st->dpy, st->graph_gc, st->salmon);
427 XDrawPoint (st->dpy, st->win, st->graph_gc,
429 boxy + boxh - 1 - (int) (x * (boxh - 1)));
431 XSetForeground (st->dpy, st->graph_gc, st->magenta);
432 XDrawPoint (st->dpy, st->win, st->graph_gc,
434 boxy + boxh - 1 - (int) (y * (boxh - 1)));
436 XSetForeground (st->dpy, st->graph_gc, st->gray50);
437 XDrawPoint (st->dpy, st->win, st->graph_gc,
439 boxy + boxh - 1 - (int) (z * (boxh - 1)));
443 get_rotation (st->rot, &x, &y, &z, True);
444 if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
446 /* put 0 in the middle */
447 x += 0.5; if (x > 1) x--;
448 y += 0.5; if (y > 1) y--;
449 z += 0.5; if (z > 1) z--;
454 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
455 XDrawRectangle (st->dpy, st->win, st->graph_gc,
456 boxx-1, boxy-1, boxw+2, boxh+2);
458 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
459 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
461 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
462 XDrawLine (st->dpy, st->win, st->graph_gc,
463 boxx + boxw - 1, boxy,
464 boxx + boxw - 1, boxy + boxh);
466 XSetForeground (st->dpy, st->graph_gc, st->magenta);
467 XDrawPoint (st->dpy, st->win, st->graph_gc,
469 boxy + boxh - 1 - (int) (x * (boxh - 1)));
474 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
475 XDrawRectangle (st->dpy, st->win, st->graph_gc,
476 boxx-1, boxy-1, boxw+2, boxh+2);
478 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
479 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
481 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
482 XDrawLine (st->dpy, st->win, st->graph_gc,
483 boxx + boxw - 1, boxy,
484 boxx + boxw - 1, boxy + boxh);
486 XSetForeground (st->dpy, st->graph_gc, st->magenta);
487 XDrawPoint (st->dpy, st->win, st->graph_gc,
489 boxy + boxh - 1 - (int) (y * (boxh - 1)));
494 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
495 XDrawRectangle (st->dpy, st->win, st->graph_gc,
496 boxx-1, boxy-1, boxw+2, boxh+2);
498 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
499 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
501 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
502 XDrawLine (st->dpy, st->win, st->graph_gc,
503 boxx + boxw - 1, boxy,
504 boxx + boxw - 1, boxy + boxh);
506 XSetForeground (st->dpy, st->graph_gc, st->magenta);
507 XDrawPoint (st->dpy, st->win, st->graph_gc,
509 boxy + boxh - 1 - (int) (z * (boxh - 1)));
513 /* Draws a blinking box in what should be the upper left corner of the
514 device, as physically oriented. The box is taller than it is wide.
517 testx11_show_orientation (struct testx11 *st)
521 int w = st->xgwa.width;
522 int h = st->xgwa.height;
527 int o = (int) current_device_rotation ();
530 // fprintf (stderr,"ROT %d -> %d\n", oo, o);
535 case 0: case 360: x = 0; y = 0; w = ww; h = hh; break;
536 case 90: case -270: x = 0; y = h-ww; w = hh; h = ww; break;
537 case -90: case 270: x = w-hh; y = 0; w = hh; h = ww; break;
538 case 180: case -180: x = w-ww; y = h-hh; w = ww; h = hh; break;
542 if (++tick > 20) tick = 0;
544 XSetForeground (st->dpy, st->graph_gc,
546 ? WhitePixelOfScreen (st->xgwa.screen)
547 : BlackPixelOfScreen (st->xgwa.screen)));
548 XFillRectangle (st->dpy, st->win, st->graph_gc,
555 testx11_draw (Display *dpy, Window win, void *st_raw)
557 struct testx11 *st = (struct testx11 *) st_raw;
558 unsigned w = st->xgwa.width, h = st->xgwa.height;
562 Drawable t = st->mode == mode_primitives ? st->backbuffer : win;
566 assert (dpy == st->dpy);
567 assert (win == st->win);
569 jwxyz_assert_display (dpy);
571 XSetWindowBackground (dpy, win, st->gray50);
575 case mode_primitives:
578 XDrawPoint (dpy, t, st->thick_line_gc, 0, 0);
579 XDrawPoint (dpy, t, st->thick_line_gc, 0, 1);
580 XDrawPoint (dpy, t, st->thick_line_gc, 1, 0);
581 XDrawPoint (dpy, t, st->thick_line_gc, 1, 1);
583 primitives_mini_rect (st, t, 2, 0);
584 primitives_mini_rect (st, t, 0, 2);
585 primitives_mini_rect (st, t, 4, 2);
586 primitives_mini_rect (st, t, 2, 4);
588 primitives_mini_rect (st, t, 30, -2);
589 primitives_mini_rect (st, t, 32, 0);
591 primitives_mini_rect (st, t, 30, h - 2);
592 primitives_mini_rect (st, t, 32, h);
594 primitives_mini_rect (st, t, -2, 30);
595 primitives_mini_rect (st, t, 0, 32);
596 primitives_mini_rect (st, t, w - 2, 30);
597 primitives_mini_rect (st, t, w, 32);
599 primitives_mini_rect (st, t, w / 2 + 4, h / 2 + 4);
601 XFillArc (dpy, t, st->copy_gc, 16, 16, 256, 256, 45 * 64, -135 * 64);
602 /* XCopyArea(dpy, t, t, st->copy_gc, 48, 48, 128, 128, 64, 64); */
605 XDrawPoint (dpy, t, st->copy_gc, w / 2, h / 2);
608 XDrawPoint (dpy, t, st->copy_gc, w / 2, 0);
609 XDrawPoint (dpy, t, st->copy_gc, w / 2, h - 1);
611 XDrawPoint (dpy, t, st->copy_gc, 16, -1);
612 XDrawPoint (dpy, t, st->copy_gc, 17, 0);
614 XDrawPoint (dpy, t, st->copy_gc, 15, h - 2);
615 XDrawPoint (dpy, t, st->copy_gc, 16, h - 1);
616 XDrawPoint (dpy, t, st->copy_gc, 17, h);
619 XPoint *points = malloc (sizeof(XPoint) * h);
620 XSegment *lines = malloc (sizeof(XSegment) * h);
621 XPoint *points2 = malloc (sizeof(XPoint) * h);
622 for(i = 0; i != h; ++i)
624 points[i].x = 8 + (i & 1);
627 lines[i].x1 = 48 + (i & 1) * 4;
632 points2[i].x = 24 + (i & 1);
634 /* XFillRectangle(st->dpy, t, st->copy_gc, 24 + (i & 1), i, 1, 1); */
637 XDrawPoints (dpy, t, st->copy_gc, points, h, CoordModeOrigin);
638 XDrawSegments (dpy, t, st->copy_gc, lines, h);
639 XDrawPoints (dpy, t, st->copy_gc, points2, h, CoordModeOrigin);
646 XDrawPoint (dpy, t, st->copy_gc, -1, 16);
647 XDrawPoint (dpy, t, st->copy_gc, 0, 17);
648 XDrawPoint (dpy, t, st->copy_gc, w - 1, 16);
649 XDrawPoint (dpy, t, st->copy_gc, w, 17);
652 XPoint *points = malloc(sizeof(XPoint) * w);
653 XSegment *lines = malloc(sizeof(XSegment) * w);
654 XPoint *points2 = malloc(sizeof(XPoint) * w);
655 for(i = 0; i != w; ++i)
658 points[i].y = 8 + (i & 1);
660 lines[i].y1 = 48 + (i & 1) * 4;
665 points2[i].y = 24 + (i & 1);
666 /* XFillRectangle(dpy, t, st->copy_gc, i, 24 + (i & 1), 1, 1); */
669 XDrawPoints (dpy, t, st->copy_gc, points, w, CoordModeOrigin);
670 XDrawSegments (dpy, t, st->copy_gc, lines, w);
672 /* Thick purple lines */
675 {31, 31, 31, 31}, /* TODO: This should not be rotated in Cocoa. */
678 XDrawSegments (dpy, t, st->thick_line_gc, seg, 2);
680 XDrawLine (dpy, t, st->thick_line_gc, 58, 43, 64, 43);
681 XDrawLine (dpy, t, st->thick_line_gc, 73, 43, 80, 43);
684 XDrawPoints (dpy, t, st->copy_gc, points2, w, CoordModeOrigin);
690 XDrawLine (dpy, t, st->copy_gc, 54, 11, 72, 22);
693 XPoint vertices[] = {{5, 5}, {5, 8}, {8, 8}, {8, 5}};
694 XFillPolygon (dpy, t, st->copy_gc, vertices, 4, Convex, CoordModeOrigin);
698 XDrawRectangle (dpy, t, st->copy_gc, 11, 11, 11, 11);
699 XFillRectangle (dpy, t, st->copy_gc, 13, 13, 8, 8);
702 /* Several ~16 pixel boxes in a row. */
706 XDrawRectangle (dpy, t, st->copy_gc, 54, 54, 16, 16);
707 XDrawRectangle (dpy, t, st->copy_gc, 55, 55, 14, 14);
709 XDrawPoint (dpy, t, st->thick_line_gc, 56, 56);
710 XDrawPoint (dpy, t, st->copy_gc, 57, 56);
714 XCopyArea (dpy, t, t, st->copy_gc, 55, 55, 15, 15, 72, 55);
718 XImage *image = XGetImage(st->dpy, t, 55, 55, 15, 15, 0xffffff, ZPixmap);
719 XPutPixel(image, 2, 0, 0x00000000);
720 XPutImage (dpy, t, st->copy_gc, image, 0, 0, 88, 55, 15, 15);
721 XDestroyImage(image);
727 XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
728 104, 55, 16, 16, 0, 0);
729 /* XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
730 105, 56, 14, 14, 1, 1);
731 XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
735 /* This point gets hidden. */
736 XDrawPoint (dpy, t, st->copy_gc, 104 + 8, 55 + 8);
738 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 0, 0);
739 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 1, 0);
740 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 15, 15);
741 XDrawRectangle (dpy, st->primitives_mini_pix, st->copy_gc,
743 XCopyArea (dpy, st->primitives_mini_pix, t, st->copy_gc,
744 0, 0, 16, 16, 104, 55);
748 XDrawLine (dpy, t, st->copy_gc, 11, 28, 22, 28);
749 XDrawLine (dpy, t, st->copy_gc, 12, 27, 12, 46);
750 XDrawLine (dpy, t, st->copy_gc, 14, 30, 14, 30);
753 XDrawArc (dpy, t, st->copy_gc, 27, 11, 19, 11, 0, 360 * 64);
755 XDrawRectangle (dpy, t, st->copy_gc, 54, 73, 64, 64);
756 XFillArc (dpy, t, st->copy_gc, 56, 75, 60, 60, 0, 360 * 64);
757 /* XDrawArc (dpy, t, st->thick_line_gc, 56, 75, 60, 60, 0, 360 * 64); */
759 XClearArea (dpy, win, 121, 55, 16, 16, False);
765 /* if(w >= 9 && h >= 10) */
768 /* Draw below the status bar. */
769 const unsigned y = 64;
771 const unsigned y = 0;
774 Screen *screen = st->xgwa.screen;
775 Visual *visual = st->xgwa.visual;
776 Pixmap pixmap = XCreatePixmap (dpy, t, 3, 10,
777 visual_depth (screen, visual));
778 unsigned long cells = cells = st->rgb[0] | st->rgb[1] | st->rgb[2];
781 XSetForeground (dpy, st->images_point_gc, st->salmon);
782 XDrawPoint (dpy, t, st->images_point_gc, 0, h - 1);
783 XDrawLine (dpy, t, st->images_point_gc, 0, y - 1, 8, y - 1);
786 images_pattern (st, t, y);
787 images_pattern (st, pixmap, 0);
788 /* Here's a good spot to verify that the pixmap contains the right colors
791 images_copy_test (dpy, t, pixmap, st->copy_gc, y, 0, 6, cells);
793 XCopyArea (dpy, pixmap, t, st->copy_gc, 0, 0, 3, 10, 3, y);
796 XImage *image = XGetImage (dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
797 XPutImage (dpy, t, st->copy_gc, image, 0, 0, 6, y, 3, 10);
798 XDestroyImage (image);
801 XFreePixmap (dpy, pixmap);
809 /* X.org isn't making a whole lot of sense here. */
811 Bool use_copy = (st->frame / 20) & 1;
814 GC gc = use_copy ? st->copy_gc : st->xor_gc;
816 XSetWindowBackground (dpy, t, st->magenta);
817 XCopyArea (dpy, t, t, gc, -2, -2, 40, 40, 20, 20);
820 XCopyArea (st->dpy, t, t, gc, -20, h - 20, 40, 40, 20, h - 60);
821 XCopyArea (dpy, t, t, gc, w - 38, h - 38, 40, 40, w - 60, h - 60);
822 XCopyArea (dpy, t, t, gc, w - 20, -20, 40, 40, w - 60, 20);
824 XSetWindowBackground (dpy, t, st->gray50);
825 XCopyArea (st->dpy, t, t, gc, -20, 64, 40, 40, 20, 64);
827 XSetWindowBackground (dpy, t, st->dark_slate_gray1);
828 XCopyArea (st->dpy, t, t, gc, -20, 112, 40, 40, 20, 112);
834 XCopyArea (st->dpy, t, st->copy_pix64, gc, 0, h - 64, 64, 64, 0, 0);
836 XSetForeground (st->dpy, st->xor_gc, st->rgb[1]);
837 XSetBackground (st->dpy, st->xor_gc, st->cyan);
839 /* XCopyArea (st->dpy, st->copy_pix64, st->copy_pix64, gc,
840 32, 32, 64, 64, 0, 0);
841 XCopyArea (st->dpy, st->copy_pix64, t, gc, 0, 0, 64, 64, 4, h - 68);
843 XCopyArea (st->dpy, st->copy_pix64, t, gc, 32, 32, 128, 64, 0, h - 64);
851 if(!(st->frame % 10)) {
852 const unsigned r = 16;
853 unsigned n = st->frame / 10;
855 XFillArc (st->dpy, st->preserve[n & 1],
856 m & 1 ? st->copy_gc : st->thick_line_gc,
857 NRAND(preserve_size) - r, NRAND(preserve_size) - r,
858 r * 2, r * 2, 0, 360 * 64);
861 XCopyArea (st->dpy, st->preserve[0], t, st->copy_gc, 0, 0,
862 preserve_size, preserve_size, 0, 0);
863 XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
864 preserve_size, preserve_size, preserve_size, 0);
865 XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
866 preserve_size, preserve_size,
867 w - preserve_size / 2, preserve_size);
873 st->erase = erase_window(st->dpy, st->win, st->erase);
877 /* Mode toggle buttons */
878 for (i = 1; i != mode_count; ++i) {
881 XRectangle button_dims;
882 button_dims.x = i0 * (button_pad + button_size) + button_pad;
883 button_dims.y = h - button_pad - button_size;
884 button_dims.width = button_size;
885 button_dims.height = button_size;
887 XFillRectangles (dpy, t, st->backdrop_black_gc, &button_dims, 1);
888 XDrawRectangle (dpy, t, st->copy_gc, button_dims.x, button_dims.y,
889 button_dims.width, button_dims.height);
891 XDrawString (dpy, t, st->copy_gc,
892 button_dims.x + button_size / 2 - 3,
893 h - button_pad - button_size / 2 + 13 / 2,
894 str, sprintf(str, "%u", i));
898 XCopyArea (dpy, t, win, st->copy_gc, 0, 0, w, h, 0, 0);
900 testx11_graph_rotator (st);
901 testx11_show_orientation (st);
908 testx11_reshape (Display *dpy, Window window, void *st_raw,
909 unsigned int w, unsigned int h)
911 struct testx11 *st = (struct testx11 *)st_raw;
915 XFreePixmap (st->dpy, st->backbuffer);
917 create_backbuffer (st);
922 testx11_event (Display *dpy, Window window, void *st_raw, XEvent *event)
924 struct testx11 *st = (struct testx11 *) st_raw;
926 Bool handled = False;
928 switch (event->xany.type)
934 XLookupString (&event->xkey, &c, 1, &keysym, 0);
936 handled = toggle_antialiasing (st);
938 if (c >= '0' && c <= '9' && c < '0' + mode_count) {
946 if (event->xbutton.y >= st->xgwa.height - button_pad * 2 - button_size) {
947 int i = (event->xbutton.x - button_pad / 2) / (button_pad + button_size) + 1;
948 if (i && i < mode_count) {
955 handled = toggle_antialiasing (st);
963 testx11_free (Display *dpy, Window window, void *st_raw)
965 /* Omitted for the sake of brevity. */
968 XSCREENSAVER_MODULE_2 ("TestX11", testx11, testx11)