/*********************************************************************** * * * ImgToolKit.c - set of routines for work with X11 server * * * * Author: Evgeni Chernyaev (chernaev@mx.ihep.su) * * * * Contains: * * int ImgCheckDisplay (dsp) * * int ImgPause (dsp, pause) * * void ImgFreeImage (image) * * XImage* ImgPickImage (dsp, x, y, w, h) * * void ImgPickPalette (dsp, window, ncol, r, g, b) * * void ImgGetRectangle (dsp, window, x, y, w, h) * * void ImgGetCurrentWindow (dsp, window, x, y, w, h) * * int ImgGetWindowById (dsp, window, x, y, w, h) * * void ImgFinalFlash (dsp, x, y, w, h) * * * * * * Copyright (C) 1993, 1994 by Evgeni Chernyaev. * * * * Permission to use, copy, modify, and distribute this software and * * its documentation for non-commercial purpose is hereby granted * * without fee, provided that the above copyright notice appear in all * * copies and that both the copyright notice and this permission * * notice appear in supporting documentation. * * * * This software is provided "as is" without express or implied * * warranty. * * * ***********************************************************************/ #include #include #include #include #include #include #define MAXCOL 256 /*********************************************************************** * * * Name: ImgCheckDisplay Date: 22.02.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Check X-display parameters * * * * Input: theDsp - pointer to display structure * * * * Return: 0 - if O.K. * * -1 - too many colors * * -2 - unable to get RootWindow attributes * * -3 - DirectColor * * -4 - TrueColor * * * ***********************************************************************/ int ImgCheckDisplay(theDsp) Display *theDsp; { int theScr; Window theRoot; XWindowAttributes theRWA; Visual *theVis; theScr = DefaultScreen(theDsp); theRoot = RootWindow(theDsp, theScr); if (DisplayCells(theDsp, theScr) > MAXCOL) return -1; if (!XGetWindowAttributes(theDsp, theRoot, &theRWA)) return -2; theVis = theRWA.visual; if (theVis == NULL) theVis = DefaultVisual(theDsp, theScr); if (theVis->class == DirectColor) return -3; if (theVis->class == TrueColor) return -4; return 0; } /*********************************************************************** * * * Name: ImgPause Date: 22.02.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Wait a few seconds for input from keyboard * * * * Input: theDsp - pointer to display structure * * pause - time delay in seconds * * * * Return: 0 - O.K. there was input from keyboard * * -1 - time out * * * ***********************************************************************/ int ImgPause(theDsp, pause) Display *theDsp; int pause; { Window theRoot; time_t t1, t2; XEvent event; theRoot = RootWindow(theDsp, DefaultScreen(theDsp)); XGrabKeyboard(theDsp, theRoot, False, GrabModeAsync, GrabModeAsync, CurrentTime); time(&t1); t2 = t1; while(1) { if ((t2 - t1) > pause) { XUngrabKeyboard(theDsp, CurrentTime); return -1; } if (0 != XCheckTypedEvent(theDsp, KeyPress, &event)) { if( XKeycodeToKeysym(theDsp, event.xkey.keycode, 0) == XK_space ){ XUngrabKeyboard(theDsp, CurrentTime); return 0; } } time(&t2); } } /*********************************************************************** * * * Name: ImgFreeImage Date: 07.01.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Free image * * * * Input: theImg - pointer to the image * * * ***********************************************************************/ void ImgFreeImage(theImg) XImage *theImg; { if (theImg) { if (theImg->data) free(theImg->data); theImg->data = NULL; XDestroyImage(theImg); } } /*********************************************************************** * * * Name: ImgPickImage Date: 22.02.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Pick image * * * * Input: theDsp - pointer to display structure * * x - x-coordinate of the upper left corner * * y - y-coordinate of the upper left corner * * width - image width * * height - image height * * * * Return: pointer to the image * * * ***********************************************************************/ XImage* ImgPickImage(theDsp, x, y, width, height) Display *theDsp; int x, y, width, height; { Window theRoot; XImage *theImg; theRoot = RootWindow(theDsp, DefaultScreen(theDsp)); theImg = XGetImage(theDsp, theRoot, x, y, width, height, AllPlanes, ZPixmap); if (!theImg || !theImg->data) { ImgFreeImage(theImg); theImg = NULL; } return theImg; } /*********************************************************************** * * * Name: ImgPickPalette Date: 22.02.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Pick palette for image * * * * Input: theDsp - pointer to display structure * * window - window * * * * Output: Ncol - number of colors * * R[] - red components * * G[] - green components * * B[] - blue components * * * ***********************************************************************/ void ImgPickPalette(theDsp, window, Ncol, R, G, B) Display *theDsp; Window window; int *Ncol, *R, *G, *B; { int i, theScr, nmaps, ncolors; Window theRoot, theWin; Colormap cmap, *cmaps; XColor colors[MAXCOL]; XWindowAttributes theAtt; theScr = DefaultScreen(theDsp); theRoot = RootWindow(theDsp, theScr); if (window != NULL && window != theRoot) theWin = window; else theWin = theRoot; XGetWindowAttributes(theDsp, theWin, &theAtt); if (theAtt.colormap && theAtt.map_installed) { ncolors = theAtt.visual->map_entries; cmap = theAtt.colormap; }else{ ncolors = DisplayCells(theDsp, theScr); cmap = DefaultColormap(theDsp, theScr); cmaps = XListInstalledColormaps(theDsp, theRoot, &nmaps); if (nmaps != 0) { for (i=0; i theRWA.width) ww = theRWA.width - xw; if ((yw+hw) > theRWA.height) hw = theRWA.height - yw; *x = xw; *y = yw; *w = ww; *h = hw; } /*********************************************************************** * * * Name: ImgFlashRectangle Date: 14.02.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Draw flashing rectangle * * * * Input: x, y - left upper corner * * w, h - width and height of rectangle * * show - show flag * * * ***********************************************************************/ static void ImgFlashRectangle(x, y, w, h, show) int x, y, w, h, show; { static int isvis = 0, mask1 = 0, mask2 = 1, xcur, ycur, wcur, hcur; static unsigned long masks[8] = { 0x01010101,0x02020203,0x04040405,0x08080809, 0x10101011,0x20202021,0x40404041,0x80808081 }; /* T U R N O F F R E C T A N G L E */ if (show == 0) { if (isvis == 0) return; XSetPlaneMask(theDsp, theGC, masks[mask1]); XDrawRectangle(theDsp, theRoot, theGC, xcur, ycur, wcur-1, hcur-1); if (wcur>3 && hcur>3) XDrawRectangle(theDsp, theRoot, theGC, xcur+1, ycur+1, wcur-3, hcur-3); isvis = 0; return; } /* T U R N O N R E C T A N G L E */ if (isvis == 0) { if (w>1 && h>1) { XSetPlaneMask(theDsp, theGC, masks[mask2]); XDrawRectangle(theDsp, theRoot, theGC, x, y, w-1, h-1); isvis = 1; } if (w>3 && h>3) XDrawRectangle(theDsp, theRoot, theGC, x+1, y+1, w-3, h-3); }else{ isvis = 0; XSetPlaneMask(theDsp, theGC, masks[mask1]); XDrawRectangle(theDsp, theRoot, theGC, xcur, ycur, wcur-1, hcur-1); if (w>1 && h>1) { XSetPlaneMask(theDsp, theGC, masks[mask2]); XDrawRectangle(theDsp, theRoot, theGC, x, y, w-1, h-1); isvis = 1; } if (wcur>3 && hcur>3) { XSetPlaneMask(theDsp, theGC, masks[mask1]); XDrawRectangle(theDsp, theRoot, theGC, xcur+1, ycur+1, wcur-3, hcur-3); } if (w>3 && h>3) { XSetPlaneMask(theDsp, theGC, masks[mask2]); XDrawRectangle(theDsp, theRoot, theGC, x+1, y+1, w-3, h-3); } } if (isvis == 1) { mask1 = mask2; mask2 = (mask2 + 1) & 7; xcur = x; ycur = y; wcur = w; hcur = h; } } /*********************************************************************** * * * Name: ImgGetRectangle Date: 23.02.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Select rectangle on the screen * * * * Input: display - pointer to display structure * * * * Output: window - window (for picking of palette) * * xorigin - x-coordinate of the upper left corner * * yorigin - y-coordinate of the upper left corner * * width - rectangle width * * height - rectangle height * * * ***********************************************************************/ void ImgGetRectangle(display, window, xorigin, yorigin, width, height) Display *display; Window *window; int *xorigin, *yorigin, *width, *height; { int x, y, rx, ry, x1, y1, x2, y2, ix, iy, iw, ih; Cursor theCrsr; Window rW, cW; unsigned int mask; XColor fc, bc; XEvent event; /* I N I T I A L I S A T I O N */ theDsp = display; theScr = DefaultScreen(theDsp); theRoot = RootWindow(theDsp, theScr); theGC = DefaultGC(theDsp, theScr); XGetWindowAttributes(theDsp, theRoot, &theRWA); /* S E T C U R S O R */ theCrsr = XCreateFontCursor(theDsp, XC_tcross); fc.red = fc.green = fc.blue = 0xffff; bc.red = bc.green = bc.blue = 0x0000; XRecolorCursor(theDsp, theCrsr, &fc, &bc); /* G R A B P O I N T E R */ XGrabPointer(theDsp, theRoot, False, 0L, GrabModeAsync, GrabModeSync, None, theCrsr, CurrentTime); XSetFunction(theDsp, theGC, GXinvert); /* start flash rectangle */ XSetSubwindowMode(theDsp, theGC, IncludeInferiors); /* G E T R E C T A N G L E */ x = -1; y = -1; while (1) { /* Wait for button press */ if (XQueryPointer(theDsp, theRoot, &rW, &cW, &rx, &ry, &x1, &y1, &mask)) { if (mask & Button1Mask) break; } if (x1 != x || y1 != y) { x = x1; y = y1; if (cW == NULL || cW == theRoot) { ix = 0; iy = 0; iw = theRWA.width; ih = theRWA.height; }else{ ImgFindRectangle(cW,x1,y1,&ix,&iy,&iw,&ih); } } ImgFlashRectangle(ix, iy, iw, ih, 1); /* turn ON rectangle */ } *xorigin = ix; *yorigin = iy; *width = iw; *height = ih; x2 = x1; y2 = y1; iw = 0; ih = 0; while (1) { /* Wait for button release */ if (XQueryPointer(theDsp, theRoot, &rW, &cW, &rx, &ry, &x, &y, &mask)) { if (0 != XCheckTypedEvent(theDsp, KeyPress,&event)) break; if (!(mask & Button1Mask)) break; } if (x != x2 || y != y2) { /* move rectangle */ ix = (x1 2 || ih > 2) { *xorigin = ix; *yorigin = iy; *width = iw; *height = ih; x = ix + iw/2; y = iy + ih/2; } rW = theRoot; while (rW != NULL) { cW = rW; XTranslateCoordinates(theDsp, theRoot, cW, x, y, &rx, &ry, &rW); } *window = cW; } /*********************************************************************** * * * Name: ImgGetCurrentWindow Date: 23.02.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Get coordinates of the current window * * * * Input: display - pointer to display structure * * * * Output: window - current window * * xorigin - x-coordinate of the upper left corner * * yorigin - y-coordinate of the upper left corner * * width - rectangle width * * height - rectangle height * * * ***********************************************************************/ void ImgGetCurrentWindow(display, window, xorigin, yorigin, width, height) Display *display; Window *window; int *xorigin, *yorigin, *width, *height; { int x, y, rx, ry; Window rW, cW; unsigned int mask; theDsp = display; theScr = DefaultScreen(theDsp); theRoot = RootWindow(theDsp, theScr); theGC = DefaultGC(theDsp, theScr); XGetWindowAttributes(theDsp, theRoot, &theRWA); XQueryPointer(theDsp, theRoot, &rW, &cW, &rx, &ry, &x, &y, &mask); if (cW == NULL) cW = theRoot; ImgFindRectangle(cW,x,y,xorigin,yorigin,width,height); /* F I N D W I N D O W F O R P I C K P A L E T T E */ rW = theRoot; while (rW != NULL) { cW = rW; XTranslateCoordinates(theDsp, theRoot, cW, x, y, &rx, &ry, &rW); } *window = cW; } /*********************************************************************** * * * Name: ImgGetWindowById Date: 01.04.94 * * Author: E.Chernyaev (IHEP/Protvino) Revised: * * * * Function: Get coordinates of window by id * * * * Input: display - pointer to display structure * * window - window id * * * * Output: xorigin - x-coordinate of the upper left corner * * yorigin - y-coordinate of the upper left corner * * width - window width * * height - window height * * * * Return: 0 - O.K. * * -1 - window does not exist * * * ***********************************************************************/ int ImgGetWindowById(display, window, xorigin, yorigin, width, height) Display *display; Window window; int *xorigin, *yorigin, *width, *height; { int x, y, w, h; unsigned int ww, hh, border, depth; Window rW; theDsp = display; theScr = DefaultScreen(theDsp); theRoot = RootWindow(theDsp, theScr); theGC = DefaultGC(theDsp, theScr); XGetWindowAttributes(theDsp, theRoot, &theRWA); if (window == theRoot) { *xorigin = 0; *yorigin = 0; *width = theRWA.width; *height = theRWA.height; return 0; } if (!XGetGeometry(theDsp, window, &rW, &x, &y, &ww, &hh, &border, &depth)) return (-1); /* XMapRaised(theDsp,window); XSync(theDsp, False); */ w = ww; h = hh; XTranslateCoordinates(theDsp, window, theRoot, 0, 0, &x, &y, &rW); if (x < 0) { w += x; x = 0; } if (y < 0) { h += y; y = 0; } if ((x+w) > theRWA.width) w = theRWA.width - x; if ((y+h) > theRWA.height) h = theRWA.height - y; *xorigin = x; *yorigin = y; *width = w; *height = h; return 0; } /*********************************************************************** * * * Name: ImgFinalFlash Date: 08.11.93 * * Author: E.Chernyaev (IHEP/Protvino) Revised: 01.04.94 * * * * Function: Final flash of the selected rectangle * * * * Input: display - pointer to display structure * * x, y - left upper corner * * w, h - width and height of the rectangle * * * ***********************************************************************/ void ImgFinalFlash(display, x, y, w, h) Display *display; int x, y, w, h; { time_t t1, t2; theDsp = display; theScr = DefaultScreen(theDsp); theRoot = RootWindow(theDsp, theScr); theGC = DefaultGC(theDsp, theScr); XGetWindowAttributes(theDsp, theRoot, &theRWA); XFlush(theDsp); theRoot = RootWindow(theDsp, DefaultScreen(theDsp)); XGrabKeyboard(theDsp, theRoot, False, GrabModeAsync, GrabModeSync, CurrentTime); XSetFunction(theDsp, theGC, GXinvert); /* start flash rectangle */ XSetSubwindowMode(theDsp, theGC, IncludeInferiors); time(&t1); t2 = t1; while(t2-t1 == 0) { ImgFlashRectangle(x, y, w, h, 1); ImgFlashRectangle(x, y, w, h, 1); ImgFlashRectangle(x, y, w, h, 1); ImgFlashRectangle(x, y, w, h, 1); ImgFlashRectangle(x, y, w, h, 1); ImgFlashRectangle(x, y, w, h, 1); ImgFlashRectangle(x, y, w, h, 1); ImgFlashRectangle(x, y, w, h, 1); time(&t2); } ImgFlashRectangle(0, 0, 0, 0, 0); /* turn OFF rectangle */ XSetFunction(theDsp, theGC, GXcopy); /* end flash rectangle */ XSetSubwindowMode(theDsp, theGC, ClipByChildren); XSetPlaneMask(theDsp, theGC, AllPlanes); XUngrabKeyboard(theDsp, CurrentTime); XSync(theDsp, False); }