summaryrefslogtreecommitdiff
path: root/Bitmap.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:52 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:52 +0000
commit9711ac0a780f686806c135045d2db9b99fbe923f (patch)
tree422a11eba052ec8e1923dcd458943fcdd8d70d04 /Bitmap.c
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'Bitmap.c')
-rw-r--r--Bitmap.c1956
1 files changed, 1956 insertions, 0 deletions
diff --git a/Bitmap.c b/Bitmap.c
new file mode 100644
index 0000000..5e92d39
--- /dev/null
+++ b/Bitmap.c
@@ -0,0 +1,1956 @@
+/* $Xorg: Bitmap.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */
+/*
+
+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
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw/XawInit.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/Drawing.h>
+#include <X11/Xatom.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xos.h>
+#include "BitmapP.h"
+
+#include <stdio.h>
+#include <math.h>
+
+#ifndef abs
+#define abs(x) ((((int)(x)) > 0) ? (x) : -(x))
+#endif
+#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
+
+void BWDebug();
+void BWChangeNotify();
+void BWSetChanged();
+void BWAbort();
+void BWUp();
+void BWDown();
+void BWLeft();
+void BWRight();
+void BWFold();
+void BWFlipHoriz();
+void BWFlipVert();
+void BWRotateRight();
+void BWRotateLeft();
+void BWSet();
+void BWClear();
+void BWInvert();
+void BWUndo();
+void BWRedraw();
+void BWTMark();
+void BWTMarkAll();
+void BWTUnmark();
+void BWTPaste();
+
+static XtActionsRec actions[] =
+{
+{"mark", BWTMark},
+{"mark-all", BWTMarkAll},
+{"unmark", BWTUnmark},
+{"paste", BWTPaste},
+{"bw-debug", BWDebug},
+{"abort", BWAbort},
+{"store-to-buffer", BWStoreToBuffer},
+{"change-notify", BWChangeNotify},
+{"set-changed", BWSetChanged},
+{"up", BWUp},
+{"down", BWDown},
+{"left", BWLeft},
+{"right", BWRight},
+{"fold", BWFold},
+{"flip-horiz", BWFlipHoriz},
+{"flip-vert", BWFlipVert},
+{"rotate-right", BWRotateRight},
+{"rotate-left", BWRotateLeft},
+{"set", BWSet},
+{"clear", BWClear},
+{"invert", BWInvert},
+{"undo", BWUndo},
+{"redraw", BWRedraw},
+};
+
+static char translations1[] =
+"\
+Shift<Btn1Down>: mark()\n\
+Shift<Btn2Down>: mark-all()\n\
+Shift<Btn3Down>: unmark()\n\
+Ctrl<BtnDown>: paste()\n\
+Ctrl<Key>l: redraw()\n\
+<Key>d: bw-debug()\n\
+<Key>a: abort()\n\
+<Key>Up: store-to-buffer()\
+ up()\
+ change-notify()\
+ set-changed()\n\
+<Key>KP_Up: store-to-buffer()\
+ up()\
+ change-notify()\
+ set-changed()\n\
+<Key>Down: store-to-buffer()\
+ down()\
+ change-notify()\
+ set-changed()\n\
+<Key>KP_Down: store-to-buffer()\
+ down()\
+ change-notify()\
+ set-changed()\n\
+<Key>Left: store-to-buffer()\
+ left()\
+ change-notify()\
+ set-changed()\n\
+<Key>KP_Left: store-to-buffer()\
+ left()\
+ change-notify()\
+ set-changed()\n\
+<Key>Right: store-to-buffer()\
+ right()\
+ change-notify()\
+ set-changed()\n\
+<Key>KP_Right: store-to-buffer()\
+ right()\
+ change-notify()\
+ set-changed()\n\
+<Key>f: store-to-buffer()\
+ fold()\
+ change-notify()\
+ set-changed()\n\
+<Key>h: store-to-buffer()\
+ flip-horiz()\
+ change-notify()\
+ set-changed()\n\
+";
+
+static char translations2[] =
+"<Key>v: store-to-buffer()\
+ flip-vert()\
+ change-notify()\
+ set-changed()\n\
+<Key>r: store-to-buffer()\
+ rotate-right()\
+ change-notify()\
+ set-changed()\n\
+<Key>l: store-to-buffer()\
+ rotate-left()\
+ change-notify()\
+ set-changed()\n\
+<Key>s: store-to-buffer()\
+ set()\
+ change-notify()\
+ set-changed()\n\
+<Key>c: store-to-buffer()\
+ clear()\
+ change-notify()\
+ set-changed()\n\
+<Key>i: store-to-buffer()\
+ invert()\
+ change-notify()\
+ set-changed()\n\
+<Key>u: undo()\
+ change-notify()\
+ set-changed()\n\
+";
+
+Atom targets[] = {
+ XA_BITMAP,
+ XA_PIXMAP
+};
+
+#include "Requests.h"
+
+static void ClassInitialize();
+static void Initialize();
+static void Redisplay();
+static void Resize();
+static void Destroy();
+static Boolean SetValues();
+
+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(w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ DEBUG ^= True;
+}
+
+Pixmap BWGetPixmap(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return GetPixmap(BW, BW->bitmap.zoom.image);
+}
+
+Pixmap BWGetUnzoomedPixmap(w)
+ 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)))
+ 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)))
+ 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 *CreateBitmapImage();
+
+XImage *ConvertToBitmapImage();
+
+XImage *GetImage(BW, pixmap)
+ 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(BW, data, width, height)
+ BitmapWidget BW;
+ char *data;
+ Dimension width, 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(image)
+ XImage **image;
+{
+ /*XDestroyImage(*image);*/
+ if (image) {
+ if (*image) {
+ if ((*image)->data)
+ XtFree((*image)->data);
+ XtFree((char *)*image);
+ }
+ *image = NULL;
+ }
+}
+
+XImage *BWGetImage(w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return BW->bitmap.image;
+}
+
+void BWChangeNotify(w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (BW->bitmap.notify)
+ (*BW->bitmap.notify)(w, event, params, num_params);
+}
+
+void BWNotify(w, proc) /* ARGSUSED */
+ Widget w;
+ void (*proc)();
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ BW->bitmap.notify = proc;
+}
+
+void BWSetChanged(w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ BW->bitmap.changed = True;
+}
+
+Boolean BWQueryChanged(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return BW->bitmap.changed;
+}
+
+void BWClearChanged(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ BW->bitmap.changed = False;
+}
+
+Boolean BWQueryStored(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return (BW->bitmap.storage != NULL);
+}
+
+Boolean BWQueryStippled(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return BW->bitmap.stippled;
+}
+
+void RedrawStippled(BW)
+ 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(w)
+ 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(w, from_x, from_y, to_x, to_y, btime)
+ Widget w;
+ Position from_x, from_y,
+ to_x, to_y;
+ Time btime;
+{
+ BWMark(w, from_x, from_y, to_x, to_y);
+
+ BWGrabSelection(w, btime);
+}
+
+Boolean BWQueryAxes(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return BW->bitmap.axes;
+}
+
+void BWSwitchAxes(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ BW->bitmap.axes ^= True;
+ BWHighlightAxes(w);
+}
+
+void BWAxes(w, _switch)
+ Widget w;
+ Boolean _switch;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (BW->bitmap.axes != _switch)
+ BWSwitchAxes(w);
+}
+
+void BWRedrawAxes(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (BW->bitmap.axes)
+ BWHighlightAxes(w);
+}
+
+void BWPutImage(w, display, drawable, gc, x, y)
+ BitmapWidget w;
+ Display *display;
+ Drawable drawable;
+ GC gc;
+ Position x, y;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ XPutImage(display, drawable, gc, BW->bitmap.image,
+ 0, 0, x, y, BW->bitmap.image->width, BW->bitmap.image->height);
+}
+
+String StripFilename(filename)
+ String filename;
+{
+ char *begin = strrchr(filename, '/');
+ char *end, *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);
+}
+
+int XmuWriteBitmapDataToFile (filename, basename,
+ width, height, datap, x_hot, y_hot)
+ String filename, basename;
+ int width, height;
+ char *datap;
+ int x_hot, 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 (!basename || !strcmp(basename, "") || !strcmp(basename, "-"))
+ basename = StripFilename(filename);
+
+ if (file) {
+ 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);
+
+ return BitmapSuccess;
+ }
+
+ return 1;
+}
+
+/*
+ *
+ */
+
+ /* ARGSUSED */
+static void CvtStringToButtonFunction(args, num_args, from_val, to_val)
+ XrmValuePtr args; /* not used */
+ Cardinal *num_args; /* not used */
+ XrmValuePtr from_val;
+ XrmValuePtr to_val;
+{
+ static 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);
+
+}
+
+void Refresh();
+
+static void ClassInitialize()
+{
+ 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(bw)
+ 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");
+ }
+}
+
+void TransferImageData();
+
+/* ARGSUSED */
+static void Initialize(wrequest, wnew, argv, argc)
+ Widget wrequest, 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_data;
+ char *buffer_data;
+ unsigned int width, height;
+ int x_hot, y_hot;
+
+ status = XmuReadBitmapDataFromFile(new->bitmap.filename,
+ &width, &height, &image_data,
+ &x_hot, &y_hot);
+ if (status == BitmapSuccess) {
+
+ buffer_data = CreateCleanData(Length(width, height));
+
+ image = CreateBitmapImage(new, (char *)image_data, width, height);
+ buffer = CreateBitmapImage(new, buffer_data, 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(new);
+}
+
+
+/* returns False if the format is wrong */
+Boolean BWParseSize(size, width, height)
+ String size;
+ Dimension *width, *height;
+{
+ int x, y;
+ unsigned int w, h;
+ int status;
+
+ status = XParseGeometry(size, &x, &y, &w, &h);
+
+ if (status & (WidthValue | HeightValue)) {
+ *width = (Dimension) w;
+ *height = (Dimension) h;
+ return True;
+ }
+ else return False;
+
+}
+
+
+Boolean BWQueryMarked(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y);
+}
+
+void FixMark(BW)
+ 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(w, filename, basename)
+ Widget w;
+ String filename, *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(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ sprintf(BW->bitmap.status,
+ "Filename: %s Basename: %s Size: %dx%d",
+ (strcmp(BW->bitmap.filename, "") ? BW->bitmap.filename : "<none>"),
+ (strcmp(BW->bitmap.basename, "") ? BW->bitmap.basename : "<none>"),
+ BW->bitmap.width, BW->bitmap.height);
+
+ return BW->bitmap.status;
+}
+
+void BWChangeFilename(w, str)
+ Widget w;
+ String str;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (str) {
+ XtFree(BW->bitmap.filename);
+ BW->bitmap.filename = XtNewString( str);
+ }
+}
+
+void BWChangeBasename(w, str)
+ Widget w;
+ String str;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (str) {
+ XtFree(BW->bitmap.basename);
+ BW->bitmap.basename = XtNewString(str);
+ }
+}
+
+
+int BWReadFile(w, filename, basename) /* ARGSUSED */
+ Widget w;
+ String filename, basename;
+{
+ 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= XtNewString(StripFilename(filename));
+
+ BWUnmark(w);
+
+ Resize(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;
+}
+
+void BWSetImage(w, image)
+ 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(BW);
+
+ if (BW->core.visible) {
+ XClearArea(XtDisplay(BW), XtWindow(BW),
+ 0, 0,
+ BW->core.width, BW->core.height,
+ True);
+ }
+}
+
+int BWWriteFile(w, filename, basename)
+ Widget w;
+ String filename, 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= XtNewString(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;
+}
+
+String BWGetFilename(w, str)
+ Widget w;
+ String *str;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ *str = XtNewString(BW->bitmap.filename);
+
+ return *str;
+}
+
+String BWGetFilepath(w, str)
+ Widget w;
+ String *str;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+ String end;
+
+ *str = XtNewString(BW->bitmap.filename);
+ end = strrchr(*str, '/');
+
+ if (end)
+ *(end + 1) = '\0';
+ else
+ **str = '\0';
+
+ return *str;
+}
+
+
+String BWGetBasename(w, str)
+ Widget w;
+ String *str;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ *str = XtNewString(BW->bitmap.basename);
+
+ return *str;
+}
+
+void FixHotSpot(BW)
+ BitmapWidget BW;
+{
+ if (!QueryInBitmap(BW, BW->bitmap.hot.x, BW->bitmap.hot.y))
+ BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet;
+}
+
+void ZoomOut(BW)
+ 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(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (BW->bitmap.zooming) {
+ ZoomOut(BW);
+
+ Resize(BW);
+ if (BW->core.visible)
+ XClearArea(XtDisplay(BW), XtWindow(BW),
+ 0, 0,
+ BW->core.width, BW->core.height,
+ True);
+ }
+}
+
+void BWZoomIn();
+
+void BWZoomMarked(w)
+ 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(w, from_x, from_y, to_x, to_y)
+ Widget w;
+ Position from_x, from_y,
+ to_x, 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; /* potencially true, could use a resource here */
+
+ FixHotSpot(BW);
+
+ Resize(BW);
+ if (BW->core.visible)
+ XClearArea(XtDisplay(BW), XtWindow(BW),
+ 0, 0,
+ BW->core.width, BW->core.height,
+ True);
+}
+
+XImage *ScaleBitmapImage();
+
+void BWRescale(w, width, height)
+ Widget w;
+ Dimension width, 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(BW);
+ if (BW->core.visible)
+ XClearArea(XtDisplay(BW), XtWindow(BW),
+ 0, 0,
+ BW->core.width, BW->core.height,
+ True);
+}
+
+Boolean BWQueryZooming(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return BW->bitmap.zooming;
+}
+
+
+static void ResizeGrid(BW, width, height)
+ BitmapWidget BW;
+ Dimension width, 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(w, width, height)
+ Widget w;
+ Dimension width, height;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ ResizeGrid(BW, width, height);
+
+ Resize(BW);
+ if (BW->core.visible)
+ XClearArea(XtDisplay(BW), XtWindow(BW),
+ 0, 0,
+ BW->core.width, BW->core.height,
+ True);
+}
+
+static void Destroy(w)
+ 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(w)
+ 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(w, event, region)
+ 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(w, x, y, width, height)
+ Widget w;
+ Position x, y;
+ Dimension width, 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(w)
+ 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);
+}
+
+void Refresh(BW, x, y, width, height)
+ BitmapWidget BW;
+ Position x, y;
+ Dimension width, 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(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return BW->bitmap.grid;
+}
+
+void BWSwitchGrid(w)
+ 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(w, _switch)
+ Widget w;
+ Boolean _switch;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (BW->bitmap.grid != _switch)
+ BWSwitchGrid(w);
+}
+
+Boolean BWQueryDashed(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return (BW->bitmap.dashed);
+}
+
+void BWSwitchDashed(w)
+ 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(w, _switch)
+ Widget w;
+ Boolean _switch;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (BW->bitmap.dashed != _switch)
+ BWSwitchDashed(w);
+}
+
+static Boolean SetValues(old, request, new, args, num_args) /* ARGSUSED */
+ Widget old, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ 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, NULL, NULL, NULL);
+
+ 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(newbw);
+
+ return (redisplay || resize);
+
+#undef NE
+}
+
+Boolean BWQueryProportional(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ return (BW->bitmap.proportional);
+}
+
+void BWSwitchProportional(w)
+ Widget w;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ BW->bitmap.proportional ^= True;
+
+ Resize(BW);
+ if (BW->core.visible)
+ XClearArea(XtDisplay(BW), XtWindow(BW),
+ 0, 0,
+ BW->core.width, BW->core.height,
+ True);
+}
+
+void BWProportional(w, _switch)
+ Widget w;
+ Boolean _switch;
+{
+ BitmapWidget BW = (BitmapWidget) w;
+
+ if (BW->bitmap.proportional != _switch)
+ BWSwitchProportional(w);
+}
+
+
+void BWTPaste(w, event, params, num_params)
+ 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);
+}
+
+void BWTMark(w, event, params, num_params)
+ 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);
+
+}
+
+void BWTMarkAll(w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ BWMarkAll(w);
+
+ BWGrabSelection(w, event->xkey.time);
+}
+
+void BWTUnmark(w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ BWUnmark(w);
+}
+
+/*****************************************************************************/