home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-247 / paintevent.c < prev    next >
C/C++ Source or Header  |  1996-06-25  |  8KB  |  307 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. /* $Id: PaintEvent.c,v 1.2 1996/04/15 14:21:49 torsten Exp $ */
  16.  
  17. #include <X11/IntrinsicP.h>
  18. #include "PaintP.h"
  19. #include "xpaint.h"
  20.  
  21. typedef void (*func_t) (Widget, void *, XEvent *, OpInfo *);
  22.  
  23. typedef struct data_s {
  24.     Widget w;
  25.     func_t func;
  26.     void *data;
  27.     int mask, flag;
  28.     int surfMask;
  29.     struct data_s *next;
  30.     OpInfo *info;
  31. } data_t;
  32.  
  33. static data_t *list = NULL;
  34.  
  35. #if 0
  36. static data_t **
  37. widgetEvent(Widget w, data_t * look)
  38. {
  39.     static data_t *d[10];
  40.     data_t *cur = list;
  41.     int n = 0;
  42.  
  43.     while (cur != NULL) {
  44.     if (cur->mask == look->mask &&
  45.         cur->flag == look->flag &&
  46.         cur->func == look->func &&
  47.         cur->w == w)
  48.         d[n++] = cur;
  49.     cur = cur->next;
  50.     }
  51.  
  52.     d[n] = NULL;
  53.  
  54.     return n == 0 ? NULL : d;
  55. }
  56. #endif
  57.  
  58. static void 
  59. opHandleEvent(Widget w, XtPointer dataArg, XEvent * event, Boolean * junk)
  60. {
  61.     data_t *data = (data_t *) dataArg;
  62.     int snap, t;
  63.     PaintWidget paint = (PaintWidget) w;
  64.     OpInfo *info = data->info;
  65.     static Window lastWindow = None;
  66.     static Display *lastDisplay = None;
  67.     static int lastType;
  68.     static int lastX, lastY;
  69.     Boolean same;
  70.     int zoom;
  71.  
  72. #if 0
  73.     XEvent myEvent;
  74.  
  75.     memcpy(&myEvent, event, sizeof(XEvent));
  76.     event = &myEvent;
  77. #endif
  78.  
  79.     /*
  80.     **  Figure out if there is a snap, either by
  81.     **   choice or by zooming
  82.      */
  83.     if ((info->zoom = GET_ZOOM(paint)) == 0)
  84.     info->zoom = 1;
  85.     if ((info->isFat = ((zoom = GET_ZOOM(paint)) > 1)))
  86.     snap = GET_ZOOM(paint);
  87.     else if (paint->paint.snapOn)
  88.     snap = paint->paint.snap;
  89.     else
  90.     snap = 1;
  91.  
  92.     same = (event->xany.window == lastWindow) &&
  93.     (event->xany.display == lastDisplay) &&
  94.     (event->xany.type == lastType);
  95.     lastWindow = event->xany.window;
  96.     lastDisplay = event->xany.display;
  97.     lastType = event->xany.type;
  98.  
  99.     /*
  100.     **  Snap events to the snap
  101.      */
  102.     if (event->type == ButtonPress || event->type == ButtonRelease) {
  103.     info->realX = event->xbutton.x;
  104.     info->realY = event->xbutton.y;
  105.     } else if (event->type == MotionNotify) {
  106.     info->realX = event->xmotion.x;
  107.     info->realY = event->xmotion.y;
  108.     }
  109.     if (((event->type == ButtonPress) ||
  110.      (event->type == ButtonRelease) ||
  111.      (event->type == MotionNotify)) && snap > 1) {
  112.     switch (event->type) {
  113.     case ButtonPress:
  114.     case ButtonRelease:
  115. #ifdef TRUNC_SNAP
  116.         event->xbutton.x = event->xbutton.x -
  117.         (event->xbutton.x % snap);
  118.         event->xbutton.y = event->xbutton.y -
  119.         (event->xbutton.y % snap);
  120. #else
  121.         t = event->xbutton.x;
  122.         t = t / snap * snap;
  123.         if (event->xbutton.x - t > snap / 2)
  124.         t += snap;
  125.         event->xbutton.x = t;
  126.         t = event->xbutton.y;
  127.         t = t / snap * snap;
  128.         if (event->xbutton.y - t > snap / 2)
  129.         t += snap;
  130.         event->xbutton.y = t;
  131. #endif
  132.         if (same && lastX == event->xbutton.x && lastY == event->xbutton.y)
  133.         return;
  134.         break;
  135.     case MotionNotify:
  136. #ifdef TRUNC_SNAP
  137.         event->xmotion.x = event->xmotion.x -
  138.         (event->xmotion.x % snap);
  139.         event->xmotion.y = event->xmotion.y -
  140.         (event->xmotion.y % snap);
  141. #else
  142.         t = event->xbutton.x;
  143.         t = t / snap * snap;
  144.         if (event->xbutton.x - t > snap / 2)
  145.         t += snap;
  146.         event->xbutton.x = t;
  147.         t = event->xbutton.y;
  148.         t = t / snap * snap;
  149.         if (event->xbutton.y - t > snap / 2)
  150.         t += snap;
  151.         event->xbutton.y = t;
  152. #endif
  153.         if (same && lastX == event->xmotion.x && lastY == event->xmotion.y)
  154.         return;
  155.         break;
  156.     }
  157.     lastX = event->xmotion.x;
  158.     lastY = event->xmotion.y;
  159.     } else {
  160.     lastX = lastY = -1;
  161.     }
  162.  
  163.     if (event->type == MotionNotify) {
  164.     info->x = (event->xmotion.x / zoom) + paint->paint.zoomX;
  165.     info->y = (event->xmotion.y / zoom) + paint->paint.zoomY;
  166.     } else if (event->type == ButtonPress || event->type == ButtonRelease) {
  167.     info->x = (event->xbutton.x / zoom) + paint->paint.zoomX;
  168.     info->y = (event->xbutton.y / zoom) + paint->paint.zoomY;
  169.     }
  170.     /*
  171.     **  In fatbits we can't tell the difference 
  172.     **   between snapping and fat bits.
  173.      */
  174.     if (info->isFat) {
  175.     info->realX = info->x;
  176.     info->realY = info->y;
  177.     } else {
  178.     info->realX = info->realX + paint->paint.zoomX;
  179.     info->realY = info->realY + paint->paint.zoomY;
  180.     }
  181.  
  182.     /*
  183.     **  If this is button down, save it for reference
  184.      */
  185.     if (event->type == ButtonPress) {
  186.     paint->paint.downX = info->realX;
  187.     paint->paint.downY = info->realY;
  188.     }
  189.     if (paint->paint.paint != None) {
  190.     PaintWidget pw = (PaintWidget) paint->paint.paint;
  191.     info->base = pw->paint.sourcePixmap;
  192.     } else {
  193.     info->base = paint->paint.sourcePixmap;
  194.     }
  195.  
  196.     if (data->surfMask & opWindow) {
  197.     int z = GET_ZOOM(paint) / 2;
  198.  
  199.     if (z != 0) {
  200.         if (event->type == MotionNotify) {
  201.         event->xmotion.x += z;
  202.         event->xmotion.y += z;
  203.         } else if (event->type == ButtonPress || event->type == ButtonRelease) {
  204.         event->xbutton.x += z;
  205.         event->xbutton.y += z;
  206.         }
  207.     }
  208.     info->surface = opWindow;
  209.     info->drawable = event->xany.window;
  210.     data->func(w, data->data, event, info);
  211.     }
  212.     if (event->type == MotionNotify) {
  213.     event->xmotion.x = info->x;
  214.     event->xmotion.y = info->y;
  215.     } else if (event->type == ButtonPress || event->type == ButtonRelease) {
  216.     event->xbutton.x = info->x;
  217.     event->xbutton.y = info->y;
  218.     }
  219.     if (data->surfMask & opPixmap) {
  220.     info->surface = opPixmap;
  221.     info->drawable = GET_PIXMAP(paint);
  222.     data->func(w, data->data, event, info);
  223.     }
  224. }
  225.  
  226. void 
  227. OpAddEventHandler(Widget w, int surfMask, int mask, Boolean flag,
  228.        void (*func) (Widget, void *, XEvent *, OpInfo *), void *data)
  229. {
  230.     PaintWidget paint = (PaintWidget) w;
  231.     PaintWidget pp = (PaintWidget) paint->paint.paint;
  232.     data_t *new = (data_t *) XtMalloc(sizeof(data_t));
  233.     OpInfo *info;
  234.  
  235.     if (new == NULL)
  236.     return;
  237.  
  238.     new->w = w;
  239.     new->func = func;
  240.     new->data = data;
  241.     new->mask = mask;
  242.     new->flag = flag;
  243.     new->surfMask = surfMask;
  244.  
  245.     info = new->info = (OpInfo *) XtMalloc(sizeof(OpInfo));
  246.     info->refCount = 1;
  247.     info->realX = 0;
  248.     info->realY = 0;
  249.  
  250.     /*
  251.     **  Now build the approprate info structure
  252.      */
  253.     if (pp == None) {
  254.     /*
  255.     ** If this is a paint widget, this is easy
  256.      */
  257.     info->first_gc = paint->paint.fgc;
  258.     info->second_gc = paint->paint.sgc;
  259.     info->base_gc = paint->paint.igc;
  260.     } else {
  261.     /*
  262.     ** For a fatbits paint widget get paint information
  263.      */
  264.     info->first_gc = pp->paint.fgc;
  265.     info->second_gc = pp->paint.sgc;
  266.     info->base_gc = pp->paint.igc;
  267.     }
  268.  
  269.     new->next = list;
  270.     list = new;
  271.  
  272.     XtAddEventHandler(w, mask, flag, opHandleEvent, (XtPointer) new);
  273. }
  274.  
  275. void 
  276. OpRemoveEventHandler(Widget w, int surfMask, int mask, Boolean flag,
  277.        void (*func) (Widget, void *, XEvent *, OpInfo *), void *data)
  278. {
  279.     data_t *cur = list;
  280.     data_t **prev = &list;
  281.  
  282.     while (cur != NULL) {
  283.     if (cur->w == w &&
  284.         cur->data == data &&
  285.         cur->mask == mask &&
  286.         cur->flag == flag &&
  287.         cur->surfMask == surfMask &&
  288.         cur->func == func)
  289.         break;
  290.     prev = &cur->next;
  291.     cur = cur->next;
  292.     }
  293.  
  294.     if (cur == NULL)
  295.     return;
  296.  
  297.     XtRemoveEventHandler(w, mask, flag, opHandleEvent, (XtPointer) cur);
  298.  
  299.     *prev = cur->next;
  300.  
  301.     cur->info->refCount--;
  302.     if (cur->info->refCount == 0)
  303.     XtFree((XtPointer) cur->info);
  304.  
  305.     XtFree((XtPointer) cur);
  306. }
  307.