From f0ca92ad7fe657f183a8146377ce15b79fec5ffa Mon Sep 17 00:00:00 2001 From: Daniel Price Date: Fri, 29 Nov 2024 19:59:28 +1100 Subject: [PATCH 1/2] (xw) more useful error message when cannot launch X-window; also more careful handling of close window event --- src/giza-driver-xw.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/giza-driver-xw.c b/src/giza-driver-xw.c index b1df934..c7e2a4f 100644 --- a/src/giza-driver-xw.c +++ b/src/giza-driver-xw.c @@ -76,6 +76,7 @@ static void _giza_expose_xw (XEvent *event); static void _giza_flush_xw_event_queue (XEvent *event); static int _giza_errors_xw (Display *display, XErrorEvent *error); +static Atom wmDeleteMessage; /*static int giza_xw_debug = 0;*/ /** @@ -116,7 +117,7 @@ _giza_open_device_xw (double width, double height, int units) XW[id].display = XOpenDisplay (NULL); if (!XW[id].display) { - _giza_error ("_giza_open_device_xw", "Connection to the X server could not be made"); + _giza_error ("_giza_open_device_xw", "Cannot launch X window (use ssh -Y not ssh / install XQuartz if on Mac)"); return 1; } @@ -196,7 +197,7 @@ _giza_open_device_xw (double width, double height, int units) XMapWindow (XW[id].display, XW[id].window); /* register interest in the delete window message */ - Atom wmDeleteMessage = XInternAtom(XW[id].display, "WM_DELETE_WINDOW", 1); + wmDeleteMessage = XInternAtom(XW[id].display, "WM_DELETE_WINDOW", 0); XSetWMProtocols(XW[id].display, XW[id].window, &wmDeleteMessage, 1); /* register the routine to handle non-fatal X errors */ @@ -374,7 +375,7 @@ _giza_xevent_loop (int mode, int moveCurs, int nanc, const int *anchorx, const i } XEvent event; - XSelectInput (XW[id].display, XW[id].window, ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask); + XSelectInput (XW[id].display, XW[id].window, ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask | StructureNotifyMask ); _giza_init_band (mode); _giza_expand_clipping_xw(); @@ -383,19 +384,22 @@ _giza_xevent_loop (int mode, int moveCurs, int nanc, const int *anchorx, const i /* wait for key press/expose (avoid using XNextEvent as breaks older systems) */ XWindowEvent(XW[id].display, XW[id].window, - (long) (ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask), &event); + (long) (ExposureMask | KeyPressMask | ButtonPressMask | PointerMotionMask | StructureNotifyMask), &event); /*XNextEvent(XW[id].display, &event);*/ /* always return x, y values for safety */ *x = 0; *y = 0; - switch (event.type) { case ClientMessage: /* catch close window event */ *ch = 'q'; - if (!strcmp( XGetAtomName( XW[id].display, event.xclient.message_type ), "WM_PROTOCOLS" )) { - return; - } + if ((Atom)event.xclient.data.l[0] == wmDeleteMessage) { + return; + } + break; + case DestroyNotify: + *ch = 'q'; + return; case Expose: /* redraw */ _giza_expose_xw (&event); break; From fbcd54144ec8c5e794c8e521609e14d2b4bc5fed Mon Sep 17 00:00:00 2001 From: Daniel Price Date: Mon, 2 Dec 2024 09:44:15 +1100 Subject: [PATCH 2/2] BUG FIX with window restoration on Mac OS, now restore from the X-Window pixmap buffer, not from the window directly; fixes #54 --- src/giza-band.c | 1 + src/giza-driver-xw.c | 4 +++- src/giza-drivers.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/giza-band.c b/src/giza-band.c index 2a529bf..be3ae7a 100644 --- a/src/giza-band.c +++ b/src/giza-band.c @@ -114,6 +114,7 @@ _giza_refresh_band (int mode, int nanc, const int *xanc, const int *yanc, int x2 /* Draw over the old band */ cairo_paint (Band.restore); + giza_flush_device(); /* int topleftx = x1 - 10; diff --git a/src/giza-driver-xw.c b/src/giza-driver-xw.c index c7e2a4f..12171bc 100644 --- a/src/giza-driver-xw.c +++ b/src/giza-driver-xw.c @@ -604,8 +604,10 @@ _giza_init_band_xw (void) /* use grey for band */ cairo_set_source_rgba (Band.box, 0.5, 0.5, 0.5, 1.0); - /* Set up restore to remove box */ + /* Set up restore to remove box (DP: 2/12/24 we now restore from pixmap instead of window to fix issue on Mac OS)*/ + Band.onscreen = cairo_xlib_surface_create (XW[id].display, XW[id].pixmap, XW[id].visual, XW[id].width, XW[id].height); Band.restore = cairo_create (Band.onscreen); + cairo_set_source_surface (Band.restore, Dev[id].surface, 0, 0); Band.maxHeight = XW[id].height; Band.maxWidth = XW[id].width; diff --git a/src/giza-drivers.c b/src/giza-drivers.c index 21fbc3e..027fe62 100644 --- a/src/giza-drivers.c +++ b/src/giza-drivers.c @@ -1164,7 +1164,7 @@ _giza_init_band (int mode) #endif default: _giza_error ("_giza_init_band", "band not implemented for this device"); - break; + break; } _giza_set_line_style (Band.ls, Band.box); double lwDevice = Band.lw * Dev[id].deviceUnitsPermm * 0.25;