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 unsigned c = ((sin ((x + st->frame / 8.0) * s0) * y_fac) - 1) / 2 * st->backdrop_ncolors / 2;
374 c = (c + st->frame) % st->backdrop_ncolors;
375 XSetBackground (st->dpy, st->backdrop_black_gc,
376 st->backdrop_colors[c].pixel);
377 XCopyPlane (st->dpy, st->backdrop_tile, st->backdrop_scratch,
378 st->backdrop_black_gc, 0, st->frame % tile_size,
379 tile_size, tile_size, x * tile_size, y * tile_size, 1);
383 /* XFillRectangle (st->dpy, t, st->backdrop_black_gc, 0, 0, w, h); */
385 for (y = 0; y < h; y += tile_count * tile_size) {
386 for (x = 0; x < w; x += tile_count * tile_size) {
387 XCopyArea (st->dpy, st->backdrop_scratch, t, st->copy_gc, 0, 0,
388 tile_count * tile_size, tile_count * tile_size, x, y);
393 static const unsigned button_pad = 16;
394 static const unsigned button_size = 64;
398 testx11_graph_rotator (struct testx11 *st)
402 int boxw = st->xgwa.width / 3;
403 int boxh = (st->xgwa.height - (22 * 5)) / 4;
404 int boxx = st->xgwa.width - boxw - 20;
405 int boxy = st->xgwa.height - boxh - 20;
409 get_position (st->rot, &x, &y, &z, True);
410 if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
413 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
414 XDrawRectangle (st->dpy, st->win, st->graph_gc,
415 boxx-1, boxy-1, boxw+2, boxh+2);
417 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
418 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
420 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
421 XDrawLine (st->dpy, st->win, st->graph_gc,
422 boxx + boxw - 1, boxy,
423 boxx + boxw - 1, boxy + boxh);
425 XSetForeground (st->dpy, st->graph_gc, st->salmon);
426 XDrawPoint (st->dpy, st->win, st->graph_gc,
428 boxy + boxh - 1 - (int) (x * (boxh - 1)));
430 XSetForeground (st->dpy, st->graph_gc, st->magenta);
431 XDrawPoint (st->dpy, st->win, st->graph_gc,
433 boxy + boxh - 1 - (int) (y * (boxh - 1)));
435 XSetForeground (st->dpy, st->graph_gc, st->gray50);
436 XDrawPoint (st->dpy, st->win, st->graph_gc,
438 boxy + boxh - 1 - (int) (z * (boxh - 1)));
442 get_rotation (st->rot, &x, &y, &z, True);
443 if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
445 /* put 0 in the middle */
446 x += 0.5; if (x > 1) x--;
447 y += 0.5; if (y > 1) y--;
448 z += 0.5; if (z > 1) z--;
453 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
454 XDrawRectangle (st->dpy, st->win, st->graph_gc,
455 boxx-1, boxy-1, boxw+2, boxh+2);
457 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
458 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
460 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
461 XDrawLine (st->dpy, st->win, st->graph_gc,
462 boxx + boxw - 1, boxy,
463 boxx + boxw - 1, boxy + boxh);
465 XSetForeground (st->dpy, st->graph_gc, st->magenta);
466 XDrawPoint (st->dpy, st->win, st->graph_gc,
468 boxy + boxh - 1 - (int) (x * (boxh - 1)));
473 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
474 XDrawRectangle (st->dpy, st->win, st->graph_gc,
475 boxx-1, boxy-1, boxw+2, boxh+2);
477 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
478 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
480 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
481 XDrawLine (st->dpy, st->win, st->graph_gc,
482 boxx + boxw - 1, boxy,
483 boxx + boxw - 1, boxy + boxh);
485 XSetForeground (st->dpy, st->graph_gc, st->magenta);
486 XDrawPoint (st->dpy, st->win, st->graph_gc,
488 boxy + boxh - 1 - (int) (y * (boxh - 1)));
493 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
494 XDrawRectangle (st->dpy, st->win, st->graph_gc,
495 boxx-1, boxy-1, boxw+2, boxh+2);
497 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
498 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
500 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
501 XDrawLine (st->dpy, st->win, st->graph_gc,
502 boxx + boxw - 1, boxy,
503 boxx + boxw - 1, boxy + boxh);
505 XSetForeground (st->dpy, st->graph_gc, st->magenta);
506 XDrawPoint (st->dpy, st->win, st->graph_gc,
508 boxy + boxh - 1 - (int) (z * (boxh - 1)));
512 /* Draws a blinking box in what should be the upper left corner of the
513 device, as physically oriented. The box is taller than it is wide.
516 testx11_show_orientation (struct testx11 *st)
520 int w = st->xgwa.width;
521 int h = st->xgwa.height;
526 int o = (int) current_device_rotation ();
529 // fprintf (stderr,"ROT %d -> %d\n", oo, o);
534 case 0: case 360: x = 0; y = 0; w = ww; h = hh; break;
535 case 90: case -270: x = 0; y = h-ww; w = hh; h = ww; break;
536 case -90: case 270: x = w-hh; y = 0; w = hh; h = ww; break;
537 case 180: case -180: x = w-ww; y = h-hh; w = ww; h = hh; break;
541 if (++tick > 20) tick = 0;
543 XSetForeground (st->dpy, st->graph_gc,
545 ? WhitePixelOfScreen (st->xgwa.screen)
546 : BlackPixelOfScreen (st->xgwa.screen)));
547 XFillRectangle (st->dpy, st->win, st->graph_gc,
554 testx11_draw (Display *dpy, Window win, void *st_raw)
556 struct testx11 *st = (struct testx11 *) st_raw;
557 unsigned w = st->xgwa.width, h = st->xgwa.height;
561 Drawable t = st->mode == mode_primitives ? st->backbuffer : win;
565 assert (dpy == st->dpy);
566 assert (win == st->win);
568 jwxyz_assert_display (dpy);
570 XSetWindowBackground (dpy, win, st->gray50);
574 case mode_primitives:
577 XDrawPoint (dpy, t, st->thick_line_gc, 0, 0);
578 XDrawPoint (dpy, t, st->thick_line_gc, 0, 1);
579 XDrawPoint (dpy, t, st->thick_line_gc, 1, 0);
580 XDrawPoint (dpy, t, st->thick_line_gc, 1, 1);
582 primitives_mini_rect (st, t, 2, 0);
583 primitives_mini_rect (st, t, 0, 2);
584 primitives_mini_rect (st, t, 4, 2);
585 primitives_mini_rect (st, t, 2, 4);
587 primitives_mini_rect (st, t, 30, -2);
588 primitives_mini_rect (st, t, 32, 0);
590 primitives_mini_rect (st, t, 30, h - 2);
591 primitives_mini_rect (st, t, 32, h);
593 primitives_mini_rect (st, t, -2, 30);
594 primitives_mini_rect (st, t, 0, 32);
595 primitives_mini_rect (st, t, w - 2, 30);
596 primitives_mini_rect (st, t, w, 32);
598 primitives_mini_rect (st, t, w / 2 + 4, h / 2 + 4);
600 XFillArc (dpy, t, st->copy_gc, 16, 16, 256, 256, 45 * 64, -135 * 64);
601 /* XCopyArea(dpy, t, t, st->copy_gc, 48, 48, 128, 128, 64, 64); */
604 XDrawPoint (dpy, t, st->copy_gc, w / 2, h / 2);
607 XDrawPoint (dpy, t, st->copy_gc, w / 2, 0);
608 XDrawPoint (dpy, t, st->copy_gc, w / 2, h - 1);
610 XDrawPoint (dpy, t, st->copy_gc, 16, -1);
611 XDrawPoint (dpy, t, st->copy_gc, 17, 0);
613 XDrawPoint (dpy, t, st->copy_gc, 15, h - 2);
614 XDrawPoint (dpy, t, st->copy_gc, 16, h - 1);
615 XDrawPoint (dpy, t, st->copy_gc, 17, h);
618 XPoint *points = malloc (sizeof(XPoint) * h);
619 XSegment *lines = malloc (sizeof(XSegment) * h);
620 XPoint *points2 = malloc (sizeof(XPoint) * h);
621 for(i = 0; i != h; ++i)
623 points[i].x = 8 + (i & 1);
626 lines[i].x1 = 48 + (i & 1) * 4;
631 points2[i].x = 24 + (i & 1);
633 /* XFillRectangle(st->dpy, t, st->copy_gc, 24 + (i & 1), i, 1, 1); */
636 XDrawPoints (dpy, t, st->copy_gc, points, h, CoordModeOrigin);
637 XDrawSegments (dpy, t, st->copy_gc, lines, h);
638 XDrawPoints (dpy, t, st->copy_gc, points2, h, CoordModeOrigin);
645 XDrawPoint (dpy, t, st->copy_gc, -1, 16);
646 XDrawPoint (dpy, t, st->copy_gc, 0, 17);
647 XDrawPoint (dpy, t, st->copy_gc, w - 1, 16);
648 XDrawPoint (dpy, t, st->copy_gc, w, 17);
651 XPoint *points = malloc(sizeof(XPoint) * w);
652 XSegment *lines = malloc(sizeof(XSegment) * w);
653 XPoint *points2 = malloc(sizeof(XPoint) * w);
654 for(i = 0; i != w; ++i)
657 points[i].y = 8 + (i & 1);
659 lines[i].y1 = 48 + (i & 1) * 4;
664 points2[i].y = 24 + (i & 1);
665 /* XFillRectangle(dpy, t, st->copy_gc, i, 24 + (i & 1), 1, 1); */
668 XDrawPoints (dpy, t, st->copy_gc, points, w, CoordModeOrigin);
669 XDrawSegments (dpy, t, st->copy_gc, lines, w);
671 /* Thick purple lines */
674 {31, 31, 31, 31}, /* TODO: This should not be rotated in Cocoa. */
677 XDrawSegments (dpy, t, st->thick_line_gc, seg, 2);
679 XDrawLine (dpy, t, st->thick_line_gc, 58, 43, 64, 43);
680 XDrawLine (dpy, t, st->thick_line_gc, 73, 43, 80, 43);
683 XDrawPoints (dpy, t, st->copy_gc, points2, w, CoordModeOrigin);
689 XDrawLine (dpy, t, st->copy_gc, 54, 11, 72, 22);
692 XPoint vertices[] = {{5, 5}, {5, 8}, {8, 8}, {8, 5}};
693 XFillPolygon (dpy, t, st->copy_gc, vertices, 4, Convex, CoordModeOrigin);
697 XDrawRectangle (dpy, t, st->copy_gc, 11, 11, 11, 11);
698 XFillRectangle (dpy, t, st->copy_gc, 13, 13, 8, 8);
701 /* Several ~16 pixel boxes in a row. */
705 XDrawRectangle (dpy, t, st->copy_gc, 54, 54, 16, 16);
706 XDrawRectangle (dpy, t, st->copy_gc, 55, 55, 14, 14);
708 XDrawPoint (dpy, t, st->thick_line_gc, 56, 56);
709 XDrawPoint (dpy, t, st->copy_gc, 57, 56);
713 XCopyArea (dpy, t, t, st->copy_gc, 55, 55, 15, 15, 72, 55);
717 XImage *image = XGetImage(st->dpy, t, 55, 55, 15, 15, 0xffffff, ZPixmap);
718 XPutPixel(image, 2, 0, 0x00000000);
719 XPutImage (dpy, t, st->copy_gc, image, 0, 0, 88, 55, 15, 15);
720 XDestroyImage(image);
726 XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
727 104, 55, 16, 16, 0, 0);
728 /* XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
729 105, 56, 14, 14, 1, 1);
730 XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
734 /* This point gets hidden. */
735 XDrawPoint (dpy, t, st->copy_gc, 104 + 8, 55 + 8);
737 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 0, 0);
738 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 1, 0);
739 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 15, 15);
740 XDrawRectangle (dpy, st->primitives_mini_pix, st->copy_gc,
742 XCopyArea (dpy, st->primitives_mini_pix, t, st->copy_gc,
743 0, 0, 16, 16, 104, 55);
747 XDrawLine (dpy, t, st->copy_gc, 11, 28, 22, 28);
748 XDrawLine (dpy, t, st->copy_gc, 12, 27, 12, 46);
749 XDrawLine (dpy, t, st->copy_gc, 14, 30, 14, 30);
752 XDrawArc (dpy, t, st->copy_gc, 27, 11, 19, 11, 0, 360 * 64);
754 XDrawRectangle (dpy, t, st->copy_gc, 54, 73, 64, 64);
755 XFillArc (dpy, t, st->copy_gc, 56, 75, 60, 60, 0, 360 * 64);
756 /* XDrawArc (dpy, t, st->thick_line_gc, 56, 75, 60, 60, 0, 360 * 64); */
758 XClearArea (dpy, win, 121, 55, 16, 16, False);
764 /* if(w >= 9 && h >= 10) */
767 /* Draw below the status bar. */
768 const unsigned y = 64;
770 const unsigned y = 0;
773 Screen *screen = st->xgwa.screen;
774 Visual *visual = st->xgwa.visual;
775 Pixmap pixmap = XCreatePixmap (dpy, t, 3, 10,
776 visual_depth (screen, visual));
777 unsigned long cells = cells = st->rgb[0] | st->rgb[1] | st->rgb[2];
780 XSetForeground (dpy, st->images_point_gc, st->salmon);
781 XDrawPoint (dpy, t, st->images_point_gc, 0, h - 1);
782 XDrawLine (dpy, t, st->images_point_gc, 0, y - 1, 8, y - 1);
785 images_pattern (st, t, y);
786 images_pattern (st, pixmap, 0);
787 /* Here's a good spot to verify that the pixmap contains the right colors
790 images_copy_test (dpy, t, pixmap, st->copy_gc, y, 0, 6, cells);
792 XCopyArea (dpy, pixmap, t, st->copy_gc, 0, 0, 3, 10, 3, y);
795 XImage *image = XGetImage (dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
796 XPutImage (dpy, t, st->copy_gc, image, 0, 0, 6, y, 3, 10);
797 XDestroyImage (image);
800 XFreePixmap (dpy, pixmap);
808 /* X.org isn't making a whole lot of sense here. */
810 Bool use_copy = (st->frame / 20) & 1;
813 GC gc = use_copy ? st->copy_gc : st->xor_gc;
815 XSetWindowBackground (dpy, t, st->magenta);
816 XCopyArea (dpy, t, t, gc, -2, -2, 40, 40, 20, 20);
819 XCopyArea (st->dpy, t, t, gc, -20, h - 20, 40, 40, 20, h - 60);
820 XCopyArea (dpy, t, t, gc, w - 38, h - 38, 40, 40, w - 60, h - 60);
821 XCopyArea (dpy, t, t, gc, w - 20, -20, 40, 40, w - 60, 20);
823 XSetWindowBackground (dpy, t, st->gray50);
824 XCopyArea (st->dpy, t, t, gc, -20, 64, 40, 40, 20, 64);
826 XSetWindowBackground (dpy, t, st->dark_slate_gray1);
827 XCopyArea (st->dpy, t, t, gc, -20, 112, 40, 40, 20, 112);
833 XCopyArea (st->dpy, t, st->copy_pix64, gc, 0, h - 64, 64, 64, 0, 0);
835 XSetForeground (st->dpy, st->xor_gc, st->rgb[1]);
836 XSetBackground (st->dpy, st->xor_gc, st->cyan);
838 /* XCopyArea (st->dpy, st->copy_pix64, st->copy_pix64, gc,
839 32, 32, 64, 64, 0, 0);
840 XCopyArea (st->dpy, st->copy_pix64, t, gc, 0, 0, 64, 64, 4, h - 68);
842 XCopyArea (st->dpy, st->copy_pix64, t, gc, 32, 32, 128, 64, 0, h - 64);
850 if(!(st->frame % 10)) {
851 const unsigned r = 16;
852 unsigned n = st->frame / 10;
854 XFillArc (st->dpy, st->preserve[n & 1],
855 m & 1 ? st->copy_gc : st->thick_line_gc,
856 NRAND(preserve_size) - r, NRAND(preserve_size) - r,
857 r * 2, r * 2, 0, 360 * 64);
860 XCopyArea (st->dpy, st->preserve[0], t, st->copy_gc, 0, 0,
861 preserve_size, preserve_size, 0, 0);
862 XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
863 preserve_size, preserve_size, preserve_size, 0);
864 XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
865 preserve_size, preserve_size,
866 w - preserve_size / 2, preserve_size);
872 st->erase = erase_window(st->dpy, st->win, st->erase);
876 /* Mode toggle buttons */
877 for (i = 1; i != mode_count; ++i) {
880 XRectangle button_dims;
881 button_dims.x = i0 * (button_pad + button_size) + button_pad;
882 button_dims.y = h - button_pad - button_size;
883 button_dims.width = button_size;
884 button_dims.height = button_size;
886 XFillRectangles (dpy, t, st->backdrop_black_gc, &button_dims, 1);
887 XDrawRectangle (dpy, t, st->copy_gc, button_dims.x, button_dims.y,
888 button_dims.width, button_dims.height);
890 XDrawString (dpy, t, st->copy_gc,
891 button_dims.x + button_size / 2 - 3,
892 h - button_pad - button_size / 2 + 13 / 2,
893 str, sprintf(str, "%u", i));
897 XCopyArea (dpy, t, win, st->copy_gc, 0, 0, w, h, 0, 0);
899 testx11_graph_rotator (st);
900 testx11_show_orientation (st);
907 testx11_reshape (Display *dpy, Window window, void *st_raw,
908 unsigned int w, unsigned int h)
910 struct testx11 *st = (struct testx11 *)st_raw;
914 XFreePixmap (st->dpy, st->backbuffer);
916 create_backbuffer (st);
921 testx11_event (Display *dpy, Window window, void *st_raw, XEvent *event)
923 struct testx11 *st = (struct testx11 *) st_raw;
925 Bool handled = False;
927 switch (event->xany.type)
933 XLookupString (&event->xkey, &c, 1, &keysym, 0);
935 handled = toggle_antialiasing (st);
937 if (c >= '0' && c <= '9' && c < '0' + mode_count) {
945 if (event->xbutton.y >= st->xgwa.height - button_pad * 2 - button_size) {
946 int i = (event->xbutton.x - button_pad / 2) / (button_pad + button_size) + 1;
947 if (i && i < mode_count) {
954 handled = toggle_antialiasing (st);
962 testx11_free (Display *dpy, Window window, void *st_raw)
964 /* Omitted for the sake of brevity. */
967 XSCREENSAVER_MODULE_2 ("TestX11", testx11, testx11)