/* Copyright (C) 1996 Scott W. Sadler All rights reserved. */ /* XsOutline.C History 03-Mar-96 1.0; Scott W. Sadler (ssadler@cisco.com) Created */ // Includes #include #include #include "XsOutline.h" // Constructor XsOutline::XsOutline (Widget w) { assert (w != 0); // Initialize _w = w; // Get window dimensions unsigned int moreJunk; unsigned int uw, uh; Window junk; XGetGeometry (XtDisplay (_w), XtWindow (_w), &junk, &_x, &_y, &uw, &uh, &moreJunk, &moreJunk); _width = uw; _height = uh; // Get initial settings _savedX = _x; _savedY = _y; _savedH = _savedW = 0; // Create the graphics context XGCValues values; unsigned long valuemask; Display *dpy = XtDisplay (_w); valuemask = GCFunction | GCLineWidth | GCSubwindowMode; values.function = GXinvert; values.line_width = 0; values.subwindow_mode = IncludeInferiors; _gc = XCreateGC (dpy, XtWindow (_w), valuemask, &values); } // Destructor XsOutline::~XsOutline ( ) { XFreeGC (XtDisplay (_w), _gc); } // go Boolean XsOutline::go (Boolean drawInitial) { XtAppContext appContext = XtWidgetToApplicationContext (_w); XEvent event; int done = 0; // Grab the pointer if (_grabPointer ( ) == False) return (False); // Draw the initial box (if requested) if (drawInitial) _drawOutline (False); // Process the events locally while (!done) { XtAppNextEvent (appContext, &event); switch (event.type) { case ButtonRelease: { // Clear the outline and break _drawOutline (True); done = 1; break; } case MotionNotify: { XEvent next; // Process only the last motion event while (XPending (XtDisplay (_w)) > 0) { XPeekEvent (XtDisplay (_w), &next); if (next.type != MotionNotify) break; XtAppNextEvent (appContext, &event); } // Send this event _motionHandler (&event); break; } default: { XtDispatchEvent (&event); break; } } } // Ungrab the pointer _ungrabPointer ( ); return (True); } // _drawOutline void XsOutline::_drawOutline (Boolean clear) { // Clear the current outline if (_savedH || _savedW) _drawIt (_savedX, _savedY, _savedW, _savedH); // Save current values _savedX = _x; _savedY = _y; _savedW = _width; _savedH = _height; // Draw the new outline (unless flagged to just clear) if (!clear) _drawIt (_x, _y, _width, _height); } // _getCursor Cursor XsOutline::_getCursor ( ) const { return (None); } // _grabPointer Boolean XsOutline::_grabPointer ( ) { // Sync everything up before being grabby XSync (XtDisplay (_w), False); // Grab the pointer if (XGrabPointer (XtDisplay (_w), XtWindow (_w), False, GrabEventMask, GrabModeAsync, GrabModeAsync, XtWindow (XtParent (_w)), _getCursor ( ), CurrentTime) != GrabSuccess) { XBell (XtDisplay (_w), 100); return (False); } return (True); } // _ungrabPointer void XsOutline::_ungrabPointer ( ) { // Ungrab the pointer XUngrabPointer (XtDisplay (_w), CurrentTime); } // _drawIt void XsOutline::_drawIt (int x, int y, int w, int h) { const int nsegs = 8; XSegment segs[nsegs]; // Across the top segs[0].x1 = x; segs[0].y1 = y; segs[0].x2 = x + w - 1; segs[0].y2 = y; segs[1].x1 = x + BorderSize; segs[1].y1 = y + BorderSize; segs[1].x2 = x + w - BorderSize - 1; segs[1].y2 = y + BorderSize; // Down the left segs[2].x1 = x + w - 1; segs[2].y1 = y + 1; segs[2].x2 = x + w - 1; segs[2].y2 = y + h - 1; segs[3].x1 = x + w - BorderSize - 1; segs[3].y1 = y + BorderSize + 1; segs[3].x2 = x + w - BorderSize - 1; segs[3].y2 = y + h - BorderSize - 1; // Across the bottom segs[4].x1 = x + 1; segs[4].y1 = y + h - 1; segs[4].x2 = x + w - 2; segs[4].y2 = y + h - 1; segs[5].x1 = x + BorderSize + 1; segs[5].y1 = y + h - BorderSize - 1; segs[5].x2 = x + w - BorderSize - 2; segs[5].y2 = y + h - BorderSize - 1; // Up the left segs[6].x1 = x; segs[6].y1 = y + h - 1; segs[6].x2 = x; segs[6].y2 = y + 1; segs[7].x1 = x + BorderSize; segs[7].y1 = y + h - BorderSize - 1; segs[7].x2 = x + BorderSize; segs[7].y2 = y + BorderSize + 1; // Draw the segments XDrawSegments (XtDisplay (_w), XtWindow (XtParent (_w)), _gc, segs, nsegs); }