/* Copyright 1989, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* * Author: Davor Matic, MIT X Consortium */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include "BitmapP.h" #include "Bitmap.h" #include #include #include #define min(x, y) ((((int)(x)) < (int)(y)) ? (x) : (y)) #define max(x, y) ((((int)(x)) > (int)(y)) ? (x) : (y)) Boolean DEBUG; #define DefaultGridTolerance 8 #define DefaultBitmapSize "16x16" #define FallbackBitmapWidth 16 #define FallbackBitmapHeight 16 #define DefaultGrid TRUE #define DefaultDashed TRUE #define DefaultStippled TRUE #define DefaultProportional TRUE #define DefaultAxes FALSE #define DefaultMargin 16 #define DefaultSquareWidth 16 #define DefaultSquareHeight 16 #define DefaultFilename "" #define Offset(field) XtOffsetOf(BitmapRec, bitmap.field) static XtResource resources[] = { {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), Offset(foreground_pixel), XtRString, XtDefaultForeground}, {XtNhighlight, XtCHighlight, XtRPixel, sizeof(Pixel), Offset(highlight_pixel), XtRString, XtDefaultForeground}, {XtNframe, XtCFrame, XtRPixel, sizeof(Pixel), Offset(frame_pixel), XtRString, XtDefaultForeground}, {XtNgridTolerance, XtCGridTolerance, XtRDimension, sizeof(Dimension), Offset(grid_tolerance), XtRImmediate, (XtPointer) DefaultGridTolerance}, {XtNsize, XtCSize, XtRString, sizeof(String), Offset(size), XtRImmediate, (XtPointer) DefaultBitmapSize}, {XtNdashed, XtCDashed, XtRBoolean, sizeof(Boolean), Offset(dashed), XtRImmediate, (XtPointer) DefaultDashed}, {XtNgrid, XtCGrid, XtRBoolean, sizeof(Boolean), Offset(grid), XtRImmediate, (XtPointer) DefaultGrid}, {XtNstippled, XtCStippled, XtRBoolean, sizeof(Boolean), Offset(stippled), XtRImmediate, (XtPointer) DefaultStippled}, {XtNproportional, XtCProportional, XtRBoolean, sizeof(Boolean), Offset(proportional), XtRImmediate, (XtPointer) DefaultProportional}, {XtNaxes, XtCAxes, XtRBoolean, sizeof(Boolean), Offset(axes), XtRImmediate, (XtPointer) DefaultAxes}, {XtNsquareWidth, XtCSquareWidth, XtRDimension, sizeof(Dimension), Offset(squareW), XtRImmediate, (XtPointer) DefaultSquareWidth}, {XtNsquareHeight, XtCSquareHeight, XtRDimension, sizeof(Dimension), Offset(squareH), XtRImmediate, (XtPointer) DefaultSquareHeight}, {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension), Offset(margin), XtRImmediate, (XtPointer) DefaultMargin}, {XtNxHot, XtCXHot, XtRPosition, sizeof(Position), Offset(hot.x), XtRImmediate, (XtPointer) NotSet}, {XtNyHot, XtCYHot, XtRPosition, sizeof(Position), Offset(hot.y), XtRImmediate, (XtPointer) NotSet}, {XtNbutton1Function, XtCButton1Function, XtRButtonFunction, sizeof(int), Offset(button_function[0]), XtRImmediate, (XtPointer) Set}, {XtNbutton2Function, XtCButton2Function, XtRButtonFunction, sizeof(int), Offset(button_function[1]), XtRImmediate, (XtPointer) Invert}, {XtNbutton3Function, XtCButton3Function, XtRButtonFunction, sizeof(int), Offset(button_function[2]), XtRImmediate, (XtPointer) Clear}, {XtNbutton4Function, XtCButton4Function, XtRButtonFunction, sizeof(int), Offset(button_function[3]), XtRImmediate, (XtPointer) Clear}, {XtNbutton5Function, XtCButton5Function, XtRButtonFunction, sizeof(int), Offset(button_function[4]), XtRImmediate, (XtPointer) Clear}, {XtNfilename, XtCFilename, XtRString, sizeof(String), Offset(filename), XtRImmediate, (XtPointer) DefaultFilename}, {XtNbasename, XtCBasename, XtRString, sizeof(String), Offset(basename), XtRImmediate, (XtPointer) DefaultFilename}, {XtNdashes, XtCDashes, XtRBitmap, sizeof(Pixmap), Offset(dashes), XtRImmediate, (XtPointer) XtUnspecifiedPixmap}, {XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap), Offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap}, }; #undef Offset static XtActionsRec actions[] = { {"mark", (XtActionProc)BWTMark}, {"mark-all", (XtActionProc)BWTMarkAll}, {"unmark", (XtActionProc)BWTUnmark}, {"paste", (XtActionProc)BWTPaste}, {"bw-debug", (XtActionProc)BWDebug}, {"abort", (XtActionProc)BWAbort}, {"store-to-buffer", (XtActionProc)BWStoreToBuffer}, {"change-notify", (XtActionProc)BWChangeNotify}, {"set-changed", (XtActionProc)BWSetChanged}, {"up", (XtActionProc)BWUp}, {"down", (XtActionProc)BWDown}, {"left", (XtActionProc)BWLeft}, {"right", (XtActionProc)BWRight}, {"fold", (XtActionProc)BWFold}, {"flip-horiz", (XtActionProc)BWFlipHoriz}, {"flip-vert", (XtActionProc)BWFlipVert}, {"rotate-right", (XtActionProc)BWRotateRight}, {"rotate-left", (XtActionProc)BWRotateLeft}, {"set", (XtActionProc)BWSet}, {"clear", (XtActionProc)BWClear}, {"invert", (XtActionProc)BWInvert}, {"undo", (XtActionProc)BWUndo}, {"redraw", (XtActionProc)BWRedraw}, }; static char translations1[] = "\ Shift: mark()\n\ Shift: mark-all()\n\ Shift: unmark()\n\ Ctrl: paste()\n\ Ctrll: redraw()\n\ d: bw-debug()\n\ a: abort()\n\ Up: store-to-buffer()\ up()\ change-notify()\ set-changed()\n\ KP_Up: store-to-buffer()\ up()\ change-notify()\ set-changed()\n\ Down: store-to-buffer()\ down()\ change-notify()\ set-changed()\n\ KP_Down: store-to-buffer()\ down()\ change-notify()\ set-changed()\n\ Left: store-to-buffer()\ left()\ change-notify()\ set-changed()\n\ KP_Left: store-to-buffer()\ left()\ change-notify()\ set-changed()\n\ Right: store-to-buffer()\ right()\ change-notify()\ set-changed()\n\ KP_Right: store-to-buffer()\ right()\ change-notify()\ set-changed()\n\ f: store-to-buffer()\ fold()\ change-notify()\ set-changed()\n\ h: store-to-buffer()\ flip-horiz()\ change-notify()\ set-changed()\n\ "; static char translations2[] = "v: store-to-buffer()\ flip-vert()\ change-notify()\ set-changed()\n\ r: store-to-buffer()\ rotate-right()\ change-notify()\ set-changed()\n\ l: store-to-buffer()\ rotate-left()\ change-notify()\ set-changed()\n\ s: store-to-buffer()\ set()\ change-notify()\ set-changed()\n\ c: store-to-buffer()\ clear()\ change-notify()\ set-changed()\n\ i: store-to-buffer()\ invert()\ change-notify()\ set-changed()\n\ u: undo()\ change-notify()\ set-changed()\n\ "; static Atom targets[] = { XA_BITMAP, XA_PIXMAP }; #include "Requests.h" static BWRequestRec requests[] = { {MarkRequest, sizeof(BWStatus), TwoPointsEngage, (XtPointer) BWDrawRectangle, TwoPointsTerminateTimed, (XtPointer) BWSelect, NULL, (XtPointer) NULL}, {RestoreRequest, sizeof(BWStatus), OnePointEngage, (XtPointer) BWDragStored, OnePointTerminate, (XtPointer) BWRestore, NULL, (XtPointer) NULL}, {ImmediateCopyRequest, sizeof(BWStatus), OnePointEngage, (XtPointer) BWDragMarked, OnePointTerminate, (XtPointer) BWCopy, NULL, (XtPointer) NULL}, {ImmediateMoveRequest, sizeof(BWStatus), OnePointEngage, (XtPointer) BWDragMarked, OnePointTerminate, (XtPointer) BWMove, NULL, (XtPointer) NULL}, {CopyRequest, sizeof(BWStatus), DragOnePointEngage, (XtPointer) Paste, DragOnePointTerminate, (XtPointer) ImmediateCopyRequest, Interface, (XtPointer) BWUnmark}, {MoveRequest, sizeof(BWStatus), DragOnePointEngage, (XtPointer) Paste, DragOnePointTerminate, (XtPointer) ImmediateMoveRequest, Interface, (XtPointer) BWUnmark}, {PointRequest, sizeof(BWStatus), DragOnePointEngage, (XtPointer) BWDrawPoint, DragOnePointTerminate, (XtPointer) BWDrawPoint, NULL, (XtPointer) NULL}, {CurveRequest, sizeof(BWStatus), DragTwoPointsEngage, (XtPointer) BWBlindLine, DragTwoPointsTerminate, (XtPointer) BWBlindLine, NULL, (XtPointer) NULL}, {LineRequest, sizeof(BWStatus), TwoPointsEngage, (XtPointer) BWDrawLine, TwoPointsTerminate, (XtPointer) BWDrawLine, NULL, (XtPointer) NULL}, {RectangleRequest, sizeof(BWStatus), TwoPointsEngage, (XtPointer) BWDrawRectangle, TwoPointsTerminate, (XtPointer) BWDrawRectangle, NULL, (XtPointer) NULL}, {FilledRectangleRequest, sizeof(BWStatus), TwoPointsEngage, (XtPointer) BWDrawRectangle, TwoPointsTerminate, (XtPointer) BWDrawFilledRectangle, NULL, (XtPointer) NULL}, {CircleRequest, sizeof(BWStatus), TwoPointsEngage, (XtPointer) BWDrawCircle, TwoPointsTerminate, (XtPointer) BWDrawCircle, NULL, (XtPointer) NULL}, {FilledCircleRequest, sizeof(BWStatus), TwoPointsEngage, (XtPointer) BWDrawCircle, TwoPointsTerminate, (XtPointer) BWDrawFilledCircle, NULL, (XtPointer) NULL}, {FloodFillRequest, sizeof(BWStatus), OnePointEngage, (XtPointer) NULL, OnePointTerminate, (XtPointer) BWFloodFill, NULL, (XtPointer) NULL}, {HotSpotRequest, sizeof(BWStatus), OnePointEngage, (XtPointer) BWDrawHotSpot, OnePointTerminate, (XtPointer) BWDrawHotSpot, NULL, (XtPointer) NULL}, {ZoomInRequest, sizeof(BWStatus), TwoPointsEngage, (XtPointer) BWDrawRectangle, TwoPointsTerminate, (XtPointer) BWZoomIn, NULL, (XtPointer) NULL}, }; static void ClassInitialize(void); static void Initialize(Widget wrequest, Widget wnew, ArgList argv, Cardinal *argc); static void Redisplay(Widget w, XEvent *event, Region region); static void Resize(Widget w); static void Destroy(Widget w); static void Refresh(BitmapWidget BW, Position x, Position y, Dimension width, Dimension height); static Boolean SetValues(Widget old, Widget request, Widget new, ArgList args, Cardinal *num_args); BitmapClassRec bitmapClassRec = { { /* core fields */ /* superclass */ (WidgetClass) &simpleClassRec, /* class_name */ "Bitmap", /* widget_size */ sizeof(BitmapRec), /* class_initialize */ ClassInitialize, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ actions, /* num_actions */ XtNumber(actions), /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ FALSE, /* compress_enterleave */ TRUE, /* visible_interest */ TRUE, /* destroy */ Destroy, /* resize */ Resize, /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL , /* set in code */ /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL, }, { /* empty */ XtInheritChangeSensitive, }, { /* targets */ targets, /* num_trets */ XtNumber(targets), /* requests */ requests, /* num_requests */ XtNumber(requests), } }; WidgetClass bitmapWidgetClass = (WidgetClass) &bitmapClassRec; /* ARGSUSED */ void BWDebug(Widget w, XEvent *event, String *params, Cardinal *num_params) { DEBUG ^= True; } Pixmap BWGetPixmap(Widget w) { BitmapWidget BW = (BitmapWidget) w; return GetPixmap(BW, BW->bitmap.zoom.image); } Pixmap BWGetUnzoomedPixmap(Widget w) { BitmapWidget BW = (BitmapWidget) w; GC gc; Pixmap pix; if (BW->bitmap.zooming) { pix = XCreatePixmap(XtDisplay(w), XtWindow(w), BW->bitmap.zoom.image->width, BW->bitmap.zoom.image->height, 1); if (!(gc = XCreateGC(XtDisplay(w), pix, (unsigned long) 0, (XGCValues *) 0))) { XFreePixmap(XtDisplay(w), pix); return (Pixmap) None; } XPutImage(XtDisplay(w), pix, gc, BW->bitmap.zoom.image, 0, 0, 0, 0, BW->bitmap.zoom.image->width, BW->bitmap.zoom.image->height); XPutImage(XtDisplay(w), pix, gc, BW->bitmap.image, 0, 0, BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y, BW->bitmap.image->width, BW->bitmap.image->height); } else { pix = XCreatePixmap(XtDisplay(w), XtWindow(w), BW->bitmap.image->width, BW->bitmap.image->height, 1); if (! (gc = XCreateGC(XtDisplay(w), pix, (unsigned long) 0, (XGCValues *) 0))){ XFreePixmap(XtDisplay(w), pix); return (Pixmap) None; } XPutImage(XtDisplay(w), pix, gc, BW->bitmap.image, 0, 0, 0, 0, BW->bitmap.image->width, BW->bitmap.image->height); } XFreeGC(XtDisplay(w), gc); return(pix); } XImage * GetImage(BitmapWidget BW, Pixmap pixmap) { Window root; int x, y; unsigned int width, height, border_width, depth; XImage *source, *image; XGetGeometry(XtDisplay(BW), pixmap, &root, &x, &y, &width, &height, &border_width, &depth); source = XGetImage(XtDisplay(BW), pixmap, x, y, width, height, 1, XYPixmap); image = ConvertToBitmapImage(BW, source); return image; } XImage * CreateBitmapImage(BitmapWidget BW, char *data, Dimension width, Dimension height) { XImage *image = XCreateImage(XtDisplay(BW), DefaultVisual(XtDisplay(BW), DefaultScreen(XtDisplay(BW))), 1, XYBitmap, 0, data, width, height, 8, ((int)width + 7) / 8); image->height = height; image->width = width; image->depth = 1; image->xoffset = 0; image->format = XYBitmap; image->data = (char *)data; image->byte_order = LSBFirst; image->bitmap_unit = 8; image->bitmap_bit_order = LSBFirst; image->bitmap_pad = 8; image->bytes_per_line = ((int)width + 7) / 8; return image; } void DestroyBitmapImage(XImage **image) { /*XDestroyImage(*image);*/ if (image) { if (*image) { if ((*image)->data) XtFree((*image)->data); XtFree((char *)*image); } *image = NULL; } } #if 0 XImage * BWGetImage(Widget w, XEvent *event, String *params, Cardinal *num_params) { BitmapWidget BW = (BitmapWidget) w; return BW->bitmap.image; } #endif void BWChangeNotify(Widget w) { BitmapWidget BW = (BitmapWidget) w; if (BW->bitmap.notify) (*BW->bitmap.notify)(w, NULL, NULL, NULL); } void BWNotify(Widget w, XtActionProc proc) { BitmapWidget BW = (BitmapWidget) w; BW->bitmap.notify = proc; } void BWSetChanged(Widget w) { BitmapWidget BW = (BitmapWidget) w; BW->bitmap.changed = True; } Boolean BWQueryChanged(Widget w) { BitmapWidget BW = (BitmapWidget) w; return BW->bitmap.changed; } void BWClearChanged(Widget w) { BitmapWidget BW = (BitmapWidget) w; BW->bitmap.changed = False; } Boolean BWQueryStored(Widget w) { BitmapWidget BW = (BitmapWidget) w; return (BW->bitmap.storage != NULL); } Boolean BWQueryStippled(Widget w) { BitmapWidget BW = (BitmapWidget) w; return BW->bitmap.stippled; } static void RedrawStippled(BitmapWidget BW) { XExposeEvent event; event.type = Expose; event.display = XtDisplay((Widget)BW); event.window = XtWindow((Widget)BW); event.x = 0; event.y = 0; event.width = BW->core.width; event.height = BW->core.height; event.count = 0; BWRedrawMark((Widget)BW); BW->bitmap.stipple_change_expose_event = True; XtDispatchEvent((XEvent *)&event); BW->bitmap.stipple_change_expose_event = False; } void BWSwitchStippled(Widget w) { BitmapWidget BW = (BitmapWidget) w; RedrawStippled(BW); BW->bitmap.stippled ^= True; XSetFillStyle(XtDisplay(BW), BW->bitmap.highlighting_gc, (BW->bitmap.stippled ? FillStippled : FillSolid)); RedrawStippled(BW); } void BWSelect(Widget w, Position from_x, Position from_y, Position to_x, Position to_y, Time btime) { BWMark(w, from_x, from_y, to_x, to_y); BWGrabSelection(w, btime); } Boolean BWQueryAxes(Widget w) { BitmapWidget BW = (BitmapWidget) w; return BW->bitmap.axes; } void BWSwitchAxes(Widget w) { BitmapWidget BW = (BitmapWidget) w; BW->bitmap.axes ^= True; BWHighlightAxes(w); } void BWAxes(Widget w, Boolean _switch) { BitmapWidget BW = (BitmapWidget) w; if (BW->bitmap.axes != _switch) BWSwitchAxes(w); } void BWRedrawAxes(Widget w) { BitmapWidget BW = (BitmapWidget) w; if (BW->bitmap.axes) BWHighlightAxes(w); } #if 0 void BWPutImage(BitmapWidget w, Display *display, Drawable drawable, GC gc, Position x, Position y) { BitmapWidget BW = (BitmapWidget) w; XPutImage(display, drawable, gc, BW->bitmap.image, 0, 0, x, y, BW->bitmap.image->width, BW->bitmap.image->height); } #endif static char * StripFilename(_Xconst _XtString filename) { const char *begin = strrchr(filename, '/'); const char *end; char *result; int length; if (filename) { begin = (begin ? begin + 1 : filename); end = strchr(begin, '.'); /* change to strrchr to allow longer names */ length = (end ? (end - begin) : strlen (begin)); result = (char *) XtMalloc (length + 1); strncpy (result, begin, length); result [length] = '\0'; return (result); } else return (NULL); } static int XmuWriteBitmapDataToFile(_Xconst _XtString filename, _Xconst _XtString basename, int width, int height, char *datap, int x_hot, int y_hot) { FILE *file; int i, data_length; data_length = Length(width, height); if(!filename || !strcmp(filename, "") || !strcmp(filename, "-")) { file = stdout; filename = "dummy"; } else file = fopen(filename, "w+"); if (file) { char *new_basename; if (!basename || !strcmp(basename, "") || !strcmp(basename, "-")) basename = new_basename = StripFilename(filename); else new_basename = NULL; fprintf(file, "#define %s_width %d\n", basename, width); fprintf(file, "#define %s_height %d\n", basename, height); if (QuerySet(x_hot, y_hot)) { fprintf(file, "#define %s_x_hot %d\n", basename, x_hot); fprintf(file, "#define %s_y_hot %d\n", basename, y_hot); } fprintf(file, "static unsigned char %s_bits[] = {\n 0x%02x", basename, (unsigned char) datap[0]); for(i = 1; i < data_length; i++) { fprintf(file, ","); fprintf(file, (i % 12) ? " " : "\n "); fprintf(file, "0x%02x", (unsigned char) datap[i]); } fprintf(file, "};\n"); if (file != stdout) fclose(file); XtFree(new_basename); return BitmapSuccess; } return 1; } /* * */ /* ARGSUSED */ static void CvtStringToButtonFunction(XrmValuePtr args, /* not used */ Cardinal *num_args, /* not used */ XrmValuePtr from_val, XrmValuePtr to_val) { static int button_function; char lower_name[80]; XmuCopyISOLatin1Lowered (lower_name, (char*)from_val->addr); if (!strcmp(lower_name, XtClear)) { button_function = Clear; to_val->addr = (XPointer) &button_function; to_val->size = sizeof(button_function); return; } if (!strcmp(lower_name, XtSet)) { button_function = Set; to_val->addr = (XPointer) &button_function; to_val->size = sizeof(button_function); return; } if (!strcmp(lower_name, XtInvert)) { button_function = Invert; to_val->addr = (XPointer) &button_function; to_val->size = sizeof(button_function); return; } XtStringConversionWarning(from_val->addr, XtRButtonFunction); button_function = Clear; to_val->addr = (XPointer) &button_function; to_val->size = sizeof(button_function); } static void ClassInitialize(void) { char *tm_table = XtMalloc(strlen(translations1) + strlen(translations2) + 1); strcpy(tm_table, translations1); strcat(tm_table, translations2); bitmapClassRec.core_class.tm_table = tm_table; XawInitializeWidgetSet(); XtAddConverter(XtRString, XtRButtonFunction, CvtStringToButtonFunction, NULL, 0); DEBUG = False; } static void SetSizeFromSizeResource(BitmapWidget bw) { if (BWParseSize(bw->bitmap.size, &bw->bitmap.width, &bw->bitmap.height) == False) { bw->bitmap.width = FallbackBitmapWidth; bw->bitmap.height = FallbackBitmapHeight; XtWarning("Cannot parse the size resource. BitmapWidget"); } } /* ARGSUSED */ static void Initialize(Widget wrequest, Widget wnew, ArgList argv, Cardinal *argc) { BitmapWidget new = (BitmapWidget) wnew; XGCValues values; XtGCMask mask; char *image_data, *buffer_data; new->bitmap.stipple_change_expose_event = False; new->bitmap.notify = NULL; new->bitmap.cardinal = 0; new->bitmap.current = 0; new->bitmap.fold = False; new->bitmap.changed = False; new->bitmap.zooming = False; new->bitmap.selection.own = False; new->bitmap.selection.limbo = False; new->bitmap.request_stack = (BWRequestStack *) XtMalloc(sizeof(BWRequestStack)); new->bitmap.request_stack[0].request = NULL; new->bitmap.request_stack[0].call_data = NULL; new->bitmap.request_stack[0].trap = False; SetSizeFromSizeResource(new); new->core.width = new->bitmap.width * new->bitmap.squareW + 2 * new->bitmap.margin; new->core.height = new->bitmap.height * new->bitmap.squareH + 2 * new->bitmap.margin; new->bitmap.hot.x = new->bitmap.hot.y = NotSet; new->bitmap.buffer_hot.x = new->bitmap.buffer_hot.y = NotSet; new->bitmap.mark.from_x = new->bitmap.mark.from_y = NotSet; new->bitmap.mark.to_x = new->bitmap.mark.to_y = NotSet; new->bitmap.buffer_mark.from_x = new->bitmap.buffer_mark.from_y = NotSet; new->bitmap.buffer_mark.to_x = new->bitmap.buffer_mark.to_y = NotSet; values.foreground = new->bitmap.foreground_pixel; values.background = new->core.background_pixel; values.foreground ^= values.background; values.function = GXxor; mask = GCForeground | GCBackground | GCFunction; new->bitmap.drawing_gc = XCreateGC(XtDisplay(new), RootWindow(XtDisplay(new), DefaultScreen(XtDisplay(new))), mask, &values); values.foreground = new->bitmap.highlight_pixel; values.background = new->core.background_pixel; values.foreground ^= values.background; values.function = GXxor; mask = GCForeground | GCBackground | GCFunction; if (new->bitmap.stipple != XtUnspecifiedPixmap) { values.stipple = new->bitmap.stipple; mask |= GCStipple | GCFillStyle; } values.fill_style = (new->bitmap.stippled ? FillStippled : FillSolid); new->bitmap.highlighting_gc = XCreateGC(XtDisplay(new), RootWindow(XtDisplay(new), DefaultScreen(XtDisplay(new))), mask, &values); values.foreground = new->bitmap.frame_pixel; values.background = new->core.background_pixel; values.foreground ^= values.background; mask = GCForeground | GCBackground | GCFunction; if (new->bitmap.dashes != XtUnspecifiedPixmap) { values.stipple = new->bitmap.dashes; mask |= GCStipple | GCFillStyle; } values.fill_style = (new->bitmap.dashed ? FillStippled : FillSolid); new->bitmap.frame_gc = XCreateGC(XtDisplay(new), RootWindow(XtDisplay(new), DefaultScreen(XtDisplay(new))), mask, &values); values.foreground = new->bitmap.highlight_pixel; values.background = new->core.background_pixel; values.foreground ^= values.background; mask = GCForeground | GCBackground | GCFunction; new->bitmap.axes_gc = XCreateGC(XtDisplay(new), RootWindow(XtDisplay(new), DefaultScreen(XtDisplay(new))), mask, &values); image_data = CreateCleanData(Length(new->bitmap.width, new->bitmap.height)); buffer_data = CreateCleanData(Length(new->bitmap.width, new->bitmap.height)); new->bitmap.storage = NULL; new->bitmap.image = CreateBitmapImage(new, image_data, new->bitmap.width, new->bitmap.height); new->bitmap.buffer = CreateBitmapImage(new, buffer_data, new->bitmap.width, new->bitmap.height); /* Read file */ { int status; XImage *image, *buffer; unsigned char *image_data2; char *buffer_data2; unsigned int width, height; int x_hot, y_hot; status = XmuReadBitmapDataFromFile(new->bitmap.filename, &width, &height, &image_data2, &x_hot, &y_hot); if (status == BitmapSuccess) { buffer_data2 = CreateCleanData(Length(width, height)); image = CreateBitmapImage(new, (char *)image_data2, width, height); buffer = CreateBitmapImage(new, buffer_data2, width, height); TransferImageData(new->bitmap.image, buffer); DestroyBitmapImage(&new->bitmap.image); DestroyBitmapImage(&new->bitmap.buffer); new->bitmap.image = image; new->bitmap.buffer = buffer; new->bitmap.width = width; new->bitmap.height = height; new->bitmap.hot.x = x_hot; new->bitmap.hot.y = y_hot; new->bitmap.changed = False; new->bitmap.zooming = False; } new->bitmap.filename = XtNewString(new->bitmap.filename); if (!strcmp(new->bitmap.basename, "")) { new->bitmap.basename = StripFilename(new->bitmap.filename); } else new->bitmap.basename = XtNewString(new->bitmap.basename); } Resize((Widget)new); } /* returns False if the format is wrong */ Boolean BWParseSize(String size, Dimension *width, Dimension *height) { int x, y; unsigned int w, h; int status; status = XParseGeometry(size, &x, &y, &w, &h); if (status & WidthValue) { *width = (Dimension) w; if (status & HeightValue) { *height = (Dimension) h; return True; } } return False; } Boolean BWQueryMarked(Widget w) { BitmapWidget BW = (BitmapWidget) w; return QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y); } static void FixMark(BitmapWidget BW) { if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { BW->bitmap.mark.from_x = min(BW->bitmap.mark.from_x, BW->bitmap.image->width); BW->bitmap.mark.from_y = min(BW->bitmap.mark.from_y, BW->bitmap.image->height); BW->bitmap.mark.to_x = min(BW->bitmap.mark.to_x, BW->bitmap.image->width); BW->bitmap.mark.to_y = min(BW->bitmap.mark.to_y, BW->bitmap.image->height); if((BW->bitmap.mark.from_x == BW->bitmap.mark.from_y) && (BW->bitmap.mark.to_x == BW->bitmap.mark.to_y)) BW->bitmap.mark.from_x = BW->bitmap.mark.from_y = BW->bitmap.mark.to_x = BW->bitmap.mark.to_y = NotSet; } } /* ARGSUSED */ int BWStoreFile(Widget w, _Xconst _XtString filename, _Xconst _XtString *basename) { BitmapWidget BW = (BitmapWidget) w; int status; unsigned char *storage_data; unsigned int width, height; int x_hot, y_hot; status = XmuReadBitmapDataFromFile(filename, &width, &height, &storage_data, &x_hot, &y_hot); if (status == BitmapSuccess) { DestroyBitmapImage(&BW->bitmap.storage); BW->bitmap.storage = CreateBitmapImage(BW, (char *)storage_data, width, height); return BitmapSuccess; } else XtWarning(" read file failed. BitmapWidget"); return status; } String BWUnparseStatus(Widget w) { BitmapWidget BW = (BitmapWidget) w; snprintf(BW->bitmap.status, sizeof(BW->bitmap.status), "Filename: %s Basename: %s Size: %dx%d", (strcmp(BW->bitmap.filename, "") ? BW->bitmap.filename : ""), (strcmp(BW->bitmap.basename, "") ? BW->bitmap.basename : ""), BW->bitmap.width, BW->bitmap.height); return BW->bitmap.status; } void BWChangeFilename(Widget w, _Xconst _XtString str) { BitmapWidget BW = (BitmapWidget) w; if (str) { XtFree(BW->bitmap.filename); BW->bitmap.filename = XtNewString( str); } } void BWChangeBasename(Widget w, _Xconst _XtString str) { BitmapWidget BW = (BitmapWidget) w; if (str) { XtFree(BW->bitmap.basename); BW->bitmap.basename = XtNewString(str); } } int BWReadFile(Widget w, _Xconst _XtString filename, _Xconst _XtString basename) /* ARGSUSED */ { BitmapWidget BW = (BitmapWidget) w; int status; XImage *image, *buffer; unsigned char *image_data; char *buffer_data; unsigned int width, height; int x_hot, y_hot; if (!filename) filename = BW->bitmap.filename; status = XmuReadBitmapDataFromFile(filename, &width, &height, &image_data, &x_hot, &y_hot); if (status == BitmapSuccess) { buffer_data = CreateCleanData(Length(width, height)); image = CreateBitmapImage(BW, (char *)image_data, width, height); buffer = CreateBitmapImage(BW, buffer_data, width, height); TransferImageData(BW->bitmap.image, buffer); DestroyBitmapImage(&BW->bitmap.image); DestroyBitmapImage(&BW->bitmap.buffer); BW->bitmap.image = image; BW->bitmap.buffer = buffer; BW->bitmap.width = width; BW->bitmap.height = height; BW->bitmap.hot.x = x_hot; BW->bitmap.hot.y = y_hot; BW->bitmap.changed = False; BW->bitmap.zooming = False; XtFree(BW->bitmap.filename); BW->bitmap.filename = XtNewString(filename); XtFree(BW->bitmap.basename); BW->bitmap.basename = StripFilename(filename); BWUnmark(w); Resize((Widget)BW); if (BW->core.visible) { XClearArea(XtDisplay(BW), XtWindow(BW), 0, 0, BW->core.width, BW->core.height, True); } return BitmapSuccess; } else XtWarning(" read file failed. BitmapWidget"); return status; } #if 0 void BWSetImage(Widget w, XImage *image) { BitmapWidget BW = (BitmapWidget) w; XImage *buffer; char *buffer_data; buffer_data = CreateCleanData(Length(image->width, image->height)); buffer = CreateBitmapImage(BW, buffer_data, (Dimension) image->width, (Dimension) image->height); TransferImageData(BW->bitmap.image, buffer); DestroyBitmapImage(&BW->bitmap.image); DestroyBitmapImage(&BW->bitmap.buffer); BW->bitmap.image = image; BW->bitmap.buffer = buffer; BW->bitmap.width = image->width; BW->bitmap.height = image->height; Resize((Widget)BW); if (BW->core.visible) { XClearArea(XtDisplay(BW), XtWindow(BW), 0, 0, BW->core.width, BW->core.height, True); } } #endif int BWWriteFile(Widget w, _Xconst _XtString filename, _Xconst _XtString basename) { BitmapWidget BW = (BitmapWidget) w; char *data; XImage *image; XPoint hot; int status; if (BW->bitmap.zooming) { data = XtMalloc(Length(BW->bitmap.zoom.image->width, BW->bitmap.zoom.image->height)); memmove( data, BW->bitmap.zoom.image->data, Length(BW->bitmap.zoom.image->width, BW->bitmap.zoom.image->height)); image = CreateBitmapImage(BW, data, (Dimension) BW->bitmap.zoom.image->width, (Dimension) BW->bitmap.zoom.image->height); CopyImageData(BW->bitmap.image, image, 0, 0, BW->bitmap.image->width - 1, BW->bitmap.image->height - 1, BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y); if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) { hot.x = BW->bitmap.hot.x + BW->bitmap.zoom.at_x; hot.y = BW->bitmap.hot.y + BW->bitmap.zoom.at_y; } else hot = BW->bitmap.zoom.hot; } else { image = BW->bitmap.image; hot = BW->bitmap.hot; } if (!filename) filename = BW->bitmap.filename; else { XtFree(BW->bitmap.filename); BW->bitmap.filename = XtNewString(filename); XtFree(BW->bitmap.basename); BW->bitmap.basename = StripFilename(filename); } if (!basename) basename = BW->bitmap.basename; else { XtFree(BW->bitmap.basename); BW->bitmap.basename = XtNewString(basename); } if (DEBUG) fprintf(stderr, "Saving filename: %s %s\n", filename, basename); status = XmuWriteBitmapDataToFile(filename, basename, image->width, image->height, image->data, hot.x, hot.y); if (BW->bitmap.zooming) DestroyBitmapImage(&image); if (status == BitmapSuccess) BW->bitmap.changed = False; return status; } _XtString BWGetFilename(Widget w, _XtString *str) { BitmapWidget BW = (BitmapWidget) w; *str = XtNewString(BW->bitmap.filename); return *str; } _XtString BWGetFilepath(Widget w, _XtString *str) { BitmapWidget BW = (BitmapWidget) w; _XtString end; *str = XtNewString(BW->bitmap.filename); assert(*str); end = strrchr(*str, '/'); if (end) *(end + 1) = '\0'; else **str = '\0'; return *str; } _XtString BWGetBasename(Widget w, _XtString *str) { BitmapWidget BW = (BitmapWidget) w; *str = XtNewString(BW->bitmap.basename); return *str; } static void FixHotSpot(BitmapWidget BW) { if (!QueryInBitmap(BW, BW->bitmap.hot.x, BW->bitmap.hot.y)) BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet; } static void ZoomOut(BitmapWidget BW) { CopyImageData(BW->bitmap.image, BW->bitmap.zoom.image, 0, 0, BW->bitmap.image->width - 1, BW->bitmap.image->height - 1, BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y); DestroyBitmapImage(&BW->bitmap.image); DestroyBitmapImage(&BW->bitmap.buffer); BW->bitmap.image = BW->bitmap.zoom.image; BW->bitmap.buffer = BW->bitmap.zoom.buffer; BW->bitmap.width = BW->bitmap.image->width; BW->bitmap.height = BW->bitmap.image->height; BW->bitmap.fold = BW->bitmap.zoom.fold; BW->bitmap.changed |= BW->bitmap.zoom.changed; BW->bitmap.grid = BW->bitmap.zoom.grid; if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) { BW->bitmap.hot.x += BW->bitmap.zoom.at_x; BW->bitmap.hot.y += BW->bitmap.zoom.at_y; } else BW->bitmap.hot = BW->bitmap.zoom.hot; BW->bitmap.mark.from_x = NotSet; BW->bitmap.mark.from_y = NotSet; BW->bitmap.mark.to_x = NotSet; BW->bitmap.mark.to_y = NotSet; BW->bitmap.zooming = False; } void BWZoomOut(Widget w) { BitmapWidget BW = (BitmapWidget) w; if (BW->bitmap.zooming) { ZoomOut(BW); Resize((Widget)BW); if (BW->core.visible) XClearArea(XtDisplay(BW), XtWindow(BW), 0, 0, BW->core.width, BW->core.height, True); } } void BWZoomMarked(Widget w) { BitmapWidget BW = (BitmapWidget) w; BWZoomIn(w, BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, BW->bitmap.mark.to_x, BW->bitmap.mark.to_y); } void BWZoomIn(Widget w, Position from_x, Position from_y, Position to_x, Position to_y) { BitmapWidget BW = (BitmapWidget) w; XImage *image, *buffer; Dimension width, height; char *image_data, *buffer_data; if (BW->bitmap.zooming) ZoomOut(BW); QuerySwap(from_x, to_x); QuerySwap(from_y, to_y); from_x = max(0, from_x); from_y = max(0, from_y); to_x = min(BW->bitmap.width - 1, to_x); to_y = min(BW->bitmap.height - 1, to_y); width = to_x - from_x + 1; height = to_y - from_y + 1; image_data = CreateCleanData(Length(width, height)); buffer_data = CreateCleanData(Length(width, height)); image = CreateBitmapImage(BW, image_data, width, height); buffer = CreateBitmapImage(BW, buffer_data, width, height); CopyImageData(BW->bitmap.image, image, from_x, from_y, to_x, to_y, 0, 0); CopyImageData(BW->bitmap.buffer, buffer, from_x, from_y, to_x, to_y, 0, 0); BW->bitmap.zoom.image = BW->bitmap.image; BW->bitmap.zoom.buffer = BW->bitmap.buffer; BW->bitmap.zoom.at_x = from_x; BW->bitmap.zoom.at_y = from_y; BW->bitmap.zoom.fold = BW->bitmap.fold; BW->bitmap.zoom.changed = BW->bitmap.changed; BW->bitmap.zoom.hot = BW->bitmap.hot; BW->bitmap.zoom.grid = BW->bitmap.grid; BW->bitmap.image = image; BW->bitmap.buffer = buffer; BW->bitmap.width = width; BW->bitmap.height = height; BW->bitmap.changed = False; BW->bitmap.hot.x -= from_x; BW->bitmap.hot.y -= from_y; BW->bitmap.mark.from_x = NotSet; BW->bitmap.mark.from_y = NotSet; BW->bitmap.mark.to_x = NotSet; BW->bitmap.mark.to_y = NotSet; BW->bitmap.zooming = True; BW->bitmap.grid = True; /* potentially true, could use a resource here */ FixHotSpot(BW); Resize((Widget)BW); if (BW->core.visible) XClearArea(XtDisplay(BW), XtWindow(BW), 0, 0, BW->core.width, BW->core.height, True); } void BWRescale(Widget w, Dimension width, Dimension height) { BitmapWidget BW = (BitmapWidget) w; XImage *image, *buffer; char *buffer_data; if (BW->bitmap.zooming) ZoomOut(BW); image = ScaleBitmapImage(BW, BW->bitmap.image, (double) width / (double) BW->bitmap.image->width, (double) height / (double) BW->bitmap.image->height); buffer_data = CreateCleanData(Length(image->width, image->height)); buffer = CreateBitmapImage(BW, buffer_data, (Dimension) image->width, (Dimension) image->height); TransferImageData(BW->bitmap.buffer, buffer); DestroyBitmapImage(&BW->bitmap.image); DestroyBitmapImage(&BW->bitmap.buffer); BW->bitmap.image = image; BW->bitmap.buffer = buffer; BW->bitmap.width = image->width; BW->bitmap.height = image->height; FixHotSpot(BW); FixMark(BW); Resize((Widget)BW); if (BW->core.visible) XClearArea(XtDisplay(BW), XtWindow(BW), 0, 0, BW->core.width, BW->core.height, True); } Boolean BWQueryZooming(Widget w) { BitmapWidget BW = (BitmapWidget) w; return BW->bitmap.zooming; } static void ResizeGrid(BitmapWidget BW, Dimension width, Dimension height) { XImage *image, *buffer; char *image_data, *buffer_data; if (BW->bitmap.zooming) ZoomOut(BW); image_data = CreateCleanData(Length(width, height)); buffer_data = CreateCleanData(Length(width, height)); image = CreateBitmapImage(BW, image_data, width, height); buffer = CreateBitmapImage(BW, buffer_data, width, height); TransferImageData(BW->bitmap.image, image); TransferImageData(BW->bitmap.buffer, buffer); DestroyBitmapImage(&BW->bitmap.image); DestroyBitmapImage(&BW->bitmap.buffer); BW->bitmap.image = image; BW->bitmap.buffer = buffer; BW->bitmap.width = width; BW->bitmap.height = height; FixHotSpot(BW); FixMark(BW); } void BWResize(Widget w, Dimension width, Dimension height) { BitmapWidget BW = (BitmapWidget) w; ResizeGrid(BW, width, height); Resize((Widget)BW); if (BW->core.visible) XClearArea(XtDisplay(BW), XtWindow(BW), 0, 0, BW->core.width, BW->core.height, True); } static void Destroy(Widget w) { BitmapWidget BW = (BitmapWidget) w; XFreeGC(XtDisplay(w), BW->bitmap.drawing_gc); XFreeGC(XtDisplay(w), BW->bitmap.highlighting_gc); XFreeGC(XtDisplay(w), BW->bitmap.frame_gc); XFreeGC(XtDisplay(w), BW->bitmap.axes_gc); BWRemoveAllRequests(w); XtFree(BW->bitmap.filename); XtFree(BW->bitmap.basename); } static void Resize(Widget w) { BitmapWidget BW = (BitmapWidget) w; Dimension squareW, squareH; squareW = max(1, ((int)BW->core.width - 2 * (int)BW->bitmap.margin) / (int)BW->bitmap.width); squareH = max(1, ((int)BW->core.height - 2 * (int)BW->bitmap.margin) / (int)BW->bitmap.height); if (BW->bitmap.proportional) BW->bitmap.squareW = BW->bitmap.squareH = min(squareW, squareH); else { BW->bitmap.squareW = squareW; BW->bitmap.squareH = squareH; } BW->bitmap.horizOffset = max((Position)BW->bitmap.margin, (Position)(BW->core.width - BW->bitmap.width * BW->bitmap.squareW) / 2); BW->bitmap.vertOffset = max((Position)BW->bitmap.margin, (Position)(BW->core.height - BW->bitmap.height * BW->bitmap.squareH) / 2); BW->bitmap.grid &= ((BW->bitmap.squareW > BW->bitmap.grid_tolerance) && (BW->bitmap.squareH > BW->bitmap.grid_tolerance)); } /* ARGSUSED */ static void Redisplay(Widget w, XEvent *event, Region region) { BitmapWidget BW = (BitmapWidget) w; if(event->type == Expose && BW->core.visible) if (BW->bitmap.stipple_change_expose_event == False) Refresh(BW, event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height); } void BWClip(Widget w, Position x, Position y, Dimension width, Dimension height) { Position from_x, from_y, to_x, to_y; BitmapWidget BW = (BitmapWidget) w; XRectangle rectangle; from_x = InBitmapX(BW, x); from_y = InBitmapY(BW, y); to_x = InBitmapX(BW, x + width); to_y = InBitmapY(BW, y + height); QuerySwap(from_x, to_x); QuerySwap(from_y, to_y); from_x = max(0, from_x); from_y = max(0, from_y); to_x = min(BW->bitmap.width - 1, to_x); to_y = min(BW->bitmap.height - 1, to_y); rectangle.x = InWindowX(BW, from_x); rectangle.y = InWindowY(BW, from_y); rectangle.width = InWindowX(BW, to_x + 1) - InWindowX(BW, from_x); rectangle.height = InWindowY(BW, to_y + 1) - InWindowY(BW, from_y); XSetClipRectangles(XtDisplay(BW), BW->bitmap.highlighting_gc, 0, 0, &rectangle, 1, Unsorted); XSetClipRectangles(XtDisplay(BW), BW->bitmap.drawing_gc, 0, 0, &rectangle, 1, Unsorted); XSetClipRectangles(XtDisplay(BW), BW->bitmap.frame_gc, 0, 0, &rectangle, 1, Unsorted); XSetClipRectangles(XtDisplay(BW), BW->bitmap.axes_gc, 0, 0, &rectangle, 1, Unsorted); } void BWUnclip(Widget w) { BitmapWidget BW = (BitmapWidget) w; XRectangle rectangle; rectangle.x = InWindowX(BW, 0); rectangle.y = InWindowY(BW, 0); rectangle.width = InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0); rectangle.height = InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0); XSetClipRectangles(XtDisplay(BW), BW->bitmap.highlighting_gc, 0, 0, &rectangle, 1, Unsorted); XSetClipRectangles(XtDisplay(BW), BW->bitmap.drawing_gc, 0, 0, &rectangle, 1, Unsorted); XSetClipRectangles(XtDisplay(BW), BW->bitmap.frame_gc, 0, 0, &rectangle, 1, Unsorted); XSetClipRectangles(XtDisplay(BW), BW->bitmap.axes_gc, 0, 0, &rectangle, 1, Unsorted); } static void Refresh(BitmapWidget BW, Position x, Position y, Dimension width, Dimension height) { XRectangle rectangle; rectangle.x = min(x, InWindowX(BW, InBitmapX(BW, x))); rectangle.y = min(y, InWindowY(BW, InBitmapY(BW, y))); rectangle.width = max(x + width, InWindowX(BW, InBitmapX(BW, x + width)+1)) - rectangle.x; rectangle.height = max(y + height, InWindowY(BW, InBitmapY(BW, y + height)+1)) - rectangle.y; XClearArea(XtDisplay(BW), XtWindow(BW), rectangle.x, rectangle.y, rectangle.width, rectangle.height, False); XSetClipRectangles(XtDisplay(BW), BW->bitmap.frame_gc, 0, 0, &rectangle, 1, Unsorted); XDrawRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.frame_gc, InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1, InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1); BWClip((Widget) BW, x, y, width, height); BWRedrawGrid((Widget) BW, x, y, width, height); BWRedrawSquares((Widget) BW, x, y, width, height); BWRedrawMark((Widget) BW); BWRedrawHotSpot((Widget) BW); BWRedrawAxes((Widget) BW); BWUnclip((Widget) BW); } Boolean BWQueryGrid(Widget w) { BitmapWidget BW = (BitmapWidget) w; return BW->bitmap.grid; } void BWSwitchGrid(Widget w) { BitmapWidget BW = (BitmapWidget) w; BW->bitmap.grid ^= TRUE; BWDrawGrid(w, 0, 0, BW->bitmap.image->width - 1, BW->bitmap.image->height - 1); } void BWGrid(Widget w, Boolean _switch) { BitmapWidget BW = (BitmapWidget) w; if (BW->bitmap.grid != _switch) BWSwitchGrid(w); } Boolean BWQueryDashed(Widget w) { BitmapWidget BW = (BitmapWidget) w; return (BW->bitmap.dashed); } void BWSwitchDashed(Widget w) { BitmapWidget BW = (BitmapWidget) w; XRectangle rectangle; BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1); rectangle.x = 0; rectangle.y = 0; rectangle.width = BW->core.width; rectangle.height = BW->core.height; XSetClipRectangles(XtDisplay(BW), BW->bitmap.frame_gc, 0, 0, &rectangle, 1, Unsorted); XDrawRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.frame_gc, InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1, InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1); BW->bitmap.dashed ^= True; XSetFillStyle(XtDisplay(BW), BW->bitmap.frame_gc, (BW->bitmap.dashed ? FillStippled : FillSolid)); XDrawRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.frame_gc, InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1, InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1); BWUnclip(w); BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1); } void BWDashed(Widget w, Boolean _switch) { BitmapWidget BW = (BitmapWidget) w; if (BW->bitmap.dashed != _switch) BWSwitchDashed(w); } static Boolean SetValues(Widget old, Widget request, Widget new, ArgList args, Cardinal *num_args) /* ARGSUSED */ { BitmapWidget oldbw = (BitmapWidget) old; BitmapWidget newbw = (BitmapWidget) new; Boolean resize = False; Boolean redisplay = False; #define NE(field) (oldbw->field != newbw->field) if (NE(bitmap.grid)) BWSwitchGrid(old); if (NE(bitmap.dashed)) BWSwitchDashed(old); if (NE(bitmap.axes)) BWSwitchAxes(old); if (NE(bitmap.stippled)) BWSwitchStippled(old); if (NE(bitmap.proportional)) resize = True; if (NE(bitmap.filename) || NE(bitmap.basename) || NE(bitmap.size)) BWChangeNotify(old); if (NE(bitmap.filename)) { if (newbw->bitmap.filename) { XtFree(oldbw->bitmap.filename); newbw->bitmap.filename = XtNewString(newbw->bitmap.filename); } else newbw->bitmap.filename = oldbw->bitmap.filename; } if (NE(bitmap.basename)) { if (newbw->bitmap.basename) { XtFree(oldbw->bitmap.basename); newbw->bitmap.basename = XtNewString(newbw->bitmap.basename); } else newbw->bitmap.basename = oldbw->bitmap.basename; } if (NE(bitmap.size)) { Dimension width, height; if (BWParseSize(newbw->bitmap.size, &width, &height)) { ResizeGrid(newbw, width, height); resize = True; } } if (NE(bitmap.margin) || NE(bitmap.grid_tolerance) || NE(bitmap.squareW) || NE(bitmap.squareH) || NE(core.height) || NE(core.width)) resize = True; if (NE(bitmap.hot.x) || NE(bitmap.hot.y)) BWSetHotSpot(old, newbw->bitmap.hot.x, newbw->bitmap.hot.y); if (NE(bitmap.foreground_pixel) || NE(core.background_pixel)) { XSetForeground(XtDisplay(new), newbw->bitmap.drawing_gc, newbw->bitmap.foreground_pixel ^ newbw->core.background_pixel); redisplay = True; } if (NE(bitmap.frame_pixel) || NE(core.background_pixel)) { XSetForeground(XtDisplay(new), newbw->bitmap.frame_gc, newbw->bitmap.frame_pixel ^ newbw->core.background_pixel); redisplay = True; } if (NE(bitmap.dashes)) { XSetStipple(XtDisplay(new), newbw->bitmap.frame_gc, newbw->bitmap.dashes); redisplay = True; } if (NE(bitmap.highlight_pixel) || NE(core.background_pixel)) { RedrawStippled(newbw); XSetForeground(XtDisplay(new), newbw->bitmap.highlighting_gc, newbw->bitmap.highlight_pixel ^ newbw->core.background_pixel); RedrawStippled(newbw); } if (NE(bitmap.stipple)) { RedrawStippled(newbw); XSetStipple(XtDisplay(new), newbw->bitmap.highlighting_gc, newbw->bitmap.stipple); RedrawStippled(newbw); } if (resize) Resize((Widget)newbw); return (redisplay || resize); #undef NE } Boolean BWQueryProportional(Widget w) { BitmapWidget BW = (BitmapWidget) w; return (BW->bitmap.proportional); } void BWSwitchProportional(Widget w) { BitmapWidget BW = (BitmapWidget) w; BW->bitmap.proportional ^= True; Resize((Widget)BW); if (BW->core.visible) XClearArea(XtDisplay(BW), XtWindow(BW), 0, 0, BW->core.width, BW->core.height, True); } #if 0 void BWProportional(Widget w, Boolean _switch) { BitmapWidget BW = (BitmapWidget) w; if (BW->bitmap.proportional != _switch) BWSwitchProportional(w); } #endif void BWTPaste(Widget w, XEvent *event, String *params, Cardinal *num_params) { BitmapWidget BW = (BitmapWidget) w; BWRequestSelection(w, event->xbutton.time, TRUE); if (!BWQueryStored(w)) return; BWEngageRequest(w, RestoreRequest, False, (char *)&(event->xbutton.state), sizeof(int)); OnePointHandler(w, (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status, event, NULL); } void BWTMark(Widget w, XEvent *event, String *params, Cardinal *num_params) { BitmapWidget BW = (BitmapWidget) w; BWEngageRequest(w, MarkRequest, False, (char *)&(event->xbutton.state), sizeof(int)); TwoPointsHandler(w, (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status, event, NULL); } void BWTMarkAll(Widget w, XEvent *event, String *params, Cardinal *num_params) { BWMarkAll(w); BWGrabSelection(w, event->xkey.time); } void BWTUnmark(Widget w, XEvent *event, String *params, Cardinal *num_params) { BWUnmark(w); } /*****************************************************************************/