Subject: xmag: selection box is invisible; alternative method provided

From: david@craft (David B. Lewis)
Date: Fri, 7 Feb 1992 11:38:34 -0500

VERSION:
    R5, public-patch-8

CLIENT MACHINE and OPERATING SYSTEM:
    Sparc/SunOS 4.1.1

DISPLAY TYPE:
	Visual XBASE12 8-bit color, beta software

WINDOW MANAGER:
	typically XDSwm

COMPILER:
	typically native cc

AREA:
	clients/xmag

SYNOPSIS:
	The selection box for xmag is drawn and immediately erased; this
happens so quickly that it is not visible.

DESCRIPTION:
	The R4 xmag had a hard-to-see selection box as well; but on this
system even it is much more visible than the R5 xmag. I need some feedback, 
particularly on resizing (nice new feature, BTW).

REPEAT BY:
	Run R5 xmag.
	See also mit/clients/xmag/xmag.c`HighlightTO.

SAMPLE FIX:
	Use same sort of static box that the window manager uses to position 
the client window; the difference when using xmag between selecting an area 
of the screen and then placing the xmag view window with TWM, for example, is 
dramatic.

Here's the set of changes that I'm using:

Bugs: 
	- one of my goals was adding as little code as possible, so these 
	changes have the same organization as the original code
	- server grab omitted, with possible resultant problems
	- leaves droppings on the menu buttons when a new xmag is invoked
	- old behavior not made a backward-compatible option
	- rubber-banding GC not changed from the original; doesn't appear
	correctly in all cases
	- man page not updated

*** xmag.c.orig	Mon Feb  3 12:29:34 1992
--- xmag.c	Tue Feb  4 10:46:07 1992
***************
*** 46,54 ****
  
  
  
- /* highlight interval */
- #define HLINTERVAL  10		
- 
  /* highlight mode */
  typedef enum { drag, resize, done } hlMode; 
  
--- 46,51 ----
***************
*** 55,61 ****
  /* highlight data structure */
  typedef struct { 
    Boolean   newScale;
!   hlMode    selectMode;
    GC        gc;
    XWindowAttributes win_info;   
    XImage     *image;
--- 52,58 ----
  /* highlight data structure */
  typedef struct { 
    Boolean   newScale;
!   hlMode    selectMode;		/* not used */
    GC        gc;
    XWindowAttributes win_info;   
    XImage     *image;
***************
*** 64,70 ****
    Widget    scaleShell, scaleInstance, pixShell, pixLabel, cmapWinList [2];
    } hlStruct, *hlPtr;
  
- static XtIntervalId hlId;
  
  
  
--- 61,66 ----
***************
*** 94,100 ****
    PopdownPixelAP(), 
    SelectRegionAP(), 
    CheckPoints(), 
!   HighlightTO(),
    CloseCB(), 
    ReplaceCB(),
    NewCB(), 
--- 90,97 ----
    PopdownPixelAP(), 
    SelectRegionAP(), 
    CheckPoints(), 
!   DoBoxResize(),
!   DoBoxDrag(),
    CloseCB(), 
    ReplaceCB(),
    NewCB(), 
***************
*** 430,466 ****
  
  
  
! /*
!  * HighlightTO() -- Timer to highlight the selection box
!  */
! static void
! HighlightTO(closure, id)	/* ARGSUSED */
!      XtPointer closure; XtIntervalId *id;
  {
-   hlPtr data = (hlPtr)closure;
-   XGrabServer(dpy);
-   if (data->selectMode == drag) {
-     XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc, 
- 		   data->x, data->y, data->width, data->height);
-     XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc, 
- 		   data->x, data->y, data->width, data->height);
-   }
-   else if (data->selectMode == resize) {	
-     Position x1 = data->homeX,
-              x2 = data->x,
-              y1 = data->homeY,
-              y2 = data->y;
      CheckPoints(&x1, &x2, &y1, &y2);
!     XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc, 
  		   x1, y1, x2 - x1, y2 - y1);
-     XDrawRectangle(dpy, DefaultRootWindow(dpy), data->gc, 
- 		   x1, y1, x2 - x1, y2 - y1);
-   }
-   XUngrabServer(dpy);
-   if (data->selectMode != done)
-     XtAppAddTimeOut(app, HLINTERVAL, HighlightTO, (XtPointer)data);
  }
  
  
  
  /*
--- 427,450 ----
  
  
  
! static void DoBoxResize (gc, x1, y1, x2, y2)
! GC gc;
! Position x1, y1, x2, y2;
  {
      CheckPoints(&x1, &x2, &y1, &y2);
!     XDrawRectangle(dpy, DefaultRootWindow(dpy), gc, 
  		   x1, y1, x2 - x1, y2 - y1);
  }
  
+ static void DoBoxDrag (gc, x, y, width, height)
+ GC gc;
+ Position x,y;
+ Dimension width, height;
+ {
+     XDrawRectangle(dpy, DefaultRootWindow(dpy), gc, 
+ 		   x, y, width, height);
+ }
+ 
  
  
  /*
***************
*** 582,591 ****
--- 566,578 ----
    hlPtr data = (hlPtr)closure;
    switch (event->type) {
    case MotionNotify:
+     DoBoxResize(data->gc, data->homeX, data->homeY, data->x, data->y);
      data->x = event->xmotion.x_root;
      data->y = event->xmotion.y_root; 
+     DoBoxResize(data->gc, data->homeX, data->homeY, data->x, data->y);
      break;
    case ButtonRelease:
+     DoBoxResize(data->gc, data->homeX, data->homeY, data->x, data->y);
      GetImageAndAttributes(FindWindow(event->xmotion.x_root,
  			event->xmotion.y_root),
  	     min(data->homeX,event->xbutton.x_root),
***************
*** 617,624 ****
--- 604,613 ----
    hlPtr data = (hlPtr)closure;
    switch (event->type) {
    case MotionNotify:		/* drag mode */
+     DoBoxDrag(data->gc, data->x, data->y, data->width, data->height);
      data->x = event->xmotion.x_root;
      data->y = event->xmotion.y_root;
+     DoBoxDrag(data->gc, data->x, data->y, data->width, data->height);
      break;
    case ButtonRelease:		/* end drag mode */
      if (event->xbutton.button == Button1) { /* get image */
***************
*** 627,632 ****
--- 616,622 ----
         *          where the depth of the window does not match the depth of
         *          the root window.
         */
+       DoBoxDrag(data->gc, data->x, data->y, data->width, data->height);
        GetImageAndAttributes(FindWindow(event->xmotion.x_root, 
  			  event->xmotion.y_root),
  	       event->xbutton.x_root, 
***************
*** 646,656 ****
--- 636,648 ----
      break;
    case ButtonPress:	
      if (event->xbutton.button == Button2) {	/* turn on resize mode */
+       DoBoxDrag(data->gc, data->x, data->y, data->width, data->height);
        data->homeX = event->xbutton.x_root; 
        data->homeY = event->xbutton.y_root;
        data->x = event->xbutton.x_root + srcWidth;
        data->y = event->xbutton.y_root + srcHeight;      
        data->selectMode = resize;
+       DoBoxResize(data->gc, data->homeX, data->homeY, data->x, data->y);
        XtRemoveEventHandler(w, PointerMotionMask|ButtonPressMask|
  			   ButtonReleaseMask, True, DragEH, (XtPointer)data);
        XChangeActivePointerGrab
***************
*** 660,665 ****
--- 652,660 ----
  		   srcWidth, srcHeight);
        XtAddEventHandler(w, PointerMotionMask|ButtonReleaseMask, 
  			True, ResizeEH, (XtPointer)data);
+       XtRemoveRawEventHandler(w, PointerMotionMask|ButtonPressMask|
+ 			      ButtonReleaseMask, True, DragEH,
+ 			      (XtPointer)data);
      }
      break;
    }
***************
*** 699,708 ****
    hlData->gc         = selectGC;
    hlData->width      = srcWidth;
    hlData->height     = srcHeight;
    XtAddRawEventHandler
      (root, PointerMotionMask|ButtonPressMask|ButtonReleaseMask, 
       True, DragEH, (XtPointer)hlData);
-   hlId = XtAppAddTimeOut(app, HLINTERVAL, HighlightTO, (XtPointer)hlData);
  }
  
  
--- 694,703 ----
    hlData->gc         = selectGC;
    hlData->width      = srcWidth;
    hlData->height     = srcHeight;
+   DoBoxDrag(hlData->gc, hlData->x, hlData->y, hlData->width, hlData->height);
    XtAddRawEventHandler
      (root, PointerMotionMask|ButtonPressMask|ButtonReleaseMask, 
       True, DragEH, (XtPointer)hlData);
  }
  
  

-- 
David B. Lewis  	[email-masked] (ignore bogus return address)
"Sir, What was the best thing before sliced bread? Yours faithfully,
Winty M. Thornton" -- The Times [London], 8 May 1991