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