home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d386 / xlispstat.lha / XLispStat / src3.lzh / UNIX / X11resizebr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-30  |  8.9 KB  |  289 lines

  1. /* X11resizebr - brush resizing dialog for X11                         */
  2. /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney                  */
  3. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  4. /* You may give out copies of this software; for conditions see the    */
  5. /* file COPYING included with this distribution.                       */
  6.  
  7. /***********************************************************************/
  8. /**                                                                   **/
  9. /**                    General Includes and Definitions               **/
  10. /**                                                                   **/
  11. /***********************************************************************/
  12.  
  13. #include <stdio.h>
  14.  
  15. #include <X11/Xlib.h>
  16. #include <X11/Xutil.h>
  17. #include <X11/Xos.h>
  18.  
  19. extern Display *StX11Display();
  20.  
  21. #define TRUE 1
  22. #define FALSE 0
  23. #define nil 0L
  24.  
  25. typedef struct {
  26.   unsigned long fore, back;
  27. } ColorPair;
  28.  
  29. /***********************************************************************/
  30. /**                                                                   **/
  31. /**                        Global Variables                           **/
  32. /**                                                                   **/
  33. /***********************************************************************/
  34.  
  35. #define WindowWidth 250
  36. #define WindowHeight 200
  37.  
  38. static char ResizeMessage1[] = "To resize brush click in";
  39. static char ResizeMessage2[] = "this window and drag";
  40. static char OK_String[] = "OK";
  41. static char CANCEL_String[] = "Cancel";
  42.  
  43. /* configuration parameters - should be set using the defaults database */
  44. extern XFontStruct *DialogFont;
  45. extern unsigned long DialogBorderColor, ButtonBorderColor;
  46. extern ColorPair DialogC, ButtonC;
  47. extern unsigned int dialog_border_width, button_border_width;
  48. extern int min_button_height, min_button_width, dialog_item_gap;
  49.  
  50. extern GC DialogGC, ResizeGC;
  51. extern Cursor ArrowCursor;
  52.  
  53. /***********************************************************************/
  54. /**                                                                   **/
  55. /**                    Resize Brush Dialog Function                   **/
  56. /**                                                                   **/
  57. /***********************************************************************/
  58.  
  59. IViewGetNewBrushSize(w, new_width, new_height)
  60.      caddr_t w;
  61.      int *new_width, *new_height;
  62. {
  63.   Window win, ok_win, cancel_win;
  64.   unsigned int width = WindowWidth, height = WindowHeight;
  65.   int left, top;
  66.   XSetWindowAttributes setwinattr;
  67.   unsigned long valuemask;
  68.   XEvent report;
  69.   int done = FALSE;
  70.   Display *dpy = StX11Display();
  71.   int screen = StX11Screen();
  72.   int brush_width, brush_height;
  73.   int cancelled = FALSE;
  74.   
  75.   /* create opaque dialog window */
  76.   left = (DisplayWidth(dpy, screen) - WindowWidth) / 2;
  77.   top = (DisplayHeight(dpy, screen) - WindowHeight) / 3;
  78.   win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
  79.                 left, top, width, height, dialog_border_width,
  80.                 DialogBorderColor, DialogC.back);
  81.  
  82.   /* set the override_redirect and save_under attributes for a dialog */
  83.   valuemask = CWOverrideRedirect | CWSaveUnder;
  84.   setwinattr.override_redirect = TRUE;
  85.   setwinattr.save_under = TRUE;
  86.   XChangeWindowAttributes(dpy, win, valuemask, &setwinattr);
  87.   XSelectInput(dpy, win, ExposureMask | ButtonPressMask | ButtonMotionMask);
  88.  
  89.   /* make the buttons */
  90.   ok_win = XCreateSimpleWindow(dpy, win, 
  91.                    dialog_item_gap, 
  92.                    WindowHeight - dialog_item_gap
  93.                    - min_button_height,
  94.                    min_button_width, min_button_height, 
  95.                    button_border_width,
  96.                    ButtonBorderColor, ButtonC.back);
  97.   XSelectInput(dpy, ok_win,
  98.            ExposureMask | EnterWindowMask |
  99.            LeaveWindowMask | ButtonPressMask | ButtonReleaseMask);
  100.   cancel_win = XCreateSimpleWindow(dpy, win, 
  101.                    WindowWidth - min_button_width 
  102.                    - dialog_item_gap, 
  103.                    WindowHeight - dialog_item_gap
  104.                    - min_button_height,
  105.                    min_button_width, min_button_height, 
  106.                    button_border_width,
  107.                    ButtonBorderColor, ButtonC.back);
  108.   XSelectInput(dpy, cancel_win,
  109.            ExposureMask | EnterWindowMask |
  110.            LeaveWindowMask | ButtonPressMask | ButtonReleaseMask);
  111.  
  112.   /* set the cursor */
  113.   XDefineCursor(dpy, win, ArrowCursor);
  114.  
  115.   /* Display (map) the windows */
  116.   XMapSubwindows(dpy, win);
  117.   XMapWindow(dpy, win);
  118.  
  119.   /* grap the pointer */
  120.   StX11ReleaseButton();
  121.   XGrabPointer(dpy, win, TRUE, 
  122.            ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
  123.            GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
  124.  
  125.   /* Loop until button is released, examining each event */
  126.   brush_width = 0;
  127.   brush_height = 0;
  128.   while (! done) {
  129.     XNextEvent(dpy, &report);
  130.     switch (report.type) {
  131.     case Expose:
  132.       if (report.xexpose.window == win) {
  133.     draw_dialog(win);
  134.       }
  135.       else if (report.xexpose.window == ok_win)
  136.     draw_button(ok_win, OK_String);
  137.       else if (report.xexpose.window == cancel_win)
  138.     draw_button(cancel_win, CANCEL_String);
  139.       else StProcessEvent(dpy, report);
  140.       break;
  141.     case ButtonPress:
  142.       if (report.xbutton.window == win)
  143.     drag_brush(report, &brush_width, &brush_height);
  144.       break;
  145.     case ButtonRelease:
  146.       if (report.xbutton.window == ok_win 
  147.       || report.xbutton.window == cancel_win) {
  148.     if (report.xbutton.window == cancel_win) cancelled = TRUE;
  149.     done = TRUE;
  150.       }
  151.       break;
  152.     case EnterNotify:
  153.       if (report.xcrossing.window == ok_win)
  154.     XSetWindowBorderWidth(dpy, ok_win, button_border_width + 1);
  155.       else if (report.xcrossing.window == cancel_win)
  156.     XSetWindowBorderWidth(dpy, cancel_win, button_border_width + 1);
  157.       break;
  158.     case LeaveNotify:
  159.       if (report.xcrossing.window == ok_win)
  160.     XSetWindowBorderWidth(dpy, ok_win, button_border_width);
  161.       else if (report.xcrossing.window == cancel_win)
  162.     XSetWindowBorderWidth(dpy, cancel_win, button_border_width);
  163.       break;
  164.     default:
  165.       break;
  166.     }
  167.   }
  168.  
  169.   /* clean up */
  170.   XDestroyWindow(dpy, win);
  171.   XFlush(dpy);
  172.  
  173.   if (new_width != nil) *new_width = brush_width;
  174.   if (new_height != nil) *new_height = brush_height;
  175.   return(! cancelled);
  176. }
  177.  
  178. static draw_dialog(win) 
  179.      Window win;
  180. {
  181.   int font_height, margin, x, y, len, text_width;
  182.   GC gc;
  183.   Display *dpy = StX11Display();
  184.   char *text;
  185.  
  186.   font_height = DialogFont->max_bounds.ascent
  187.               + DialogFont->max_bounds.descent;
  188.   margin = DialogFont->max_bounds.descent / 2;
  189.  
  190.   gc = DialogGC;
  191.  
  192.   text = ResizeMessage1;
  193.   len = strlen(text);
  194.   text_width = XTextWidth(DialogFont, text, len);
  195.   x = (WindowWidth - text_width) / 2;
  196.   y = DialogFont->max_bounds.ascent + margin;
  197.   XDrawString(dpy, win, gc, x, y, text, len);      
  198.  
  199.   text = ResizeMessage2;
  200.   len = strlen(text);
  201.   text_width = XTextWidth(DialogFont, text, len);
  202.   x = (WindowWidth - text_width) / 2;
  203.   y = 2 * y;
  204.   XDrawString(dpy, win, gc, x, y, text, len);      
  205. }
  206.  
  207. static draw_button(win, text)
  208.      Window win;
  209.      char *text;
  210. {
  211.   int font_height, x, y, len, text_width;
  212.   GC gc;
  213.   Display *dpy = StX11Display();
  214.   
  215.   len = strlen(text);
  216.   text_width = XTextWidth(DialogFont, text, len);
  217.  
  218.   font_height = DialogFont->max_bounds.ascent
  219.               + DialogFont->max_bounds.descent;
  220.  
  221.   x = (min_button_width - text_width) / 2;
  222.   y = DialogFont->max_bounds.ascent + (min_button_height - font_height) / 2; 
  223.   
  224.   gc = DialogGC;
  225.   XDrawString(dpy, win, gc, x, y, text, len);    
  226. }
  227.  
  228. static drag_brush(report, pwidth, pheight)
  229.      XEvent report;
  230.      int *pwidth, *pheight;
  231. {
  232.   Window win = report.xbutton.window, child;
  233.   Display *dpy = StX11Display();
  234.   int done = FALSE, newx, newy;
  235.   int xinit = report.xbutton.x, yinit = report.xbutton.y, x = xinit, y = yinit;
  236.   GC gc = ResizeGC;
  237.   
  238.   XDrawRectangle(dpy, win, gc, xinit, yinit, 0, 0); /* to draw */
  239.  
  240.   /* Loop until button is released, examining each event */
  241.   while (! done) {
  242.     XNextEvent(dpy, &report);
  243.     switch (report.type) {
  244.     case MotionNotify:
  245.       if (win == report.xmotion.window) {
  246.     newx = report.xmotion.x;
  247.     newy = report.xmotion.y;
  248.       }
  249.       else {
  250.     XTranslateCoordinates(dpy, report.xmotion.window, win,
  251.                   report.xmotion.x, report.xmotion.y, &newx, &newy,
  252.                   &child);
  253.       }
  254.       XDrawRectangle(dpy, win, gc, 
  255.              (xinit < x) ? xinit : x,
  256.              (yinit < y) ? yinit : y, 
  257.              (xinit < x) ? x - xinit : xinit - x, 
  258.              (yinit < y) ? y - yinit : yinit - y); /* to erase */
  259.       x = newx;
  260.       y = newy;
  261.       XDrawRectangle(dpy, win, gc, 
  262.              (xinit < x) ? xinit : x,
  263.              (yinit < y) ? yinit : y, 
  264.              (xinit < x) ? x - xinit : xinit - x, 
  265.              (yinit < y) ? y - yinit : yinit - y); /* to draw */
  266.       break;
  267.     case ButtonRelease:
  268.       done = TRUE;
  269.       break;
  270.     default:
  271.       break;
  272.     }
  273.   }
  274.  
  275.   XDrawRectangle(dpy, win, gc, 
  276.          (xinit < x) ? xinit : x,
  277.          (yinit < y) ? yinit : y, 
  278.          (xinit < x) ? x - xinit : xinit - x, 
  279.          (yinit < y) ? y - yinit : yinit - y); /* to erase */
  280.  
  281.   *pwidth = (x < xinit) ? xinit - x : x - xinit;
  282.   *pheight = (y < yinit) ? yinit - y : y - yinit;
  283. }
  284.  
  285. #ifdef TODO
  286. try to leave brush up after it has been set
  287. use dashed lines
  288. #endif TODO
  289.