From c2a21c0f6a770f989833d0bd35761e17f9843353 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 26 Feb 2023 18:49:47 -0800 Subject: [PATCH] altos/draw: Split out draw test scaffolding from lco-test.c Allows it to be reused. Signed-off-by: Keith Packard --- src/draw/frame.c | 92 ++++++++++++++++++----------------- src/draw/lco-test.c | 49 +------------------ src/draw/test-frame.c | 108 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+), 90 deletions(-) create mode 100644 src/draw/test-frame.c diff --git a/src/draw/frame.c b/src/draw/frame.c index 84b30b36..45cca105 100644 --- a/src/draw/frame.c +++ b/src/draw/frame.c @@ -183,7 +183,17 @@ MatchLineStyle(char *s) return LineSolid; } +void +HandleButtonPress(Display *dpy, Window win, GC gc, XEvent *ev); + +void +HandleButtonRelease(Display *dpy, Window win, GC gc, XEvent *ev); + +void +HandleMotionNotify(Display *dpy, Window win, GC gc, XEvent *ev); + #ifdef TRACK_POINTER + #define PASS_BUTTONS typedef struct _Position { int seen; @@ -192,10 +202,16 @@ typedef struct _Position { int end_x, end_y; } PositionRec, *PositionPtr; -PositionRec positions[5]; +void +Draw(Display *dpy, Window win, GC gc, PositionRec positions[5]); void -UpdatePositions (state, x, y) +Undraw(Display *dpy, Window win, GC gc, PositionRec positions[5]); + +PositionRec current_positions[5]; + +static void +UpdatePositions (unsigned state, int x, int y) { int i; @@ -203,69 +219,53 @@ UpdatePositions (state, x, y) for (i = 0; i < 5; i++) { if (state & (1 << i)) { - positions[i].cur_x = x; - positions[i].cur_y = y; + current_positions[i].cur_x = x; + current_positions[i].cur_y = y; } } } void -HandleButtonPress (dpy, win, gc, ev) - Display *dpy; - Window win; - GC gc; - XEvent *ev; +HandleButtonPress (Display *dpy, Window win, GC gc, XEvent *ev) { XButtonEvent *bev = (XButtonEvent *) ev; - Undraw (dpy, win, gc, positions); - positions[bev->button - 1].seen = 1; - positions[bev->button - 1].start_x = bev->x; - positions[bev->button - 1].start_y = bev->y; - positions[bev->button - 1].cur_x = bev->x; - positions[bev->button - 1].cur_y = bev->y; - positions[bev->button - 1].end_x = bev->x; - positions[bev->button - 1].end_y = bev->y; + Undraw (dpy, win, gc, current_positions); + current_positions[bev->button - 1].seen = 1; + current_positions[bev->button - 1].start_x = bev->x; + current_positions[bev->button - 1].start_y = bev->y; + current_positions[bev->button - 1].cur_x = bev->x; + current_positions[bev->button - 1].cur_y = bev->y; + current_positions[bev->button - 1].end_x = bev->x; + current_positions[bev->button - 1].end_y = bev->y; UpdatePositions (bev->state, bev->x, bev->y); - Draw (dpy, win, gc, positions); + Draw (dpy, win, gc, current_positions); } void -HandleButtonRelease (dpy, win, gc, ev) - Display *dpy; - Window win; - GC gc; - XEvent *ev; +HandleButtonRelease (Display *dpy, Window win, GC gc, XEvent *ev) { XButtonEvent *bev = (XButtonEvent *) ev; - Undraw (dpy, win, gc, positions); + Undraw (dpy, win, gc, current_positions); UpdatePositions (bev->state, bev->x, bev->y); - positions[bev->button - 1].end_x = bev->x; - positions[bev->button - 1].end_y = bev->y; - Draw (dpy, win, gc, positions); + current_positions[bev->button - 1].end_x = bev->x; + current_positions[bev->button - 1].end_y = bev->y; + Draw (dpy, win, gc, current_positions); } void -HandleMotionNotify (dpy, win, gc, ev) - Display *dpy; - Window win; - GC gc; - XEvent *ev; +HandleMotionNotify (Display *dpy, Window win, GC gc, XEvent *ev) { XMotionEvent *mev = (XMotionEvent *) ev; - Undraw (dpy, win, gc, positions); + Undraw (dpy, win, gc, current_positions); UpdatePositions (mev->state, mev->x, mev->y); - Draw (dpy, win, gc, positions); + Draw (dpy, win, gc, current_positions); } -void -DisplayPositions (dpy, win, gc, positions) - Display *dpy; - Window win; - GC gc; - PositionRec positions[5]; +static inline void +DisplayPositions (Display *dpy, Window win, GC gc, PositionRec positions[5]) { static char text[1024]; static int hastext; @@ -274,10 +274,10 @@ DisplayPositions (dpy, win, gc, positions) int dir, font_ascent, font_descent; XCharStruct overall; - XTextExtents (default_font , text, strlen(text), + XTextExtents (default_font, text, (int) strlen(text), &dir, &font_ascent, &font_descent, &overall); if (hastext) - XClearArea (dpy, win, 0, 0, overall.width, font_ascent + font_descent, False); + XClearArea (dpy, win, 0, 0, (unsigned) overall.width, (unsigned) (font_ascent + font_descent), False); pos = 0; for (i = 0; i < 5; i++) { @@ -288,7 +288,7 @@ DisplayPositions (dpy, win, gc, positions) sprintf (text + pos, "%1d: (%4d,%4d),(%4d,%4d)", i, positions[i].start_x, positions[i].start_y, positions[i].cur_x, positions[i].cur_y); - pos = strlen (text); + pos = (int) strlen (text); } } XDrawString (dpy, win, gc, 0, font_ascent, text, pos); @@ -366,6 +366,9 @@ int screen; int current_timeout = TIMEOUT; #endif +void +Setup(Display *dpy, Window win); + void HandleExpose(Display *dpy, Window win, GC gc); @@ -466,6 +469,9 @@ main (int argc, char **argv) int has_fg_pixel = 0, has_bg_pixel = 0; int has_colormap = 0; unsigned long gc_mask; +#ifndef PASS_KEYS + char quit_string[10]; +#endif unsigned long window_mask; if (!rop_name) diff --git a/src/draw/lco-test.c b/src/draw/lco-test.c index 0221fbb9..02d2b5de 100644 --- a/src/draw/lco-test.c +++ b/src/draw/lco-test.c @@ -16,32 +16,10 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#define IMAGE_SCALE 8 -#define WIDTH 128 -#define HEIGHT 64 - -#define IMAGE_WIDTH (WIDTH * IMAGE_SCALE) -#define IMAGE_HEIGHT (HEIGHT * IMAGE_SCALE) - -#define DEFAULT_WIDTH IMAGE_WIDTH -#define DEFAULT_HEIGHT IMAGE_HEIGHT - #define TIMEOUT 50 #define PASS_KEYS -#include "frame.c" -#include "ao_draw.h" - -#define STRIDE ((WIDTH + 31) / 32) - -static uint32_t bits[STRIDE * HEIGHT]; - -static struct ao_bitmap fb = { - .base = bits, - .stride = STRIDE, - .width = WIDTH, - .height = HEIGHT -}; +#include "test-frame.c" #define BIG_FONT FrutigerLT_Roman_64_font #define VOLT_FONT FrutigerLT_Roman_64_font @@ -118,10 +96,6 @@ static const float pad_volts = 12.3f; static const float lco_volts = 4.1f; static const int rssi = -30; -#define IMAGE_STRIDE ((IMAGE_WIDTH + 31) / 32) - -static uint32_t image_bits[IMAGE_STRIDE * IMAGE_HEIGHT]; - static int boxes[] = { 1, 2, 3, 5, 8, 11, 13, 17, 19, 23, 29, 31, 37, 62, 97 }; static int max_box = 97; @@ -241,26 +215,7 @@ void HandleExpose(Display *dpy, Window win, GC gc) break; } - XImage *source_image = XCreateImage(dpy, visual, 1, XYBitmap, 0, (char *) bits, WIDTH, HEIGHT, 32, STRIDE*4); - XImage *image = XCreateImage(dpy, visual, 1, XYBitmap, 0, (char *) image_bits, IMAGE_WIDTH, IMAGE_HEIGHT, 32, IMAGE_STRIDE * 4); - int ix, iy; - int dx, dy; - - for (iy = 0; iy < HEIGHT; iy++) { - for (ix = 0; ix < WIDTH; ix++) { - unsigned long bit = XGetPixel(source_image, ix, iy); - for (dy = 0; dy < IMAGE_SCALE; dy++) { - - for (dx = 0; dx < IMAGE_SCALE; dx++) { - XPutPixel(image, ix * IMAGE_SCALE + dx, iy * IMAGE_SCALE + dy, bit); - } - } - } - } - XSetForeground(dpy, gc, WhitePixel(dpy, screen)); - XSetBackground(dpy, gc, BlackPixel(dpy, screen)); - XPutImage(dpy, win, gc, image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); - free(image); + DoDisplay(dpy, win, gc); } void diff --git a/src/draw/test-frame.c b/src/draw/test-frame.c new file mode 100644 index 00000000..3b764eb3 --- /dev/null +++ b/src/draw/test-frame.c @@ -0,0 +1,108 @@ +/* + * Copyright © 2023 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#define IMAGE_SCALE 8 +#define WIDTH 128 +#define HEIGHT 64 + +#define IMAGE_WIDTH (WIDTH * IMAGE_SCALE) +#define IMAGE_HEIGHT (HEIGHT * IMAGE_SCALE) +#define IMAGE_STRIDE ((IMAGE_WIDTH + 31) / 32) + +#define DEFAULT_WIDTH IMAGE_WIDTH +#define DEFAULT_HEIGHT IMAGE_HEIGHT + +#define PASS_SETUP + +#include "frame.c" +#include "ao_draw.h" + +#include +#include +#include + +#define STRIDE ((WIDTH + 31) / 32) + +static uint32_t bits[STRIDE * HEIGHT]; + +static struct ao_bitmap fb = { + .base = bits, + .stride = STRIDE, + .width = WIDTH, + .height = HEIGHT +}; + +static XImage *shm_image; +static XImage *nonshm_image; +static XShmSegmentInfo shm_info; + +void +Setup(Display *dpy, Window win) +{ + (void) win; + if (XShmQueryExtension(dpy)) { + shm_image = XShmCreateImage(dpy, visual, (unsigned) depth, ZPixmap, NULL, &shm_info, IMAGE_WIDTH, IMAGE_HEIGHT); + shm_info.shmid = shmget(IPC_PRIVATE, (size_t) (shm_image->bytes_per_line * shm_image->height), IPC_CREAT|0777); + shm_info.shmaddr = shm_image->data = shmat(shm_info.shmid, 0, 0); + shm_info.readOnly = True; + XShmAttach(dpy, &shm_info); + } else { + nonshm_image = XCreateImage(dpy, visual, (unsigned) depth, ZPixmap, 0, NULL, + IMAGE_WIDTH, IMAGE_HEIGHT, 32, IMAGE_STRIDE * 4); + nonshm_image->data = calloc((size_t) nonshm_image->bytes_per_line, (size_t) nonshm_image->height); + } +} + +static void +DoDisplay(Display *dpy, Window win, GC gc) +{ + int ix, iy, ib; + int dx, dy; + XImage *image; + uint32_t *w, *scan, d; + unsigned long white = WhitePixel(dpy, screen); + unsigned long black = BlackPixel(dpy, screen); + + if (shm_image) + image = shm_image; + else + image = nonshm_image; + + scan = bits; + for (iy = 0; iy < HEIGHT; iy++) { + w = scan; + scan += STRIDE; + for (ix = 0; ix < WIDTH; ix += 32) { + d = *w++; + for (ib = 0; ib < 32 && ix + ib < WIDTH; ib++) { + unsigned long p = d & 1 ? white : black; + d >>= 1; + for (dy = 0; dy < IMAGE_SCALE; dy++) { + + for (dx = 0; dx < IMAGE_SCALE; dx++) { + XPutPixel(image, (ix + ib) * IMAGE_SCALE + dx, iy * IMAGE_SCALE + dy, p); + } + } + } + } + } + if (shm_image) + XShmPutImage(dpy, win, gc, image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, False); + else + XPutImage(dpy, win, gc, image, 0, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); +} -- 2.30.2