home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / bitmap / Bitmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-24  |  48.0 KB  |  1,909 lines

  1. /*
  2.  * $XConsortium: Bitmap.c,v 1.38 91/07/24 15:46:52 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Davor Matic, MIT X Consortium
  24.  */
  25.  
  26. #include <X11/IntrinsicP.h>
  27. #include <X11/StringDefs.h>
  28. #include <X11/Xaw/XawInit.h>
  29. #include <X11/Xmu/CharSet.h>
  30. #include <X11/Xmu/Drawing.h>
  31. #include <X11/Xatom.h>
  32. #include <X11/Xfuncs.h>
  33. #include <X11/Xos.h>
  34. #include "BitmapP.h"
  35.     
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <math.h>
  39.  
  40. #ifndef abs
  41. #define abs(x)                        ((((int)(x)) > 0) ? (x) : -(x))
  42. #endif
  43. #define min(x, y)                     ((((int)(x)) < (int)(y)) ? (x) : (y))
  44. #define max(x, y)                     ((((int)(x)) > (int)(y)) ? (x) : (y))
  45.  
  46. Boolean DEBUG;
  47.  
  48. #define DefaultGridTolerance 8
  49. #define DefaultBitmapSize    "16x16"
  50. #define FallbackBitmapWidth  16
  51. #define FallbackBitmapHeight 16
  52. #define DefaultGrid          TRUE
  53. #define DefaultDashed        TRUE
  54. #define DefaultStippled      TRUE
  55. #define DefaultProportional  TRUE
  56. #define DefaultAxes          FALSE
  57. #define DefaultMargin        16
  58. #define DefaultSquareWidth   16
  59. #define DefaultSquareHeight  16
  60. #define DefaultFilename      ""
  61.  
  62. #define Offset(field) XtOffsetOf(BitmapRec, bitmap.field)
  63.  
  64. static XtResource resources[] = {
  65. {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  66.      Offset(foreground_pixel), XtRString, XtDefaultForeground},
  67. {XtNhighlight, XtCHighlight, XtRPixel, sizeof(Pixel),
  68.      Offset(highlight_pixel), XtRString, XtDefaultForeground},
  69. {XtNframe, XtCFrame, XtRPixel, sizeof(Pixel),
  70.      Offset(frame_pixel), XtRString, XtDefaultForeground},
  71. {XtNgridTolerance, XtCGridTolerance, XtRDimension, sizeof(Dimension),
  72.      Offset(grid_tolerance), XtRImmediate, (XtPointer) DefaultGridTolerance},
  73. {XtNsize, XtCSize, XtRString, sizeof(String),
  74.      Offset(size), XtRImmediate, (XtPointer) DefaultBitmapSize},
  75. {XtNdashed, XtCDashed, XtRBoolean, sizeof(Boolean),
  76.      Offset(dashed), XtRImmediate, (XtPointer) DefaultDashed},
  77. {XtNgrid, XtCGrid, XtRBoolean, sizeof(Boolean),
  78.      Offset(grid), XtRImmediate, (XtPointer) DefaultGrid},
  79. {XtNstippled, XtCStippled, XtRBoolean, sizeof(Boolean),
  80.      Offset(stippled), XtRImmediate, (XtPointer) DefaultStippled},
  81. {XtNproportional, XtCProportional, XtRBoolean, sizeof(Boolean),
  82.      Offset(proportional), XtRImmediate, (XtPointer) DefaultProportional},
  83. {XtNaxes, XtCAxes, XtRBoolean, sizeof(Boolean),
  84.      Offset(axes), XtRImmediate, (XtPointer) DefaultAxes},
  85. {XtNsquareWidth, XtCSquareWidth, XtRDimension, sizeof(Dimension),
  86.      Offset(squareW), XtRImmediate, (XtPointer) DefaultSquareWidth},
  87. {XtNsquareHeight, XtCSquareHeight, XtRDimension, sizeof(Dimension),
  88.      Offset(squareH), XtRImmediate, (XtPointer) DefaultSquareHeight},
  89. {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension),
  90.      Offset(margin), XtRImmediate, (XtPointer) DefaultMargin},
  91. {XtNxHot, XtCXHot, XtRPosition, sizeof(Position),
  92.      Offset(hot.x), XtRImmediate, (XtPointer) NotSet},
  93. {XtNyHot, XtCYHot, XtRPosition, sizeof(Position),
  94.      Offset(hot.y), XtRImmediate, (XtPointer) NotSet},
  95. {XtNbutton1Function, XtCButton1Function, XtRButtonFunction, sizeof(int),
  96.      Offset(button_function[0]), XtRImmediate, (XtPointer) Set},
  97. {XtNbutton2Function, XtCButton2Function, XtRButtonFunction, sizeof(int),
  98.      Offset(button_function[1]), XtRImmediate, (XtPointer) Invert},
  99. {XtNbutton3Function, XtCButton3Function, XtRButtonFunction, sizeof(int),
  100.      Offset(button_function[2]), XtRImmediate, (XtPointer) Clear},
  101. {XtNbutton4Function, XtCButton4Function, XtRButtonFunction, sizeof(int),
  102.      Offset(button_function[3]), XtRImmediate, (XtPointer) Clear},
  103. {XtNbutton5Function, XtCButton5Function, XtRButtonFunction, sizeof(int),
  104.      Offset(button_function[4]), XtRImmediate, (XtPointer) Clear},
  105. {XtNfilename, XtCFilename, XtRString, sizeof(String),
  106.      Offset(filename), XtRImmediate, (XtPointer) DefaultFilename},
  107. {XtNbasename, XtCBasename, XtRString, sizeof(String),
  108.      Offset(basename), XtRImmediate, (XtPointer) DefaultFilename},
  109. {XtNdashes, XtCDashes, XtRBitmap, sizeof(Pixmap),
  110.      Offset(dashes), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
  111. {XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap),
  112.      Offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
  113. };
  114. #undef Offset
  115.  
  116. void BWDebug();
  117. void BWChangeNotify();
  118. void BWSetChanged();
  119. void BWAbort();
  120. void BWUp();
  121. void BWDown();
  122. void BWLeft();
  123. void BWRight();
  124. void BWFold();
  125. void BWFlipHoriz();
  126. void BWFlipVert();
  127. void BWRotateRight();
  128. void BWRotateLeft();
  129. void BWSet();
  130. void BWClear();
  131. void BWInvert();
  132. void BWUndo();
  133. void BWRedraw();
  134. void BWTMark();
  135. void BWTMarkAll();
  136. void BWTUnmark();
  137. void BWTPaste();
  138.  
  139. static XtActionsRec actions[] =
  140. {
  141. {"mark",               BWTMark},
  142. {"mark-all",           BWTMarkAll},
  143. {"unmark",             BWTUnmark},
  144. {"paste",              BWTPaste},
  145. {"bw-debug",           BWDebug},
  146. {"abort",              BWAbort},
  147. {"store-to-buffer",    BWStoreToBuffer},
  148. {"change-notify",      BWChangeNotify},
  149. {"set-changed",        BWSetChanged},
  150. {"up",                 BWUp},
  151. {"down",               BWDown},
  152. {"left",               BWLeft},
  153. {"right",              BWRight},
  154. {"fold",               BWFold},
  155. {"flip-horiz",         BWFlipHoriz},
  156. {"flip-vert",          BWFlipVert},
  157. {"rotate-right",       BWRotateRight},
  158. {"rotate-left",        BWRotateLeft},
  159. {"set",                BWSet},
  160. {"clear",              BWClear},
  161. {"invert",             BWInvert},
  162. {"undo",               BWUndo},
  163. {"redraw",             BWRedraw},
  164. };
  165.  
  166. static char translations1[] =
  167. "\
  168. Shift<Btn1Down>: mark()\n\
  169. Shift<Btn2Down>: mark-all()\n\
  170. Shift<Btn3Down>: unmark()\n\
  171. Ctrl<BtnDown>:   paste()\n\
  172. Ctrl<Key>l: redraw()\n\
  173. <Key>d:     bw-debug()\n\
  174. <Key>a:     abort()\n\
  175. <Key>Up:    store-to-buffer()\
  176.             up()\
  177.             change-notify()\
  178.             set-changed()\n\
  179. <Key>Down:  store-to-buffer()\
  180.             down()\
  181.             change-notify()\
  182.             set-changed()\n\
  183. <Key>Left:  store-to-buffer()\
  184.             left()\
  185.             change-notify()\
  186.             set-changed()\n\
  187. <Key>Right: store-to-buffer()\
  188.             right()\
  189.             change-notify()\
  190.             set-changed()\n\
  191. <Key>f:     store-to-buffer()\
  192.             fold()\
  193.             change-notify()\
  194.             set-changed()\n\
  195. <Key>h:     store-to-buffer()\
  196.             flip-horiz()\
  197.             change-notify()\
  198.             set-changed()\n\
  199. ";
  200.  
  201. static char translations2[] =
  202. "<Key>v:     store-to-buffer()\
  203.             flip-vert()\
  204.             change-notify()\
  205.             set-changed()\n\
  206. <Key>r:     store-to-buffer()\
  207.             rotate-right()\
  208.             change-notify()\
  209.             set-changed()\n\
  210. <Key>l:     store-to-buffer()\
  211.             rotate-left()\
  212.             change-notify()\
  213.             set-changed()\n\
  214. <Key>s:     store-to-buffer()\
  215.             set()\
  216.             change-notify()\
  217.             set-changed()\n\
  218. <Key>c:     store-to-buffer()\
  219.             clear()\
  220.             change-notify()\
  221.             set-changed()\n\
  222. <Key>i:     store-to-buffer()\
  223.             invert()\
  224.             change-notify()\
  225.             set-changed()\n\
  226. <Key>u:     undo()\
  227.             change-notify()\
  228.             set-changed()\n\
  229. ";
  230.  
  231. Atom targets[] = {
  232.     XA_BITMAP,
  233.     XA_PIXMAP
  234. };
  235.  
  236. #include "Requests.h"
  237.  
  238. static void ClassInitialize();
  239. static void Initialize();
  240. static void Redisplay();
  241. static void Resize();
  242. static void Destroy();
  243. static Boolean SetValues();
  244.  
  245. BitmapClassRec bitmapClassRec = {
  246. {   /* core fields */
  247.     /* superclass        */    (WidgetClass) &simpleClassRec,
  248.     /* class_name        */    "Bitmap",
  249.     /* widget_size        */    sizeof(BitmapRec),
  250.     /* class_initialize        */    ClassInitialize,
  251.     /* class_part_initialize    */    NULL,
  252.     /* class_inited        */    FALSE,
  253.     /* initialize        */    Initialize,
  254.     /* initialize_hook        */    NULL,
  255.     /* realize            */    XtInheritRealize,
  256.     /* actions            */    actions,
  257.     /* num_actions        */    XtNumber(actions),
  258.     /* resources        */    resources,
  259.     /* num_resources        */    XtNumber(resources),
  260.     /* xrm_class        */    NULLQUARK,
  261.     /* compress_motion        */    TRUE,
  262.     /* compress_exposure    */    FALSE,
  263.     /* compress_enterleave    */    TRUE,
  264.     /* visible_interest        */    TRUE,
  265.     /* destroy            */    Destroy,
  266.     /* resize            */    Resize,
  267.     /* expose            */    Redisplay,
  268.     /* set_values        */    SetValues,
  269.     /* set_values_hook        */    NULL,
  270.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  271.     /* get_values_hook        */    NULL,
  272.     /* accept_focus        */    NULL,
  273.     /* version            */    XtVersion,
  274.     /* callback_private        */    NULL,
  275.     /* tm_table            */    NULL , /* set in code */
  276.     /* query_geometry        */    XtInheritQueryGeometry,
  277.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  278.     /* extension        */    NULL,
  279.   },
  280.   { 
  281.     /* empty            */    XtInheritChangeSensitive,
  282.   },
  283.   {
  284.     /* targets                  */      targets,
  285.     /* num_trets                */      XtNumber(targets),
  286.     /* requests                 */      requests,
  287.     /* num_requests             */      XtNumber(requests),
  288.   }
  289. };
  290.  
  291. WidgetClass bitmapWidgetClass = (WidgetClass) &bitmapClassRec;
  292.     
  293. /* ARGSUSED */
  294.  
  295. void BWDebug(w)
  296.     Widget w;
  297. {
  298.     DEBUG ^= True;
  299. }
  300.  
  301. Pixmap BWGetPixmap(w) 
  302.     Widget w;
  303. {
  304.     BitmapWidget BW = (BitmapWidget) w;
  305.  
  306.     return GetPixmap(BW, BW->bitmap.zoom.image);
  307. }
  308.  
  309. Pixmap BWGetUnzoomedPixmap(w)
  310.     Widget w;
  311. {
  312.     BitmapWidget BW = (BitmapWidget) w;
  313.     GC gc;
  314.     Pixmap pix;
  315.     
  316.     if (BW->bitmap.zooming) {    
  317.     pix = XCreatePixmap(XtDisplay(w), XtWindow(w), 
  318.                 BW->bitmap.zoom.image->width, 
  319.                 BW->bitmap.zoom.image->height, 1);
  320.     if (!(gc = XCreateGC(XtDisplay(w), pix, 
  321.                  (unsigned long) 0, (XGCValues *) 0)))
  322.         return (Pixmap) None;
  323.     
  324.     XPutImage(XtDisplay(w), pix, gc, 
  325.           BW->bitmap.zoom.image, 
  326.           0, 0, 0, 0, 
  327.           BW->bitmap.zoom.image->width, 
  328.           BW->bitmap.zoom.image->height);
  329.     XPutImage(XtDisplay(w), pix, gc, 
  330.           BW->bitmap.image, 
  331.           0, 0, 
  332.           BW->bitmap.zoom.at_x,
  333.           BW->bitmap.zoom.at_y,
  334.           BW->bitmap.image->width, 
  335.           BW->bitmap.image->height);
  336.     }
  337.     else {
  338.     pix = XCreatePixmap(XtDisplay(w), XtWindow(w), 
  339.                 BW->bitmap.image->width, 
  340.                 BW->bitmap.image->height, 1);
  341.     if (! (gc = XCreateGC(XtDisplay(w), pix, 
  342.                   (unsigned long) 0, (XGCValues *) 0)))
  343.         return (Pixmap) None;
  344.     
  345.     XPutImage(XtDisplay(w), pix, gc, 
  346.           BW->bitmap.image, 
  347.           0, 0, 0, 0,
  348.           BW->bitmap.image->width, 
  349.           BW->bitmap.image->height);
  350.     }
  351.     XFreeGC(XtDisplay(w), gc);
  352.     return(pix);
  353. }
  354.  
  355. XImage *CreateBitmapImage();
  356.  
  357. XImage *ConvertToBitmapImage();
  358.  
  359. XImage *GetImage(BW, pixmap)
  360.     BitmapWidget BW;
  361.     Pixmap pixmap;
  362. {
  363.     Window root;
  364.     int x, y;
  365.     unsigned int width, height, border_width, depth;
  366.     XImage *source, *image;
  367.  
  368.     XGetGeometry(XtDisplay(BW), pixmap, &root, &x, &y,
  369.          &width, &height, &border_width, &depth);
  370.  
  371.     source = XGetImage(XtDisplay(BW), pixmap, x, y, width, height,
  372.              1, XYPixmap);
  373.  
  374.     image = ConvertToBitmapImage(BW, source);
  375.  
  376.     return image;
  377. }
  378.  
  379. XImage *CreateBitmapImage(BW, data, width, height)
  380.     BitmapWidget BW;
  381.     char *data;
  382.     Dimension width, height;
  383. {
  384.     XImage *image = XCreateImage(XtDisplay(BW),
  385.                  DefaultVisual(XtDisplay(BW), 
  386.                            DefaultScreen(XtDisplay(BW))),
  387.                  1, XYBitmap, 0, 
  388.                  data, width, height,
  389.                  8, ((int)width + 7) / 8);
  390.  
  391.     image->height = height;
  392.     image->width = width;
  393.     image->depth = 1;
  394.     image->xoffset = 0;
  395.     image->format = XYBitmap;
  396.     image->data = (char *)data;
  397.     image->byte_order = LSBFirst;
  398.     image->bitmap_unit = 8;
  399.     image->bitmap_bit_order = LSBFirst;
  400.     image->bitmap_pad = 8;
  401.     image->bytes_per_line = ((int)width + 7) / 8;
  402.  
  403.     return image;
  404. }
  405.  
  406. void DestroyBitmapImage(image)
  407.     XImage **image;
  408. {
  409.     /*XDestroyImage(*image);*/
  410.     if (image) {
  411.     if (*image) {
  412.         if ((*image)->data)
  413.         XtFree((*image)->data);
  414.         XtFree((char *)*image);
  415.     }
  416.     *image = NULL;
  417.     }
  418. }
  419.  
  420. XImage *BWGetImage(w)
  421.     Widget w;
  422. {
  423.     BitmapWidget BW = (BitmapWidget) w;
  424.  
  425.     return BW->bitmap.image;
  426. }
  427.  
  428. void BWChangeNotify(w, client_data, call_data)
  429.      Widget       w;
  430.      caddr_t      client_data;
  431.      caddr_t      call_data;
  432. {
  433.     BitmapWidget BW = (BitmapWidget) w;
  434.  
  435.     if (BW->bitmap.notify)
  436.     (*BW->bitmap.notify)(w, client_data, call_data);
  437. }
  438.  
  439. void BWNotify(w, proc)        /* ARGSUSED */
  440.      Widget   w;
  441.      void   (*proc)();
  442. {
  443.     BitmapWidget BW = (BitmapWidget) w;
  444.  
  445.     BW->bitmap.notify = proc;
  446. }
  447.  
  448. void BWSetChanged(w)
  449.     Widget w;
  450. {
  451.     BitmapWidget BW = (BitmapWidget) w;
  452.     
  453.     BW->bitmap.changed = True;
  454. }
  455.  
  456. Boolean BWQueryChanged(w)
  457.     Widget w;
  458. {
  459.     BitmapWidget BW = (BitmapWidget) w;
  460.     
  461.     return BW->bitmap.changed;
  462. }
  463.  
  464. void BWClearChanged(w)
  465.     Widget w;
  466. {
  467.     BitmapWidget BW = (BitmapWidget) w;
  468.     
  469.     BW->bitmap.changed = False;
  470. }
  471.  
  472. Boolean BWQueryStored(w)
  473.     Widget w;
  474. {
  475.     BitmapWidget BW = (BitmapWidget) w;
  476.     
  477.     return (BW->bitmap.storage != NULL);
  478. }
  479.  
  480. Boolean BWQueryStippled(w)
  481.     Widget w;
  482. {
  483.     BitmapWidget BW = (BitmapWidget) w;
  484.  
  485.     return BW->bitmap.stippled;
  486. }
  487.  
  488. void RedrawStippled(BW)
  489.      BitmapWidget(BW);
  490. {
  491.   XExposeEvent event;
  492.   
  493.   event.type = Expose;
  494.   event.display = XtDisplay((Widget)BW);
  495.   event.window = XtWindow((Widget)BW);
  496.   event.x = 0;
  497.   event.y = 0;
  498.   event.width = BW->core.width;
  499.   event.height = BW->core.height;
  500.   event.count = 0;
  501.   
  502.   BWRedrawMark((Widget)BW);
  503.   
  504.   BW->bitmap.stipple_change_expose_event = True; 
  505.   
  506.   XtDispatchEvent((XEvent *)&event);
  507.   
  508.   BW->bitmap.stipple_change_expose_event = False;
  509. }
  510.  
  511. void BWSwitchStippled(w)
  512.     Widget w;
  513. {
  514.     BitmapWidget BW = (BitmapWidget) w;
  515.  
  516.     RedrawStippled(BW);
  517.  
  518.     BW->bitmap.stippled ^= True;
  519.     XSetFillStyle(XtDisplay(BW), BW->bitmap.highlighting_gc,
  520.           (BW->bitmap.stippled ? FillStippled : FillSolid));
  521.  
  522.     RedrawStippled(BW);    
  523. }
  524.  
  525. void BWSelect(w, from_x, from_y, to_x, to_y, btime)
  526.     Widget w;
  527.     Position from_x, from_y,
  528.          to_x, to_y;
  529.     Time btime;
  530. {
  531.     BWMark(w, from_x, from_y, to_x, to_y);
  532.  
  533.     BWGrabSelection(w, btime);
  534. }
  535.  
  536. Boolean BWQueryAxes(w)
  537.     Widget w;
  538. {
  539.     BitmapWidget BW = (BitmapWidget) w;
  540.  
  541.     return BW->bitmap.axes;
  542. }
  543.  
  544. void BWSwitchAxes(w)
  545.      Widget w;
  546. {
  547.     BitmapWidget BW = (BitmapWidget) w;
  548.  
  549.     BW->bitmap.axes ^= True;
  550.     BWHighlightAxes(w);
  551. }
  552.  
  553. void BWAxes(w, _switch)
  554.     Widget w;
  555.     Boolean _switch;
  556. {
  557.     BitmapWidget BW = (BitmapWidget) w;
  558.     
  559.     if (BW->bitmap.axes != _switch)
  560.     BWSwitchAxes(w);
  561. }
  562.  
  563. void BWRedrawAxes(w)
  564.     Widget w;
  565. {
  566.     BitmapWidget BW = (BitmapWidget) w;
  567.     
  568.     if (BW->bitmap.axes)
  569.     BWHighlightAxes(w);
  570. }
  571.  
  572. void BWPutImage(w, display, drawable, gc, x, y)
  573.      BitmapWidget w;
  574.      Display     *display;
  575.      Drawable     drawable;
  576.      GC           gc;
  577.      Position     x, y;
  578. {
  579.     BitmapWidget BW = (BitmapWidget) w;
  580.  
  581.   XPutImage(display, drawable, gc, BW->bitmap.image,
  582.         0, 0, x, y, BW->bitmap.image->width, BW->bitmap.image->height);
  583. }
  584.  
  585. String StripFilename(filename)
  586.     String filename;
  587. {
  588.     char *begin = rindex (filename, '/');
  589.     char *end, *result;
  590.     int length;
  591.     
  592.     if (filename) {
  593.     begin = (begin ? begin + 1 : filename);
  594.     end = index (begin, '.'); /* change to rindex to allow longer names */
  595.     length = (end ? (end - begin) : strlen (begin));
  596.     result = (char *) XtMalloc (length + 1);
  597.     strncpy (result, begin, length);
  598.     result [length] = '\0';
  599.     return (result);
  600.     }
  601.     else
  602.     return (NULL);
  603. }
  604.  
  605. int XmuWriteBitmapDataToFile (filename, basename, 
  606.                   width, height, datap, x_hot, y_hot)
  607.     String filename, basename;
  608.     int width, height;
  609.     char *datap;
  610.     int x_hot, y_hot;
  611. {
  612.     FILE *file;
  613.     int i, data_length;
  614.     
  615.     data_length = Length(width, height);
  616.     
  617.     if(!filename || !strcmp(filename, "") || !strcmp(filename, "-")) {   
  618.     file = stdout;
  619.     filename = "dummy";
  620.     }
  621.     else
  622.         file = fopen(filename, "w+");
  623.     
  624.     if (!basename || !strcmp(basename, "") || !strcmp(basename, "-"))
  625.     basename = StripFilename(filename);
  626.     
  627.     if (file) {
  628.     fprintf(file, "#define %s_width %d\n", basename, width);
  629.     fprintf(file, "#define %s_height %d\n", basename, height);
  630.     if (QuerySet(x_hot, y_hot)) {
  631.         fprintf(file, "#define %s_x_hot %d\n", basename, x_hot);
  632.         fprintf(file, "#define %s_y_hot %d\n", basename, y_hot);
  633.     }
  634.     fprintf(file, "static char %s_bits[] = {\n   0x%02x",
  635.         basename, (unsigned char) datap[0]);
  636.     for(i = 1; i < data_length; i++) {
  637.         fprintf(file, ",");
  638.         fprintf(file, (i % 12) ? " " : "\n   ");
  639.         fprintf(file, "0x%02x", (unsigned char) datap[i]);
  640.     }
  641.     fprintf(file, "};\n");
  642.     
  643.     if (file != stdout)
  644.         fclose(file);
  645.  
  646.     return BitmapSuccess;
  647.     }
  648.     
  649.     return 1;
  650. }
  651.  
  652. /*
  653.  *
  654.  */
  655.  
  656.                 /* ARGSUSED */
  657. static void CvtStringToButtonFunction(args, num_args, from_val, to_val)
  658.     XrmValuePtr args;        /* not used */
  659.     Cardinal    *num_args;      /* not used */
  660.     XrmValuePtr from_val;
  661.     XrmValuePtr to_val;
  662. {
  663.   static button_function;
  664.   char lower_name[80];
  665.  
  666.   XmuCopyISOLatin1Lowered (lower_name, (char*)from_val->addr);
  667.   
  668.   if (!strcmp(lower_name, XtClear)) {
  669.     button_function = Clear;
  670.     to_val->addr = (caddr_t) &button_function;
  671.     to_val->size = sizeof(button_function);
  672.     return;
  673.   }
  674.   
  675.   if (!strcmp(lower_name, XtSet)) {
  676.     button_function = Set;
  677.     to_val->addr = (caddr_t) &button_function;
  678.     to_val->size = sizeof(button_function);
  679.     return;
  680.   }
  681.  
  682.   if (!strcmp(lower_name, XtInvert)) {
  683.     button_function = Invert;
  684.     to_val->addr = (caddr_t) &button_function;
  685.     to_val->size = sizeof(button_function);
  686.     return;
  687.   }
  688.   
  689.   XtStringConversionWarning(from_val->addr, XtRButtonFunction);
  690.   button_function = Clear;
  691.   to_val->addr = (caddr_t) &button_function;
  692.   to_val->size = sizeof(button_function);
  693.   
  694. }
  695.  
  696. void Refresh();
  697.  
  698. static void ClassInitialize()
  699. {
  700.   char *tm_table = XtMalloc(strlen(translations1) + strlen(translations2) + 1);
  701.   strcpy(tm_table, translations1);
  702.   strcat(tm_table, translations2);
  703.   bitmapClassRec.core_class.tm_table = tm_table;
  704.  
  705.   XawInitializeWidgetSet();
  706.   XtAddConverter(XtRString, XtRButtonFunction, CvtStringToButtonFunction,
  707.          NULL, 0);
  708.   DEBUG = False;
  709. }
  710.  
  711. static void SetSizeFromSizeResource(bw)
  712.      BitmapWidget bw;
  713. {
  714.   if (BWParseSize(bw->bitmap.size, 
  715.           &bw->bitmap.width,
  716.           &bw->bitmap.height)
  717.       ==
  718.       False) {
  719.     bw->bitmap.width = FallbackBitmapWidth;
  720.     bw->bitmap.height = FallbackBitmapHeight;
  721.     XtWarning("Cannot parse the size resource.  BitmapWidget");
  722.   }
  723. }
  724.  
  725. void TransferImageData();
  726.  
  727. /* ARGSUSED */
  728. static void Initialize(request, new, argv, argc)
  729.     BitmapWidget request, new;
  730.     ArgList argv;
  731.     Cardinal argc;
  732. {
  733.     XGCValues  values;
  734.     XtGCMask   mask;
  735.     char *image_data, *buffer_data;
  736.  
  737.     new->bitmap.stipple_change_expose_event = False;
  738.     new->bitmap.notify = NULL;
  739.     new->bitmap.cardinal = 0;
  740.     new->bitmap.current = 0;
  741.     new->bitmap.fold = False;
  742.     new->bitmap.changed = False;
  743.     new->bitmap.zooming = False;
  744.     new->bitmap.selection.own = False;
  745.     new->bitmap.selection.limbo = False;
  746.  
  747.     new->bitmap.request_stack = (BWRequestStack *)
  748.     XtMalloc(sizeof(BWRequestStack));
  749.  
  750.     new->bitmap.request_stack[0].request = NULL;
  751.     new->bitmap.request_stack[0].call_data = NULL;
  752.     new->bitmap.request_stack[0].trap = False;
  753.  
  754.     SetSizeFromSizeResource(new);
  755.  
  756.     new->core.width = new->bitmap.width * new->bitmap.squareW + 
  757.     2 * new->bitmap.margin;
  758.     new->core.height = new->bitmap.height * new->bitmap.squareH + 
  759.     2 * new->bitmap.margin;
  760.   
  761.     new->bitmap.hot.x = new->bitmap.hot.y = NotSet;
  762.     new->bitmap.buffer_hot.x = new->bitmap.buffer_hot.y = NotSet;
  763.   
  764.     new->bitmap.mark.from_x = new->bitmap.mark.from_y = NotSet;
  765.     new->bitmap.mark.to_x = new->bitmap.mark.to_y = NotSet;
  766.     new->bitmap.buffer_mark.from_x = new->bitmap.buffer_mark.from_y = NotSet;
  767.     new->bitmap.buffer_mark.to_x = new->bitmap.buffer_mark.to_y = NotSet;
  768.  
  769.     values.foreground = new->bitmap.foreground_pixel;
  770.     values.background = new->core.background_pixel;
  771.     values.foreground ^= values.background;
  772.     values.function = GXxor;
  773.     mask = GCForeground | GCBackground | GCFunction;
  774.     new->bitmap.drawing_gc = XCreateGC(XtDisplay(new), 
  775.                        RootWindow(XtDisplay(new), 
  776.                        DefaultScreen(XtDisplay(new))),
  777.                        mask, &values);
  778.  
  779.     values.foreground = new->bitmap.highlight_pixel;
  780.     values.background = new->core.background_pixel;
  781.     values.foreground ^= values.background;
  782.     values.function = GXxor;
  783.     mask = GCForeground | GCBackground | GCFunction;
  784.     if (new->bitmap.stipple != XtUnspecifiedPixmap)
  785.     {
  786.     values.stipple = new->bitmap.stipple;
  787.     mask |= GCStipple | GCFillStyle;
  788.     }
  789.     values.fill_style = (new->bitmap.stippled ? FillStippled : FillSolid);
  790.  
  791.     new->bitmap.highlighting_gc = XCreateGC(XtDisplay(new), 
  792.                         RootWindow(XtDisplay(new), 
  793.                            DefaultScreen(XtDisplay(new))), 
  794.                         mask, &values);
  795.  
  796.  
  797.     values.foreground = new->bitmap.frame_pixel;
  798.     values.background = new->core.background_pixel;
  799.     values.foreground ^= values.background;
  800.     mask = GCForeground | GCBackground | GCFunction;
  801.     if (new->bitmap.dashes != XtUnspecifiedPixmap)
  802.     {
  803.     values.stipple = new->bitmap.dashes;
  804.     mask |= GCStipple | GCFillStyle;
  805.     }
  806.     values.fill_style = (new->bitmap.dashed ? FillStippled : FillSolid);
  807.  
  808.     new->bitmap.frame_gc = XCreateGC(XtDisplay(new), 
  809.                      RootWindow(XtDisplay(new), 
  810.                         DefaultScreen(XtDisplay(new))),
  811.                      mask, &values);
  812.  
  813.     values.foreground = new->bitmap.highlight_pixel;
  814.     values.background = new->core.background_pixel;
  815.     values.foreground ^= values.background;
  816.     mask = GCForeground | GCBackground | GCFunction;
  817.     new->bitmap.axes_gc = XCreateGC(XtDisplay(new), 
  818.                      RootWindow(XtDisplay(new), 
  819.                         DefaultScreen(XtDisplay(new))),
  820.                      mask, &values);
  821.  
  822.     image_data = CreateCleanData(Length(new->bitmap.width, 
  823.                     new->bitmap.height));
  824.     buffer_data = CreateCleanData(Length(new->bitmap.width, 
  825.                      new->bitmap.height));
  826.  
  827.     new->bitmap.storage = NULL;
  828.     
  829.     new->bitmap.image = CreateBitmapImage(new, 
  830.                       image_data,
  831.                       new->bitmap.width,
  832.                       new->bitmap.height);
  833.     new->bitmap.buffer = CreateBitmapImage(new, 
  834.                        buffer_data,
  835.                        new->bitmap.width,
  836.                        new->bitmap.height);
  837.  
  838.     /* Read file */
  839.     {
  840.     int status;
  841.     XImage *image, *buffer;
  842.     unsigned char *image_data;
  843.     char *buffer_data;
  844.     unsigned int width, height;
  845.     int x_hot, y_hot;
  846.     
  847.     status = XmuReadBitmapDataFromFile(new->bitmap.filename, 
  848.                        &width, &height, &image_data,
  849.                        &x_hot, &y_hot);
  850.     if (status == BitmapSuccess) {
  851.         
  852.         buffer_data = CreateCleanData(Length(width, height));
  853.         
  854.         image = CreateBitmapImage(new, image_data, width, height);
  855.         buffer = CreateBitmapImage(new, buffer_data, width, height);
  856.     
  857.         TransferImageData(new->bitmap.image, buffer);
  858.     
  859.         DestroyBitmapImage(&new->bitmap.image);
  860.         DestroyBitmapImage(&new->bitmap.buffer);
  861.     
  862.         new->bitmap.image = image;
  863.         new->bitmap.buffer = buffer;
  864.         new->bitmap.width = width;
  865.         new->bitmap.height = height;
  866.         
  867.         new->bitmap.hot.x = x_hot;
  868.         new->bitmap.hot.y = y_hot;
  869.         
  870.         new->bitmap.changed = False;
  871.         new->bitmap.zooming = False;
  872.     }
  873.  
  874.     new->bitmap.filename = XtNewString(new->bitmap.filename);
  875.     
  876.     if (!strcmp(new->bitmap.basename, "")) {
  877.         new->bitmap.basename = StripFilename(new->bitmap.filename);
  878.     }
  879.     else
  880.       new->bitmap.basename = XtNewString(new->bitmap.basename);
  881.     }
  882.  
  883.     Resize(new);
  884. }
  885.  
  886.  
  887. /* returns False if the format is wrong */
  888. Boolean BWParseSize(size, width, height)
  889.      String size;
  890.      Dimension *width, *height;
  891. {
  892.   int x, y;
  893.   unsigned int w, h;
  894.   int status;
  895.  
  896.   status = XParseGeometry(size, &x, &y, &w, &h);
  897.  
  898.   if (status & (WidthValue | HeightValue)) {
  899.     *width = (Dimension) w;
  900.     *height = (Dimension) h;
  901.     return True;
  902.   }
  903.   else return False;
  904.  
  905. }
  906.  
  907.  
  908. Boolean BWQueryMarked(w)
  909.     Widget w;
  910. {
  911.     BitmapWidget BW = (BitmapWidget) w;
  912.  
  913.     return QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y);
  914. }
  915.  
  916. void FixMark(BW)
  917.     BitmapWidget BW;
  918. {
  919.     if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) {
  920.     BW->bitmap.mark.from_x = min(BW->bitmap.mark.from_x, 
  921.                      BW->bitmap.image->width);
  922.     BW->bitmap.mark.from_y = min(BW->bitmap.mark.from_y, 
  923.                      BW->bitmap.image->height);
  924.     BW->bitmap.mark.to_x = min(BW->bitmap.mark.to_x, 
  925.                    BW->bitmap.image->width);
  926.     BW->bitmap.mark.to_y = min(BW->bitmap.mark.to_y, 
  927.                    BW->bitmap.image->height);
  928.     
  929.     if((BW->bitmap.mark.from_x == BW->bitmap.mark.from_y) &&
  930.        (BW->bitmap.mark.to_x   == BW->bitmap.mark.to_y))
  931.         BW->bitmap.mark.from_x = 
  932.         BW->bitmap.mark.from_y =
  933.             BW->bitmap.mark.to_x = 
  934.             BW->bitmap.mark.to_y = NotSet;
  935.     }
  936. }
  937.  
  938. /* ARGSUSED */
  939. int BWStoreFile(w, filename, basename)
  940.     Widget w;
  941.     String filename, *basename;
  942. {
  943.     BitmapWidget BW = (BitmapWidget) w;
  944.     int status;
  945.     unsigned char *storage_data;
  946.     unsigned int width, height;
  947.     int x_hot, y_hot;
  948.     
  949.     status = XmuReadBitmapDataFromFile(filename, &width, &height,
  950.                        &storage_data, &x_hot, &y_hot);
  951.     if (status == BitmapSuccess) {
  952.  
  953.     DestroyBitmapImage(&BW->bitmap.storage);
  954.     
  955.     BW->bitmap.storage = CreateBitmapImage(BW, storage_data, width, height);
  956.  
  957.     return BitmapSuccess;
  958.     }
  959.     else
  960.     XtWarning(" read file failed.  BitmapWidget");
  961.     
  962.     return status;
  963. }
  964.  
  965. String BWUnparseStatus(w)
  966.     Widget w;
  967. {
  968.     BitmapWidget BW = (BitmapWidget) w;
  969.     
  970.     sprintf(BW->bitmap.status, 
  971.         "Filename: %s  Basename: %s  Size: %dx%d",
  972.         (strcmp(BW->bitmap.filename, "") ? BW->bitmap.filename : "<none>"),
  973.         (strcmp(BW->bitmap.basename, "") ? BW->bitmap.basename : "<none>"),
  974.         BW->bitmap.width, BW->bitmap.height);
  975.  
  976.     return BW->bitmap.status;
  977. }
  978.  
  979. void BWChangeFilename(w, str)
  980.     Widget w;
  981.     String str;
  982. {
  983.   BitmapWidget BW = (BitmapWidget) w;
  984.   
  985.   if (str) {
  986.     XtFree(BW->bitmap.filename);
  987.     BW->bitmap.filename = XtNewString( str);
  988.   }
  989. }
  990.  
  991. void BWChangeBasename(w, str)
  992.     Widget w;
  993.     String str;
  994. {
  995.   BitmapWidget BW = (BitmapWidget) w;
  996.   
  997.   if (str) {
  998.     XtFree(BW->bitmap.basename);
  999.     BW->bitmap.basename = XtNewString(str);
  1000.   }
  1001. }
  1002.  
  1003.  
  1004. int BWReadFile(w, filename, basename) /* ARGSUSED */
  1005.     Widget w;
  1006.     String filename, basename;
  1007. {
  1008.     BitmapWidget BW = (BitmapWidget) w;
  1009.     int status;
  1010.     XImage *image, *buffer;
  1011.     unsigned char *image_data;
  1012.     char *buffer_data;
  1013.     unsigned int width, height;
  1014.     int x_hot, y_hot;
  1015.     
  1016.     if (!filename)
  1017.     filename = BW->bitmap.filename;
  1018.  
  1019.     status = XmuReadBitmapDataFromFile(filename, &width, &height, &image_data,
  1020.                        &x_hot, &y_hot);
  1021.     if (status == BitmapSuccess) {
  1022.     
  1023.     buffer_data = CreateCleanData(Length(width, height));
  1024.     
  1025.     image = CreateBitmapImage(BW, image_data, width, height);
  1026.     buffer = CreateBitmapImage(BW, buffer_data, width, height);
  1027.     
  1028.     TransferImageData(BW->bitmap.image, buffer);
  1029.     
  1030.     DestroyBitmapImage(&BW->bitmap.image);
  1031.     DestroyBitmapImage(&BW->bitmap.buffer);
  1032.     
  1033.     BW->bitmap.image = image;
  1034.     BW->bitmap.buffer = buffer;
  1035.     BW->bitmap.width = width;
  1036.     BW->bitmap.height = height;
  1037.     
  1038.     BW->bitmap.hot.x = x_hot;
  1039.     BW->bitmap.hot.y = y_hot;
  1040.     
  1041.     BW->bitmap.changed = False;
  1042.     BW->bitmap.zooming = False;
  1043.     
  1044.     XtFree(BW->bitmap.filename);
  1045.     BW->bitmap.filename = XtNewString(filename);
  1046.     XtFree(BW->bitmap.basename);
  1047.     BW->bitmap.basename= XtNewString(StripFilename(filename));
  1048.  
  1049.     BWUnmark(w);
  1050.     
  1051.     Resize(BW);
  1052.  
  1053.     if (BW->core.visible) {
  1054.         XClearArea(XtDisplay(BW), XtWindow(BW),
  1055.                0, 0, 
  1056.                BW->core.width, BW->core.height,
  1057.                True);
  1058.     }
  1059.     
  1060.     return BitmapSuccess;
  1061.     }
  1062.     else
  1063.     XtWarning(" read file failed.  BitmapWidget");
  1064.     
  1065.     return status;
  1066. }
  1067.  
  1068. int BWSetImage(w, image)
  1069.     Widget w;
  1070.     XImage *image;
  1071. {
  1072.     BitmapWidget BW = (BitmapWidget) w;
  1073.     XImage *buffer;
  1074.     char *buffer_data;
  1075.     
  1076.     buffer_data = CreateCleanData(Length(image->width, image->height));
  1077.     buffer = CreateBitmapImage(BW, buffer_data, 
  1078.                    (Dimension) image->width, 
  1079.                    (Dimension) image->height);
  1080.     
  1081.     TransferImageData(BW->bitmap.image, buffer);
  1082.     
  1083.     DestroyBitmapImage(&BW->bitmap.image);
  1084.     DestroyBitmapImage(&BW->bitmap.buffer);
  1085.     
  1086.     BW->bitmap.image = image;
  1087.     BW->bitmap.buffer = buffer;
  1088.     BW->bitmap.width = image->width;
  1089.     BW->bitmap.height = image->height;
  1090.     
  1091.     Resize(BW);
  1092.     
  1093.     if (BW->core.visible) {
  1094.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1095.            0, 0, 
  1096.            BW->core.width, BW->core.height,
  1097.            True);    
  1098.     }
  1099. }
  1100.  
  1101. int BWWriteFile(w, filename, basename)
  1102.     Widget w;
  1103.     String filename, basename;
  1104. {
  1105.     BitmapWidget BW = (BitmapWidget) w;
  1106.     char *data;
  1107.     XImage *image;
  1108.     XPoint hot;
  1109.     int status;
  1110.     
  1111.     if (BW->bitmap.zooming) {
  1112.         data = XtMalloc(Length(BW->bitmap.zoom.image->width, 
  1113.                    BW->bitmap.zoom.image->height));
  1114.     bcopy(BW->bitmap.zoom.image->data, data,
  1115.           Length(BW->bitmap.zoom.image->width, 
  1116.              BW->bitmap.zoom.image->height));
  1117.     image = CreateBitmapImage(BW, data,
  1118.                   (Dimension) BW->bitmap.zoom.image->width,
  1119.                   (Dimension) BW->bitmap.zoom.image->height);
  1120.     CopyImageData(BW->bitmap.image, image, 
  1121.               0, 0, 
  1122.               BW->bitmap.image->width - 1,
  1123.               BW->bitmap.image->height - 1,
  1124.               BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y);
  1125.     
  1126.     if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) {
  1127.         hot.x = BW->bitmap.hot.x + BW->bitmap.zoom.at_x;
  1128.         hot.y = BW->bitmap.hot.y + BW->bitmap.zoom.at_y;
  1129.     }
  1130.     else
  1131.         hot = BW->bitmap.zoom.hot;
  1132.     }
  1133.     else {
  1134.     image = BW->bitmap.image;
  1135.     hot = BW->bitmap.hot;
  1136.     }
  1137.     
  1138.     if (!filename) filename = BW->bitmap.filename;
  1139.     else {
  1140.     XtFree(BW->bitmap.filename);
  1141.     BW->bitmap.filename = XtNewString(filename);
  1142.     XtFree(BW->bitmap.basename);
  1143.     BW->bitmap.basename= XtNewString(StripFilename(filename));
  1144.     }
  1145.     if (!basename) basename = BW->bitmap.basename;
  1146.     else {
  1147.     XtFree(BW->bitmap.basename);
  1148.     BW->bitmap.basename = XtNewString(basename);
  1149.     }
  1150.  
  1151.     if (DEBUG)
  1152.     fprintf(stderr, "Saving filename: %s %s\n", filename, basename);
  1153.  
  1154.     status = XmuWriteBitmapDataToFile(filename, basename,
  1155.                       image->width, image->height, image->data,
  1156.                       hot.x, hot.y);
  1157.     if (BW->bitmap.zooming)
  1158.     DestroyBitmapImage(&image);
  1159.     
  1160.     if (status == BitmapSuccess)
  1161.     BW->bitmap.changed = False;
  1162.     
  1163.     return status;
  1164. }
  1165.  
  1166. String BWGetFilename(w, str)
  1167.     Widget w;
  1168.     String *str;
  1169. {
  1170.     BitmapWidget BW = (BitmapWidget) w;
  1171.     
  1172.     *str = XtNewString(BW->bitmap.filename);
  1173.  
  1174.     return *str;
  1175. }
  1176.  
  1177. String BWGetFilepath(w, str)
  1178.     Widget w;
  1179.     String *str;
  1180. {
  1181.     BitmapWidget BW = (BitmapWidget) w;
  1182.     String end;
  1183.  
  1184.     *str = XtNewString(BW->bitmap.filename);
  1185.     end = rindex(*str, '/');
  1186.  
  1187.     if (end)
  1188.     *(end + 1) = '\0';
  1189.     else 
  1190.     **str = '\0';
  1191.  
  1192.     return *str;
  1193. }
  1194.  
  1195.  
  1196. String BWGetBasename(w, str)
  1197.     Widget w;
  1198.     String *str;
  1199. {
  1200.     BitmapWidget BW = (BitmapWidget) w;
  1201.     
  1202.     *str = XtNewString(BW->bitmap.basename);
  1203.  
  1204.     return *str;
  1205. }
  1206.  
  1207. void FixHotSpot(BW)
  1208.     BitmapWidget BW;
  1209. {
  1210.     if (!QueryInBitmap(BW, BW->bitmap.hot.x, BW->bitmap.hot.y))
  1211.     BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet;
  1212. }
  1213.  
  1214. void ZoomOut(BW)
  1215.     BitmapWidget BW;
  1216. {
  1217.     CopyImageData(BW->bitmap.image, BW->bitmap.zoom.image, 
  1218.           0, 0, 
  1219.           BW->bitmap.image->width - 1,
  1220.           BW->bitmap.image->height - 1,
  1221.           BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y);
  1222.     
  1223.     DestroyBitmapImage(&BW->bitmap.image);
  1224.     DestroyBitmapImage(&BW->bitmap.buffer);
  1225.     
  1226.     BW->bitmap.image = BW->bitmap.zoom.image;
  1227.     BW->bitmap.buffer = BW->bitmap.zoom.buffer;
  1228.     BW->bitmap.width = BW->bitmap.image->width;
  1229.     BW->bitmap.height = BW->bitmap.image->height;
  1230.     BW->bitmap.fold = BW->bitmap.zoom.fold;
  1231.     BW->bitmap.changed |= BW->bitmap.zoom.changed;
  1232.     BW->bitmap.grid = BW->bitmap.zoom.grid;
  1233.  
  1234.     if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) {
  1235.     BW->bitmap.hot.x += BW->bitmap.zoom.at_x;
  1236.     BW->bitmap.hot.y += BW->bitmap.zoom.at_y;
  1237.     }
  1238.     else
  1239.     BW->bitmap.hot = BW->bitmap.zoom.hot;
  1240.     
  1241.     BW->bitmap.mark.from_x = NotSet;
  1242.     BW->bitmap.mark.from_y = NotSet;
  1243.     BW->bitmap.mark.to_x = NotSet;
  1244.     BW->bitmap.mark.to_y = NotSet;
  1245.     BW->bitmap.zooming = False;
  1246. }    
  1247.  
  1248. void BWZoomOut(w)
  1249.     Widget w;
  1250. {
  1251.     BitmapWidget BW = (BitmapWidget) w;
  1252.     
  1253.     if (BW->bitmap.zooming) {
  1254.     ZoomOut(BW);
  1255.     
  1256.     Resize(BW);
  1257.     if (BW->core.visible)
  1258.         XClearArea(XtDisplay(BW), XtWindow(BW),
  1259.                0, 0, 
  1260.                BW->core.width, BW->core.height,
  1261.                True);
  1262.     }
  1263. }
  1264.  
  1265. void BWZoomIn();
  1266.  
  1267. void BWZoomMarked(w)
  1268.     Widget w;
  1269. {
  1270.     BitmapWidget BW = (BitmapWidget) w;
  1271.  
  1272.     BWZoomIn(w, 
  1273.          BW->bitmap.mark.from_x, BW->bitmap.mark.from_y,
  1274.          BW->bitmap.mark.to_x,   BW->bitmap.mark.to_y);
  1275. }
  1276.  
  1277. void BWZoomIn(w, from_x, from_y, to_x, to_y)
  1278.     Widget w;
  1279.     Position from_x, from_y,
  1280.          to_x, to_y;
  1281. {
  1282.     BitmapWidget BW = (BitmapWidget) w;
  1283.     XImage *image, *buffer;    
  1284.     Dimension width, height;
  1285.     char *image_data, *buffer_data;
  1286.   
  1287.     if (BW->bitmap.zooming)
  1288.     ZoomOut(BW);
  1289.     
  1290.     QuerySwap(from_x, to_x);
  1291.     QuerySwap(from_y, to_y);
  1292.     from_x = max(0, from_x);
  1293.     from_y = max(0, from_y);
  1294.     to_x = min(BW->bitmap.width - 1, to_x);
  1295.     to_y = min(BW->bitmap.height - 1, to_y);
  1296.     
  1297.     width = to_x - from_x + 1;
  1298.     height = to_y - from_y + 1;
  1299.  
  1300.     image_data = CreateCleanData(Length(width, height));
  1301.     buffer_data = CreateCleanData(Length(width, height));
  1302.  
  1303.     image = CreateBitmapImage(BW, image_data, width, height);
  1304.     buffer = CreateBitmapImage(BW, buffer_data, width, height);
  1305.  
  1306.     CopyImageData(BW->bitmap.image, image, from_x, from_y, to_x, to_y, 0, 0);
  1307.     CopyImageData(BW->bitmap.buffer, buffer, from_x, from_y, to_x, to_y, 0, 0);
  1308.     
  1309.     BW->bitmap.zoom.image = BW->bitmap.image;
  1310.     BW->bitmap.zoom.buffer = BW->bitmap.buffer;
  1311.     BW->bitmap.zoom.at_x = from_x;
  1312.     BW->bitmap.zoom.at_y = from_y;
  1313.     BW->bitmap.zoom.fold = BW->bitmap.fold;
  1314.     BW->bitmap.zoom.changed = BW->bitmap.changed;
  1315.     BW->bitmap.zoom.hot = BW->bitmap.hot;
  1316.     BW->bitmap.zoom.grid = BW->bitmap.grid;
  1317.  
  1318.     BW->bitmap.image = image;
  1319.     BW->bitmap.buffer = buffer;
  1320.     BW->bitmap.width = width;
  1321.     BW->bitmap.height = height;
  1322.     BW->bitmap.changed = False;
  1323.     BW->bitmap.hot.x -= from_x;
  1324.     BW->bitmap.hot.y -= from_y;
  1325.     BW->bitmap.mark.from_x = NotSet;
  1326.     BW->bitmap.mark.from_y = NotSet;
  1327.     BW->bitmap.mark.to_x = NotSet;
  1328.     BW->bitmap.mark.to_y = NotSet;
  1329.     BW->bitmap.zooming = True;
  1330.     BW->bitmap.grid = True; /* potencially true, could use a resource here */
  1331.  
  1332.     FixHotSpot(BW);
  1333.  
  1334.     Resize(BW);
  1335.     if (BW->core.visible)
  1336.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1337.            0, 0, 
  1338.            BW->core.width, BW->core.height,
  1339.            True);
  1340. }
  1341.  
  1342. XImage *ScaleBitmapImage();
  1343.  
  1344. void BWRescale(w, width, height)
  1345.     Widget w;
  1346.     Dimension width, height;
  1347. {
  1348.     BitmapWidget BW = (BitmapWidget) w;
  1349.     XImage *image, *buffer;
  1350.     char *buffer_data;
  1351.  
  1352.     if (BW->bitmap.zooming)
  1353.     ZoomOut(BW);
  1354.         
  1355.     image = ScaleBitmapImage(BW, BW->bitmap.image, 
  1356.                (double) width / (double) BW->bitmap.image->width,
  1357.                (double) height / (double) BW->bitmap.image->height);
  1358.  
  1359.     buffer_data = CreateCleanData(Length(image->width, image->height));
  1360.     buffer = CreateBitmapImage(BW, buffer_data, 
  1361.                    (Dimension) image->width, 
  1362.                    (Dimension) image->height);
  1363.     
  1364.     TransferImageData(BW->bitmap.buffer, buffer);
  1365.  
  1366.     DestroyBitmapImage(&BW->bitmap.image);
  1367.     DestroyBitmapImage(&BW->bitmap.buffer);
  1368.     
  1369.     BW->bitmap.image = image;
  1370.     BW->bitmap.buffer = buffer;
  1371.     BW->bitmap.width = image->width;
  1372.     BW->bitmap.height = image->height;
  1373.     
  1374.     FixHotSpot(BW);
  1375.     FixMark(BW);
  1376.  
  1377.     Resize(BW);
  1378.     if (BW->core.visible)
  1379.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1380.            0, 0, 
  1381.            BW->core.width, BW->core.height,
  1382.            True);
  1383. }
  1384.  
  1385. Boolean BWQueryZooming(w)
  1386.     Widget w;
  1387. {
  1388.     BitmapWidget BW = (BitmapWidget) w;
  1389.  
  1390.     return BW->bitmap.zooming;
  1391. }
  1392.  
  1393.  
  1394. static void ResizeGrid(BW, width, height)
  1395.      BitmapWidget BW;
  1396.      Dimension width, height;
  1397. {
  1398.   XImage *image, *buffer;
  1399.   char *image_data, *buffer_data;
  1400.   
  1401.   if (BW->bitmap.zooming)
  1402.     ZoomOut(BW);
  1403.   
  1404.   image_data = CreateCleanData(Length(width, height));
  1405.   buffer_data = CreateCleanData(Length(width, height));
  1406.   
  1407.   image = CreateBitmapImage(BW, image_data, width, height);
  1408.   buffer = CreateBitmapImage(BW, buffer_data, width, height);
  1409.   
  1410.   TransferImageData(BW->bitmap.image, image);
  1411.   TransferImageData(BW->bitmap.buffer, buffer);
  1412.   
  1413.   DestroyBitmapImage(&BW->bitmap.image);
  1414.   DestroyBitmapImage(&BW->bitmap.buffer);
  1415.   
  1416.   BW->bitmap.image = image;
  1417.   BW->bitmap.buffer = buffer;
  1418.   BW->bitmap.width = width;
  1419.   BW->bitmap.height = height;
  1420.   
  1421.   FixHotSpot(BW);
  1422.   FixMark(BW);
  1423. }
  1424.  
  1425. void BWResize(w, width, height)
  1426.     Widget w;
  1427.     Dimension width, height;
  1428. {
  1429.     BitmapWidget BW = (BitmapWidget) w;
  1430.  
  1431.     ResizeGrid(BW, width, height);
  1432.  
  1433.     Resize(BW);
  1434.     if (BW->core.visible)
  1435.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1436.            0, 0, 
  1437.            BW->core.width, BW->core.height,
  1438.            True);
  1439. }
  1440.  
  1441. static void Destroy(w)
  1442.     Widget w;
  1443. {
  1444.     BitmapWidget BW = (BitmapWidget) w;
  1445.  
  1446.     XFreeGC(XtDisplay(w), BW->bitmap.drawing_gc);
  1447.     XFreeGC(XtDisplay(w), BW->bitmap.highlighting_gc);
  1448.     XFreeGC(XtDisplay(w), BW->bitmap.frame_gc);
  1449.     XFreeGC(XtDisplay(w), BW->bitmap.axes_gc);
  1450.     BWRemoveAllRequests(w);
  1451.  
  1452.     XtFree(BW->bitmap.filename);
  1453.     XtFree(BW->bitmap.basename);
  1454. }
  1455.  
  1456.  
  1457. static void Resize(BW)
  1458.      BitmapWidget BW;
  1459. {
  1460.     Dimension squareW, squareH;
  1461.  
  1462.     squareW = max(1, ((int)BW->core.width - 2 * (int)BW->bitmap.margin) / 
  1463.           (int)BW->bitmap.width);
  1464.     squareH = max(1, ((int)BW->core.height - 2 * (int)BW->bitmap.margin) / 
  1465.           (int)BW->bitmap.height);
  1466.  
  1467.     if (BW->bitmap.proportional)
  1468.     BW->bitmap.squareW = BW->bitmap.squareH = min(squareW, squareH);
  1469.     else {
  1470.     BW->bitmap.squareW = squareW;
  1471.     BW->bitmap.squareH = squareH;
  1472.     }
  1473.     
  1474.     BW->bitmap.horizOffset = max((Position)BW->bitmap.margin, 
  1475.                  (Position)(BW->core.width - 
  1476.                         BW->bitmap.width * 
  1477.                         BW->bitmap.squareW) / 2);
  1478.     BW->bitmap.vertOffset = max((Position)BW->bitmap.margin, 
  1479.                 (Position)(BW->core.height - 
  1480.                        BW->bitmap.height * 
  1481.                        BW->bitmap.squareH) / 2);
  1482.  
  1483.     BW->bitmap.grid &= ((BW->bitmap.squareW > BW->bitmap.grid_tolerance) && 
  1484.             (BW->bitmap.squareH > BW->bitmap.grid_tolerance));
  1485. }
  1486.  
  1487. /* ARGSUSED */
  1488. static void Redisplay(BW, event, region)
  1489.      BitmapWidget BW;
  1490.      XEvent      *event;
  1491.      Region       region;
  1492. {
  1493.   if(event->type == Expose
  1494.      &&
  1495.      BW->core.visible)
  1496.     if (BW->bitmap.stipple_change_expose_event == False)
  1497.       Refresh(BW, 
  1498.           event->xexpose.x, event->xexpose.y,
  1499.           event->xexpose.width, event->xexpose.height);
  1500. }
  1501.  
  1502. void BWClip(w, x, y, width, height)
  1503.     Widget  w;
  1504.     Position x, y;
  1505.     Dimension width, height;
  1506. {
  1507.     Position      from_x, from_y,
  1508.                   to_x, to_y;
  1509.     BitmapWidget BW = (BitmapWidget) w;
  1510.     XRectangle rectangle;
  1511.   
  1512.     from_x = InBitmapX(BW, x);
  1513.     from_y = InBitmapY(BW, y);
  1514.     to_x = InBitmapX(BW, x + width);
  1515.     to_y = InBitmapY(BW, y + height);
  1516.     QuerySwap(from_x, to_x);
  1517.     QuerySwap(from_y, to_y);
  1518.     from_x = max(0, from_x);
  1519.     from_y = max(0, from_y);
  1520.     to_x = min(BW->bitmap.width - 1, to_x);
  1521.     to_y = min(BW->bitmap.height - 1, to_y);
  1522.  
  1523.     rectangle.x = InWindowX(BW, from_x);
  1524.     rectangle.y = InWindowY(BW, from_y);
  1525.     rectangle.width = InWindowX(BW, to_x  + 1) - InWindowX(BW, from_x);
  1526.     rectangle.height = InWindowY(BW, to_y + 1) - InWindowY(BW, from_y);
  1527.     XSetClipRectangles(XtDisplay(BW),
  1528.                BW->bitmap.highlighting_gc,
  1529.                0, 0,
  1530.                &rectangle, 1,
  1531.                Unsorted);
  1532.     XSetClipRectangles(XtDisplay(BW),
  1533.                BW->bitmap.drawing_gc,
  1534.                0, 0,
  1535.                &rectangle, 1,
  1536.                Unsorted);
  1537.     XSetClipRectangles(XtDisplay(BW),
  1538.                BW->bitmap.frame_gc,
  1539.                0, 0,
  1540.                &rectangle, 1,
  1541.                Unsorted);
  1542.     XSetClipRectangles(XtDisplay(BW),
  1543.                BW->bitmap.axes_gc,
  1544.                0, 0,
  1545.                &rectangle, 1,
  1546.                Unsorted);
  1547. }
  1548.  
  1549. void BWUnclip(w)
  1550.     Widget w;
  1551. {
  1552.     BitmapWidget BW = (BitmapWidget) w;
  1553.     XRectangle rectangle;
  1554.   
  1555.     rectangle.x = InWindowX(BW, 0);
  1556.     rectangle.y = InWindowY(BW, 0);
  1557.     rectangle.width = InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0);
  1558.     rectangle.height = InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0);
  1559.     XSetClipRectangles(XtDisplay(BW),
  1560.                BW->bitmap.highlighting_gc,
  1561.                0, 0,
  1562.                &rectangle, 1,
  1563.                Unsorted);
  1564.     XSetClipRectangles(XtDisplay(BW),
  1565.                BW->bitmap.drawing_gc,
  1566.                0, 0,
  1567.                &rectangle, 1,
  1568.                Unsorted);
  1569.     XSetClipRectangles(XtDisplay(BW),
  1570.                BW->bitmap.frame_gc,
  1571.                0, 0,
  1572.                &rectangle, 1,
  1573.                Unsorted);
  1574.     XSetClipRectangles(XtDisplay(BW),
  1575.                BW->bitmap.axes_gc,
  1576.                0, 0,
  1577.                &rectangle, 1,
  1578.                Unsorted);
  1579. }
  1580.  
  1581. void Refresh(BW, x, y, width, height)
  1582.     BitmapWidget BW;
  1583.     Position     x, y;
  1584.     Dimension    width, height;
  1585. {
  1586.     XRectangle rectangle;
  1587.  
  1588.     rectangle.x = min(x, InWindowX(BW, InBitmapX(BW, x)));
  1589.     rectangle.y = min(y, InWindowY(BW, InBitmapY(BW, y)));
  1590.     rectangle.width = max(x + width,
  1591.              InWindowX(BW, InBitmapX(BW, x + width)+1)) - rectangle.x;
  1592.     rectangle.height = max(y + height,
  1593.              InWindowY(BW, InBitmapY(BW, y + height)+1)) - rectangle.y;
  1594.     
  1595.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1596.            rectangle.x, rectangle.y,
  1597.            rectangle.width, rectangle.height,
  1598.            False);
  1599.  
  1600.     XSetClipRectangles(XtDisplay(BW),
  1601.                BW->bitmap.frame_gc,
  1602.                0, 0,
  1603.                &rectangle, 1,
  1604.                Unsorted);
  1605.  
  1606.     XDrawRectangle(XtDisplay(BW), XtWindow(BW),
  1607.            BW->bitmap.frame_gc,
  1608.            InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
  1609.            InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, 
  1610.            InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
  1611.  
  1612.     BWClip((Widget) BW, x, y, width, height);
  1613.  
  1614.     BWRedrawGrid((Widget) BW, x, y, width, height);
  1615.  
  1616.     BWRedrawSquares((Widget) BW, x, y, width, height);
  1617.  
  1618.     BWRedrawMark((Widget) BW);
  1619.     BWRedrawHotSpot((Widget) BW);
  1620.     BWRedrawAxes((Widget) BW);
  1621.     BWUnclip((Widget) BW);
  1622. }
  1623.  
  1624. Boolean BWQueryGrid(w)
  1625.     Widget w;
  1626. {
  1627.     BitmapWidget BW = (BitmapWidget) w;
  1628.  
  1629.     return BW->bitmap.grid;
  1630. }
  1631.  
  1632. void BWSwitchGrid(w)
  1633.     Widget w;
  1634. {
  1635.     BitmapWidget BW = (BitmapWidget) w;
  1636.     BW->bitmap.grid ^= TRUE;
  1637.     BWDrawGrid(w,
  1638.            0, 0,
  1639.            BW->bitmap.image->width - 1, BW->bitmap.image->height - 1);
  1640. }
  1641.  
  1642. void BWGrid(w, _switch)
  1643.     Widget w;
  1644.     Boolean _switch;
  1645. {
  1646.     BitmapWidget BW = (BitmapWidget) w;
  1647.     
  1648.     if (BW->bitmap.grid != _switch)
  1649.     BWSwitchGrid(w);
  1650. }
  1651.  
  1652. Boolean BWQueryDashed(w)
  1653.     Widget w;
  1654. {
  1655.     BitmapWidget BW = (BitmapWidget) w;
  1656.  
  1657.     return (BW->bitmap.dashed);
  1658. }
  1659.  
  1660. void BWSwitchDashed(w)
  1661.     Widget w;
  1662. {
  1663.     BitmapWidget BW = (BitmapWidget) w;
  1664.     XRectangle rectangle;
  1665.  
  1666.     BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1);
  1667.  
  1668.     rectangle.x = 0;
  1669.     rectangle.y = 0;
  1670.     rectangle.width = BW->core.width;
  1671.     rectangle.height = BW->core.height;
  1672.  
  1673.     XSetClipRectangles(XtDisplay(BW),
  1674.                BW->bitmap.frame_gc,
  1675.                0, 0,
  1676.                &rectangle, 1,
  1677.                Unsorted);
  1678.  
  1679.     XDrawRectangle(XtDisplay(BW), XtWindow(BW),
  1680.            BW->bitmap.frame_gc,
  1681.            InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
  1682.            InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, 
  1683.            InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
  1684.     
  1685.     BW->bitmap.dashed ^= True;
  1686.     XSetFillStyle(XtDisplay(BW), BW->bitmap.frame_gc,
  1687.           (BW->bitmap.dashed ? FillStippled : FillSolid));
  1688.  
  1689.     XDrawRectangle(XtDisplay(BW), XtWindow(BW),
  1690.            BW->bitmap.frame_gc,
  1691.            InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
  1692.            InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, 
  1693.            InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
  1694.  
  1695.     BWUnclip(w);
  1696.    
  1697.     BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1);
  1698. }
  1699.  
  1700. void BWDashed(w, _switch)
  1701.     Widget w;
  1702.     Boolean _switch;
  1703. {
  1704.     BitmapWidget BW = (BitmapWidget) w;
  1705.     
  1706.     if (BW->bitmap.dashed != _switch)
  1707.     BWSwitchDashed(w);
  1708. }
  1709.  
  1710. static Boolean SetValues(old, request, new, args, num_args) /* ARGSUSED */
  1711.      Widget old, request, new;
  1712.      ArgList args;
  1713.      Cardinal num_args;
  1714. {
  1715.   BitmapWidget oldbw = (BitmapWidget) old;
  1716.   BitmapWidget newbw = (BitmapWidget) new;
  1717.   Boolean resize = False;
  1718.   Boolean redisplay = False;
  1719.  
  1720. #define NE(field) (oldbw->field != newbw->field)
  1721.  
  1722.   if (NE(bitmap.grid))
  1723.     BWSwitchGrid(old);
  1724.  
  1725.   if (NE(bitmap.dashed))
  1726.     BWSwitchDashed(old);
  1727.  
  1728.   if (NE(bitmap.axes))
  1729.     BWSwitchAxes(old);
  1730.  
  1731.   if (NE(bitmap.stippled))
  1732.     BWSwitchStippled(old);
  1733.  
  1734.   if (NE(bitmap.proportional))
  1735.     resize = True;
  1736.  
  1737.   if (NE(bitmap.filename) || NE(bitmap.basename)  || NE(bitmap.size))
  1738.     BWChangeNotify(old, NULL, NULL);
  1739.  
  1740.   if (NE(bitmap.filename))
  1741.     if (newbw->bitmap.filename) {
  1742.       XtFree(oldbw->bitmap.filename);
  1743.       newbw->bitmap.filename = XtNewString(newbw->bitmap.filename);
  1744.     }
  1745.     else 
  1746.       newbw->bitmap.filename = oldbw->bitmap.filename;
  1747.  
  1748.   if (NE(bitmap.basename))
  1749.     if (newbw->bitmap.basename) {
  1750.       XtFree(oldbw->bitmap.basename);
  1751.       newbw->bitmap.basename = XtNewString(newbw->bitmap.basename);
  1752.     }
  1753.     else 
  1754.       newbw->bitmap.basename = oldbw->bitmap.basename;
  1755.   
  1756.   if (NE(bitmap.size)) {
  1757.     Dimension width, height;
  1758.     
  1759.     if (BWParseSize(newbw->bitmap.size, &width, &height)) { 
  1760.       ResizeGrid(newbw, width, height);
  1761.       resize = True;
  1762.     }
  1763.   }
  1764.   
  1765.   if (NE(bitmap.margin) || 
  1766.       NE(bitmap.grid_tolerance) ||
  1767.       NE(bitmap.squareW) ||
  1768.       NE(bitmap.squareH) ||
  1769.       NE(core.height) ||
  1770.       NE(core.width))
  1771.     resize = True;
  1772.  
  1773.   if (NE(bitmap.hot.x) || NE(bitmap.hot.y))
  1774.     BWSetHotSpot(old, newbw->bitmap.hot.x, newbw->bitmap.hot.y);
  1775.     
  1776.   if (NE(bitmap.foreground_pixel) || NE(core.background_pixel)) {
  1777.     XSetForeground(XtDisplay(new), 
  1778.            newbw->bitmap.drawing_gc,
  1779.            newbw->bitmap.foreground_pixel 
  1780.            ^ 
  1781.            newbw->core.background_pixel);
  1782.     redisplay = True;
  1783.   }
  1784.  
  1785.   if (NE(bitmap.frame_pixel) || NE(core.background_pixel)) {
  1786.     XSetForeground(XtDisplay(new), 
  1787.            newbw->bitmap.frame_gc,
  1788.            newbw->bitmap.frame_pixel
  1789.            ^ 
  1790.            newbw->core.background_pixel);
  1791.     redisplay = True;
  1792.   }
  1793.  
  1794.   if (NE(bitmap.dashes)) {
  1795.     XSetStipple(XtDisplay(new),
  1796.         newbw->bitmap.frame_gc,
  1797.         newbw->bitmap.dashes);
  1798.     redisplay = True;
  1799.   }
  1800.  
  1801.   if (NE(bitmap.highlight_pixel) || NE(core.background_pixel)) {
  1802.     RedrawStippled(newbw);
  1803.     XSetForeground(XtDisplay(new), 
  1804.            newbw->bitmap.highlighting_gc,
  1805.            newbw->bitmap.highlight_pixel
  1806.            ^ 
  1807.            newbw->core.background_pixel);
  1808.     RedrawStippled(newbw);
  1809.   }
  1810.  
  1811.   if (NE(bitmap.stipple)) {
  1812.     RedrawStippled(newbw);
  1813.     XSetStipple(XtDisplay(new),
  1814.         newbw->bitmap.highlighting_gc,
  1815.         newbw->bitmap.stipple);
  1816.     RedrawStippled(newbw);
  1817.   }
  1818.   
  1819.   if (resize) Resize(newbw);
  1820.  
  1821.     return (redisplay || resize);
  1822.  
  1823. #undef NE
  1824. }
  1825.  
  1826. Boolean BWQueryProportional(w)
  1827.     Widget w;
  1828. {
  1829.     BitmapWidget BW = (BitmapWidget) w;
  1830.  
  1831.     return (BW->bitmap.proportional);
  1832. }
  1833.  
  1834. void BWSwitchProportional(w)
  1835.     Widget w;
  1836. {
  1837.     BitmapWidget BW = (BitmapWidget) w;
  1838.  
  1839.     BW->bitmap.proportional ^= True;
  1840.  
  1841.     Resize(BW);
  1842.     if (BW->core.visible)
  1843.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1844.            0, 0, 
  1845.            BW->core.width, BW->core.height,
  1846.            True);
  1847. }
  1848.  
  1849. void BWProportional(w, _switch)
  1850.     Widget w;
  1851.     Boolean _switch;
  1852. {
  1853.     BitmapWidget BW = (BitmapWidget) w;
  1854.  
  1855.     if (BW->bitmap.proportional != _switch)
  1856.     BWSwitchProportional(w);
  1857. }
  1858.  
  1859.  
  1860. void BWTPaste(w, event)
  1861.     Widget  w;
  1862.     XEvent *event;
  1863. {
  1864.     BitmapWidget BW = (BitmapWidget) w;
  1865.  
  1866.     BWRequestSelection(w, event->xbutton.time, TRUE);
  1867.  
  1868.     if (!BWQueryStored(w))
  1869.     return;
  1870.     
  1871.     BWEngageRequest(w, RestoreRequest, False, 
  1872.             (char *)&(event->xbutton.state), sizeof(int));
  1873.     
  1874.     OnePointHandler(w,
  1875.            (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status,
  1876.            event);
  1877. }
  1878.  
  1879. void BWTMark(w, event)
  1880.     Widget  w;
  1881.     XEvent *event;
  1882. {
  1883.     BitmapWidget BW = (BitmapWidget) w;
  1884.  
  1885.     BWEngageRequest(w, MarkRequest, False,
  1886.             (char *)&(event->xbutton.state), sizeof(int));
  1887.     TwoPointsHandler(w,
  1888.             (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status,
  1889.          event);
  1890.  
  1891. }
  1892.  
  1893. void BWTMarkAll(w, event)
  1894.     Widget w;
  1895.     XEvent *event;
  1896. {
  1897.     BWMarkAll(w);
  1898.  
  1899.     BWGrabSelection(w, event->xkey.time);
  1900. }
  1901.  
  1902. void BWTUnmark(w)
  1903.     Widget w;
  1904. {
  1905.     BWUnmark(w);
  1906. }
  1907.  
  1908. /*****************************************************************************/
  1909.