xwindow.c
Upload User: shhuayu888
Upload Date: 2013-03-28
Package Size: 1788k
Code Size: 17k
Category:

Windows Develop

Development Platform:

Unix_Linux

  1. /****************************************************************************
  2.  File Name  : xwindow.c
  3.  Purpose    : provides x-window interface routines
  4.  Release    : Version 1.0
  5.  Date     : Aug 31,1995
  6. GSNAKE API is jointly developed by the Information Technology Institute (ITI), Singapore, and the School of Applied Science, Nanyang Technological
  7. University (NTU), Singapore. 
  8. These software programs are available to the user without any license or royalty fees. Permission is hereby granted to use, copy, modify, and distribute this software and its documentation for any purpose. ITI and NTU gives no warranty, express, implied, or statuary for the software and/or documentation provided, including, without limitation, waranty of merchantibility and warranty of fitness for a particular purpose. The software provided hereunder is on an "as is"  basis, and ITI and NTU has no obligation to provide maintenance, support, updates, enhancements, or modifications.
  9. GSNAKE API is available for any UNIX compatible system. User feedback, bugs, or software and manual suggestions should be sent via electronic mail to one of the following, who may or may not act on them as he/she desires :
  10. asschan@ntu.ac.sg
  11. kflai@iti.gov.sg
  12. ***************************************************************************/
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <X11/Xlib.h>
  16. #include <X11/Xutil.h>
  17. #include "gsnake.h"
  18. /* ---- internal constants and variables used by x window manager ---- */
  19. #define COLORMAPSIZE 256
  20. #define ALLOC_COLOR 1 /* allocate color for snaxel */
  21. #define TITLE "gsnake"
  22. #define VERBOSE 1
  23. #define INCH            72       /* one inch = 72 points */
  24. #define BORDERWIDTH 5 /* border width = 5 pixels */
  25. static int FirstTime = 1 ; /* to raise X window */
  26. static Display         *gDisplay=NULL; /* display and others */
  27. static int gScreen;
  28. static Window gWindow;
  29. static Visual *gVisual;
  30. static GC        imageGC; /* graphic contexts */
  31. static GC pointGC ;
  32. static GC rectGC;
  33. static unsigned long  pixels[COLORMAPSIZE]; /* pixel values */
  34. static int c_map_size; /* colormap size */
  35. static XEvent any_event;
  36. static char  *Title = NULL;
  37. /* expand ratio for higher level snaxels */
  38. static int              ci_expand = 1;
  39. static int              POINT_DIM = 3;  /* dimension of point in plotting */
  40. static int              POINT_OFF = 0; /* offset in plotting point */
  41. /* ----- internal function prototypes ------ */
  42. int  xwin_init(short width, short height, char *title, char alloc_color, 
  43. char verbose);
  44. void  xwin_close(void);
  45. Display *xwin_setupXWindow(char *DisplayName, char *title, short width, 
  46. short height, int *screen, Window *window, Visual **visual, 
  47. int verbose);
  48. void  xwin_setupGC(unsigned long *pixels, int *c_map_size, char alloc_color);
  49. void xwin_setTitle(char *title)
  50. {
  51. Title = strdup(title);
  52. }
  53. void xwin_raiseWindow(short width, short height)
  54. {
  55. if( FirstTime ) {
  56. xwin_init(width, height, ((Title) ? Title : TITLE), 1, VERBOSE);
  57. FirstTime = 0 ;
  58. }
  59. else
  60.   XResizeWindow(gDisplay, gWindow, width, height);
  61. }
  62. /* create an x window of specified dimensions and initialize the graphics
  63.    context to display gray level images and drawing snake points and lines */
  64. xwin_init(
  65. short  width, 
  66. short  height, /* size of x window to be raised */
  67. char  *title, /* title of the window */
  68. char  alloc_color, /* 1 : alloc color for points */
  69. char  verbose /* 1 : turns verbose on */
  70. ) {
  71. /* create and raise X window */
  72. gDisplay = xwin_setupXWindow((char *) NULL, title, width, height, 
  73. &gScreen, &gWindow, &gVisual, verbose) ;
  74. /* create gray level GC */
  75. xwin_setupGC(pixels, &c_map_size, alloc_color);
  76. return (gDisplay) ? 1 : 0 ;
  77. /* close the x window */
  78. void xwin_close(void)
  79. {
  80. if(gDisplay) XCloseDisplay(gDisplay) ;
  81. }
  82. /* create a raise a simple X window */
  83. Display *xwin_setupXWindow(
  84. char  *DisplayName, /* name of display */
  85. char *title, /* title of window */
  86. short width, 
  87. short height, /* width and height of window */
  88. int *screen, /* RETURN : default screen */
  89. Window  *window, /* RETURN : created window */
  90. Visual  **visual, /* RETURN : POINTER to vidual found */
  91. int verbose /* 1 : set verbose on */
  92. ){
  93. Display *display ; /* graphic display */
  94. Window rootWindow ; /* the root window */
  95. XSizeHints gHint ; /* hints to X Server on window raising */
  96. unsigned long gForegrnd, gBackgrnd ;
  97. int status, depth ;
  98. /* connect to default X Server */
  99. display = XOpenDisplay(DisplayName) ;
  100. if( display == NULL ) { 
  101.        fprintf(stderr, "nERROR: Cannot connect to X server [%s]n", 
  102.   XDisplayName(DisplayName) );
  103.        return NULL ;
  104.     }
  105.  
  106.     *screen = DefaultScreen( display);
  107.    rootWindow = RootWindow( display, *screen);
  108.     gBackgrnd = WhitePixel( display, *screen);
  109.     gForegrnd = BlackPixel( display, *screen);
  110.    
  111.     *visual = DefaultVisual(display, *screen) ;
  112.     depth = DefaultDepth(display, *screen) ;
  113. /* provide hints on where to raise the window */
  114. gHint.x = 100 ;
  115. gHint.y = 200 ;
  116.     gHint.width = width ;
  117.     gHint.height =  height ; 
  118. gHint.flags = PPosition | PSize;
  119. /* actually create the window */
  120. *window = XCreateSimpleWindow( display, rootWindow, 
  121. gHint.x, gHint.y, gHint.width, gHint.height,
  122. (unsigned int) BORDERWIDTH, gForegrnd, gBackgrnd);
  123. XSetWMNormalHints(display, *window, &gHint) ;
  124.     XSelectInput( display, *window, 
  125. ButtonPressMask | KeyPressMask | ExposureMask |
  126. ButtonReleaseMask | Button1MotionMask );
  127.    XMapRaised(display, *window);
  128. XStoreName(display, *window, title);
  129. XFlush(display) ;
  130. /* print out information on x window if required */
  131. if( verbose == 1 ) {
  132. fprintf(stdout, "n%s version %d of the %sn",
  133. ServerVendor(display),
  134. VendorRelease(display),
  135. "X Window System") ;
  136. fprintf(stdout, "Color plane depth : %d %snn", depth,
  137. ( (depth == 1) ? "(mono)": "") ) ;
  138. }
  139. return display ;
  140. }
  141. /* set-up graphics context */
  142. void xwin_setupGC(
  143. unsigned long *pixels,
  144. int *c_map_size,
  145. char alloc_color
  146. ) {
  147.     XGCValues gc_values;
  148.     unsigned long mask;
  149.     XColor xcolor, rgb_color, hw_color;
  150.     int i, j, status ;
  151. Colormap color_map;
  152. *c_map_size = 0 ;
  153. color_map = DefaultColormap(gDisplay, gScreen) ;
  154.        while (XAllocColorCells(gDisplay, color_map, False, NULL, 0,
  155.      &(pixels[*c_map_size]), 1))
  156. (*c_map_size)++;
  157.        xcolor.flags = DoRed | DoGreen | DoBlue;
  158.        for (i = 0; i < *c_map_size; ++i)
  159.        {
  160. xcolor.pixel = pixels[i];
  161.   xcolor.red = (unsigned short) (i << 8);
  162.   xcolor.green = (unsigned short) (i << 8); 
  163.   xcolor.blue = (unsigned short) (i << 8); 
  164.   XStoreColor(gDisplay, color_map, &xcolor);
  165.        }
  166. /* this is the GC for handling the image */
  167.        mask = GCForeground | GCBackground | GCLineWidth | GCFunction;
  168.        gc_values.function = GXcopy;
  169.        gc_values.foreground = pixels[*c_map_size - 1];
  170.        gc_values.background = pixels[0];
  171.        gc_values.line_width = 2 ;
  172.        imageGC = XCreateGC(gDisplay, gWindow, mask, &gc_values);
  173. /* this is the GC for handling the points */
  174. if( alloc_color ) {
  175. hw_color.pixel = gc_values.foreground ;
  176. status = XAllocNamedColor(gDisplay, color_map, "red", 
  177. &hw_color, &rgb_color) ;
  178. gc_values.foreground = hw_color.pixel ;
  179. }
  180. pointGC = XCreateGC(gDisplay, gWindow, mask, &gc_values) ;
  181. XSetForeground(gDisplay, pointGC, (unsigned long) gc_values.foreground);
  182.    
  183. /* this is the GC for handling the line */
  184. if( alloc_color ) {
  185. hw_color.pixel = gc_values.foreground ;
  186. status = XAllocNamedColor(gDisplay, color_map, "green", 
  187. &hw_color, &rgb_color) ;
  188. gc_values.foreground = hw_color.pixel ;
  189. }
  190. rectGC = XCreateGC(gDisplay, gWindow, mask, &gc_values) ;
  191. XSetForeground(gDisplay, rectGC, (unsigned long) gc_values.foreground);
  192. }
  193. XImage *xwin_creatXimage(float *data, short height, short width, unsigned char magnify)
  194. {
  195. register short i, j, m, n ;
  196. unsigned char *box ;
  197. float *dptr ;
  198. float maxmag, minmag;
  199. double range ;
  200. int index ;
  201.    /*  Set up an image data structure for handling the image. */
  202. box = (unsigned char *) _iMemAlloc(sizeof(unsigned char) * 
  203. height * width * magnify * magnify) ;
  204. for(i=0, dptr=data, maxmag = minmag = *dptr ; i<height; i++)
  205.    for(j=0; j<width; j++, dptr++) {
  206.     maxmag = MAX(maxmag, *dptr);
  207.     minmag = MIN(minmag, *dptr);
  208.    }
  209. range = (maxmag - minmag)/0.9 ; /* use 90% of the range */
  210. /* put values in ximage data pointer */
  211. for (i = 0, dptr=data; i < height; ++i)
  212.             for (j = 0; j < width; ++j, ++dptr)  {
  213.             
  214. index = (int) ((double) c_map_size * (*dptr-minmag)/range);
  215.      for(m=0; m<magnify; m++)
  216.        for(n=0; n<magnify; n++) 
  217.         box[(i*magnify+m)*magnify*width + 
  218.              j*magnify + n] = pixels[index] ;
  219. }
  220. return XCreateImage(gDisplay, DefaultVisual(gDisplay, gScreen), 
  221.     (unsigned int) 8, ZPixmap, 0, (char *) box, 
  222.     width*magnify, magnify*height, 8,  
  223.     width*magnify);   
  224. }
  225. void xwin_drawImg(XImage *ximg, int xoffset, int yoffset)
  226. {
  227. XPutImage(gDisplay, gWindow, imageGC, ximg, 
  228. 0, 0, xoffset, yoffset, ximg->width, ximg->height) ;
  229. XFlush(gDisplay) ; 
  230. }
  231. void xwin_DrawLine( short x1, short y1, 
  232.     short x2, short y2, 
  233.     unsigned char blowup )
  234. {
  235. XDrawLine(gDisplay, gWindow, pointGC,
  236. blowup*x1, blowup*y1, blowup*x2, blowup*y2 );
  237. XFlush(gDisplay);
  238. }
  239. void xwin_DrawRect(int x1,int y1,int x2,int y2,int mag)
  240. {
  241. x1 = x1 * mag;
  242. y1 = y1 * mag;
  243. x2 = x2 * mag; 
  244. y2 = y2 * mag;
  245.         XDrawLine(gDisplay,gWindow,rectGC,x1,y1,x2,y1);
  246.         XDrawLine(gDisplay,gWindow,rectGC,x1,y1,x1,y2);
  247. XDrawLine(gDisplay,gWindow,rectGC,x2,y1,x2,y2);
  248. XDrawLine(gDisplay,gWindow,rectGC,x1,y2,x2,y2);
  249. XFlush(gDisplay);
  250. }
  251. void xwin_SelRegion( int *sx, int  *sy, int *length, int *height)
  252. {
  253.     int done =_FALSE;
  254. XEvent event;
  255. int x=0,y=0 ;
  256. *sx = *sy = *length = *height = 0;
  257. fprintf(stdout,"nn Left Button:click and Drag n");
  258. while (!done){
  259. XNextEvent(gDisplay, &event);
  260. switch (event.type){
  261. case ButtonPress:
  262. *sx = x = event.xbutton.x;
  263. *sy = y = event.xbutton.y;
  264. XSetFunction(gDisplay,rectGC,GXxor);
  265. break;
  266. case ButtonRelease:
  267. done = _TRUE;
  268. xwin_DrawRect(*sx,*sy,x,y,1);
  269. break;
  270. case MotionNotify:
  271. if (*sx)
  272. {
  273.    xwin_DrawRect(*sx,*sy,x,y,1); 
  274.    x = event.xbutton.x;
  275.    y = event.xbutton.y;
  276.    *length = abs(x-*sx);
  277.    *height = abs(y-*sy);
  278.    xwin_DrawRect(*sx,*sy,x,y,1);
  279. }
  280. break;
  281. }
  282. }
  283. if (x<*sx) *sx = x;
  284. if (y<*sy) *sy = y;
  285. }
  286. /* initialize the object by specifying significant points (drag) */
  287. void xwin_InitSnakeDrag( short *row, short *col,
  288.                         short *numpts, int spacing)
  289. {
  290.         int done = _FALSE ;
  291.         XEvent event ;
  292.         int x, y;
  293.         fprintf(stdout, "nn  Left Button : Drag, Right Button : Donenn");
  294.         while( !done ) {
  295.             XNextEvent(gDisplay, &event) ;
  296.             switch (event.type) {
  297.                 case ButtonPress :      /* initialize first point */
  298.                         *numpts = 0 ;
  299.                         *(col + *numpts) = event.xbutton.x ;
  300.                         *(row + *numpts) = event.xbutton.y ;
  301.                         XFillRectangle(gDisplay, gWindow, pointGC,
  302.                                         *(col + *numpts)+POINT_OFF,
  303.                                         *(row + *numpts)+POINT_OFF,
  304.                                         POINT_DIM, POINT_DIM) ;
  305.                         break ;
  306.                 case ButtonRelease :    /* done */
  307.                         done = _TRUE ;
  308.                         break ;
  309.                 case MotionNotify :    /* fill points at appropriate distance */                        x = event.xbutton.x ;
  310.                         y = event.xbutton.y ;
  311.                         if( MAX( abs(x-*(col+*numpts)), abs(y-*(row+*numpts)) )
  312.                                 >= spacing ) {
  313.                                 XFillRectangle(gDisplay, gWindow, pointGC,
  314.                                         x+POINT_OFF, y+POINT_OFF, 
  315. POINT_DIM, POINT_DIM) ;
  316.                                 *numpts += 1 ;
  317.                                 *(col + *numpts) = x ;
  318.                                 *(row + *numpts) = y ;
  319.                                 if( *numpts >= MAX_SNAKEPTS - 1 )
  320.                                         done = _TRUE ;
  321.                         }
  322.                         break ;
  323.                 }
  324.         }
  325. }
  326. /* ShapeContour allows manual adjustment of snaxel locations. Requires 
  327.    start of row and column data */
  328. short XgetVicinity(int x,int y, double *row, double *col,short numpts)
  329. {
  330.     short count=0;
  331.     
  332. while (count< numpts)
  333. {
  334. if ((y < *(row+count)+3) && (y > *(row+count)-3))
  335. if ((x < *(col+count)+3) && (x > *(col+count)-3))
  336. return count;
  337. count++;
  338. }
  339. return -1;     /* Chosen point is not near any snaxel */
  340. }
  341.    
  342. void xwin_ShapeContour(XImage *ximg,double *row, double *col,short numpts )
  343. {
  344. int done = _FALSE, end = _FALSE ;
  345.         XEvent event ;
  346.         int x, y,i;
  347.         int target= -1;
  348.         fprintf(stdout, "nn  Left Button : Drag, Right Button : Donenn");
  349.         while( !end ) {
  350.             XNextEvent(gDisplay, &event) ;
  351.             switch (event.type) {
  352.                 case ButtonPress :      /* initialize first point */
  353. if (event.xbutton.button !=Button1) 
  354. {
  355. end = _TRUE;
  356. XSetFunction(gDisplay,pointGC,GXcopy);
  357. }
  358. else
  359. {
  360. done = _FALSE;
  361. x= event.xbutton.x;
  362. y= event.xbutton.y;
  363.           target = XgetVicinity(x,y,row,col,numpts); 
  364.         
  365.                   }
  366.                         break ;
  367.                 case ButtonRelease :    /* done */
  368.                         done = _TRUE ;
  369.                         if (target != -1)    
  370.                            for (i=0;i<numpts;i++)
  371.                          XFillRectangle(gDisplay, gWindow, pointGC,
  372.                                  ROUNDOFF(*(col + i)),ROUNDOFF(*(row + i)),
  373. POINT_DIM, POINT_DIM);
  374.                         
  375.                         target = -1;
  376.                         break ;
  377.                 case MotionNotify :    /* fill points at appropriate distance*/
  378.                         if (target!=-1)
  379.                         {
  380.                                 XPutImage(gDisplay, gWindow, imageGC, ximg,
  381.                                    x-3,y-3,x-3,y-3,POINT_DIM+5,POINT_DIM+5);
  382.                                 XFlush(gDisplay) ;
  383.                                                       
  384.                                 x = event.xbutton.x;
  385.                                 y = event.xbutton.y;
  386.                                 XFillRectangle(gDisplay, gWindow, pointGC,
  387.                                         x, y, POINT_DIM, POINT_DIM) ;
  388.                                 *(col + target) = x ;
  389.                                 *(row + target) = y ;
  390. }
  391.                         break;
  392.                            
  393.                }
  394.         }
  395. }
  396. /* initialize the object by specifying significant points (click) */
  397. void xwin_InitSnakeClick( short *row, short *col,
  398.                         short *numpts)
  399. {
  400.         BOOLEAN done = _FALSE;
  401.         XEvent event;
  402.         fprintf(stdout, "nn  Left Button : Click, Right Button : Donenn");
  403.         *numpts = 0;
  404.         while( !done ) {
  405.                 XNextEvent(gDisplay, &event) ;
  406.                 if(event.type != ButtonPress) /* only wait for button event */
  407.                         continue ;
  408.                 if(event.xbutton.button != Button1)  /* exit button pressed */
  409.                         done = _TRUE ;
  410.                 else {
  411.                         *(col + *numpts) = event.xbutton.x ;
  412.                         *(row + *numpts) = event.xbutton.y ;
  413.                         XFillRectangle(gDisplay, gWindow, pointGC,
  414.                                 *(col + *numpts)+POINT_OFF,
  415.                                 *(row + *numpts)+POINT_OFF,
  416.                                 POINT_DIM, POINT_DIM);
  417.                         *numpts += 1;
  418.                 }
  419.         }
  420. }
  421. int xwin_MovePoint(XImage *ximg, short Xsrc, short Ysrc,
  422. short Xdest, short Ydest,
  423.    int pt_offx, int pt_offy)
  424. {
  425.         XPutImage(gDisplay, gWindow, imageGC, ximg,
  426.                 ci_expand*Xsrc, ci_expand*Ysrc, 
  427. ci_expand*(Xsrc+pt_offx)+POINT_OFF, 
  428. ci_expand*(Ysrc+pt_offy)+POINT_OFF, 
  429. POINT_DIM, POINT_DIM) ; 
  430.         XFillRectangle(gDisplay, gWindow, pointGC,
  431. ci_expand*(Xdest+pt_offx)+POINT_OFF, 
  432. ci_expand*(Ydest+pt_offy)+POINT_OFF, 
  433. POINT_DIM, POINT_DIM) ;
  434.         XFlush(gDisplay) ;
  435.         return ( (XCheckTypedWindowEvent(gDisplay, gWindow, ButtonPress,
  436.                         &any_event) == True) ? _FALSE : _TRUE ) ;
  437. }
  438.  
  439. /* set expand ration */
  440. void xwin_setexpandratio(short expand,
  441.  unsigned char blowup )
  442. {
  443.         ci_expand = (int)expand *(int)blowup;
  444. POINT_OFF = -(POINT_DIM/2 - (blowup+1)/2) ;
  445. }
  446. void xwin_DrawPoint( short row, short col )
  447. {
  448.  XFillRectangle(gDisplay, gWindow, pointGC,
  449. ci_expand*col+POINT_OFF,
  450. ci_expand*row+POINT_OFF,
  451. POINT_DIM, POINT_DIM) ;
  452.  XFlush(gDisplay) ;
  453. }
  454. void xwin_clrpoint( XImage *ximg, short col, short row )
  455. {
  456. XPutImage(gDisplay, gWindow, imageGC, ximg,
  457.                 ci_expand*col, ci_expand*row, 
  458. ci_expand*col, ci_expand*row, 
  459. POINT_DIM, POINT_DIM) ;
  460. }