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"
26 # define jwxyz_XSetAntiAliasing(dpy, gc, p)
29 #ifndef jwxyz_assert_display
30 # define jwxyz_assert_display(dpy)
33 #define countof(a) (sizeof(a) / sizeof(*(a)))
35 static const char *testx11_defaults [] = {
36 ".background: #a020f0", /* purple */
39 "*ignoreRotation: True",
44 static XrmOptionDescRec testx11_options [] = {
64 XWindowAttributes xgwa;
72 /* Pixels from XAllocPixel. */
73 unsigned long rgb[3], salmon, magenta, gray50, dark_slate_gray1, cyan;
79 /* These X11 objects aren't altered after creation, except for:
80 - copy_gc and thick_line_gc get anti-aliasing toggled.
81 - xor_gc's clip mask (if it's turned on) always covers the entire window.
83 GC copy_gc, mono_gc, thick_line_gc, xor_gc, graph_gc;
84 Pixmap clip_mask_tile;
86 /* Backdrop stuff, naturally. */
88 Pixmap backdrop_tile, backdrop_scratch;
89 XColor backdrop_colors[64];
92 /* The following items may be modified by various test modes. */
93 Pixmap primitives_mini_pix;
110 fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM));
115 check_no_mem (void *ptr)
123 alloc_color (struct testx11 *st,
124 unsigned short r, unsigned short g, unsigned short b)
130 color.flags = DoRed | DoGreen | DoBlue;
131 XAllocColor (st->dpy, st->xgwa.colormap, &color);
136 create_backbuffer(struct testx11 *st)
139 st->backbuffer = XCreatePixmap (st->dpy, st->win,
140 st->xgwa.width, st->xgwa.height,
146 toggle_antialiasing (struct testx11 *st)
148 st->anti_alias_p ^= True;
149 jwxyz_XSetAntiAliasing (st->dpy, st->copy_gc, st->anti_alias_p);
150 jwxyz_XSetAntiAliasing (st->dpy, st->thick_line_gc, st->anti_alias_p);
156 primitives_mini_rect(struct testx11 *st, Drawable t, int x, int y)
158 XFillRectangle(st->dpy, t, st->copy_gc, x, y, 2, 2);
162 images_copy_test (Display *dpy, Drawable src, Drawable dst, GC gc,
163 int src_y, int dst_x, int dst_y, unsigned long cells)
165 XCopyArea(dpy, src, dst, gc, 0, src_y, 3, 2, dst_x, dst_y);
168 XImage *image = XGetImage(dpy, src, 0, src_y, 3, 2, cells, ZPixmap);
169 XPutImage(dpy, dst, gc, image, 0, 0, dst_x, dst_y + 2, 3, 2);
170 XDestroyImage(image);
175 images_pattern (struct testx11 *st, Drawable d, unsigned y)
178 for (x = 0; x != 3; ++x) {
179 XSetForeground(st->dpy, st->images_point_gc, st->rgb[x]);
180 XDrawPoint(st->dpy, d, st->images_point_gc, x, y);
181 XSetForeground(st->dpy, st->images_point_gc, st->rgb[2 - x]);
182 XFillRectangle(st->dpy, d, st->images_point_gc, x, y + 1, 1, 1);
185 images_copy_test (st->dpy, d, d, st->images_point_gc, y, 0, y + 2,
186 st->rgb[0] | st->rgb[1] | st->rgb[2]);
189 static const unsigned tile_size = 16;
190 static const unsigned tile_count = 8;
192 static const unsigned preserve_size = 128;
195 make_clip_mask (struct testx11 *st)
197 /* Activate this for extra Fun! */
199 /* This is kind of slow, but that's OK, because this only happens on int
202 unsigned w = st->xgwa.width, h = st->xgwa.height;
204 Pixmap mask = XCreatePixmap (st->dpy, st->clip_mask_tile, w, h, 1);
206 for (y = 0; y < h; y += 8) {
207 for (x = 0; x < w; x += 8) {
208 XCopyArea (st->dpy, st->clip_mask_tile, mask, st->mono_gc,
213 XSetClipMask (st->dpy, st->xor_gc, mask);
214 XFreePixmap (st->dpy, mask);
220 colorbars (struct testx11 *st)
222 draw_colorbars (st->xgwa.screen, st->xgwa.visual, st->win,
223 st->xgwa.colormap, 0, 0, st->xgwa.width, st->xgwa.height);
228 testx11_init (Display *dpy, Window win)
230 static const char backdrop_pattern[] = {
231 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07', /* Zig */
232 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01', /* Zag */
233 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07', /* etc. */
234 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01',
235 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07',
236 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01',
237 '\xff', '\x00', '\xfe', '\x01', '\xfc', '\x03', '\xf8', '\x07',
238 '\xf0', '\x0f', '\xf8', '\x07', '\xfc', '\x03', '\xfe', '\x01',
241 static const char clip_bits[] = {
242 '\x33', '\x33', '\xcc', '\xcc', '\x33', '\x33', '\xcc', '\xcc'
245 struct testx11 *st = (struct testx11 *) malloc (sizeof(*st));
253 XGetWindowAttributes (dpy, win, &st->xgwa);
255 create_backbuffer (st);
257 st->rgb[0] = alloc_color (st, 0xffff, 0x0000, 0x0000);
258 st->rgb[1] = alloc_color (st, 0x0000, 0xffff, 0x0000);
259 st->rgb[2] = alloc_color (st, 0x0000, 0x0000, 0xffff);
260 st->salmon = alloc_color (st, 0xffff, 0x7fff, 0x7fff);
261 st->magenta = alloc_color (st, 0xffff, 0x0000, 0xffff);
262 st->gray50 = alloc_color (st, 0x8000, 0x8000, 0x8000);
263 st->dark_slate_gray1 = alloc_color (st, 0x8000, 0xffff, 0xffff);
264 st->cyan = alloc_color (st, 0x0000, 0xffff, 0xffff);
266 st->backdrop_tile = XCreatePixmapFromBitmapData (dpy, win,
267 (char *) backdrop_pattern,
268 tile_size, tile_size * 2,
271 st->clip_mask_tile = XCreatePixmapFromBitmapData (dpy, win,
272 (char *) clip_bits, 8, 8,
276 unsigned s = tile_size * tile_count;
277 st->backdrop_scratch = XCreatePixmap (dpy, win, s, s, st->xgwa.depth);
280 st->backdrop_ncolors = countof (st->backdrop_colors);
281 make_color_loop (st->xgwa.screen, st->xgwa.visual, st->xgwa.colormap,
282 180, 1, 0.5, 210, 1, 0.5, 240, 1, 0.5,
283 st->backdrop_colors, &st->backdrop_ncolors, True, NULL);
288 st->mode = mode_primitives;
290 st->mode = mode_welcome;
293 st->anti_alias_p = False;
295 gcv.function = GXcopy;
296 gcv.foreground = st->cyan;
297 gcv.background = st->magenta;
299 gcv.cap_style = CapRound;
300 /* TODO: Real X11 uses fixed by default. */
301 gcv.font = XLoadFont (dpy, "fixed");
302 st->copy_gc = XCreateGC (dpy, win,
303 GCFunction | GCForeground | GCBackground
304 | GCLineWidth | GCCapStyle | GCFont, &gcv);
306 gcv.foreground = BlackPixelOfScreen (st->xgwa.screen);
307 st->backdrop_black_gc = XCreateGC (dpy, win, GCForeground, &gcv);
309 gcv.foreground = alloc_color (st, 0x8000, 0x4000, 0xffff);
311 gcv.cap_style = CapProjecting;
312 st->thick_line_gc = XCreateGC (dpy, win,
313 GCForeground | GCLineWidth | GCCapStyle,
316 gcv.function = GXxor;
317 st->xor_gc = XCreateGC (dpy, win, GCFunction, &gcv);
319 st->images_point_gc = XCreateGC (dpy, win, 0, NULL);
321 st->graph_gc = XCreateGC (dpy, win, 0, &gcv);
323 st->mono_gc = XCreateGC (dpy, st->clip_mask_tile, 0, &gcv);
325 st->copy_pix64 = XCreatePixmap(dpy, win, 64, 64, st->xgwa.depth);
327 st->primitives_mini_pix = XCreatePixmap (dpy, win, 16, 24, st->xgwa.depth);
330 static const char text[] = "Welcome from testx11_init().";
332 XDrawString (dpy, win, st->copy_gc, 16, 16, text, countof (text) - 1);
338 XCreatePixmap(dpy, win, preserve_size, preserve_size, st->xgwa.depth);
340 XCreatePixmap(dpy, win, preserve_size, preserve_size, st->xgwa.depth);
342 toggle_antialiasing (st);
344 jwxyz_assert_display (dpy);
346 st->rot = make_rotator (2, 2, 2, 2, 0.01, False);
352 backdrop (struct testx11 *st, Drawable t)
354 unsigned w = st->xgwa.width, h = st->xgwa.height;
357 for (y = 0; y != tile_count; ++y) {
358 const float s0 = 2 * M_PI / tile_count;
359 float y_fac = sin ((y + st->frame / 16.0) * s0);
360 for (x = 0; x != tile_count; ++x) {
361 unsigned c = ((sin ((x + st->frame / 8.0) * s0) * y_fac) - 1) / 2 * st->backdrop_ncolors / 2;
362 c = (c + st->frame) % st->backdrop_ncolors;
363 XSetBackground (st->dpy, st->backdrop_black_gc,
364 st->backdrop_colors[c].pixel);
365 XCopyPlane (st->dpy, st->backdrop_tile, st->backdrop_scratch,
366 st->backdrop_black_gc, 0, st->frame % tile_size,
367 tile_size, tile_size, x * tile_size, y * tile_size, 1);
371 /* XFillRectangle (st->dpy, t, st->backdrop_black_gc, 0, 0, w, h); */
373 for (y = 0; y < h; y += tile_count * tile_size) {
374 for (x = 0; x < w; x += tile_count * tile_size) {
375 XCopyArea (st->dpy, st->backdrop_scratch, t, st->copy_gc, 0, 0,
376 tile_count * tile_size, tile_count * tile_size, x, y);
381 static const unsigned button_pad = 16;
382 static const unsigned button_size = 64;
386 testx11_graph_rotator (struct testx11 *st)
390 int boxw = st->xgwa.width / 3;
391 int boxh = (st->xgwa.height - (22 * 5)) / 4;
392 int boxx = st->xgwa.width - boxw - 20;
393 int boxy = st->xgwa.height - boxh - 20;
397 get_position (st->rot, &x, &y, &z, True);
398 if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
401 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
402 XDrawRectangle (st->dpy, st->win, st->graph_gc,
403 boxx-1, boxy-1, boxw+2, boxh+2);
405 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
406 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
408 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
409 XDrawLine (st->dpy, st->win, st->graph_gc,
410 boxx + boxw - 1, boxy,
411 boxx + boxw - 1, boxy + boxh);
413 XSetForeground (st->dpy, st->graph_gc, st->salmon);
414 XDrawPoint (st->dpy, st->win, st->graph_gc,
416 boxy + boxh - 1 - (int) (x * (boxh - 1)));
418 XSetForeground (st->dpy, st->graph_gc, st->magenta);
419 XDrawPoint (st->dpy, st->win, st->graph_gc,
421 boxy + boxh - 1 - (int) (y * (boxh - 1)));
423 XSetForeground (st->dpy, st->graph_gc, st->gray50);
424 XDrawPoint (st->dpy, st->win, st->graph_gc,
426 boxy + boxh - 1 - (int) (z * (boxh - 1)));
430 get_rotation (st->rot, &x, &y, &z, True);
431 if (x < 0 || x >= 1 || y < 0 || y >= 1 || z < 0 || z >= 1) abort();
433 /* put 0 in the middle */
434 x += 0.5; if (x > 1) x--;
435 y += 0.5; if (y > 1) y--;
436 z += 0.5; if (z > 1) z--;
441 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
442 XDrawRectangle (st->dpy, st->win, st->graph_gc,
443 boxx-1, boxy-1, boxw+2, boxh+2);
445 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
446 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
448 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
449 XDrawLine (st->dpy, st->win, st->graph_gc,
450 boxx + boxw - 1, boxy,
451 boxx + boxw - 1, boxy + boxh);
453 XSetForeground (st->dpy, st->graph_gc, st->magenta);
454 XDrawPoint (st->dpy, st->win, st->graph_gc,
456 boxy + boxh - 1 - (int) (x * (boxh - 1)));
461 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
462 XDrawRectangle (st->dpy, st->win, st->graph_gc,
463 boxx-1, boxy-1, boxw+2, boxh+2);
465 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
466 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
468 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
469 XDrawLine (st->dpy, st->win, st->graph_gc,
470 boxx + boxw - 1, boxy,
471 boxx + boxw - 1, boxy + boxh);
473 XSetForeground (st->dpy, st->graph_gc, st->magenta);
474 XDrawPoint (st->dpy, st->win, st->graph_gc,
476 boxy + boxh - 1 - (int) (y * (boxh - 1)));
481 XSetForeground (st->dpy, st->graph_gc, st->dark_slate_gray1);
482 XDrawRectangle (st->dpy, st->win, st->graph_gc,
483 boxx-1, boxy-1, boxw+2, boxh+2);
485 XCopyArea (st->dpy, st->win, st->win, st->graph_gc,
486 boxx+1, boxy, boxw-1, boxh, boxx, boxy);
488 XSetForeground (st->dpy, st->graph_gc, BlackPixelOfScreen (st->xgwa.screen));
489 XDrawLine (st->dpy, st->win, st->graph_gc,
490 boxx + boxw - 1, boxy,
491 boxx + boxw - 1, boxy + boxh);
493 XSetForeground (st->dpy, st->graph_gc, st->magenta);
494 XDrawPoint (st->dpy, st->win, st->graph_gc,
496 boxy + boxh - 1 - (int) (z * (boxh - 1)));
500 /* Draws a blinking box in what should be the upper left corner of the
501 device, as physically oriented. The box is taller than it is wide.
504 testx11_show_orientation (struct testx11 *st)
508 int w = st->xgwa.width;
509 int h = st->xgwa.height;
514 int o = (int) current_device_rotation ();
517 // fprintf (stderr,"ROT %d -> %d\n", oo, o);
522 case 0: case 360: x = 0; y = 0; w = ww; h = hh; break;
523 case 90: case -270: x = 0; y = h-ww; w = hh; h = ww; break;
524 case -90: case 270: x = w-hh; y = 0; w = hh; h = ww; break;
525 case 180: case -180: x = w-ww; y = h-hh; w = ww; h = hh; break;
529 if (++tick > 20) tick = 0;
531 XSetForeground (st->dpy, st->graph_gc,
533 ? WhitePixelOfScreen (st->xgwa.screen)
534 : BlackPixelOfScreen (st->xgwa.screen)));
535 XFillRectangle (st->dpy, st->win, st->graph_gc,
542 testx11_draw (Display *dpy, Window win, void *st_raw)
544 struct testx11 *st = (struct testx11 *) st_raw;
545 unsigned w = st->xgwa.width, h = st->xgwa.height;
549 Drawable t = st->mode == mode_primitives ? st->backbuffer : win;
553 assert (dpy == st->dpy);
554 assert (win == st->win);
556 jwxyz_assert_display (dpy);
558 XSetWindowBackground (dpy, win, st->gray50);
562 case mode_primitives:
565 XDrawPoint (dpy, t, st->thick_line_gc, 0, 0);
566 XDrawPoint (dpy, t, st->thick_line_gc, 0, 1);
567 XDrawPoint (dpy, t, st->thick_line_gc, 1, 0);
568 XDrawPoint (dpy, t, st->thick_line_gc, 1, 1);
570 primitives_mini_rect (st, t, 2, 0);
571 primitives_mini_rect (st, t, 0, 2);
572 primitives_mini_rect (st, t, 4, 2);
573 primitives_mini_rect (st, t, 2, 4);
575 primitives_mini_rect (st, t, 30, -2);
576 primitives_mini_rect (st, t, 32, 0);
578 primitives_mini_rect (st, t, 30, h - 2);
579 primitives_mini_rect (st, t, 32, h);
581 primitives_mini_rect (st, t, -2, 30);
582 primitives_mini_rect (st, t, 0, 32);
583 primitives_mini_rect (st, t, w - 2, 30);
584 primitives_mini_rect (st, t, w, 32);
586 primitives_mini_rect (st, t, w / 2 + 4, h / 2 + 4);
588 XFillArc (dpy, t, st->copy_gc, 16, 16, 256, 256, 45 * 64, -135 * 64);
589 /* XCopyArea(dpy, t, t, st->copy_gc, 48, 48, 128, 128, 64, 64); */
592 XDrawPoint (dpy, t, st->copy_gc, w / 2, h / 2);
595 XDrawPoint (dpy, t, st->copy_gc, w / 2, 0);
596 XDrawPoint (dpy, t, st->copy_gc, w / 2, h - 1);
598 XDrawPoint (dpy, t, st->copy_gc, 16, -1);
599 XDrawPoint (dpy, t, st->copy_gc, 17, 0);
601 XDrawPoint (dpy, t, st->copy_gc, 15, h - 2);
602 XDrawPoint (dpy, t, st->copy_gc, 16, h - 1);
603 XDrawPoint (dpy, t, st->copy_gc, 17, h);
606 XPoint *points = malloc (sizeof(XPoint) * h);
607 XSegment *lines = malloc (sizeof(XSegment) * h);
608 XPoint *points2 = malloc (sizeof(XPoint) * h);
609 for(i = 0; i != h; ++i)
611 points[i].x = 8 + (i & 1);
614 lines[i].x1 = 48 + (i & 1) * 4;
619 points2[i].x = 24 + (i & 1);
621 /* XFillRectangle(st->dpy, t, st->copy_gc, 24 + (i & 1), i, 1, 1); */
624 XDrawPoints (dpy, t, st->copy_gc, points, h, CoordModeOrigin);
625 XDrawSegments (dpy, t, st->copy_gc, lines, h);
626 XDrawPoints (dpy, t, st->copy_gc, points2, h, CoordModeOrigin);
633 XDrawPoint (dpy, t, st->copy_gc, -1, 16);
634 XDrawPoint (dpy, t, st->copy_gc, 0, 17);
635 XDrawPoint (dpy, t, st->copy_gc, w - 1, 16);
636 XDrawPoint (dpy, t, st->copy_gc, w, 17);
639 XPoint *points = malloc(sizeof(XPoint) * w);
640 XSegment *lines = malloc(sizeof(XSegment) * w);
641 XPoint *points2 = malloc(sizeof(XPoint) * w);
642 for(i = 0; i != w; ++i)
645 points[i].y = 8 + (i & 1);
647 lines[i].y1 = 48 + (i & 1) * 4;
652 points2[i].y = 24 + (i & 1);
653 /* XFillRectangle(dpy, t, st->copy_gc, i, 24 + (i & 1), 1, 1); */
656 XDrawPoints (dpy, t, st->copy_gc, points, w, CoordModeOrigin);
657 XDrawSegments (dpy, t, st->copy_gc, lines, w);
659 /* Thick purple lines */
662 {31, 31, 31, 31}, /* TODO: This should not be rotated in Cocoa. */
665 XDrawSegments (dpy, t, st->thick_line_gc, seg, 2);
667 XDrawLine (dpy, t, st->thick_line_gc, 58, 43, 64, 43);
668 XDrawLine (dpy, t, st->thick_line_gc, 73, 43, 80, 43);
671 XDrawPoints (dpy, t, st->copy_gc, points2, w, CoordModeOrigin);
677 XDrawLine (dpy, t, st->copy_gc, 54, 11, 72, 22);
680 XPoint vertices[] = {{5, 5}, {5, 8}, {8, 8}, {8, 5}};
681 XFillPolygon (dpy, t, st->copy_gc, vertices, 4, Convex, CoordModeOrigin);
685 XDrawRectangle (dpy, t, st->copy_gc, 11, 11, 11, 11);
686 XFillRectangle (dpy, t, st->copy_gc, 13, 13, 8, 8);
689 /* Several ~16 pixel boxes in a row. */
693 XDrawRectangle (dpy, t, st->copy_gc, 54, 54, 16, 16);
694 XDrawRectangle (dpy, t, st->copy_gc, 55, 55, 14, 14);
696 XDrawPoint (dpy, t, st->thick_line_gc, 56, 56);
697 XDrawPoint (dpy, t, st->copy_gc, 57, 56);
701 XCopyArea (dpy, t, t, st->copy_gc, 55, 55, 15, 15, 72, 55);
705 XImage *image = XGetImage(st->dpy, t, 55, 55, 15, 15, 0xffffff, ZPixmap);
706 XPutPixel(image, 2, 0, 0x00000000);
707 XPutImage (dpy, t, st->copy_gc, image, 0, 0, 88, 55, 15, 15);
708 XDestroyImage(image);
714 XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
715 104, 55, 16, 16, 0, 0);
716 /* XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
717 105, 56, 14, 14, 1, 1);
718 XCopyArea (dpy, t, st->primitives_mini_pix, st->copy_gc,
722 /* This point gets hidden. */
723 XDrawPoint (dpy, t, st->copy_gc, 104 + 8, 55 + 8);
725 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 0, 0);
726 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 1, 0);
727 XDrawPoint (dpy, st->primitives_mini_pix, st->copy_gc, 15, 15);
728 XDrawRectangle (dpy, st->primitives_mini_pix, st->copy_gc,
730 XCopyArea (dpy, st->primitives_mini_pix, t, st->copy_gc,
731 0, 0, 16, 16, 104, 55);
735 XDrawLine (dpy, t, st->copy_gc, 11, 28, 22, 28);
736 XDrawLine (dpy, t, st->copy_gc, 12, 27, 12, 46);
737 XDrawLine (dpy, t, st->copy_gc, 14, 30, 14, 30);
740 XDrawArc (dpy, t, st->copy_gc, 27, 11, 19, 11, 0, 360 * 64);
742 XDrawRectangle (dpy, t, st->copy_gc, 54, 73, 64, 64);
743 XFillArc (dpy, t, st->copy_gc, 56, 75, 60, 60, 0, 360 * 64);
744 /* XDrawArc (dpy, t, st->thick_line_gc, 56, 75, 60, 60, 0, 360 * 64); */
746 XClearArea (dpy, win, 121, 55, 16, 16, False);
752 /* if(w >= 9 && h >= 10) */
755 /* Draw below the status bar. */
756 const unsigned y = 64;
758 const unsigned y = 0;
761 Screen *screen = st->xgwa.screen;
762 Visual *visual = st->xgwa.visual;
763 Pixmap pixmap = XCreatePixmap (dpy, t, 3, 10,
764 visual_depth (screen, visual));
765 unsigned long cells = cells = st->rgb[0] | st->rgb[1] | st->rgb[2];
768 XSetForeground (dpy, st->images_point_gc, st->salmon);
769 XDrawPoint (dpy, t, st->images_point_gc, 0, h - 1);
770 XDrawLine (dpy, t, st->images_point_gc, 0, y - 1, 8, y - 1);
773 images_pattern (st, t, y);
774 images_pattern (st, pixmap, 0);
775 /* Here's a good spot to verify that the pixmap contains the right colors
778 images_copy_test (dpy, t, pixmap, st->copy_gc, y, 0, 6, cells);
780 XCopyArea (dpy, pixmap, t, st->copy_gc, 0, 0, 3, 10, 3, y);
783 XImage *image = XGetImage (dpy, pixmap, 0, 0, 3, 10, cells, ZPixmap);
784 XPutImage (dpy, t, st->copy_gc, image, 0, 0, 6, y, 3, 10);
785 XDestroyImage (image);
788 XFreePixmap (dpy, pixmap);
796 /* X.org isn't making a whole lot of sense here. */
798 Bool use_copy = (st->frame / 20) & 1;
801 GC gc = use_copy ? st->copy_gc : st->xor_gc;
803 XSetWindowBackground (dpy, t, st->magenta);
804 XCopyArea (dpy, t, t, gc, -2, -2, 40, 40, 20, 20);
807 XCopyArea (st->dpy, t, t, gc, -20, h - 20, 40, 40, 20, h - 60);
808 XCopyArea (dpy, t, t, gc, w - 38, h - 38, 40, 40, w - 60, h - 60);
809 XCopyArea (dpy, t, t, gc, w - 20, -20, 40, 40, w - 60, 20);
811 XSetWindowBackground (dpy, t, st->gray50);
812 XCopyArea (st->dpy, t, t, gc, -20, 64, 40, 40, 20, 64);
814 XSetWindowBackground (dpy, t, st->dark_slate_gray1);
815 XCopyArea (st->dpy, t, t, gc, -20, 112, 40, 40, 20, 112);
821 XCopyArea (st->dpy, t, st->copy_pix64, gc, 0, h - 64, 64, 64, 0, 0);
823 XSetForeground (st->dpy, st->xor_gc, st->rgb[1]);
824 XSetBackground (st->dpy, st->xor_gc, st->cyan);
826 /* XCopyArea (st->dpy, st->copy_pix64, st->copy_pix64, gc,
827 32, 32, 64, 64, 0, 0);
828 XCopyArea (st->dpy, st->copy_pix64, t, gc, 0, 0, 64, 64, 4, h - 68);
830 XCopyArea (st->dpy, st->copy_pix64, t, gc, 32, 32, 128, 64, 0, h - 64);
838 if(!(st->frame % 10)) {
839 const unsigned r = 16;
840 unsigned n = st->frame / 10;
842 XFillArc (st->dpy, st->preserve[n & 1],
843 m & 1 ? st->copy_gc : st->thick_line_gc,
844 NRAND(preserve_size) - r, NRAND(preserve_size) - r,
845 r * 2, r * 2, 0, 360 * 64);
848 XCopyArea (st->dpy, st->preserve[0], t, st->copy_gc, 0, 0,
849 preserve_size, preserve_size, 0, 0);
850 XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
851 preserve_size, preserve_size, preserve_size, 0);
852 XCopyArea (st->dpy, st->preserve[1], t, st->copy_gc, 0, 0,
853 preserve_size, preserve_size,
854 w - preserve_size / 2, preserve_size);
860 st->erase = erase_window(st->dpy, st->win, st->erase);
864 /* Mode toggle buttons */
865 for (i = 1; i != mode_count; ++i) {
868 XRectangle button_dims;
869 button_dims.x = i0 * (button_pad + button_size) + button_pad;
870 button_dims.y = h - button_pad - button_size;
871 button_dims.width = button_size;
872 button_dims.height = button_size;
874 XFillRectangles (dpy, t, st->backdrop_black_gc, &button_dims, 1);
875 XDrawRectangle (dpy, t, st->copy_gc, button_dims.x, button_dims.y,
876 button_dims.width, button_dims.height);
878 XDrawString (dpy, t, st->copy_gc,
879 button_dims.x + button_size / 2 - 3,
880 h - button_pad - button_size / 2 + 13 / 2,
881 str, sprintf(str, "%u", i));
885 XCopyArea (dpy, t, win, st->copy_gc, 0, 0, w, h, 0, 0);
887 testx11_graph_rotator (st);
888 testx11_show_orientation (st);
895 testx11_reshape (Display *dpy, Window window, void *st_raw,
896 unsigned int w, unsigned int h)
898 struct testx11 *st = (struct testx11 *)st_raw;
902 XFreePixmap (st->dpy, st->backbuffer);
904 create_backbuffer (st);
909 testx11_event (Display *dpy, Window window, void *st_raw, XEvent *event)
911 struct testx11 *st = (struct testx11 *) st_raw;
913 Bool handled = False;
915 switch (event->xany.type)
921 XLookupString (&event->xkey, &c, 1, &keysym, 0);
923 handled = toggle_antialiasing (st);
925 if (c >= '0' && c <= '9' && c < '0' + mode_count) {
933 if (event->xbutton.y >= st->xgwa.height - button_pad * 2 - button_size) {
934 int i = (event->xbutton.x - button_pad / 2) / (button_pad + button_size) + 1;
935 if (i && i < mode_count) {
942 handled = toggle_antialiasing (st);
950 testx11_free (Display *dpy, Window window, void *st_raw)
952 /* Omitted for the sake of brevity. */
955 XSCREENSAVER_MODULE_2 ("TestX11", testx11, testx11)