diff options
-rw-r--r-- | BitEdit.c | 1122 | ||||
-rw-r--r-- | Bitmap-color.ad | 19 | ||||
-rw-r--r-- | Bitmap.ad | 229 | ||||
-rw-r--r-- | Bitmap.c | 1956 | ||||
-rw-r--r-- | Bitmap.h | 276 | ||||
-rw-r--r-- | BitmapP.h | 194 | ||||
-rw-r--r-- | CutPaste.c | 223 | ||||
-rw-r--r-- | Dashes | 4 | ||||
-rw-r--r-- | Dialog.c | 204 | ||||
-rw-r--r-- | Dialog.h | 56 | ||||
-rw-r--r-- | Down | 13 | ||||
-rw-r--r-- | Excl | 17 | ||||
-rw-r--r-- | FlipHoriz | 13 | ||||
-rw-r--r-- | FlipVert | 13 | ||||
-rw-r--r-- | Fold | 13 | ||||
-rw-r--r-- | Graphics.c | 1602 | ||||
-rw-r--r-- | Handlers.c | 677 | ||||
-rw-r--r-- | Left | 13 | ||||
-rw-r--r-- | ReqMach.c | 279 | ||||
-rw-r--r-- | Requests.h | 146 | ||||
-rw-r--r-- | Right | 13 | ||||
-rw-r--r-- | RotateLeft | 13 | ||||
-rw-r--r-- | RotateRight | 13 | ||||
-rw-r--r-- | Stipple | 4 | ||||
-rw-r--r-- | Term | 14 | ||||
-rw-r--r-- | Up | 13 | ||||
-rw-r--r-- | atobm.c | 293 | ||||
-rw-r--r-- | bitmap.icon | 14 | ||||
-rw-r--r-- | bitmap.man | 659 | ||||
-rw-r--r-- | bmtoa.c | 191 |
30 files changed, 8296 insertions, 0 deletions
diff --git a/BitEdit.c b/BitEdit.c new file mode 100644 index 0000000..7477392 --- /dev/null +++ b/BitEdit.c @@ -0,0 +1,1122 @@ +/* $Xorg: BitEdit.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 <stdio.h> +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Xaw/Paned.h> +#include <X11/Xaw/Form.h> +#include <X11/Xaw/Box.h> +#include <X11/Xaw/Command.h> +#include <X11/Xaw/Toggle.h> +#include <X11/Xaw/MenuButton.h> +#include <X11/Xaw/SimpleMenu.h> +#include <X11/Xaw/SmeLine.h> +#include <X11/Xaw/SmeBSB.h> +#include "Bitmap.h" + +#include <X11/bitmaps/xlogo16> + +static char *usage = "[-options ...] filename\n\ +\n\ +where options include all standard toolkit options plus:\n\ + -size WIDTHxHEIGHT\n\ + -sw dimension\n\ + -sh dimension\n\ + -gt dimension\n\ + -grid, +grid\n\ + -axes, +axes\n\ + -dashed, +dashed\n\ + -stippled, +stippled\n\ + -proportional, +proportional\n\ + -basename basename\n\ + -dashes filename\n\ + -stipple filename\n\ + -hl color\n\ + -fr color\n\ +\n\ +The default WIDTHxHEIGHT is 16x16.\n"; + +static XrmOptionDescRec options[] = { + { "-axes", "*bitmap.axes", XrmoptionNoArg, "True"}, + { "+axes", "*bitmap.axes", XrmoptionNoArg, "False"}, + { "-basename", "*bitmap.basename", XrmoptionSepArg, NULL}, + { "-dashed", "*bitmap.dashed", XrmoptionNoArg, "True"}, + { "+dashed", "*bitmap.dashed", XrmoptionNoArg, "False"}, + { "-dashes", "*bitmap.dashes", XrmoptionSepArg, NULL}, + { "-fr", "*bitmap.frame", XrmoptionSepArg, NULL}, + { "-gt", "*bitmap.gridTolerance",XrmoptionSepArg, NULL}, + { "-grid", "*bitmap.grid", XrmoptionNoArg, "True"}, + { "+grid", "*bitmap.grid", XrmoptionNoArg, "False"}, + { "-hl", "*bitmap.highlight", XrmoptionSepArg, NULL}, + { "-proportional","*bitmap.proportional", XrmoptionNoArg, "True"}, + { "+proportional","*bitmap.proportional", XrmoptionNoArg, "False"}, + { "-size", "*bitmap.size", XrmoptionSepArg, NULL}, + { "-sh", "*bitmap.squareHeight", XrmoptionSepArg, NULL}, + { "-sw", "*bitmap.squareWidth", XrmoptionSepArg, NULL}, + { "-stipple", "*bitmap.stipple", XrmoptionSepArg, NULL}, + { "-stippled", "*bitmap.stippled", XrmoptionNoArg, "True"}, + { "+stippled", "*bitmap.stippled", XrmoptionNoArg, "False"}, +}; + +typedef struct { + int id; + String name; + Boolean trap; + Widget widget; + } ButtonRec; + +static ButtonRec file_menu[] = { +#define New 101 + {New, "new", True}, +#define Load 102 + {Load, "load", True}, +#define Insert 103 + {Insert, "insert", True}, +#define Save 104 + {Save, "save", True}, +#define SaveAs 105 + {SaveAs, "saveAs", True}, +#define Resize 106 + {Resize, "resize", True}, +#define Rescale 107 + {Rescale, "rescale", True}, +#define Filename 108 + {Filename, "filename", True}, +#define Basename 109 + {Basename, "basename", True}, +#define Dummy -1 + {Dummy, "line", False}, +#define Quit 110 + {Quit, "quit", True}, +}; + +static ButtonRec edit_menu[] = { +#define Image 201 + {Image, "image", True}, +#define Grid 203 + {Grid, "grid", True}, +#define Dashed 204 + {Dashed, "dashed", True}, +#define Axes 205 + {Axes, "axes", True}, +#define Stippled 206 + {Stippled, "stippled", True}, +#define Proportional 207 + {Proportional, "proportional", True}, +#define Zoom 208 + {Zoom, "zoom", True}, +/* Dummy */ + {Dummy, "line", False}, +#define Cut 209 + {Cut, "cut", True}, +#define Copy 210 + {Copy, "copy", True}, +#define Paste 211 + {Paste, "paste", True}, +}; + +static ButtonRec buttons[] = { +/*#define Clear 1*/ + {Clear, "clear", False}, +/*#define Set 2*/ + {Set, "set", False}, +/*#define Invert 3*/ + {Invert, "invert", False}, +#define Mark 26 + {Mark, "mark", True}, +#define Unmark 27 + {Unmark, "unmark", False}, +#define CopyImm 4 + {CopyImm, "copy", True}, +#define MoveImm 5 + {MoveImm, "move", True}, +#define FlipHoriz 6 + {FlipHoriz, "flipHoriz", False}, +#define Up 7 + {Up, "up", False}, +#define FlipVert 8 + {FlipVert, "flipVert", False}, +#define Left 9 + {Left, "left", False}, +#define Fold 10 + {Fold, "fold", False}, +#define Right 11 + {Right, "right", False}, +#define RotateLeft 12 + {RotateLeft, "rotateLeft", False}, +#define Down 13 + {Down, "down", False}, +#define RotateRight 14 + {RotateRight, "rotateRight", False}, +#define Point 15 + {Point, "point", True}, +#define Curve 16 + {Curve, "curve", True}, +#define Line 17 + {Line, "line", True}, +#define Rectangle 18 + {Rectangle, "rectangle", True}, +#define FilledRectangle 19 + {FilledRectangle, "filledRectangle", True}, +#define Circle 20 + {Circle, "circle", True}, +#define FilledCircle 21 + {FilledCircle, "filledCircle", True}, +#define FloodFill 22 + {FloodFill, "floodFill", True}, +#define SetHotSpot 23 + {SetHotSpot, "setHotSpot", True}, +#define ClearHotSpot 24 + {ClearHotSpot, "clearHotSpot", False}, +#define Undo 25 + {Undo, "undo", False}, +}; + +#include "Dialog.h" + +static Widget + top_widget, + parent_widget, + formy_widget, + fileButton_widget, fileMenu_widget, + editButton_widget, editMenu_widget, + status_widget, + pane_widget, + form_widget, + bitmap_widget, + image_shell, + box_widget, + normal_image_widget, + inverted_image_widget; +static Boolean image_visible = False; +static Pixmap check_mark; +static Dialog input_dialog, error_dialog, qsave_dialog; +static Time btime; +static String filename = NULL, base_name = NULL, format; +static char message[80]; + + +void FixMenu(); +void SwitchImage(); +void SwitchGrid(); +void SwitchDashed(); +void SwitchAxes(); +void SwitchStippled(); +void SwitchProportional(); +void SwitchZoom(); +void DoCut(); +void DoCopy(); +void DoPaste(); +void DoNew(); +void DoLoad(); +void DoInsert(); +void DoSave(); +void DoSaveAs(); +void DoResize(); +void DoRescale(); +void DoFilename(); +void DoBasename(); +void DoQuit(); + +static XtActionsRec actions_table[] = { + {"fix-menu", FixMenu}, + {"switch-image", SwitchImage}, + {"switch-grid", SwitchGrid}, + {"switch-dashed", SwitchDashed}, + {"switch-axes", SwitchAxes}, + {"switch-stippled", SwitchStippled}, + {"switch-proportional", SwitchProportional}, + {"switch-zoom", SwitchZoom}, + {"do-cut", DoCut}, + {"do-copy", DoCopy}, + {"do-paste", DoPaste}, + {"do-new", DoNew}, + {"do-load", DoLoad}, + {"do-insert", DoInsert}, + {"do-save", DoSave}, + {"do-save-as", DoSaveAs}, + {"do-resize", DoResize}, + {"do-rescale", DoRescale}, + {"do-filename", DoFilename}, + {"do-basename", DoBasename}, + {"do-quit", DoQuit} +}; + +static Atom wm_delete_window; + +void FixImage() +{ + Pixmap old_image, image; + int n; + Arg wargs[2]; + + if (!image_visible) return; + + n=0; + XtSetArg(wargs[n], XtNbitmap, &old_image); n++; + XtGetValues(normal_image_widget, wargs, n); + + + image = BWGetUnzoomedPixmap(bitmap_widget); + + n=0; + XtSetArg(wargs[n], XtNbitmap, image); n++; + XtSetValues(normal_image_widget, wargs, n); + XtSetValues(inverted_image_widget, wargs, n); + + if (old_image != XtUnspecifiedPixmap) + XFreePixmap(XtDisplay(bitmap_widget), old_image); +} + +FixStatus() +{ + int n; + Arg wargs[2]; + String str, label; + + str = BWUnparseStatus(bitmap_widget); + + n=0; + XtSetArg(wargs[n], XtNlabel, &label); n++; + XtGetValues(status_widget, wargs, n); + + if (strcmp(str, label)) { + n = 0; + XtSetArg(wargs[n], XtNlabel, str); n++; + XtSetValues(status_widget, wargs, n); + } + + /*XtFree(str); */ +} + +void FixUp() +{ + FixImage(); + FixStatus(); +} + +void FixEntry(w, id) + Widget w; + int *id; +{ + int n; + Arg wargs[2]; + Time dummy = 0; + + n = 0; + + switch (*id) { + + case Image: + XtSetArg(wargs[n], XtNleftBitmap, + image_visible ? check_mark : None); n++; + break; + + case Grid: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryGrid(bitmap_widget) ? check_mark : None); n++; + break; + + case Dashed: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryDashed(bitmap_widget) ? check_mark : None); n++; + break; + + case Axes: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryAxes(bitmap_widget) ? check_mark : None); n++; + break; + + case Stippled: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryStippled(bitmap_widget) ? check_mark : None); n++; + break; + + case Proportional: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryProportional(bitmap_widget) ? check_mark : None); n++; + break; + + case Zoom: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryZooming(bitmap_widget) ? check_mark : None); n++; + break; + + case Copy: + case Cut: + XtSetArg(wargs[n], XtNsensitive, BWQueryMarked(bitmap_widget)); n++; + break; + + case Paste: + XtSetArg(wargs[n], XtNsensitive, + BWQuerySelection(bitmap_widget, dummy)); n++; + break; + + default: + return; + } + + XtSetValues(w, wargs, n); +} + +/* ARGSUSED */ +void FixMenu(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + int i; + + btime = event->xbutton.time; + + for (i = 0; i < XtNumber(edit_menu); i++) + FixEntry(edit_menu[i].widget, &edit_menu[i].id); +} + +static int zero = 0; +#define Plain (char *)&zero,sizeof(int) +/* ARGSUSED */ +void TheCallback(w, clientData, callData) + Widget w; /* not used */ + XtPointer clientData, callData; +{ + int *id = (int *)clientData; + switch (*id) { + + case New: + DoNew(); + break; + + case Load: + DoLoad(); + break; + + case Insert: + DoInsert(); + break; + + case Save: + DoSave(); + break; + + case SaveAs: + DoSaveAs(); + break; + + case Resize: + DoResize(); + break; + + case Rescale: + DoRescale(); + break; + + case Filename: + DoFilename(); + break; + + case Basename: + DoBasename(); + break; + + case Image: + SwitchImage(); + break; + + case Grid: + SwitchGrid(); + break; + + case Dashed: + SwitchDashed(); + break; + + case Axes: + SwitchAxes(); + break; + + case Stippled: + SwitchStippled(); + break; + + case Proportional: + SwitchProportional(); + break; + + case Zoom: + SwitchZoom(); + break; + + case Cut: + DoCut(); + break; + + case Copy: + DoCopy(); + break; + + case Paste: + DoPaste(); + break; + + case Clear: + BWStoreToBuffer(bitmap_widget); + BWClear(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Set: + BWStoreToBuffer(bitmap_widget); + BWSet(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); +break; + + case Invert: + BWStoreToBuffer(bitmap_widget); + BWInvert(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Mark: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, MarkRequest, True, Plain); + break; + + case Unmark: + BWUnmark(bitmap_widget); + break; + + case CopyImm: + BWRemoveAllRequests(bitmap_widget); + if (BWQueryMarked(bitmap_widget)) { + BWAddRequest(bitmap_widget, MarkRequest, False, Plain); + BWEngageRequest(bitmap_widget, CopyRequest, True, Plain); + } + else { + BWEngageRequest(bitmap_widget, MarkRequest, False, Plain); + BWAddRequest(bitmap_widget, CopyRequest, True, Plain); + } + break; + + case MoveImm: + BWRemoveAllRequests(bitmap_widget); + if (BWQueryMarked(bitmap_widget)) { + BWAddRequest(bitmap_widget, MarkRequest, False, Plain); + BWEngageRequest(bitmap_widget, MoveRequest, True, Plain); + } + else { + BWEngageRequest(bitmap_widget, MarkRequest, False, Plain); + BWAddRequest(bitmap_widget, MoveRequest, True, Plain); + } + break; + + case Up: + BWStoreToBuffer(bitmap_widget); + BWUp(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Down: + BWStoreToBuffer(bitmap_widget); + BWDown(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Left: + BWStoreToBuffer(bitmap_widget); + BWLeft(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Right: + BWStoreToBuffer(bitmap_widget); + BWRight(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Fold: + BWStoreToBuffer(bitmap_widget); + BWFold(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case FlipHoriz: + BWStoreToBuffer(bitmap_widget); + BWFlipHoriz(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case FlipVert: + BWStoreToBuffer(bitmap_widget); + BWFlipVert(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case RotateRight: + BWStoreToBuffer(bitmap_widget); + BWRotateRight(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case RotateLeft: + BWStoreToBuffer(bitmap_widget); + BWRotateLeft(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Point: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, PointRequest, True, Plain); + break; + + case Curve: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, CurveRequest, True, Plain); + break; + + case Line: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, LineRequest, True, Plain); + break; + + case Rectangle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, RectangleRequest, True, Plain); + break; + + case FilledRectangle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, FilledRectangleRequest, True, Plain); + break; + + case Circle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, CircleRequest, True, Plain); + break; + + case FilledCircle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, FilledCircleRequest, True, Plain); + break; + + case FloodFill: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, FloodFillRequest, True, Plain); + break; + + case SetHotSpot: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, HotSpotRequest, True, Plain); + break; + + case ClearHotSpot: + BWStoreToBuffer(bitmap_widget); + BWClearHotSpot(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Undo: + BWUndo(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + break; + + case Quit: + DoQuit(bitmap_widget, NULL, NULL, NULL); + break; + } /* don't add anything below this line */ +} + +/* ARGSUSED */ + +void SwitchImage() +{ + if (image_visible) { + XtPopdown(image_shell); + image_visible = False; + } + else { + Position image_x, image_y; + int n; + Arg wargs[3]; + + XtTranslateCoords(bitmap_widget, + 10, 10, &image_x, &image_y); + + n = 0; + XtSetArg(wargs[n], XtNx, image_x); n++; + XtSetArg(wargs[n], XtNy, image_y); n++; + XtSetValues(image_shell, wargs, n); + + image_visible = True; + + FixImage(); + XtPopup(image_shell, XtGrabNone); + FixImage(); + } +} + +void SwitchGrid() +{ + BWSwitchGrid(bitmap_widget); +} + +void SwitchDashed() +{ + BWSwitchDashed(bitmap_widget); +} + +void SwitchAxes() +{ + BWSwitchAxes(bitmap_widget); +} + +void SwitchStippled() +{ + BWSwitchStippled(bitmap_widget); +} + +void SwitchProportional() +{ + BWSwitchProportional(bitmap_widget); +} + +void SwitchZoom() +{ + if (BWQueryZooming(bitmap_widget)) { + BWZoomOut(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + } + else { + if (BWQueryMarked(bitmap_widget)) { + BWStoreToBuffer(bitmap_widget); + BWZoomMarked(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + } + else { + BWEngageRequest(bitmap_widget, ZoomInRequest, False, Plain); + } + } +} + +void DoCut() +{ + BWStore(bitmap_widget); + BWStoreToBuffer(bitmap_widget); + BWClearMarked(bitmap_widget); + BWUnmark(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); +} + +void DoCopy() +{ + BWStore(bitmap_widget); + BWUnmark(bitmap_widget); +} + +void DoPaste() +{ + BWRequestSelection(bitmap_widget, btime, TRUE); + BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain); +} + +void DoNew() +{ + BWGetFilename(bitmap_widget, &filename); + if (PopupDialog(input_dialog, "New file:", + filename, &filename, XtGrabExclusive) == Okay) { + BWChangeFilename(bitmap_widget, filename); + BWChangeBasename(bitmap_widget, filename); + BWStoreToBuffer(bitmap_widget); + BWClear(bitmap_widget); + BWClearHotSpot(bitmap_widget); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWClearChanged(bitmap_widget); + BWUnmark(bitmap_widget); + FixStatus(); + } +} + +void DoLoad() +{ + if (BWQueryChanged(bitmap_widget)) { + BWGetFilename(bitmap_widget, &filename); + RetryLoadSave: + switch (PopupDialog(qsave_dialog, "Save file before loading?", + filename, &filename, XtGrabExclusive)) { + case Yes: + if (BWWriteFile(bitmap_widget, filename, NULL) + != BitmapSuccess) { + sprintf(message, "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryLoadSave; + } + break; + + case Cancel: + return; + } + } + BWGetFilepath(bitmap_widget, &filename); + RetryLoad: + if (PopupDialog(input_dialog, "Load file:", + filename, &filename, XtGrabExclusive) == Okay) { + if (BWReadFile(bitmap_widget, filename, NULL) != BitmapSuccess) { + sprintf(message, "Can't read file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryLoad; + } + else { + BWChangeNotify(bitmap_widget, NULL, NULL); + BWClearChanged(bitmap_widget); + FixStatus(); + } + } +} + +void DoInsert() +{ + BWGetFilepath(bitmap_widget, &filename); + RetryInsert: + if (PopupDialog(input_dialog, "Insert file:", + filename, &filename, XtGrabExclusive) == Okay) { + if (BWStoreFile(bitmap_widget, filename, NULL) != BitmapSuccess) { + sprintf(message, "Can't read file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryInsert; + } + else { + BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain); + } + } +} + +void DoSave() +{ + BWGetFilename(bitmap_widget, &filename); + if (!strcmp(filename, "")) + DoSaveAs(); + else if (BWWriteFile(bitmap_widget, NULL, NULL) != BitmapSuccess) { + sprintf(message, "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + DoSaveAs(); + } + else { + BWClearChanged(bitmap_widget); + } +} + +void DoSaveAs() +{ + BWGetFilename(bitmap_widget, &filename); + RetrySave: + if (PopupDialog(input_dialog, "Save file:", + filename, &filename, XtGrabExclusive) == Okay) { + if (BWWriteFile(bitmap_widget, filename, NULL) != BitmapSuccess) { + sprintf(message, "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetrySave; + } + else { + BWClearChanged(bitmap_widget); + FixStatus(); + } + } +} + +void DoResize() +{ + Dimension width, height; + format = ""; + RetryResize: + if (PopupDialog(input_dialog, "Resize to WIDTHxHEIGHT:", + format, &format, XtGrabExclusive) == Okay) { + if (BWParseSize(format, &width, &height)) { + BWResize(bitmap_widget, width, height); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + FixStatus(); + } + else { + sprintf(message, "Wrong format: %s", format); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryResize; + } + } +} + +void DoRescale() +{ + Dimension width, height; + + format = ""; + RetryRescale: + if (PopupDialog(input_dialog, "Rescale to WIDTHxHEIGHT:", + format, &format, XtGrabExclusive) == Okay) { + if (BWParseSize(format, &width, &height)) { + BWRescale(bitmap_widget, width, height); + BWChangeNotify(bitmap_widget, NULL, NULL); + BWSetChanged(bitmap_widget); + FixStatus(); + } + else { + sprintf(message, "Wrong format: %s", format); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryRescale; + } + } +} + +void DoFilename() +{ + BWGetFilename(bitmap_widget, &filename); + if (PopupDialog(input_dialog, "Change filename:", + filename, &filename, XtGrabExclusive) == Okay) { + BWChangeFilename(bitmap_widget, filename); + FixStatus(); + } +} + +void DoBasename() +{ + BWGetBasename(bitmap_widget, &base_name); + if (PopupDialog(input_dialog, "Change basename:", + base_name, &base_name, XtGrabExclusive) == Okay) { + BWChangeBasename(bitmap_widget, base_name); + FixStatus(); + } +} + +void DoQuit(w, event, params, num_params) /* ARGSUSED */ + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (BWQueryChanged(bitmap_widget)) { + BWGetFilename(bitmap_widget, &filename); + RetryQuit: + switch (PopupDialog(qsave_dialog, "Save file before quitting?", + filename, &filename, XtGrabExclusive)) { + case Yes: + if (BWWriteFile(bitmap_widget, filename, NULL) + != BitmapSuccess) { + sprintf(message, "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryQuit; + else return; + } + break; + + case Cancel: + return; + } + } + exit(0); +} + +void main(argc, argv) + int argc; + char *argv[]; +{ + int i, n; + Arg wargs[2]; + Widget w; + Widget radio_group; XtPointer radio_data; + + top_widget = XtInitialize(NULL, "Bitmap", + options, XtNumber(options), &argc, argv); + + if (argc > 2) { + fprintf(stderr, usage); + exit (0); + } + + check_mark = XCreateBitmapFromData(XtDisplay(top_widget), + RootWindowOfScreen(XtScreen(top_widget)), + (char *) xlogo16_bits, + xlogo16_width, + xlogo16_height); + + XtAddActions(actions_table, XtNumber(actions_table)); + XtOverrideTranslations + (top_widget, + XtParseTranslationTable("<Message>WM_PROTOCOLS: do-quit()")); + + parent_widget = XtCreateManagedWidget("parent", panedWidgetClass, + top_widget, NULL, 0); + + formy_widget = XtCreateManagedWidget("formy", formWidgetClass, + parent_widget, NULL, 0); + + fileMenu_widget = XtCreatePopupShell("fileMenu", + simpleMenuWidgetClass, + formy_widget, NULL, 0); + + fileButton_widget = XtCreateManagedWidget("fileButton", + menuButtonWidgetClass, + formy_widget, NULL, 0); + for (i = 0; i < XtNumber(file_menu); i++) { + w = XtCreateManagedWidget(file_menu[i].name, + (file_menu[i].trap ? + smeBSBObjectClass : smeLineObjectClass), + fileMenu_widget, NULL, 0), + XtAddCallback(w, + XtNcallback, + TheCallback, + (XtPointer)&file_menu[i].id); + + file_menu[i].widget = w; + } + + editMenu_widget = XtCreatePopupShell("editMenu", + simpleMenuWidgetClass, + formy_widget, NULL, 0); + + editButton_widget = XtCreateManagedWidget("editButton", + menuButtonWidgetClass, + formy_widget, NULL, 0); + + for (i = 0; i < XtNumber(edit_menu); i++) { + w = XtCreateManagedWidget(edit_menu[i].name, + (edit_menu[i].trap ? + smeBSBObjectClass : smeLineObjectClass), + editMenu_widget, NULL, 0), + XtAddCallback(w, + XtNcallback, + TheCallback, + (XtPointer)&edit_menu[i].id); + + edit_menu[i].widget = w; + } + + status_widget = XtCreateManagedWidget("status", labelWidgetClass, + formy_widget, NULL, 0); + + pane_widget = XtCreateManagedWidget("pane", panedWidgetClass, + parent_widget, NULL, 0); + + form_widget = XtCreateManagedWidget("form", formWidgetClass, + pane_widget, NULL, 0); + + for (i = 0; i < XtNumber(buttons); i++) { + w = XtCreateManagedWidget(buttons[i].name, + (buttons[i].trap ? + toggleWidgetClass : commandWidgetClass), + form_widget, NULL, 0); + + XtAddCallback(w, + XtNcallback, + TheCallback, + (XtPointer)&buttons[i].id); + + buttons[i].widget = w; + + if (buttons[i].id == Point) { + radio_group = buttons[i].widget; + radio_data = buttons[i].name; + } + } + bitmap_widget = XtCreateManagedWidget("bitmap", bitmapWidgetClass, + pane_widget, NULL, 0); + XtRealizeWidget(top_widget); + if (argc > 1) + if (BWReadFile(bitmap_widget, argv[1], NULL)) + + wm_delete_window = XInternAtom(XtDisplay(top_widget), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(top_widget), XtWindow(top_widget), + &wm_delete_window, 1); + + + image_shell = XtCreatePopupShell("image", transientShellWidgetClass, + top_widget, NULL, 0); + + box_widget = XtCreateManagedWidget("box", boxWidgetClass, + image_shell, NULL, 0); + + normal_image_widget = XtCreateManagedWidget("normalImage", + labelWidgetClass, + box_widget, NULL, 0); + + inverted_image_widget = XtCreateManagedWidget("invertedImage", + labelWidgetClass, + box_widget, NULL, 0); + + n=0; + XtSetArg(wargs[n], XtNbitmap, BWGetUnzoomedPixmap(bitmap_widget)); n++; + XtSetValues(normal_image_widget, wargs, n); + XtSetValues(inverted_image_widget, wargs, n); + + XtRealizeWidget(image_shell); + + BWNotify(bitmap_widget, FixUp); + + FixStatus(); + + input_dialog = CreateDialog(top_widget, "input", Okay | Cancel); + error_dialog = CreateDialog(top_widget, "error", Abort | Retry); + qsave_dialog = CreateDialog(top_widget, "qsave", Yes | No | Cancel); + + XawToggleSetCurrent(radio_group, radio_data); + BWEngageRequest(bitmap_widget, PointRequest, True, Plain); + + XtMainLoop(); +} diff --git a/Bitmap-color.ad b/Bitmap-color.ad new file mode 100644 index 0000000..bd88b6e --- /dev/null +++ b/Bitmap-color.ad @@ -0,0 +1,19 @@ +! $Xorg: Bitmap-co.ad,v 1.3 2000/08/17 19:53:49 cpqbld Exp $ +! The App-defaults file for Bitmap on a color screen. + +#include "Bitmap" + +*background: medium blue +*foreground: cyan +*borderColor: plum +*frame: deep sky blue +*highlight: magenta +*Command.background: purple +*Toggle.background: purple +*MenuButton.background: purple +*Command.foreground: white +*Toggle.foreground: white +*MenuButton.foreground: white +*status.foreground: green +*Dialog.icon.foreground: pale green +*bitmap.stippled: off diff --git a/Bitmap.ad b/Bitmap.ad new file mode 100644 index 0000000..5047c12 --- /dev/null +++ b/Bitmap.ad @@ -0,0 +1,229 @@ +! $Xorg: Bitmap.ad,v 1.3 2000/08/17 19:53:49 cpqbld Exp $ +! The App-defaults file for Bitmap. + +*TransientShell.allowShellResize: True +*shapeStyle: oval +*cursor: left_ptr +*pane.orientation: horizontal + +*Form*top: ChainTop +*Form*bottom: ChainTop +*Form*left: ChainLeft +*Form*right: ChainLeft + +*MenuButton.leftBitmap: menu12 +*form*width: 120 +*form*height: 15 + +*baseTranslations:#override\ + Ctrl<Key>c: do-quit()\n\ + <Key>q: do-quit()\n\ + Ctrl<Key>n: do-new()\n\ + Ctrl<Key>f: do-load()\n\ + Ctrl<Key>i: do-insert()\n\ + Ctrl<Key>s: do-save()\n\ + Ctrl<Key>w: do-save-as()\n\ + Ctrl<Key>r: do-resize()\n\ + Ctrl<Key>x: do-rescale()\n\ + Ctrl<Key>e: do-filename()\n\ + Ctrl<Key>b: do-basename()\n\ + Meta<Key>i: switch-image()\n\ + Meta<Key>g: switch-grid()\n\ + Meta<Key>d: switch-dashed()\n\ + Meta<Key>a: switch-axes()\n\ + Meta<Key>s: switch-stippled()\n\ + Meta<Key>p: switch-proportional()\n\ + Meta<Key>z: switch-zoom()\n\ + Meta<Key>c: do-cut()\n\ + Meta<Key>w: do-copy()\n\ + Meta<Key>y: do-paste() + + +*Toggle.translations: <EnterWindow>: highlight(WhenUnset)\n\ + <LeaveWindow>: unhighlight()\n\ + <Btn1Down>,<Btn1Up>: set() notify() + +*MenuButton.translations:<EnterWindow>: highlight()\n\ + <LeaveWindow>: reset()\n\ + Any<BtnDown>: reset() fix-menu() PopupMenu() + +*Dialog*baseTranslations:#override\ + <Key>Return: set-dialog-button(okay, yes, retry)\n\ + Ctrl<Key>g: set-dialog-button(cancel, abort) +*image*baseTranslations:#override\ + <Btn1Down>,<Btn1Up>: switch-image() +*image*width: 0 +*image*height: 0 +*image*Label.internalWidth: 0 +*image*Label.internalHeight: 0 +*image*normalImage.foreground: white +*image*normalImage.background: black +*image*invertedImage.foreground: black +*image*invertedImage.background: white + +*bitmap.cursor: tcross +*bitmap.dashes: Dashes +*bitmap.stipple: Stipple +*bitmap.stippled: on + +*TransientShell.width: 300 + +*input*icon: Term +*qsave*icon: Term +*error*icon: Excl +*Dialog.yes.label: Yes +*Dialog.no.label: No +*Dialog.okay.label: OK +*Dialog.abort.label: Abort +*Dialog.cancel.label: Cancel +*Dialog.retry.label: Retry + +*MenuButton.width: 58 + +*SimpleMenu.width: 0 +*SimpleMenu.height: 0 +*SimpleMenu.cursor: hand2 +*SimpleMenu.line.height: 0 + +*fileButton.label: File +*fileButton.menuName: fileMenu + +*editButton.label: Edit +*editButton.fromHoriz: fileButton +*editButton.menuName: editMenu + +*formy.status*top: ChainTop +*formy.status*bottom: ChainTop +*formy.status*left: ChainLeft +*formy.status*right: ChainRight +*status.fromHoriz: editButton +*status.borderWidth: 0 + +*SmeBSB.HorizontalMargins: 32 + +*fileMenu.new.label: New (Ctrl-N)... +*fileMenu.load.label: Load (Ctrl-F)... +*fileMenu.insert.label: Insert (Ctrl-I)... +*fileMenu.save.label: Save (Ctrl-S) +*fileMenu.saveAs.label: Save As (Ctrl-W)... +*fileMenu.resize.label: Resize (Ctrl-R)... +*fileMenu.rescale.label: Rescale (Ctrl-X)... +*fileMenu.filename.label: Filename (Ctrl-E)... +*fileMenu.basename.label: Basename (Ctrl-B)... +*fileMenu.quit.label: Quit (Ctrl-C, Q) + +*editMenu.image.label: Image (Meta-I) +*editMenu.grid.label: Grid (Meta-G) +*editMenu.dashed.label: Dashed (Meta-D) +*editMenu.axes.label: Axes (Meta-A) +*editMenu.stippled.label: Stippled (Meta-S) +*editMenu.proportional.label: Proportional (Meta-P) +*editMenu.zoom.label: Zoom (Meta-Z) +*editMenu.cut.label: Cut (Meta-C) +*editMenu.copy.label: Copy (Meta-W) +*editMenu.paste.label: Paste (Meta-Y, Ctrl-mb) + +*form.clear.label: Clear +*form.set.fromVert: clear +*form.set.label: Set +*form.invert.fromVert: set +*form.invert.label: Invert + +*form.mark.vertDistance: 10 +*form.mark.fromVert: invert +*form.mark.label: Mark +*form.unmark.fromVert: mark +*form.unmark.label: Unmark + +*form.copy.vertDistance: 10 +*form.copy.fromVert: unmark +*form.copy.radioGroup: mark +*form.copy.label: Copy +*form.move.fromVert: copy +*form.move.radioGroup: copy +*form.move.label: Move + +*form.flipHoriz.vertDistance: 10 +*form.flipHoriz.width: 36 +*form.flipHoriz.height: 36 +*form.flipHoriz.fromVert: move +*form.flipHoriz.bitmap: FlipHoriz +*form.up.vertDistance: 10 +*form.up.width: 36 +*form.up.height: 36 +*form.up.fromVert: move +*form.up.fromHoriz: flipHoriz +*form.up.bitmap: Up +*form.flipVert.vertDistance: 10 +*form.flipVert.width: 36 +*form.flipVert.height: 36 +*form.flipVert.fromVert: move +*form.flipVert.fromHoriz: up +*form.flipVert.bitmap: FlipVert +*form.left.width: 36 +*form.left.height: 36 +*form.left.fromVert: flipHoriz +*form.left.bitmap: Left +*form.fold.width: 36 +*form.fold.height: 36 +*form.fold.fromVert: up +*form.fold.fromHoriz: left +*form.fold.bitmap: Fold +*form.right.width: 36 +*form.right.height: 36 +*form.right.fromVert: flipVert +*form.right.fromHoriz: fold +*form.right.bitmap: Right +*form.rotateLeft.width: 36 +*form.rotateLeft.height: 36 +*form.rotateLeft.fromVert: left +*form.rotateLeft.bitmap: RotateLeft +*form.down.width: 36 +*form.down.height: 36 +*form.down.fromVert: fold +*form.down.fromHoriz: rotateLeft +*form.down.bitmap: Down +*form.rotateRight.width: 36 +*form.rotateRight.height: 36 +*form.rotateRight.fromVert: right +*form.rotateRight.fromHoriz: down +*form.rotateRight.bitmap: RotateRight + +*form.point.vertDistance: 10 +*form.point.fromVert: rotateLeft +*form.point.radioGroup: move +*form.point.label: Point +*form.curve.fromVert: point +*form.curve.radioGroup: point +*form.curve.label: Curve +*form.line.fromVert: curve +*form.line.radioGroup: curve +*form.line.label: Line +*form.rectangle.fromVert: line +*form.rectangle.radioGroup: line +*form.rectangle.label: Rectangle +*form.filledRectangle.fromVert: rectangle +*form.filledRectangle.radioGroup: rectangle +*form.filledRectangle.label: Filled Rectangle +*form.circle.fromVert: filledRectangle +*form.circle.radioGroup: filledRectangle +*form.circle.label: Circle +*form.filledCircle.fromVert: circle +*form.filledCircle.radioGroup: circle +*form.filledCircle.label: Filled Circle +*form.floodFill.fromVert: filledCircle +*form.floodFill.radioGroup: filledCircle +*form.floodFill.label: Flood Fill + +*form.setHotSpot.vertDistance: 10 +*form.setHotSpot.fromVert: floodFill +*form.setHotSpot.radioGroup: floodFill +*form.setHotSpot.label: Set Hot Spot +*form.clearHotSpot.fromVert: setHotSpot +*form.clearHotSpot.label: Clear Hot Spot + +*form.undo.vertDistance: 10 +*form.undo.fromVert: clearHotSpot +*form.undo.label: Undo + + 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); +} + +/*****************************************************************************/ diff --git a/Bitmap.h b/Bitmap.h new file mode 100644 index 0000000..135ce95 --- /dev/null +++ b/Bitmap.h @@ -0,0 +1,276 @@ +/* $Xorg: Bitmap.h,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 + */ + + +#ifndef _Bitmap_h +#define _Bitmap_h + +/**************************************************************** + * + * Bitmap widget + * + ****************************************************************/ + +#include <X11/Xaw/Simple.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + foreground Foredround Pixel XtDefaultForeground + highlight Highlight Pixel XtDefaultForeground + frame Frame Pixel XtDefaultForeground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + mappedWhenManaged MappedWhenManaged Boolean True + resize Resize Boolean True + sensitive Sensitive Boolean True + width Width Dimension 0 + height Height Dimension 0 + size Size String 32x32 + squareWidht SquareWidht Dimension 16 + squareHeight SquareHeight Dimension 16 + x Position Position 320 + y Position Position 320 + xHot XHot Position NotSet + yHot YHot Position NotSet + margin Margin Dimension 16 + grid Grid Boolean True + gridTolerance GridTolerance Dimension 8 + dashed Dashed Boolean True + dashes Dashes Bitmap XtUnspecifiedPixmap + stippled Stippled Boolean True + stipple Sripple Bitmap XtUnspecifiedPixmap + proportional Proportional Boolean True + axes Axes Boolean True + button1Function Button1Function ButtonFunction Set + button2Function Button2Function ButtonFunction Invert + button3Function Button3Function ButtonFunction Clear + button4Function Button4Function ButtonFunction Invert + button5Function Button5Function ButtonFunction Invert + filename Filename String None + basename Basename String None +*/ + +/* define any special resource names here that are not in <X11/StringDefs.h> */ + +#define XtNbitmapResource "bitmapResource" +#define XtNstipple "stipple" +#define XtNstippled "stippled" +#define XtNdashes "dashes" +#define XtNdashed "dashed" +#define XtNgrid "grid" +#define XtNgridTolerance "gridTolerance" +#define XtNaxes "axes" +#define XtNbitmapSize "bitmapSize" +#define XtNsize "size" +#define XtNsquareWidth "squareWidth" +#define XtNsquareHeight "squareHeight" +#define XtNxHot "xHot" +#define XtNyHot "yHot" +#define XtNbutton1Function "button1Function" +#define XtNbutton2Function "button2Function" +#define XtNbutton3Function "button3Function" +#define XtNbutton4Function "button4Function" +#define XtNbutton5Function "button5Function" +#define XtNfilename "filename" +#define XtNbasename "basename" +#define XtNmouseForeground "mouseForeground" +#define XtNmouseBackground "mouseBackground" +#define XtNframe "frame" +#define XtNmargin "margin" +#define XtNproportional "proportional" + +#define XtCBitmapResource "BitmapResource" +#define XtCHighlight "Highlight" +#define XtCStipple "Stipple" +#define XtCStippled "Stippled" +#define XtCDashes "Dashes" +#define XtCDashed "Dashed" +#define XtCGrid "Grid" +#define XtCGridTolerance "GridTolerance" +#define XtCAxes "Axes" +#define XtBitmapSize "BitmapSize" +#define XtCSize "Size" +#define XtCSquareWidth "SquareWidth" +#define XtCSquareHeight "SquareHeight" +#define XtCXHot "XHot" +#define XtCYHot "YHot" +#define XtCButton1Function "Button1Function" +#define XtCButton2Function "Button2Function" +#define XtCButton3Function "Button3Function" +#define XtCButton4Function "Button4Function" +#define XtCButton5Function "Button5Function" +#define XtCFilename "Filename" +#define XtCBasename "Basename" +#define XtCFrame "Frame" +#ifndef XtCMargin +#define XtCMargin "Margin" +#endif +#define XtCProportional "Proportional" + +#define XtRButtonFunction "ButtonFunction" + +/* bitmap defines */ + +#define NotSet -1 +#define Clear 0 +#define Set 1 +#define Invert 2 +#define Highlight 3 +#define On True +#define Off False + +#define XtClear "clear" +#define XtSet "set" +#define XtInvert "invert" + +#define MarkRequest "MarkRequest" +#define StoreRequest "StoreRequest" +#define RestoreRequest "RestoreRequest" +#define CopyRequest "CopyRequest" +#define MoveRequest "MoveRequest" +#define PointRequest "PointRequest" +#define LineRequest "LineRequest" +#define CurveRequest "CurveRequest" +#define RectangleRequest "RectangleRequest" +#define FilledRectangleRequest "FilledRectangleRequest" +#define CircleRequest "CircleRequest" +#define FilledCircleRequest "FilledCircleRequest" +#define FloodFillRequest "FloodFillRequest" +#define HotSpotRequest "HotSpotRequest" +#define ZoomInRequest "ZoomInRequest" +#define PasteRequest "PasteRequest" +#define ImmediateCopyRequest "ImmediateCopyRequest" +#define ImmediateMoveRequest "ImmediateMoveRequest" + +/* bitmap exports */ + +extern Boolean BWEngageRequest(); +extern Boolean BWTreminateRequest(); + +extern void BWClearAll(); +extern void BWSetAll(); +extern void BWInvertAll(); +extern void BWUp(); +extern void BWDown(); +extern void BWLeft(); +extern void BWRight(); +extern void BWRotateRight(); +extern void BWRotateLeft(); +extern void BWSwitchGrid(); +extern void BWGrid(); +extern void BWSwitchDashed(); +extern void BWDashed(); +extern void BWSwitchAxes(); +extern void BWAxes(); +extern void BWDrawSquare(); +extern void BWDrawLine(); +extern void BWDrawRectangle(); +extern void BWDrawFilledRectangle(); +extern void BWDrawCircle(); +extern void BWDrawFilledCircle(); +extern void BWFloodFill(); +extern void BWMark(); +extern void BWMarkAll(); +extern void BWUnmark(); +extern void BWSelect(); +extern void BWUnmark(); +extern void BWStore(); +extern void BWStoreToBuffer(); +extern void BWUndo(); +extern void BWResize(); +extern void BWClip(); +extern void BWUnclip(); +extern void BWGrabSelection(); +extern void BWRequestSelection(); +extern void BWSetChanged(); +extern Boolean BWQueryChanged(); +extern int BWReadFile(); +extern int BWWriteFile(); +extern String BWUnparseStatus(); +extern String BWGetFilename(); +extern String BWGetBasename(); +extern void BWChangeBasename(); +extern void BWRemoveAllRequests(); +extern void BWClearHotSpot(); +extern Boolean BWQueryMarked(); +extern void BWFold(); +extern void BWClear(); +extern void BWSet(); +extern void BWInvert(); +extern void BWFlipHoriz(); +extern void BWFlipVert(); +extern void BWClearMarked(); +extern Boolean BWAddRequest(); +extern void BWChangeNotify(); +extern Pixmap BWGetUnzoomedPixmap(); +extern void BWClearChanged(); +extern Boolean BWQueryStored(); +extern Boolean BWQueryStippled(); +extern void BWSwitchStippled(); +extern void BWRedrawMark(); +extern Boolean BWQueryAxes(); +extern void BWHighlightAxes(); +extern void BWChangedFilename(); +extern String BWGetFilepath(); +extern void BWZoomOut(); +extern void BWZoomMarked(); +extern void BWRescale(); +extern Boolean BWQueryZooming(); +extern void BWRedrawGrid(); +extern void BWRedrawSquares(); +extern void BWRedrawHotSpot(); +extern Boolean BWQueryGrid(); +extern Boolean BWQueryDashed(); +extern Boolean BWQueryProportional(); +extern void BWSwitchProportional(); +extern void BWDrawGrid(); +extern void BWChangeFilename(); +extern Boolean BWParseSize(); + +typedef struct _BWRequestRec BWRequestRec; +typedef char *BWRequest; + +/* declare specific BitmapWidget class and instance datatypes */ + +typedef struct _BitmapClassRec *BitmapWidgetClass; +typedef struct _BitmapRec *BitmapWidget; +/* declare the class constant */ + +extern WidgetClass bitmapWidgetClass; + +#endif /* _Bitmap_h */ + + diff --git a/BitmapP.h b/BitmapP.h new file mode 100644 index 0000000..eb351cc --- /dev/null +++ b/BitmapP.h @@ -0,0 +1,194 @@ +/* $Xorg: BitmapP.h,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 + */ + + + +#ifndef _BitmapP_h +#define _BitmapP_h + +#include "Bitmap.h" +#include <X11/Xaw/SimpleP.h> + +typedef struct { + Atom *targets; + Cardinal num_targets; + BWRequestRec *requests; + Cardinal num_requests; + BWRequestRec *request[100]; + +} BitmapClassPart; + +/* Full class record declaration */ +typedef struct _BitmapClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + BitmapClassPart bitmap_class; +} BitmapClassRec; + +extern BitmapClassRec bitmapClassRec; + +/**********/ +struct _BWRequestRec { + char *name; + int status_size; + void (*engage)(); + XtPointer engage_client_data; + void (*terminate)(); + XtPointer terminate_client_data; + void (*remove)(); + XtPointer remove_client_data; +} ; + +typedef struct { + Position from_x, from_y, + to_x, to_y; +} BWArea; + +typedef struct { + BWRequestRec *request; + XtPointer status; + Boolean trap; + XtPointer call_data; +} BWRequestStack; + +typedef struct { + XImage *image, *buffer; + XPoint hot; + Position at_x, at_y; + Boolean fold; + Boolean grid; + Boolean changed; +} BWZoom; + +typedef struct { + Boolean own; + Boolean limbo; +} BWSelection; + +/* New fields for the Bitmap widget record */ +typedef struct { + /* resources */ + Pixel foreground_pixel; + Pixel highlight_pixel; + Pixel frame_pixel; + Pixmap stipple; + Boolean stippled; + Boolean proportional; + Boolean grid; + Dimension grid_tolerance; + Pixmap dashes; + Boolean dashed; + Boolean axes; + Boolean resize; + Dimension margin, squareW, squareH, width, height; + XPoint hot; + int button_function[5]; + String filename, basename; + /* private state */ + String size; + Position horizOffset, vertOffset; + void (*notify)(); + BWRequestStack *request_stack; + Cardinal cardinal, current; + /*Boolean trapping;*/ + XImage *image, *buffer, *storage; + XPoint buffer_hot; + BWArea mark, buffer_mark; + GC drawing_gc; + GC highlighting_gc; + GC frame_gc; + GC axes_gc; + Boolean changed; + Boolean fold; + Boolean zooming; + BWZoom zoom; + XtPointer *value; + char status[80]; + BWSelection selection; + Boolean stipple_change_expose_event; +} BitmapPart; + +/* Full instance record declaration */ +typedef struct _BitmapRec { + CorePart core; + SimplePart simple; + BitmapPart bitmap; +} BitmapRec; + +/* Private functions */ + +#define Length(width, height)\ + (((int)(width) + 7) / 8 * (height)) + +#define InBitmapX(BW, x)\ + (Position)(min((Position)((Dimension)(max(BW->bitmap.horizOffset,x) -\ + BW->bitmap.horizOffset) /\ + BW->bitmap.squareW), BW->bitmap.width - 1)) + +#define InBitmapY(BW, y)\ + (Position)(min((Position)((Dimension)(max(BW->bitmap.vertOffset, y) -\ + BW->bitmap.vertOffset) /\ + BW->bitmap.squareH), BW->bitmap.height - 1)) + +#define InWindowX(BW, x)\ + (Position) (BW->bitmap.horizOffset + ((x) * BW->bitmap.squareW)) + +#define InWindowY(BW, y)\ + (Position) (BW->bitmap.vertOffset + ((y) * BW->bitmap.squareH)) + +#define GetPixmap(BW, image)\ + XCreateBitmapFromData(XtDisplay(BW), XtWindow(BW),\ + image->data, image->width, image->height) + + +#define QuerySet(x, y) (((x) != NotSet) && ((y) != NotSet)) + +#define bit int + +#define QueryZero(x, y) (((x) == 0) || ((y) == 0)) + +#define Swap(x, y) {Position t; t = x; x = y; y = t;} + +#define QuerySwap(x, y) if(x > y) Swap(x, y) + +#define QueryInBitmap(BW, x, y)\ + (((x) >= 0) && ((x) < BW->bitmap.image->width) &&\ + ((y) >= 0) && ((y) < BW->bitmap.image->height)) + +#define Value(BW, button) (BW->bitmap.button_function[button - 1]) + +#define CreateCleanData(length) XtCalloc(length, sizeof(char)) +XImage *CreateBitmapImage(); +void DestroyBitmapImage(); + +#endif /* _BitmapP_h */ diff --git a/CutPaste.c b/CutPaste.c new file mode 100644 index 0000000..7b20fcc --- /dev/null +++ b/CutPaste.c @@ -0,0 +1,223 @@ +/* $Xorg: CutPaste.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/Xatom.h> +#include "BitmapP.h" + +#include <stdio.h> +#include <math.h> + +#ifndef abs +#define abs(x) (((x) > 0) ? (x) : -(x)) +#endif +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#define max(x, y) (((x) > (y)) ? (x) : (y)) + + +extern Boolean DEBUG; + +/***************************************************************************** + * Cut and Paste * + *****************************************************************************/ + +/* ARGSUSED */ +Boolean ConvertSelection(w, selection, target, type, val_ret, length, format) + Widget w; + Atom *selection, *target, *type; + XtPointer *val_ret; + unsigned long *length; + int *format; +{ + XPointer *value = (XPointer *)val_ret; + BitmapWidget BW = (BitmapWidget) w; + Pixmap *pixmap; + char *data; + XImage *image; + Dimension width, height; + + switch (*target) { + +/* XA_TARGETS undefined ?!? + + case XA_TARGETS: + *type = XA_ATOM; + *value = (XPointer) bitmapClassRec.bitmap_class.targets; + *length = bitmapClassRec.bitmap_class.num_targets; + *format = 32; + return True; + +*/ + + case XA_BITMAP: + case XA_PIXMAP: + if (BWQueryMarked(w)) { + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + data = CreateCleanData(Length(width, height)); + image = CreateBitmapImage(BW, data, width, height); + CopyImageData(BW->bitmap.image, image, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 0, 0); + pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap)); + *pixmap = GetPixmap(BW, image); + DestroyBitmapImage(&image); + } + else if (BWQueryStored(w)) { + pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap)); + *pixmap = GetPixmap(BW, BW->bitmap.storage); + } + else return False; + *type = XA_PIXMAP; + *value = (XPointer) pixmap; + *length = 1; + *format = 32; + return True; + + default: + return False; + } +} + +/* ARGSUSED */ +void LoseSelection(w, selection) + Widget w; + Atom *selection; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (DEBUG) + fprintf(stderr, "Lost Selection\n"); + BW->bitmap.selection.own = False; + + BWUnmark(w); +} + +/* ARGSUSED */ +void SelectionDone(w, selection, target) + Widget w; + Atom *selection, *target; +{ +/* Done Automatically ?!? + + BitmapWidget BW = (BitmapWidget) w; + + if (*target != XA_TARGETS) + XtFree(BW->bitmap.value); + +*/ +} + +void BWGrabSelection(w, btime) + Widget w; + Time btime; +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.selection.own = XtOwnSelection(w, XA_PRIMARY, btime, + ConvertSelection, + LoseSelection, + SelectionDone); + if (DEBUG && BW->bitmap.selection.own) + fprintf(stderr, "Own the selection\n"); +} + +XImage *GetImage(); + +/* ARGSUSED */ +void SelectionCallback(w, cldat, selection, type, val, length, format) + Widget w; + XtPointer cldat; + Atom *selection, *type; + XtPointer val; + unsigned long *length; + int *format; +{ + XPointer value = (XPointer)val; + BitmapWidget BW = (BitmapWidget) w; + Pixmap *pixmap; + + switch (*type) { + + case XA_BITMAP: + case XA_PIXMAP: + DestroyBitmapImage(&BW->bitmap.storage); + pixmap = (Pixmap *) value; + BW->bitmap.storage = GetImage(BW, *pixmap); + XFree((char *)pixmap); + break; + + default: + XtWarning(" selection request failed. BitmapWidget"); + break; + } + + BW->bitmap.selection.limbo = FALSE; +} + +void BWRequestSelection(w, btime, wait) + Widget w; + Time btime; + Boolean wait; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.selection.own) + BWStore(w); + else { + XtGetSelectionValue(w, XA_PRIMARY, XA_PIXMAP, + SelectionCallback, NULL, btime); + + BW->bitmap.selection.limbo = TRUE; + + if (wait) + while (BW->bitmap.selection.limbo) { + XEvent event; + XtNextEvent(&event); + XtDispatchEvent(&event); + } + } +} + +/* ARGSUSED */ +/* Returns true if there is a transferable selection */ +Boolean BWQuerySelection(w, btime) + Widget w; + Time btime; +{ +/* To be written. XA_TARGETS to be used. So far undefined ?!? */ + + return True; +} +/*****************************************************************************/ @@ -0,0 +1,4 @@ +#define Dashes_width 2 +#define Dashes_height 2 +static char Dashes_bits[] = { + 0x01, 0x02}; diff --git a/Dialog.c b/Dialog.c new file mode 100644 index 0000000..ebf0a3b --- /dev/null +++ b/Dialog.c @@ -0,0 +1,204 @@ +/* $Xorg: Dialog.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/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> +#include <X11/Xaw/Dialog.h> +#include <X11/Xaw/Command.h> +#include <X11/Xmu/CharSet.h> + +#include "Dialog.h" + +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#define max(x, y) (((x) > (y)) ? (x) : (y)) + +static void SetDialogButton(); + +static XtActionsRec actions_table[] = { + {"set-dialog-button", SetDialogButton}, +}; + +static DialogButton dialog_buttons[] = { + {"yes", Yes}, + {"no", No}, + {"maybe", Maybe}, + {"okay", Okay}, + {"abort", Abort}, + {"cancel", Cancel}, + {"retry", Retry}, +}; + +static unsigned long selected; + +/* ARGSUSED */ +static void SetSelected(w, clientData, callData) /* ARGSUSED */ + Widget w; + XtPointer clientData, callData; +{ + String name = (String)clientData; + int i; + + for (i = 0; i < XtNumber(dialog_buttons); i++) + if (!strcmp(dialog_buttons[i].name, name)) + selected |= dialog_buttons[i].flag; +} + +/* ARGSUSED */ +static void SetDialogButton(w, event, argv, argc) + Widget w; /* not used */ + XEvent *event; /* not used */ + String *argv; + Cardinal *argc; +{ + char button_name[80]; + XtPointer dummy = NULL; + int i; + + for (i = 0; i < *argc; i++) { + XmuCopyISOLatin1Lowered (button_name, argv[i]); + SetSelected(w, button_name, dummy); + } +} + +static Boolean firstTime = True; + +Dialog CreateDialog(top_widget, name, options) + Widget top_widget; + String name; + unsigned long options; +{ + int i; + Dialog popup; + + popup = (Dialog) XtMalloc(sizeof(_Dialog)); + + if (popup) { + if (firstTime) { + XtAddActions(actions_table, XtNumber(actions_table)); + firstTime = False; + } + popup->top_widget = top_widget; + popup->shell_widget = XtCreatePopupShell(name, + transientShellWidgetClass, + top_widget, NULL, 0); + popup->dialog_widget = XtCreateManagedWidget("dialog", + dialogWidgetClass, + popup->shell_widget, + NULL, 0); + for (i = 0; i < XtNumber(dialog_buttons); i++) + if (options & dialog_buttons[i].flag) + XawDialogAddButton(popup->dialog_widget, + dialog_buttons[i].name, + SetSelected, dialog_buttons[i].name); + popup->options = options; + return popup; + } + else + return NULL; +} + +void PopdownDialog(popup, answer) + Dialog popup; + String *answer; +{ + if (answer) + *answer = XawDialogGetValueString(popup->dialog_widget); + + XtPopdown(popup->shell_widget); +} + +unsigned long PopupDialog(popup, message, suggestion, answer, grab) + Dialog popup; + String message, suggestion, *answer; + XtGrabKind grab; +{ + Position popup_x, popup_y, top_x, top_y; + Dimension popup_width, popup_height, top_width, top_height, border_width; + int n; + Arg wargs[4]; + + n = 0; + XtSetArg(wargs[n], XtNlabel, message); n++; + XtSetArg(wargs[n], XtNvalue, suggestion); n++; + XtSetValues(popup->dialog_widget, wargs, n); + + XtRealizeWidget(popup->shell_widget); + + n = 0; + XtSetArg(wargs[n], XtNx, &top_x); n++; + XtSetArg(wargs[n], XtNy, &top_y); n++; + XtSetArg(wargs[n], XtNwidth, &top_width); n++; + XtSetArg(wargs[n], XtNheight, &top_height); n++; + XtGetValues(popup->top_widget, wargs, n); + + n = 0; + XtSetArg(wargs[n], XtNwidth, &popup_width); n++; + XtSetArg(wargs[n], XtNheight, &popup_height); n++; + XtSetArg(wargs[n], XtNborderWidth, &border_width); n++; + XtGetValues(popup->shell_widget, wargs, n); + + popup_x = max(0, + min(top_x + ((Position)top_width - (Position)popup_width) / 2, + (Position)DisplayWidth(XtDisplay(popup->shell_widget), + DefaultScreen(XtDisplay(popup->shell_widget))) - + (Position)popup_width - 2 * (Position)border_width)); + popup_y = max(0, + min(top_y + ((Position)top_height - (Position)popup_height) / 2, + (Position)DisplayHeight(XtDisplay(popup->shell_widget), + DefaultScreen(XtDisplay(popup->shell_widget))) - + (Position)popup_height - 2 * (Position)border_width)); + n = 0; + XtSetArg(wargs[n], XtNx, popup_x); n++; + XtSetArg(wargs[n], XtNy, popup_y); n++; + XtSetValues(popup->shell_widget, wargs, n); + + selected = None; + + XtPopup(popup->shell_widget, grab); + XWarpPointer(XtDisplay(popup->shell_widget), + XtWindow(popup->top_widget), + XtWindow(popup->shell_widget), + 0, 0, top_width, top_height, + popup_width / 2, popup_height / 2); + + while ((selected & popup->options) == None) { + XEvent event; + XtNextEvent(&event); + XtDispatchEvent(&event); + } + + PopdownDialog(popup, answer); + + return (selected & popup->options); +} diff --git a/Dialog.h b/Dialog.h new file mode 100644 index 0000000..12e0c6c --- /dev/null +++ b/Dialog.h @@ -0,0 +1,56 @@ +/* $Xorg: Dialog.h,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 + */ + + +/*#define None 0*/ +#define Yes 1<<1 +#define No 1<<2 +#define Maybe 1<<3 /* :-) */ +#define Okay 1<<4 +#define Abort 1<<5 +#define Cancel 1<<6 +#define Retry 1<<7 + +typedef struct { + Widget top_widget, shell_widget, dialog_widget; + unsigned long options; +} _Dialog, *Dialog; + +typedef struct { + String name; + unsigned long flag; +} DialogButton; + +extern Dialog CreateDialog(); +extern unsigned long PopupDialog(); +extern void PopdownDialog(); @@ -0,0 +1,13 @@ +#define Down_width 30 +#define Down_height 30 +static char Down_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x18, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0xf0, 0xb8, 0xe3, 0x01, 0xf0, 0x59, 0xf3, 0x01, + 0xb0, 0xbb, 0xbb, 0x01, 0x70, 0x5f, 0xdf, 0x01, 0xe0, 0xbe, 0xef, 0x00, + 0xc0, 0x5d, 0x77, 0x00, 0x80, 0xab, 0x3a, 0x00, 0x00, 0x57, 0x1d, 0x00, + 0x00, 0xae, 0x0e, 0x00, 0x00, 0x5c, 0x07, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00}; @@ -0,0 +1,17 @@ +#define Excl_width 40 +#define Excl_height 32 +static char Excl_bits[] = { + 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, + 0x00, 0x00, 0x80, 0xc3, 0x01, 0x00, 0x00, 0xc0, 0x99, 0x03, 0x00, 0x00, + 0xc0, 0x34, 0x03, 0x00, 0x00, 0xe0, 0x6a, 0x07, 0x00, 0x00, 0x70, 0x76, + 0x0e, 0x00, 0x00, 0x70, 0x6a, 0x0e, 0x00, 0x00, 0x38, 0x76, 0x1c, 0x00, + 0x00, 0x18, 0x6a, 0x18, 0x00, 0x00, 0x1c, 0x76, 0x38, 0x00, 0x00, 0x0e, + 0x6a, 0x70, 0x00, 0x00, 0x06, 0x76, 0x60, 0x00, 0x00, 0x07, 0x6a, 0xe0, + 0x00, 0x80, 0x03, 0x76, 0xc0, 0x01, 0x80, 0x03, 0x6a, 0xc0, 0x01, 0xc0, + 0x01, 0x76, 0x80, 0x03, 0xc0, 0x00, 0x6a, 0x00, 0x03, 0xe0, 0x00, 0x34, + 0x00, 0x07, 0x70, 0x00, 0x18, 0x00, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x0e, + 0x38, 0x00, 0x3c, 0x00, 0x1c, 0x1c, 0x00, 0x76, 0x00, 0x38, 0x1c, 0x00, + 0x6a, 0x00, 0x38, 0x0e, 0x00, 0x76, 0x00, 0x70, 0x0e, 0x00, 0x3c, 0x00, + 0x70, 0x1e, 0x00, 0x00, 0x00, 0x78, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xfc, + 0xff, 0xff, 0xff, 0x3f}; diff --git a/FlipHoriz b/FlipHoriz new file mode 100644 index 0000000..a72da3d --- /dev/null +++ b/FlipHoriz @@ -0,0 +1,13 @@ +#define FlipHoriz_width 30 +#define FlipHoriz_height 30 +static char FlipHoriz_bits[] = { + 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x1d, 0x00, + 0x00, 0x80, 0x3b, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xee, 0x00, + 0x00, 0x00, 0xdc, 0x01, 0xc0, 0xff, 0xbf, 0x03, 0xe0, 0xff, 0x5f, 0x07, + 0xb0, 0xaa, 0xaa, 0x0e, 0x58, 0x55, 0x55, 0x1d, 0xac, 0xaa, 0xaa, 0x0e, + 0xfe, 0xff, 0x5f, 0x07, 0xff, 0xff, 0xbf, 0x03, 0x6b, 0x00, 0xdc, 0x01, + 0x77, 0x00, 0xee, 0x00, 0x6b, 0x00, 0x77, 0x00, 0x77, 0x80, 0x3b, 0x00, + 0x6b, 0x80, 0x1d, 0x00, 0x77, 0x80, 0x0f, 0x00, 0x6b, 0x80, 0x07, 0x00, + 0xff, 0x1f, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xac, 0x06, 0x00, 0x00, + 0x58, 0x03, 0x00, 0x00, 0xb0, 0x06, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, + 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/FlipVert b/FlipVert new file mode 100644 index 0000000..f5df65b --- /dev/null +++ b/FlipVert @@ -0,0 +1,13 @@ +#define FlipVert_width 30 +#define FlipVert_height 30 +static char FlipVert_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x75, 0x00, 0x00, + 0xe0, 0xea, 0x00, 0x00, 0x70, 0xd5, 0x01, 0x00, 0xb8, 0xaa, 0x03, 0x00, + 0xdc, 0x75, 0x07, 0x00, 0xee, 0xfb, 0x0e, 0x00, 0xf7, 0xf5, 0x1d, 0x00, + 0xbb, 0xbb, 0x1b, 0x00, 0x9f, 0x35, 0x1f, 0x00, 0x8f, 0x3b, 0x1e, 0x00, + 0x80, 0x35, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x80, 0x35, 0x20, 0x08, + 0x80, 0x3b, 0x60, 0x0c, 0x80, 0x35, 0xe0, 0x0e, 0x80, 0x3b, 0xe0, 0x0f, + 0x80, 0x35, 0x60, 0x0d, 0x80, 0x3b, 0xe0, 0x0e, 0x80, 0xf5, 0x7f, 0x0d, + 0x00, 0xfb, 0xff, 0x06, 0x00, 0xb6, 0x6a, 0x03, 0x00, 0x7c, 0xf5, 0x01, + 0x00, 0xb8, 0xea, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xe0, 0x3f, 0x00}; @@ -0,0 +1,13 @@ +#define Fold_width 30 +#define Fold_height 30 +static char Fold_bits[] = { + 0xff, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x57, 0xf5, 0xab, 0x3a, + 0xab, 0xff, 0x7f, 0x35, 0xd7, 0x3f, 0xff, 0x3a, 0xab, 0x03, 0x70, 0x35, + 0x57, 0x07, 0xb8, 0x3a, 0xbb, 0x0e, 0x5c, 0x37, 0x7f, 0x1d, 0xae, 0x3f, + 0xfb, 0x3a, 0xd7, 0x37, 0xdf, 0xf5, 0xeb, 0x3e, 0x9b, 0xeb, 0x75, 0x36, + 0x1f, 0xd7, 0x3a, 0x3e, 0x1f, 0xae, 0x1d, 0x3e, 0x0e, 0xfc, 0x0e, 0x1c, + 0x0e, 0xdc, 0x0f, 0x1c, 0x1f, 0x6e, 0x1d, 0x3e, 0x1f, 0xd7, 0x3a, 0x3e, + 0x9b, 0xeb, 0x75, 0x36, 0xdf, 0xf5, 0xeb, 0x3e, 0xfb, 0x3a, 0xd7, 0x37, + 0x7f, 0x1d, 0xae, 0x3f, 0xbb, 0x0e, 0x5c, 0x37, 0x57, 0x07, 0xb8, 0x3a, + 0xab, 0x03, 0x70, 0x35, 0xd7, 0x3f, 0xff, 0x3a, 0xab, 0xff, 0x7f, 0x35, + 0x57, 0xf5, 0xab, 0x3a, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f}; diff --git a/Graphics.c b/Graphics.c new file mode 100644 index 0000000..918b7c3 --- /dev/null +++ b/Graphics.c @@ -0,0 +1,1602 @@ +/* $Xorg: Graphics.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/Xfuncs.h> +#include "BitmapP.h" + +#include <stdio.h> +#include <math.h> + +#ifndef abs +#define abs(x) (((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)) +#ifndef rint +#define rint(x) floor(x + 0.5) +#endif + +/*****************************************************************************\ + * Graphics * +\*****************************************************************************/ + +#define GetBit(image, x, y)\ + ((bit)((*(image->data + (x) / 8 + (y) * image->bytes_per_line) &\ + (1 << ((x) % 8))) ? 1 : 0)) + + +bit BWGetBit(w, x, y) + Widget w; + Position x, y; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QueryInBitmap(BW, x, y)) + return GetBit(BW->bitmap.image, x, y); + else + return NotSet; +} + + +#define InvertBit(image, x, y)\ + (*(image->data + (x) / 8 + (y) * image->bytes_per_line) ^=\ + (bit) (1 << ((x) % 8))) + + +#define SetBit(image, x, y)\ + (*(image->data + (x) / 8 + (y) * image->bytes_per_line) |=\ + (bit) (1 << ((x) % 8))) + +#define ClearBit(image, x, y)\ + (*(image->data + (x) / 8 + (y) * image->bytes_per_line) &=\ + (bit)~(1 << ((x) % 8))) + + +#define HighlightSquare(BW, x, y)\ + XFillRectangle(XtDisplay(BW), XtWindow(BW),\ + BW->bitmap.highlighting_gc,\ + InWindowX(BW, x), InWindowY(BW, y),\ + BW->bitmap.squareW, BW->bitmap.squareH) +/* +void HighlightSquare(BW, x, y) + BitmapWidget BW; + Position x, y; +{ + XFillRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.highlighting_gc, + InWindowX(BW, x), InWindowY(BW, y), + BW->bitmap.squareW, BW->bitmap.squareH); +} +*/ + +#define DrawSquare(BW, x, y)\ + XFillRectangle(XtDisplay(BW), XtWindow(BW),\ + BW->bitmap.drawing_gc,\ + InWindowX(BW, x), InWindowY(BW, y),\ + BW->bitmap.squareW, BW->bitmap.squareH) + +/* +void DrawSquare(BW, x, y) + BitmapWidget BW; + Position x, y; +{ + XFillRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.drawing_gc, + InWindowX(BW, x), InWindowY(BW, y), + BW->bitmap.squareW, BW->bitmap.squareH); +} +*/ + +#define InvertPoint(BW, x, y)\ + {InvertBit(BW->bitmap.image, x, y); DrawSquare(BW, x, y);} + +#define DrawPoint(BW, x, y, value)\ + if (GetBit(BW->bitmap.image, x, y) != value)\ + InvertPoint(BW, x, y) + +void BWDrawPoint(w, x, y, value) + Widget w; + Position x, y; + bit value; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QueryInBitmap(BW, x, y)) { + if (value == Highlight) + HighlightSquare(BW, x, y); + else + DrawPoint(BW, x, y, value); + } +} + +XPoint *HotSpotShape(BW, x ,y) + BitmapWidget BW; + Position x, y; +{ + static XPoint points[5]; + + points[0].x = InWindowX(BW, x); + points[0].y = InWindowY(BW, y + 1.0/2); + points[1].x = InWindowX(BW, x + 1.0/2); + points[1].y = InWindowY(BW, y + 1); + points[2].x = InWindowX(BW, x + 1); + points[2].y = InWindowY(BW, y + 1.0/2); + points[3].x = InWindowX(BW, x + 1.0/2); + points[3].y = InWindowY(BW, y); + points[4].x = InWindowX(BW, x); + points[4].y = InWindowY(BW, y + 1.0/2); + + return points; +} + +#define DrawHotSpot(BW, x, y)\ + XFillPolygon(XtDisplay(BW), XtWindow(BW), BW->bitmap.drawing_gc,\ + HotSpotShape(BW, x, y), 5, Convex, CoordModeOrigin) + +#define HighlightHotSpot(BW, x, y)\ + XFillPolygon(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc,\ + HotSpotShape(BW, x, y), 5, Convex, CoordModeOrigin) + +XImage *CreateBitmapImage(); +void DestroyBitmapImage(); + +void BWRedrawHotSpot(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) + DrawHotSpot(BW, BW->bitmap.hot.x, BW->bitmap.hot.y); +} + +void BWClearHotSpot(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) { + DrawHotSpot(BW, BW->bitmap.hot.x, BW->bitmap.hot.y); + BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet; + } +} + +void BWDrawHotSpot(w, x, y, value) + Widget w; + Position x, y; + int value; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QueryInBitmap(BW, x, y)) { + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) && + ((BW->bitmap.hot.x == x) && (BW->bitmap.hot.y == y))) { + if ((value == Clear) || (value == Invert)) { + BWClearHotSpot(w); + } + } + else + if ((value == Set) || (value == Invert)) { + BWClearHotSpot(w); + DrawHotSpot(BW, x, y); + BW->bitmap.hot.x = x; + BW->bitmap.hot.y = y; + } + + if (value == Highlight) + HighlightHotSpot(BW, x, y); + } +} + +void BWSetHotSpot(w, x, y) + Widget w; + Position x, y; +{ + if (QuerySet(x, y)) + BWDrawHotSpot(w, x, y, Set); + else + BWClearHotSpot(w); +} + +/* high level procedures */ + +void BWRedrawSquares(w, x, y, width, height) + Widget w; + register Position x, y; + Dimension width, height; +{ + BitmapWidget BW = (BitmapWidget) w; + Position from_x = InBitmapX(BW, x); + Position from_y = InBitmapY(BW, y); + Position to_x = InBitmapX(BW, x + width); + Position 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.image->width - 1, to_x); + to_y = min(BW->bitmap.image->height - 1, to_y); + + for (x = from_x; x <= to_x; x++) + for (y = from_y; y <= to_y; y++) + if (GetBit(BW->bitmap.image, x, y)) DrawSquare(BW, x, y); +} + +void BWDrawGrid(w, from_x, from_y, to_x, to_y) + Widget w; + Position from_x, from_y, + to_x, to_y; +{ + BitmapWidget BW = (BitmapWidget) w; + int i; + + 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.image->width - 1, to_x); + to_y = min(BW->bitmap.image->height - 1, to_y); + + for(i = from_x + (from_x == 0); i <= to_x; i++) + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.frame_gc, + InWindowX(BW, i), InWindowY(BW, from_y), + InWindowX(BW, i), InWindowY(BW, to_y + 1)); + + for(i = from_y + (from_y == 0); i <= to_y; i++) + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.frame_gc, + InWindowX(BW, from_x), InWindowY(BW, i), + InWindowX(BW, to_x + 1), InWindowY(BW, i)); +} + + +void BWRedrawGrid(w, x, y, width, height) + Widget w; + Position x, y; + Dimension width, height; +{ + BitmapWidget BW = (BitmapWidget) w; + Position from_x = InBitmapX(BW, x); + Position from_y = InBitmapY(BW, y); + Position to_x = InBitmapX(BW, x + width); + Position to_y = InBitmapY(BW, y + height); + + if (BW->bitmap.grid) + BWDrawGrid(w, from_x, from_y, to_x, to_y); +} + +void BWDrawLine(w, from_x, from_y, to_x, to_y, value) + Widget w; + Position from_x, from_y, + to_x, to_y; + int value; +{ + Position i; + register double x, y; + double dx, dy, delta; + + dx = to_x - from_x; + dy = to_y - from_y; + x = from_x + 0.5; + y = from_y + 0.5; + delta = max(abs(dx), abs(dy)); + if (delta > 0) { + dx /= delta; + dy /= delta; + for(i = 0; i <= delta; i++) { + BWDrawPoint(w, (Position) x, (Position) y, value); + x += dx; + y += dy; + } + } + else + BWDrawPoint(w, from_x, from_y, value); +} + +void BWBlindLine(w, from_x, from_y, to_x, to_y, value) + Widget w; + Position from_x, from_y, + to_x, to_y; + int value; +{ + Position i; + register double x, y; + double dx, dy, delta; + + dx = to_x - from_x; + dy = to_y - from_y; + x = from_x + 0.5; + y = from_y + 0.5; + delta = max(abs(dx), abs(dy)); + if (delta > 0) { + dx /= delta; + dy /= delta; + x += dx; + y += dy; + for(i = 1; i <= delta; i++) { + BWDrawPoint(w, (Position) x, (Position) y, value); + x += dx; + y += dy; + } + } + else + BWDrawPoint(w, from_x, from_y, value); +} + +void BWDrawRectangle(w, from_x, from_y, to_x, to_y, value) + Widget w; + Position from_x, from_y, + to_x, to_y; + int value; +{ + register Position i; + Dimension delta, width, height; + + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + + width = to_x - from_x; + height = to_y - from_y; + + delta = max(width, height); + + if (!QueryZero(width, height)) { + for (i = 0; (int)i < (int)delta; i++) { + if ((int)i < (int)width) { + BWDrawPoint(w, from_x + i, from_y, value); + BWDrawPoint(w, to_x - i, to_y, value); + } + if ((int)i < (int)height) { + BWDrawPoint(w, from_x, to_y - i, value); + BWDrawPoint(w, to_x, from_y + i, value); + } + } + } + else + BWDrawLine(w, + from_x, from_y, + to_x, to_y, value); +} + +void BWDrawFilledRectangle(w, from_x, from_y, to_x, to_y, value) + Widget w; + Position from_x, from_y, + to_x, to_y; + int value; +{ + register Position x, y; + + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + + for (x = from_x; x <= to_x; x++) + for (y = from_y; y <= to_y; y++) + BWDrawPoint(w, x, y, value); +} + +void BWDrawCircle(w, origin_x, origin_y, point_x, point_y, value) + Widget w; + Position origin_x, origin_y, + point_x, point_y; + int value; +{ + register Position i, delta; + Dimension dx, dy, half; + double radius; + + dx = abs(point_x - origin_x); + dy = abs(point_y - origin_y); + radius = sqrt((double) ((int)dx * (int)dx + (int)dy * (int)dy)); + if (radius < 1.0) { + BWDrawPoint(w, origin_x, origin_y, value); + } + else { + BWDrawPoint(w, origin_x - (Position) floor(radius), origin_y, value); + BWDrawPoint(w, origin_x + (Position) floor(radius), origin_y, value); + BWDrawPoint(w, origin_x, origin_y - (Position) floor(radius), value); + BWDrawPoint(w, origin_x, origin_y + (Position) floor(radius), value); + } + half = radius / sqrt(2.0); + for(i = 1; (int)i <= (int)half; i++) { + delta = sqrt(radius * radius - i * i); + BWDrawPoint(w, origin_x - delta, origin_y - i, value); + BWDrawPoint(w, origin_x - delta, origin_y + i, value); + BWDrawPoint(w, origin_x + delta, origin_y - i, value); + BWDrawPoint(w, origin_x + delta, origin_y + i, value); + if (i != delta) { + BWDrawPoint(w, origin_x - i, origin_y - delta, value); + BWDrawPoint(w, origin_x - i, origin_y + delta, value); + BWDrawPoint(w, origin_x + i, origin_y - delta, value); + BWDrawPoint(w, origin_x + i, origin_y + delta, value); + } + } +} + +void BWDrawFilledCircle(w, origin_x, origin_y, point_x, point_y, value) + Widget w; + Position origin_x, origin_y, + point_x, point_y; + int value; +{ + register Position i, j, delta; + Dimension dx, dy; + double radius; + + dx = abs(point_x - origin_x); + dy = abs(point_y - origin_y); + radius = sqrt((double) ((int)dx * (int)dx + (int)dy * (int)dy)); + for(j = origin_x - (Position) floor(radius); + j <= origin_x + (Position) floor(radius); j++) + BWDrawPoint(w, j, origin_y, value); + for(i = 1; i <= (Position) floor(radius); i++) { + delta = sqrt(radius * radius - i * i); + for(j = origin_x - delta; j <= origin_x + delta; j++) { + BWDrawPoint(w, j, origin_y - i, value); + BWDrawPoint(w, j, origin_y + i, value); + } + } +} + +#define QueryFlood(BW, x, y, value)\ + ((GetBit(BW->bitmap.image, x, y) !=\ + (value & 1)) && QueryInBitmap(BW, x, y)) + +#define Flood(BW, x, y, value)\ + {if (value == Highlight) HighlightSquare(BW, x, y);\ + else InvertPoint(BW, x, y);} + +/* +void FloodLoop(BW, x, y, value) + BitmapWidget BW; + Position x, y; + int value; +{ + if (QueryFlood(BW, x, y, value)) { + Flood(BW, x, y, value); + FloodLoop(BW, x, y - 1, value); + FloodLoop(BW, x - 1, y, value); + FloodLoop(BW, x, y + 1, value); + FloodLoop(BW, x + 1, y, value); + } +} +*/ + +void FloodLoop(BW, x, y, value) + BitmapWidget BW; + Position x, y; + int value; +{ + Position save_x, save_y, x_left, x_right; + + if (QueryFlood(BW, x, y, value)) + Flood(BW, x, y, value) + + + save_x = x; + save_y = y; + + x++; + while (QueryFlood(BW, x, y, value)) { + Flood(BW, x, y, value); + x++; + } + x_right = --x; + + x = save_x; + x--; + while (QueryFlood(BW, x, y, value)) { + Flood(BW, x, y, value); + x--; + } + x_left = ++x; + + + x = x_left; + y = save_y; + y++; + + while (x <= x_right) { + Boolean flag = False; + Position x_enter; + + while (QueryFlood(BW, x, y, value) && (x <= x_right)) { + flag = True; + x++; + } + + if (flag) { + if ((x == x_right) && QueryFlood(BW, x, y, value)) + FloodLoop(BW, x, y, value); + else + FloodLoop(BW, x - 1, y, value); + } + + x_enter = x; + + while (!QueryFlood(BW, x, y, value) && (x < x_right)) + x++; + + if (x == x_enter) x++; + } + + x = x_left; + y = save_y; + y--; + + while (x <= x_right) { + Boolean flag = False; + Position x_enter; + + while (QueryFlood(BW, x, y, value) && (x <= x_right)) { + flag = True; + x++; + } + + if (flag) { + if ((x == x_right) && QueryFlood(BW, x, y, value)) + FloodLoop(BW, x, y, value); + else + FloodLoop(BW, x - 1, y, value); + } + + x_enter = x; + + while (!QueryFlood(BW, x, y, value) && (x < x_right)) + x++; + + if (x == x_enter) x++; + } +} + +void BWFloodFill(w, x, y, value) + Widget w; + Position x, y; + int value; +{ + BitmapWidget BW = (BitmapWidget) w; + int pixel; + + pixel = GetBit(BW->bitmap.image, x, y); + + if (value == Invert) + FloodLoop(BW, x, y, (pixel ? Clear : Set)); + else if (value != pixel) + FloodLoop(BW, x, y, value); +} + +#define QueryHotInMark(BW)\ + ((BW->bitmap.hot.x == max(BW->bitmap.mark.from_x,\ + min(BW->bitmap.hot.x, BW->bitmap.mark.to_x)))\ + &&\ + (BW->bitmap.hot.y == max(BW->bitmap.mark.from_y,\ + min(BW->bitmap.hot.y, BW->bitmap.mark.to_y)))) + +void BWUp(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, up, down; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_y - from_y) == 0) + return; + + for(x = from_x; x <= to_x; x++) { + first = up = GetBit(BW->bitmap.image, x, to_y); + for(y = to_y - 1; y >= from_y; y--) { + down = GetBit(BW->bitmap.image, x, y); + if (up != down) + InvertPoint(BW, x, y); + up =down; + } + if(first != down) + InvertPoint(BW, x, to_y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.hot.x, + (BW->bitmap.hot.y - 1 + BW->bitmap.image->height) % + BW->bitmap.image->height); + +} + +void BWDown(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, down, up; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_y - from_y) == 0) + return; + + for(x = from_x; x <= to_x; x++) { + first = down = GetBit(BW->bitmap.image, x, from_y); + for(y = from_y + 1; y <= to_y; y++) { + up = GetBit(BW->bitmap.image, x, y); + if (down != up) + InvertPoint(BW, x, y); + down = up; + } + if(first != up) + InvertPoint(BW, x, from_y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.hot.x, + (BW->bitmap.hot.y + 1) % BW->bitmap.image->height); +} + +void BWLeft(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, left, right; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_x - from_x) == 0) + return; + + for(y = from_y; y <= to_y; y++) { + first = left = GetBit(BW->bitmap.image, to_x, y); + for(x = to_x - 1; x >= from_x; x--) { + right = GetBit(BW->bitmap.image, x, y); + if (left != right) + InvertPoint(BW, x, y); + left = right; + } + if(first != right) + InvertPoint(BW, to_x, y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + (BW->bitmap.hot.x - 1 + BW->bitmap.image->width) % + BW->bitmap.image->width, + BW->bitmap.hot.y); +} + +void BWRight(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, right, left; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_x - from_x) == 0) + return; + + for(y = from_y; y <= to_y; y++) { + first = right = GetBit(BW->bitmap.image, from_x, y); + for(x = from_x + 1; x <= to_x; x++) { + left = GetBit(BW->bitmap.image, x, y); + if (right != left) + InvertPoint(BW, x, y); + right = left; + } + if(first != left) + InvertPoint(BW, from_x, y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + (BW->bitmap.hot.x + 1) % BW->bitmap.image->width, + BW->bitmap.hot.y); +} + +void TransferImageData(); + +void BWFold(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y, new_x, new_y; + Dimension horiz, vert; + char *storage_data; + XImage *storage; + + storage_data = CreateCleanData(Length(BW->bitmap.image->width, + BW->bitmap.image->height)); + + storage = CreateBitmapImage(BW, storage_data, + (Dimension) BW->bitmap.image->width, + (Dimension) BW->bitmap.image->height); + + TransferImageData(BW->bitmap.image, storage); + + BW->bitmap.fold ^= True; + horiz = (BW->bitmap.image->width + BW->bitmap.fold) / 2; + vert = (BW->bitmap.image->height + BW->bitmap.fold) / 2; + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) { + new_x = (int)(x + horiz) % (int)BW->bitmap.image->width; + new_y = (int)(y + vert) % (int)BW->bitmap.image->height; + if(GetBit(BW->bitmap.image, new_x, new_y) != + GetBit(storage, x, y)) + InvertPoint(BW, new_x, new_y); + } + + DestroyBitmapImage(&storage); + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) + BWSetHotSpot(w, + (Position) + ((int)(BW->bitmap.hot.x+horiz) + %(int)BW->bitmap.image->width), + (Position) + ((int)(BW->bitmap.hot.y+vert) + %(int)BW->bitmap.image->height) + ); +} + + +void BWClear(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + int i, length; + + length = Length(BW->bitmap.image->width, BW->bitmap.image->height); + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) + if (GetBit(BW->bitmap.image, x, y)) + DrawSquare(BW, x, y); + + for (i = 0; i < length; i++) + BW->bitmap.image->data[i] = 0; + +} + +void BWSet(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + int i, length; + + length = Length(BW->bitmap.image->width, BW->bitmap.image->height); + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) + if (!GetBit(BW->bitmap.image, x, y)) + DrawSquare(BW, x, y); + + for (i = 0; i < length; i++) + BW->bitmap.image->data[i] = 255; + +} + +void BWRedraw(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, BW->core.width, BW->core.height, + True); +} + +void BWInvert(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + int i, length; + + length = Length(BW->bitmap.image->width, BW->bitmap.image->height); + + XFillRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.drawing_gc, + InWindowX(BW, 0), InWindowY(BW, 0), + InWindowX(BW, BW->bitmap.image->width) - InWindowX(BW, 0), + InWindowY(BW, BW->bitmap.image->height) - InWindowY(BW, 0)); + + for (i = 0; i < length; i++) + BW->bitmap.image->data[i] ^= 255; +} + +void BWFlipHoriz(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + Position from_x, from_y, to_x, to_y; + float half; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + half = (float) (to_y - from_y) / 2.0 + 0.5; + + if (half == 0.0) + return; + + for (x = from_x; x <= to_x; x++) + for (y = 0; y < half; y++) + if (GetBit(BW->bitmap.image, x, from_y + y) != + GetBit(BW->bitmap.image, x, to_y - y)) { + InvertPoint(BW, x, from_y + y); + InvertPoint(BW, x, to_y - y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.hot.x, + BW->bitmap.image->height - 1 - BW->bitmap.hot.y); +} + +void BWFlipVert(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + Position from_x, from_y, to_x, to_y; + float half; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + half = (float) (to_x - from_x) / 2.0 + 0.5; + + if (half == 0) + return; + + for (y = from_y; y <= to_y; y++) + for (x = 0; x < half; x++) + if (GetBit(BW->bitmap.image, from_x + x, y) != + GetBit(BW->bitmap.image, to_x - x, y)) { + InvertPoint(BW, from_x + x, y); + InvertPoint(BW, to_x - x, y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.image->width - 1 - BW->bitmap.hot.x, + BW->bitmap.hot.y); +} + + +void BWRotateRight(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y, delta, shift, tmp; + Position half_width, half_height; + XPoint hot; + bit quad1, quad2, quad3, quad4; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + half_width = floor((to_x - from_x) / 2.0 + 0.5); + half_height = floor((to_y - from_y ) / 2.0 + 0.5); + shift = min((Position)(to_x - from_x), (Position)(to_y - from_y )) % 2; + delta = min((Position) half_width, (Position) half_height) - shift; + + for (x = 0; x <= delta; x++) { + for (y = 1 - shift; y <= delta; y++) { + quad1 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + quad2 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + quad3 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + quad4 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + + if (quad1 != quad2) + InvertPoint(BW, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + if (quad2 != quad3) + InvertPoint(BW, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + if (quad3 != quad4) + InvertPoint(BW, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + if (quad4 != quad1) + InvertPoint(BW, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + } + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) { + hot.x = BW->bitmap.hot.x - half_width; + hot.y = BW->bitmap.hot.y - half_height; + if (hot.x >= 0) hot.x += shift; + if (hot.y >= 0) hot.y += shift; + tmp = hot.x; + hot.x = - hot.y; + hot.y = tmp; + if (hot.x > 0) hot.x -= shift; + if (hot.y > 0) hot.y -= shift; + hot.x += half_width; + hot.y += half_height; + if (QueryInBitmap(BW, hot.x, hot.y)) + BWSetHotSpot(w, hot.x, hot.y); + } + +} + +void BWRotateLeft(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y,delta, shift, tmp; + Position half_width, half_height; + XPoint hot; + bit quad1, quad2, quad3, quad4; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + half_width = floor((to_x - from_x) / 2.0 + 0.5); + half_height = floor((to_y - from_y ) / 2.0 + 0.5); + shift = min((Position)(to_x - from_x), (Position)(to_y - from_y )) % 2; + delta = min((Position) half_width, (Position) half_height) - shift; + + for (x = 0; x <= delta; x++) { + for (y = 1 - shift; y <= delta; y++) { + quad1 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + quad2 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + quad3 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + quad4 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + + if (quad1 != quad4) + InvertPoint(BW, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + if (quad2 != quad1) + InvertPoint(BW, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + if (quad3 != quad2) + InvertPoint(BW, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + if (quad4 != quad3) + InvertPoint(BW, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + } + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) { + hot.x = BW->bitmap.hot.x - half_width; + hot.y = BW->bitmap.hot.y - half_height; + if (hot.x >= 0) hot.x += shift; + if (hot.y >= 0) hot.y += shift; + tmp = hot.x; + hot.x = hot.y; + hot.y = - tmp; + if (hot.x > 0) hot.x -= shift; + if (hot.y > 0) hot.y -= shift; + hot.x += half_width; + hot.y += half_height; + if (QueryInBitmap(BW, hot.x, hot.y)) + BWSetHotSpot(w, hot.x, hot.y); + } +} + + +void CopyImageData(source, destination, from_x, from_y, to_x, to_y, at_x, at_y) + XImage *source, *destination; + Position from_x, from_y, to_x, to_y, at_x, at_y; +{ + Position x, y, delta_x, delta_y; + + delta_x = to_x - from_x + 1; + delta_y = to_y - from_y + 1; + + for (x = 0; x < delta_x; x++) + for (y = 0; y < delta_y; y++) + if (GetBit(source, from_x + x, from_y + y)) + SetBit(destination, at_x + x, at_y + y); + else + ClearBit(destination, at_x + x, at_y + y); +} + +XImage *ConvertToBitmapImage(BW, image) + BitmapWidget BW; + XImage *image; +{ + XImage *bitmap_image; + char *data; + Position x, y; + + data = CreateCleanData(Length(image->width, image->height)); + bitmap_image = CreateBitmapImage(BW, data, + (Dimension) image->width, + (Dimension) image->height); + + for (x = 0; x < min(image->width, bitmap_image->width); x++) + for (y = 0; y < min(image->height, bitmap_image->height); y++) + if ((XGetPixel(image, x, y) != 0) != GetBit(bitmap_image, x, y)) + InvertBit(bitmap_image, x, y); + + return bitmap_image; +} + +void TransferImageData(source, destination) + XImage *source, *destination; +{ + Position x, y; + + for (x = 0; x < min(source->width, destination->width); x++) + for (y = 0; y < min(source->height, destination->height); y++) + if (GetBit(source, x, y) != GetBit(destination, x, y)) + InvertBit(destination, x, y); +} + +void BWStore(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + Dimension width, height; + char *storage_data; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + + DestroyBitmapImage(&BW->bitmap.storage); + + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + + storage_data = CreateCleanData(Length(width, height)); + + BW->bitmap.storage = CreateBitmapImage(BW, + storage_data, + width, height); + + CopyImageData(BW->bitmap.image, BW->bitmap.storage, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + 0, 0); + } +} + +void BWClearMarked(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) + BWDrawFilledRectangle(w, + BW->bitmap.mark.from_x, + BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, + BW->bitmap.mark.to_y, + Clear); +} + + +void BWDragMarked(w, at_x, at_y) + Widget w; + Position at_x, at_y; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) + BWDrawRectangle(w, + at_x, at_y, + at_x + BW->bitmap.mark.to_x - BW->bitmap.mark.from_x, + at_y + BW->bitmap.mark.to_y - BW->bitmap.mark.from_y, + Highlight); +} + +void BWDragStored(w, at_x, at_y) + Widget w; + Position at_x, at_y; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.storage) + BWDrawRectangle(w, + at_x, at_y, + at_x + BW->bitmap.storage->width - 1, + at_y + BW->bitmap.storage->height - 1, + Highlight); +} + +void DrawImageData(BW, image, at_x, at_y, value) + BitmapWidget BW; + XImage *image; + Position at_x, at_y; + int value; +{ + Position x, y; + Boolean C, S, I, H; + bit A, B; + + C = value == Clear; + S = value == Set; + I = value == Invert; + H = value == Highlight; + + for (x = 0; x < image->width; x++) + for (y = 0; y < image->height; y++) { + A = GetBit(image, x, y); + B = GetBit(BW->bitmap.image, at_x + x, at_y + y); + if (A & C | (A | B) & S | (A ^ B) & I | (A | B) & H) + value = (A & H) ? Highlight : Set; + else + value = Clear; + BWDrawPoint((Widget) BW, + at_x + x, at_y + y, + value); + } +} + +void BWRestore(w, at_x, at_y, value) + Widget w; + Position at_x, at_y; + int value; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.storage) { + DrawImageData(BW, BW->bitmap.storage, at_x, at_y, value); + /*DestroyBitmapImage(&BW->bitmap.storage);*/ + } +} + +void BWCopy(w, at_x, at_y, value) + Widget w; + Position at_x, at_y; + int value; +{ + BitmapWidget BW = (BitmapWidget) w; + XImage *storage; + char *storage_data; + Dimension width, height; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + + storage_data = CreateCleanData(Length(width, height)); + + storage = CreateBitmapImage(BW, storage_data, width, height); + + CopyImageData(BW->bitmap.image, storage, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + 0, 0); + + DrawImageData(BW, storage, at_x, at_y, value); + + DestroyBitmapImage(&storage); + } +} + +void BWMark(); + +void BWMove(w, at_x, at_y, value) + Widget w; + Position at_x, at_y; + int value; +{ + BitmapWidget BW = (BitmapWidget) w; + XImage *storage; + char *storage_data; + Dimension width, height; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + + storage_data = CreateCleanData(Length(width, height)); + + storage = CreateBitmapImage(BW, storage_data, width, height); + + CopyImageData(BW->bitmap.image, storage, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + 0, 0); + + BWDrawFilledRectangle(w, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + Clear); + + DrawImageData(BW, storage, at_x, at_y, value); + + BWMark(w, at_x, at_y, + at_x + BW->bitmap.mark.to_x - BW->bitmap.mark.from_x, + at_y + BW->bitmap.mark.to_y - BW->bitmap.mark.from_y); + + DestroyBitmapImage(&storage); + } +} + +void BWRedrawMark(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) + XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.from_y), + InWindowX(BW, BW->bitmap.mark.to_x + 1) - + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.to_y + 1) - + InWindowY(BW, BW->bitmap.mark.from_y)); +} + +void BWStoreToBuffer(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + memmove( BW->bitmap.buffer->data, BW->bitmap.image->data, + Length(BW->bitmap.image->width, BW->bitmap.image->height)); + + BW->bitmap.buffer_hot = BW->bitmap.hot; + BW->bitmap.buffer_mark = BW->bitmap.mark; +} + +void BWUnmark(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.buffer_mark = BW->bitmap.mark; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.from_y), + InWindowX(BW, BW->bitmap.mark.to_x + 1) - + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.to_y + 1) - + InWindowY(BW, BW->bitmap.mark.from_y)); + + BW->bitmap.mark.from_x = BW->bitmap.mark.from_y = NotSet; + BW->bitmap.mark.to_x = BW->bitmap.mark.to_y = NotSet; + } +} + +void BWMark(w, from_x, from_y, to_x, to_y) + Widget w; + Position from_x, from_y, + to_x, to_y; +{ + BitmapWidget BW = (BitmapWidget) w; + + BWUnmark(w); + + if (QuerySet(from_x, from_y)) { + if ((from_x == to_x) && (from_y == to_y)) { + /* + BW->bitmap.mark.from_x = 0; + BW->bitmap.mark.from_y = 0; + BW->bitmap.mark.to_x = BW->bitmap.image->width - 1; + BW->bitmap.mark.to_y = BW->bitmap.image->height - 1; + */ + return; + } + else { + 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.image->width - 1, to_x); + to_y = min(BW->bitmap.image->height - 1, to_y); + + BW->bitmap.mark.from_x = from_x; + BW->bitmap.mark.from_y = from_y; + BW->bitmap.mark.to_x = to_x; + BW->bitmap.mark.to_y = to_y; + } + + XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.from_y), + InWindowX(BW, BW->bitmap.mark.to_x + 1) - + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.to_y +1) - + InWindowY(BW, BW->bitmap.mark.from_y)); + } +} + +void BWMarkAll(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + BWMark(w, 0, 0, BW->bitmap.image->width - 1, BW->bitmap.image->height - 1); +} + +void BWUndo(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y; + char *tmp_data; + XPoint tmp_hot; + BWArea tmp_mark; + + tmp_data = BW->bitmap.image->data; + BW->bitmap.image->data = BW->bitmap.buffer->data; + BW->bitmap.buffer->data = tmp_data; + + tmp_hot = BW->bitmap.hot; + tmp_mark = BW->bitmap.mark; + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) + if (GetBit(BW->bitmap.image, x, y) != GetBit(BW->bitmap.buffer, x, y)) + DrawSquare(BW, x, y); + + BWSetHotSpot(w, BW->bitmap.buffer_hot.x, BW->bitmap.buffer_hot.y); +/* + BWMark(w, BW->bitmap.buffer_mark.from_x, BW->bitmap.buffer_mark.from_y, + BW->bitmap.buffer_mark.to_x, BW->bitmap.buffer_mark.to_y); +*/ + BW->bitmap.buffer_hot = tmp_hot; + BW->bitmap.buffer_mark= tmp_mark; + +} + +void BWHighlightAxes(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, 0), + InWindowY(BW, 0), + InWindowX(BW, BW->bitmap.width), + InWindowY(BW, BW->bitmap.height)); + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, BW->bitmap.width), + InWindowY(BW, 0), + InWindowX(BW, 0), + InWindowY(BW, BW->bitmap.height)); + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, 0), + InWindowY(BW, (float)BW->bitmap.height / 2.0), + InWindowX(BW, BW->bitmap.width), + InWindowY(BW, (float)BW->bitmap.height / 2.0)); + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, (float)BW->bitmap.width / 2.0), + InWindowY(BW, 0), + InWindowX(BW, (float)BW->bitmap.width / 2.0), + InWindowY(BW, BW->bitmap.height)); +} + +typedef struct { + Position *x, *y; + Dimension *width, *height; +} Table; + +XImage *ScaleBitmapImage(BW, src, scale_x, scale_y) + BitmapWidget BW; + XImage *src; + double scale_x, scale_y; +{ + char *data; + XImage *dst; + Table table; + Position x, y, w, h; + Dimension width, height; + bit pixel; + + width = max(rint(scale_x * src->width), 1); + height = max(rint(scale_y * src->height), 1); + + data = CreateCleanData(Length(width, height)); + dst = CreateBitmapImage(BW, data, width, height); + + /* + * It would be nice to check if width or height < 1.0 and + * average the skipped pixels. But, it is slow as it is now. + */ + if (scale_x == 1.0 && scale_y == 1.0) + memmove( dst->data, src->data, Length(width, height)); + else { + table.x = (Position *) XtMalloc(sizeof(Position) * src->width); + table.y = (Position *) XtMalloc(sizeof(Position) * src->height); + table.width = (Dimension *) XtMalloc(sizeof(Dimension) * src->width); + table.height = (Dimension *) XtMalloc(sizeof(Dimension) * src->height); + + for (x = 0; x < src->width; x++) { + table.x[x] = rint(scale_x * x); + table.width[x] = rint(scale_x * (x + 1)) - rint(scale_x * x); + } + for (y = 0; y < src->height; y++) { + table.y[y] = rint(scale_y * y); + table.height[y] = rint(scale_y * (y + 1)) - rint(scale_y * y); + } + + for (x = 0; x < src->width; x++) + for (y = 0; y < src->height; y++) { + pixel = GetBit(src, x, y); + for (w = 0; (int)w < (int)table.width[x]; w++) + for (h = 0; (int)h < (int)table.height[y]; h++) + if (pixel) SetBit(dst, + table.x[x] + w, + table.y[y] + h); + } + + XtFree((char *)table.x); + XtFree((char *)table.y); + XtFree((char *)table.width); + XtFree((char *)table.height); + } + + return (dst); +} + +/*****************************************************************************/ diff --git a/Handlers.c b/Handlers.c new file mode 100644 index 0000000..52f7f63 --- /dev/null +++ b/Handlers.c @@ -0,0 +1,677 @@ +/* $Xorg: Handlers.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 "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)) + +#include "Requests.h" + +extern Boolean DEBUG; + +/***************************************************************************** + * Handlers * + *****************************************************************************/ + +#define QueryInSquare(BW, x, y, square_x, square_y)\ + ((InBitmapX(BW, x) == (square_x)) &&\ + (InBitmapY(BW, y) == (square_y))) + + +void DragOnePointHandler(w, client_data, event, cont) /* ARGSUSED */ + Widget w; + XtPointer client_data; + XEvent *event; + Boolean *cont; +{ + BWStatus *status = (BWStatus *)client_data; + BitmapWidget BW = (BitmapWidget) w; + + if (DEBUG) + fprintf(stderr, "D1PH "); + + switch (event->type) { + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->at_x, status->at_y)) { + BWStoreToBuffer(w); + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + status->success = status->draw ? True : False; + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, status->value); + } + break; + + case ButtonRelease: + if (QuerySet(status->at_x, status->at_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + status->success = status->draw ? True : False; + /* SUPPRESS 701 */ + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->at_x, status->at_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->at_x, status->at_y)) { + status->at_x = InBitmapX(BW, event->xmotion.x); + status->at_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, status->value); + } + } + break; + + } +} + +void DragOnePointEngage(w, status, draw, state) + Widget w; + BWStatus *status; + void (*draw)(); + int *state; +{ + + status->at_x = NotSet; + status->at_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragOnePointHandler, (XtPointer)status); +} + +/* ARGSUSED */ +void DragOnePointTerminate(w, status, client_data) + Widget w; + BWStatus *status; + XtPointer client_data; +{ + + if (status->success) { + BWChangeNotify(w, NULL, NULL); + BWSetChanged(w); + } + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragOnePointHandler, (XtPointer)status); + +} + +void OnePointHandler(w, client_data, event, cont) /* ARGSUSED */ + Widget w; + XtPointer client_data; + XEvent *event; + Boolean *cont; +{ + BWStatus *status = (BWStatus *)client_data; + BitmapWidget BW = (BitmapWidget) w; + + if (DEBUG) + fprintf(stderr, "1PH "); + + switch (event->type) { + + case Expose: + if (QuerySet(status->at_x, status->at_y)) { + BWClip(w, event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + + BWUnclip(w); + } + break; + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->at_x, status->at_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + } + break; + + case ButtonRelease: + if (QuerySet(status->at_x, status->at_y)) { + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + status->success = True; + + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->at_x, status->at_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->at_x, status->at_y)) { + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + status->at_x = InBitmapX(BW, event->xmotion.x); + status->at_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + } + } + break; + } +} + +void OnePointEngage(w, status, draw, state) + Widget w; + BWStatus *status; + void (*draw)(); + int *state; +{ + status->at_x = NotSet; + status->at_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); +} + +void OnePointImmediateEngage(w, status, draw, state) + Widget w; + BWStatus *status; + void (*draw)(); + int *state; +{ + status->at_x = 0; + status->at_y = 0; + status->draw = draw; + status->success = False; + status->state = *state; + + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); +} + +void OnePointTerminate(w, status, draw) + Widget w; + BWStatus *status; + void (*draw)(); +{ + + if (status->success && draw) { + BWStoreToBuffer(w); + (*draw)(w, + status->at_x, status->at_y, + status->value); + BWChangeNotify(w, NULL, NULL); + BWSetChanged(w); + } + else + if (QuerySet(status->at_x, status->at_y)) + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); +} + +void OnePointTerminateTransparent(w, status, draw) + Widget w; + BWStatus *status; + void (*draw)(); +{ + + if (status->success && draw) + (*draw)(w, + status->at_x, status->at_y, + status->value); + else + if (QuerySet(status->at_x, status->at_y)) + if (status->draw) + (*status->draw)(w, + status->at_x, status->at_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); + +} + + +void TwoPointsHandler(w, client_data, event, cont) /* ARGSUSED */ + Widget w; + XtPointer client_data; + XEvent *event; + Boolean *cont; +{ + BitmapWidget BW = (BitmapWidget) w; + BWStatus *status = (BWStatus *)client_data; + if (DEBUG) + fprintf(stderr, "2PH "); + + switch (event->type) { + + case Expose: + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) { + BWClip(w, event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + BWUnclip(w); + } + break; + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->from_x, status->from_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->from_x = InBitmapX(BW, event->xbutton.x); + status->from_y = InBitmapY(BW, event->xbutton.y); + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + } + break; + + case ButtonRelease: + if (QuerySet(status->from_x, status->from_y)) { + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + status->success = True; + + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->from_x, status->from_y)) { + if (QuerySet(status->to_x, status->to_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->to_x, status->to_y)) { + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + status->to_x = InBitmapX(BW, event->xmotion.x); + status->to_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + } + } + else { + status->to_x = InBitmapX(BW, event->xmotion.x); + status->to_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + } + } + break; + } +} + +void TwoPointsEngage(w, status, draw, state) + Widget w; + BWStatus *status; + void (*draw)(); + int *state; +{ + + status->from_x = NotSet; + status->from_y = NotSet; + status->to_x = NotSet; + status->to_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +void TwoPointsTerminate(w, status, draw) + Widget w; + BWStatus *status; + void (*draw)(); +{ + + if (status->success && draw) { + BWStoreToBuffer(w); + (*draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->value); + BWChangeNotify(w, NULL, NULL); + BWSetChanged(w); + } + else + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +void TwoPointsTerminateTransparent(w, status, draw) + Widget w; + BWStatus *status; + void (*draw)(); +{ + + if (status->success && draw) + (*draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->value); + else + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +void TwoPointsTerminateTimed(w, status, draw) + Widget w; + BWStatus *status; + void (*draw)(); +{ + + if (status->success && draw) + (*draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->btime); + else + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +/* ARGSUSED */ +void Interface(w, status, action) + Widget w; + XtPointer status; + void (*action)(); +{ + (*action)(w); +} + +void Paste(w, at_x, at_y, value) + Widget w; + Position at_x, at_y; + int value; +{ + BitmapWidget BW = (BitmapWidget) w; + BWStatus *my_status; + BWRequest request; + + my_status = (BWStatus *) + BW->bitmap.request_stack[BW->bitmap.current].status; + + my_status->draw = NULL; + + request = (BWRequest) + BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data; + + BWTerminateRequest(w, FALSE); + + if ((at_x == max(BW->bitmap.mark.from_x, min(at_x, BW->bitmap.mark.to_x))) + && + (at_y == max(BW->bitmap.mark.from_y, min(at_y, BW->bitmap.mark.to_y)))) { + + BWStatus *status; + + if (DEBUG) + fprintf(stderr, "Prepaste request: %s\n", request); + + BWEngageRequest(w, request, False, (char *)&(my_status->state), sizeof(int)); + + status = (BWStatus *) + BW->bitmap.request_stack[BW->bitmap.current].status; + + status->at_x = at_x; + status->at_y = at_y; + status->value = value; + (*status->draw) (w, at_x, at_y, Highlight); + } + else { + + BWStatus *status; + + BWEngageRequest(w, MarkRequest, False, (char *)&(my_status->state), sizeof(int)); + + status = (BWStatus *) + BW->bitmap.request_stack[BW->bitmap.current].status; + + status->from_x = status->to_x = at_x; + status->from_y = status->to_y = at_y; + status->value = value; + (*status->draw) (w, at_x, at_y, at_x, at_y, Highlight); + } +} + + +void DragTwoPointsHandler(w, client_data, event, cont) /* ARGSUSED */ + Widget w; + XtPointer client_data; + XEvent *event; + Boolean *cont; +{ + BitmapWidget BW = (BitmapWidget) w; + BWStatus *status = (BWStatus *)client_data; + + if (DEBUG) + fprintf(stderr, "D2PH "); + + switch (event->type) { + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->from_x, status->from_y)) { + BWStoreToBuffer(w); + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->from_x = InBitmapX(BW, event->xbutton.x); + status->from_y = InBitmapY(BW, event->xbutton.y); + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + status->success = status->draw ? True : False; + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, status->value); + } + break; + + case ButtonRelease: + if (QuerySet(status->from_x, status->from_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->from_x = status->to_x; + status->from_y = status->to_y; + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + status->success = True; + + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->from_x, status->from_y)) { + if (QuerySet(status->to_x, status->to_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->to_x, status->to_y)) { + status->from_x = status->to_x; + status->from_y = status->to_y; + status->to_x = InBitmapX(BW, event->xmotion.x); + status->to_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, status->value); + } + } + } + break; + } +} + +void DragTwoPointsEngage(w, status, draw, state) + Widget w; + BWStatus *status; + void (*draw)(); + int *state; +{ + + status->from_x = NotSet; + status->from_y = NotSet; + status->to_x = NotSet; + status->to_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragTwoPointsHandler, (XtPointer)status); +} + +void DragTwoPointsTerminate(w, status, draw) + Widget w; + BWStatus *status; + void (*draw)(); +{ + + if (status->success && draw) { + if ((status->from_x != status->to_x) + || + (status->from_y != status->to_y)) + (*draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->value); + BWChangeNotify(w, NULL, NULL); + BWSetChanged(w); + } + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragTwoPointsHandler, (XtPointer)status); +} + +/*****************************************************************************/ @@ -0,0 +1,13 @@ +#define Left_width 30 +#define Left_height 30 +static char Left_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x1d, 0x00, 0x00, + 0xe0, 0x0e, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0xb8, 0xff, 0xff, 0x1f, + 0x5c, 0xff, 0xff, 0x0f, 0xae, 0xaa, 0xaa, 0x06, 0x57, 0x55, 0x55, 0x03, + 0xae, 0xaa, 0xaa, 0x06, 0x5c, 0xff, 0xff, 0x0f, 0xb8, 0xff, 0xff, 0x1f, + 0x70, 0x07, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0xc0, 0x1d, 0x00, 0x00, + 0x80, 0x3b, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/ReqMach.c b/ReqMach.c new file mode 100644 index 0000000..a048084 --- /dev/null +++ b/ReqMach.c @@ -0,0 +1,279 @@ +/* $Xorg: ReqMach.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/Xfuncs.h> +#include <X11/Xos.h> +#include "BitmapP.h" + +#include <stdio.h> +#include <math.h> + +#ifndef abs +#define abs(x) (((x) > 0) ? (x) : -(x)) +#endif +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#define max(x, y) (((x) > (y)) ? (x) : (y)) + + +extern Boolean DEBUG; + +/*****************************************************************************\ + * Request Machine: stacks up and handles requests from application calls. * +\*****************************************************************************/ + +/* + * Searches for a request record of a request specified by its name. + * Returns a pointer to the record or NULL if the request was not found. + */ +BWRequestRec *FindRequest(name) + BWRequest name; +{ + int i; + + for (i = 0; i < bitmapClassRec.bitmap_class.num_requests; i++) + if (!strcmp(name, bitmapClassRec.bitmap_class.requests[i].name)) + return &bitmapClassRec.bitmap_class.requests[i]; + + return NULL; +} + +/* + * Adds a request to the request stack and does proper initializations. + * Returns TRUE if the request was found and FALSE otherwise. + */ +Boolean BWAddRequest(w, name, trap, call_data, call_data_size) + Widget w; + BWRequest name; + Boolean trap; + XtPointer call_data; + Cardinal call_data_size; +{ + BitmapWidget BW = (BitmapWidget) w; + BWRequestRec *request; + + request = FindRequest(name); + if(request) { + if (DEBUG) + fprintf(stderr, "Adding... Cardinal: %d\n", BW->bitmap.cardinal + 1); + + BW->bitmap.request_stack = (BWRequestStack *) + XtRealloc((char *)BW->bitmap.request_stack, + (++BW->bitmap.cardinal + 1) * sizeof(BWRequestStack)); + + BW->bitmap.request_stack[BW->bitmap.cardinal].request = request; + BW->bitmap.request_stack[BW->bitmap.cardinal].status = + XtMalloc(request->status_size); + BW->bitmap.request_stack[BW->bitmap.cardinal].trap = trap; + BW->bitmap.request_stack[BW->bitmap.cardinal].call_data = + XtMalloc(call_data_size); + memmove( BW->bitmap.request_stack[BW->bitmap.cardinal].call_data, + call_data, + call_data_size); + + return True; + } + else { + XtWarning("bad request name. BitmapWidget"); + return False; + } +} + +/* + * Engages the request designated by the current parameter. + * Returnes TRUE if the request has an engage function and FALSE otherwise. + */ +Boolean Engage(BW, current) + BitmapWidget BW; + Cardinal current; +{ + BW->bitmap.current = current; + + if (DEBUG) + fprintf(stderr, "Request: %s\n", + BW->bitmap.request_stack[current].request->name); + + if (BW->bitmap.request_stack[current].request->engage) { + (*BW->bitmap.request_stack[current].request->engage) + ((Widget) BW, + BW->bitmap.request_stack[current].status, + BW->bitmap.request_stack[current].request->engage_client_data, + BW->bitmap.request_stack[current].call_data); + return True; + } + else + return False; +} + +Boolean BWTerminateRequest(); +Boolean BWRemoveRequest(); + +/* + * Scans down the request stack removing all requests untill it finds + * one to be trapped. + */ +void TrappingLoop(BW) + BitmapWidget BW; +{ + + if (DEBUG) + fprintf(stderr, "Scanning... Current: %d\n", BW->bitmap.current); + if ((BW->bitmap.current > 0) + && + (!BW->bitmap.request_stack[BW->bitmap.current--].trap)) { + BWRemoveRequest((Widget) BW); + TrappingLoop(BW); + } + else + if (BW->bitmap.cardinal > 0) { + if (DEBUG) + fprintf(stderr, "Trapping... Current: %d\n", BW->bitmap.current+1); + if(!Engage(BW, ++BW->bitmap.current)) + BWTerminateRequest((Widget) BW, True); + } +} +/* + * Terimantes the current request and continues with next request if con = TRUE + * Returnes TRUE if there is any number of requests left on the stack. + */ +Boolean BWTerminateRequest(w, cont) + Widget w; + Boolean cont; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.current > 0) { + if (DEBUG) + fprintf(stderr, "Terminating... Current: %d\n", BW->bitmap.current); + if (BW->bitmap.request_stack[BW->bitmap.current].request->terminate) + (*BW->bitmap.request_stack[BW->bitmap.current].request->terminate) + (w, + BW->bitmap.request_stack[BW->bitmap.current].status, + BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data, + BW->bitmap.request_stack[BW->bitmap.current].call_data); + + if (cont) { + if (BW->bitmap.current == BW->bitmap.cardinal) + TrappingLoop(BW); + else { + if (DEBUG) + fprintf(stderr, "Continuing... Current: %d\n", BW->bitmap.current+1); + if (!Engage(BW, ++BW->bitmap.current)) + BWTerminateRequest(w, True); + } + } + else + BW->bitmap.current = 0; + } + + return BW->bitmap.current; +} + +/* + * Simple interface to BWTerminateRequest that takes only a widget. + */ +void BWAbort(w) + Widget w; +{ + BWTerminateRequest(w, True); +} + +/* + * Removes the top request from the request stack. If the request is active + * it will terminate it. + * Returns TRUE if the number of requests left on the stack != 0. + */ +Boolean BWRemoveRequest(w) + Widget w; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.cardinal > 0) { + if (DEBUG) + fprintf(stderr, "Removing... Cardinal: %d\n", BW->bitmap.cardinal); + if (BW->bitmap.current == BW->bitmap.cardinal) + BWTerminateRequest(w, False); + + if (BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove) + (*BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove) + (w, + BW->bitmap.request_stack[BW->bitmap.cardinal].status, + BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove_client_data, + BW->bitmap.request_stack[BW->bitmap.cardinal].call_data); + + XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].status); + XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].call_data); + BW->bitmap.request_stack = (BWRequestStack *) + XtRealloc((char *)BW->bitmap.request_stack, + (--BW->bitmap.cardinal + 1) * sizeof(BWRequestStack)); + + return True; + } + else + return False; +} + +void BWRemoveAllRequests(w) + Widget w; +{ /* SUPPRESS 530 */ + while (BWRemoveRequest(w)) {/* removes all requests from the stack */} +} + +/* + * Adds the request to the stack and performs engaging ritual. + * Returns TRUE if the request was found, FALSE otherwise. + */ +Boolean BWEngageRequest(w, name, trap, call_data, call_data_size) + Widget w; + BWRequest name; + Boolean trap; + XtPointer call_data; + Cardinal call_data_size; +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BWAddRequest(w, name, trap, call_data, call_data_size)) { + BWTerminateRequest(w, False); + if (DEBUG) + fprintf(stderr, "Engaging... Cardinal: %d\n", BW->bitmap.cardinal); + if (!Engage(BW, BW->bitmap.cardinal)) + BWTerminateRequest(w, True); + + return True; + } + else + return False; +} + +/************************* End of the Request Machine ************************/ diff --git a/Requests.h b/Requests.h new file mode 100644 index 0000000..ea20d29 --- /dev/null +++ b/Requests.h @@ -0,0 +1,146 @@ +/* $Xorg: Requests.h,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 + */ + +typedef struct { + Boolean success; + Position at_x, at_y; + Position from_x, from_y, + to_x, to_y; + void (*draw)(); + int value; + Time btime; + int state; +} BWStatus; + +void OnePointEngage(); +void OnePointTerminate(); +void OnePointTerminateTransparent(); +void DragOnePointEngage(); +void DragOnePointTerminate(); +void TwoPointsEngage(); +void TwoPointsTerminate(); +void TwoPointsTerminateTransparent(); +void TwoPointsTerminateTimed(); +void DragTwoPointsEngage(); +void DragTwoPointsTerminate(); +void Interface(); +void Paste(); + +void BWMark(); +void BWUnmark(); +void BWStore(); +void BWDragMarked(); +void BWDragStored(); +void BWRestore(); +void BWCopy(); +void BWMove(); +void BWDrawPoint(); +void BWDrawLine(); +void BWBlindLine(); +void BWDrawRectangle(); +void BWDrawFilledRectangle(); +void BWDrawCircle(); +void BWDrawFilledCircle(); +void BWFloodFill(); +void BWDrawHotSpot(); +void BWChangeNotify(); +void BWZoomIn(); + +static BWRequestRec requests[] = /* SUPPRESS 592 */ +{ +{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}, +}; + @@ -0,0 +1,13 @@ +#define Right_width 30 +#define Right_height 30 +static char Right_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, + 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x1d, 0x00, 0x00, 0x80, 0x3b, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xdc, 0x01, + 0xff, 0xff, 0xbf, 0x03, 0xfe, 0xff, 0x5f, 0x07, 0xac, 0xaa, 0xaa, 0x0e, + 0x58, 0x55, 0x55, 0x1d, 0xac, 0xaa, 0xaa, 0x0e, 0xfe, 0xff, 0x5f, 0x07, + 0xff, 0xff, 0xbf, 0x03, 0x00, 0x00, 0xdc, 0x01, 0x00, 0x00, 0xee, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x80, 0x1d, 0x00, + 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/RotateLeft b/RotateLeft new file mode 100644 index 0000000..c4d4b14 --- /dev/null +++ b/RotateLeft @@ -0,0 +1,13 @@ +#define RotateLeft_width 30 +#define RotateLeft_height 30 +static char RotateLeft_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, + 0x00, 0x6e, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, + 0xc0, 0x1d, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0x70, 0xff, 0x0f, 0x00, + 0xb8, 0xfe, 0x1f, 0x00, 0x5c, 0x55, 0x35, 0x00, 0xae, 0xaa, 0x6a, 0x00, + 0x5c, 0x55, 0xd5, 0x00, 0xb8, 0xfe, 0xff, 0x01, 0x70, 0xff, 0xff, 0x03, + 0xe0, 0x0e, 0x58, 0x03, 0xc0, 0x1d, 0xb8, 0x03, 0x80, 0x3b, 0x58, 0x03, + 0x00, 0x77, 0xb8, 0x03, 0x00, 0x6e, 0x58, 0x03, 0x00, 0x7c, 0xb8, 0x03, + 0x00, 0x78, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, + 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x18, 0x03, + 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/RotateRight b/RotateRight new file mode 100644 index 0000000..d54f3c7 --- /dev/null +++ b/RotateRight @@ -0,0 +1,13 @@ +#define RotateRight_width 30 +#define RotateRight_height 30 +static char RotateRight_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, + 0x00, 0x80, 0x1d, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x00, 0x77, 0x00, + 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xdc, 0x01, 0x00, 0xfc, 0xbf, 0x03, + 0x00, 0xfe, 0x5f, 0x07, 0x00, 0xab, 0xaa, 0x0e, 0x80, 0x55, 0x55, 0x1d, + 0xc0, 0xaa, 0xaa, 0x0e, 0xe0, 0xff, 0x5f, 0x07, 0xf0, 0xff, 0xbf, 0x03, + 0xb0, 0x06, 0xdc, 0x01, 0x70, 0x07, 0xee, 0x00, 0xb0, 0x06, 0x77, 0x00, + 0x70, 0x87, 0x3b, 0x00, 0xb0, 0x86, 0x1d, 0x00, 0x70, 0x87, 0x0f, 0x00, + 0xb0, 0x86, 0x07, 0x00, 0x70, 0x07, 0x00, 0x00, 0xb0, 0x06, 0x00, 0x00, + 0xf0, 0x07, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -0,0 +1,4 @@ +#define Stipple_width 2 +#define Stipple_height 2 +static char Stipple_bits[] = { + 0x01, 0x00}; @@ -0,0 +1,14 @@ +#define Term_width 32 +#define Term_height 32 +static char Term_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x04, 0x00, 0x00, 0x20, + 0xe4, 0xff, 0xff, 0x27, 0x14, 0x00, 0x00, 0x28, 0x14, 0x80, 0x01, 0x28, + 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, + 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x00, 0x28, + 0x14, 0x80, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, + 0x14, 0x00, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, 0x14, 0x00, 0x00, 0x28, + 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xf8, 0xff, 0xff, 0x1f, + 0xfe, 0xff, 0xff, 0x7f, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, + 0x02, 0x00, 0xc0, 0x5f, 0x02, 0x00, 0x00, 0x40, 0xfa, 0xff, 0xff, 0x5f, + 0xae, 0xaa, 0xaa, 0x6a, 0x56, 0x55, 0x55, 0x55, 0xab, 0xaa, 0xaa, 0xea, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}; @@ -0,0 +1,13 @@ +#define Up_width 30 +#define Up_height 30 +static char Up_bits[] = { + 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x5c, 0x07, 0x00, 0x00, 0xae, 0x0e, 0x00, + 0x00, 0x57, 0x1d, 0x00, 0x80, 0xab, 0x3a, 0x00, 0xc0, 0x5d, 0x77, 0x00, + 0xe0, 0xbe, 0xef, 0x00, 0x70, 0x5f, 0xdf, 0x01, 0xb0, 0xbb, 0xbb, 0x01, + 0xf0, 0x59, 0xf3, 0x01, 0xf0, 0xb8, 0xe3, 0x01, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x18, 0x03, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -0,0 +1,293 @@ +/* $Xorg: atobm.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1988, 1993, 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. + +*/ + +/* + * atobm - ascii to bitmap filter + * Author: Jim Fulton, MIT X Consortium + */ + +#include <stdio.h> +#include <ctype.h> +#include <X11/Xos.h> + +extern char *malloc(), *calloc(); + +char *ProgramName; + +static void usage () +{ + fprintf (stderr, "usage: %s [-options ...] [filename]\n\n", + ProgramName); + fprintf (stderr, + "where options include:\n"); + fprintf (stderr, + " -chars cc chars to use for 0 and 1 bits, respectively\n"); + fprintf (stderr, + " -name variable name to use in bitmap file\n"); + fprintf (stderr, + " -xhot number x position of hotspot\n"); + fprintf (stderr, + " -yhot number y position of hotspot\n"); + fprintf (stderr, "\n"); + exit (1); +} + + +char *cify_name (name) + char *name; +{ + int length = name ? strlen (name) : 0; + int i; + + for (i = 0; i < length; i++) { /* strncpy (result, begin, length); */ + char c = name[i]; + if (!((isascii(c) && isalnum(c)) || c == '_')) name[i] = '_'; + } + return name; +} + +char *StripName(name) + char *name; +{ + char *begin = strrchr(name, '/'); + char *end, *result; + int length; + + begin = (begin ? begin+1 : name); + end = strchr(begin, '.'); /* change to strrchr to allow longer names */ + length = (end ? (end - begin) : strlen (begin)); + result = (char *) malloc (length + 1); + strncpy (result, begin, length); + result [length] = '\0'; + return (result); +} + +main (argc, argv) + int argc; + char **argv; +{ + int i; + int xhot = -1, yhot = -1; + char *filename = NULL; + char *chars = "-#"; + char *name = NULL; + FILE *fp; + + ProgramName = argv[0]; + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (arg[0] == '-') { + switch (arg[1]) { + case '\0': + filename = NULL; + continue; + case 'c': + if (++i >= argc) usage (); + chars = argv[i]; + continue; + case 'n': + if (++i >= argc) usage (); + name = argv[i]; + continue; + case 'x': + if (++i >= argc) usage (); + xhot = atoi (argv[i]); + continue; + case 'y': + if (++i >= argc) usage (); + yhot = atoi (argv[i]); + continue; + default: + usage (); + } + } else { + filename = arg; + } + } + + if (strlen (chars) != 2) { + fprintf (stderr, + "%s: bad character list \"%s\", must have exactly 2 characters\n", + ProgramName, chars); + exit (1); + } + + if (filename) { + fp = fopen (filename, "r"); + if (!fp) { + fprintf (stderr, "%s: unable to open file \"%s\".\n", + ProgramName, filename); + exit (1); + } + } else { + fp = stdin; + } + + if (!name) name = filename ? StripName (filename) : ""; + cify_name (name); + doit (fp, filename, chars, xhot, yhot, name); + + if (filename) (void) fclose (fp); + exit (0); +} + + +doit (fp, filename, chars, xhot, yhot, name) + FILE *fp; + char *filename; + char *chars; + int xhot, yhot; + char *name; +{ + int i, j; + int last_character; + char buf[BUFSIZ]; + char *cp, *newline; + int width = 0, height = 0; + int len; + int removespace = (((isascii(chars[0]) && isspace(chars[0])) || + (isascii(chars[1]) && isspace(chars[1]))) ? 0 : 1); + int lineno = 0; + int bytes_per_scanline = 0; + struct _scan_list { + int allocated; + int used; + unsigned char *scanlines; + struct _scan_list *next; + } *head = NULL, *slist; + static unsigned char masktable[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; + int padded = 0; + +#define NTOALLOC 16 +#define NewSList() \ + slist = (struct _scan_list *) calloc (1, sizeof *slist); \ + if (!slist) { \ + fprintf (stderr, "%s: unable to allocate scan list\n", \ + ProgramName); \ + return; \ + } \ + slist->allocated = NTOALLOC * bytes_per_scanline; \ + slist->scanlines = (unsigned char *) calloc(slist->allocated, 1); \ + if (!slist->scanlines) { \ + fprintf (stderr, "%s: unable to allocate char array\n", \ + ProgramName); \ + return; \ + } \ + slist->used = 0; \ + slist->next = NULL; + + while (1) { + buf[0] = '\0'; + lineno++; + if (fgets (buf, sizeof buf, fp) == NULL) break; + + cp = buf; + if (removespace) { + for (cp = buf; *cp && isascii(*cp) && isspace(*cp); cp++) ; + } + if (*cp == '\n' || !*cp) continue; /* empty line */ + + newline = strchr(cp, '\n'); + if (!newline) { + fprintf (stderr, "%s: line %d too long.\n", + ProgramName, lineno); + return; + } + + if (removespace) { + for (; --newline > cp && isascii(*newline) && isspace(*newline); ); + newline++; + } + + if (newline == cp + 1) continue; + + *newline = '\0'; + len = strlen (cp); + + if (width == 0) { + width = len; + padded = ((width & 7) != 0); + bytes_per_scanline = (len + 7) / 8; + NewSList (); + head = slist; + } else if (width != len) { + fprintf (stderr, + "%s: line %d is %d characters wide instead of %d\n", + ProgramName, lineno, len, width); + return; + } + + if (slist->used + 1 >= slist->allocated) { + struct _scan_list *old = slist; + NewSList (); + old->next = slist; + } + + /* okay, parse the line and stick values into the scanline array */ + for (i = 0; i < width; i++) { + int ind = (i & 7); + int on = 0; + + if (cp[i] == chars[1]) { + on = 1; + } else if (cp[i] != chars[0]) { + fprintf (stderr, "%s: bad character '%c' on line %d\n", + ProgramName, cp[i], lineno); + } + + if (on) slist->scanlines[slist->used] |= masktable[ind]; + if (ind == 7) slist->used++; + } + if (padded) slist->used++; + height++; + } + + printf ("#define %s_width %d\n", name, width); + printf ("#define %s_height %d\n", name, height); + if (xhot >= 0) printf ("#define %s_x_hot %d\n", name, xhot); + if (yhot >= 0) printf ("#define %s_y_hot %d\n", name, yhot); + printf ("\n"); + printf ("static unsigned char %s_bits[] = {\n", name); + + j = 0; + last_character = height * bytes_per_scanline - 1; + for (slist = head; slist; slist = slist->next) { + for (i = 0; i < slist->used; i++) { + printf (" 0x%02x", slist->scanlines[i]); + if (j != last_character) putchar (','); + if ((j % 12) == 11) putchar ('\n'); + j++; + } + } + printf (" };\n"); + return; +} diff --git a/bitmap.icon b/bitmap.icon new file mode 100644 index 0000000..53105c7 --- /dev/null +++ b/bitmap.icon @@ -0,0 +1,14 @@ +#define bitmap_width 32 +#define bitmap_height 32 +static char bitmap_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf8, 0xfd, 0xff, 0xff, 0xfb, + 0x85, 0x08, 0x23, 0xfa, 0x95, 0x28, 0x23, 0xfa, 0x95, 0x29, 0x67, 0xfa, + 0xb5, 0x69, 0x67, 0xfa, 0xb5, 0x69, 0x67, 0xfa, 0xb5, 0x69, 0x67, 0xfa, + 0x85, 0x09, 0x67, 0xfa, 0xfd, 0xff, 0xff, 0xfb, 0x85, 0x18, 0x21, 0xfa, + 0x95, 0x18, 0x25, 0xfa, 0x95, 0x39, 0x65, 0xfa, 0xb5, 0x39, 0x6d, 0xfa, + 0xb5, 0x39, 0x6d, 0xfa, 0xb5, 0x39, 0x6d, 0xfa, 0x85, 0x39, 0x61, 0xfa, + 0xfd, 0xff, 0xff, 0xfb, 0x45, 0x18, 0xf9, 0xfb, 0x45, 0x19, 0xe1, 0xfb, + 0x4d, 0x39, 0xd3, 0xfb, 0x4d, 0x3b, 0xab, 0xfb, 0x4d, 0x3b, 0x57, 0xfb, + 0x4d, 0x3b, 0xaf, 0xfa, 0x4d, 0x38, 0x5f, 0xfd, 0xfd, 0xff, 0xbf, 0xfa, + 0x01, 0x00, 0x40, 0xf5, 0xff, 0xff, 0xff, 0xea, 0xff, 0xff, 0xff, 0xe5, + 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff}; diff --git a/bitmap.man b/bitmap.man new file mode 100644 index 0000000..f2e90b6 --- /dev/null +++ b/bitmap.man @@ -0,0 +1,659 @@ +.\" $Xorg: bitmap.man,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ +.\" Copyright 1993, 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. +.TH BITMAP 1 "Release 6.4" "X Version 11" +.SH NAME +bitmap, bmtoa, atobm \- bitmap editor and converter utilities for the X Window System +.SH SYNOPSIS +.B bitmap +[ +.I \-options +\&.\|.\|. ] [ +.I filename +] [ +.I basename +] +.sp +.B bmtoa +[ +.B \-chars +\&.\|.\|. ] [ +.I filename +] +.sp +.B atobm +[ +.B \-chars +.I cc +] [ +.B \-name +.I variable +] [ +.B \-xhot +.I number +] [ +.B \-yhot +.I number +] [ +.I filename +] +.SH DESCRIPTION +The \fIbitmap\fP program is a rudimentary tool for creating or editing +rectangular images made up of 1's and 0's. Bitmaps are used in X for +defining clipping regions, cursor shapes, icon shapes, and tile and +stipple patterns. +.PP +The \fIbmtoa\fP and \fIatobm\fP filters convert \fIbitmap\fP files (FILE +FORMAT) to and from ASCII strings. They are most commonly used to +quickly print out bitmaps and to generate versions for including in text. +.SH COMMAND LINE OPTIONS +\fIBitmap\fP supports the standard X Toolkit command line arguments +(see \fIX\fP(1)). The following additional arguments are supported as well. +.TP 4 +.B \-size\fI WIDTHxHEIGHT\fP +Specifies size of the grid in squares. +.TP 4 +.B \-sw\fI dimension\fP +Specifies the width of squares in pixels. +.TP 4 +.B \-sh\fI dimension\fP +Specifies the height of squares in pixels. +.TP 4 +.B \-gt\fI dimension\fP +Grid tolerance. If the square dimensions fall below the specified +value, grid will be automatically turned off. +.TP 4 +.B \-grid, +grid +./&.B \-grid\fI on/off\fP +Turns on or off the grid lines. +.TP 4 +.B \-axes, +axes +./&./&.B \-axes\fI on/off\fP +Turns on or off the major axes. +.TP 4 +.B \-dashed, +dashed +./&.B \-dashed\fI on/off\fP +Turns on or off dashing for the frame and grid lines. +.TP 4 +.B \-stippled, +stippled +./&.B \-stippled\fI on/off\fP +Turns on or off stippling of highlighted squares. +.TP 4 +.B \-proportional, +proportional\fI +./&.B \-proportional\fI on/off\fP +Turns proportional mode on or off. If proportional mode is on, +square width is equal to square height. If proportional mode is +off,\fI bitmap\fP will use the smaller square dimension, if they +were initially different. +.TP 4 +.B \-dashes\fI filename\fP +Specifies the bitmap to be used as a stipple for dashing. +.TP 4 +.B \-stipple\fI filename\fP +Specifies the bitmap to be used as a stipple for highlighting. +.TP 4 +.B \-hl\fI color\fP +Specifies the color used for highlighting. +.TP 4 +.B \-fr\fI color\fP +Specifies the color used for the frame and grid lines. +.TP 4 +.B filename +Specifies the bitmap to be initially loaded into the program. +If the file does not exist,\fI bitmap\fP will assume it is a new file. +.TP 4 +.B basename +Specifies the basename to be used in the C code output file. +If it is different than the basename in the working file,\fI bitmap\fP +will change it when saving the file. +.PP +\fIBmtoa\fP accepts the following option: +.TP 4 +.B \-chars \fIcc\fP +This option specifies the pair of characters to use in the string version +of the bitmap. The first character is used for 0 bits and the second character +is used for 1 bits. The default is to use dashes (\-) for 0's and sharp signs +(#) for 1's. +.PP +\fIAtobm\fP accepts the following options: +.TP 4 +.B \-chars \fIcc\fP +This option specifies the pair of characters to use when converting string +bitmaps into arrays of numbers. The first character represents a 0 bit and +the second character represents a 1 bit. The default is to use dashes (\-) +for 0's and sharp signs (#) for 1's. +.TP 4 +.B \-name \fIvariable\fP +This option specifies the variable name to be used when writing out the +bitmap file. The default is to use the basename of the \fIfilename\fP command +line argument or leave it blank if the standard input is read. +.TP 4 +.B \-xhot \fInumber\fP +This option specifies the X coordinate of the hotspot. Only positive values +are allowed. By default, no hotspot information is included. +.TP 4 +.B \-yhot \fInumber\fP +This option specifies the Y coordinate of the hotspot. Only positive values +are allowed. By default, no hotspot information is included. +.SH USAGE +\fIBitmap\fP displays grid in which each square represents a single +bit in the picture being edited. Actual size of the bitmap image, as +it would appear normaly and inverted, can be obtained by pressing\fB +Meta-I\fP key. You are free to move the image popup out of the way to +continue editing. Pressing the left mouse button in the popup window +or\fB Meta-I\fP again will remove the real size bitmap image. +.PP +If the bitmap is to be used for defining a cursor, one of the squares +in the images may be designated as the hot spot. This determines +where the cursor is actually pointing. For cursors with sharp tips +(such as arrows or fingers), this is usually at the end of the tip; +for symmetric cursors (such as crosses or bullseyes), this is usually +at the center. +.PP +Bitmaps are stored as small C code fragments suitable for including in +applications. They provide an array of bits as well as symbolic +constants giving the width, height, and hot spot (if specified) that +may be used in creating cursors, icons, and tiles. +.SH EDITING +To edit a bitmap image simply click on one of the buttons with drawing +commands (\fBPoint, Curve, Line, Rectangle,\fP etc.) and move the +pointer into the bitmap grid window. Press one of the buttons on your +mouse and the appropriate action will take place. You can either set, +clear or invert the gird squares. Setting a grid square corresponds +to setting a bit in the bitmap image to 1. Clearing a grid square +corresponds to setting a bit in the bitmap image to 0. Inverting a +grid square corresponds to changing a bit in the bitmap image from 0 to +1 or 1 to 0, depending what its previous state was. The +default behavior of mouse buttons is as specified below. +.sp +.nf + MouseButton1 Set + MouseButton2 Invert + MouseButton3 Clear + MouseButton4 Clear + MouseButton5 Clear +.fi +.sp +This default behavior can be changed by setting the button function +resources. An example is provided below. +.sp +.nf + bitmap*button1Function: Set + bitmap*button2Function: Clear + bitmap*button3Function: Invert + etc. +.fi +.sp +The button function applies to all drawing commands, including copying, +moving and pasting, flood filling and setting the hot spot. +.SH DRAWING COMMANDS +Here is the list of drawing commands accessible through the +buttons at the left side of the application's window. Some commands +can be aborted by pressing A inside the bitmap window, allowing the +user to select different guiding points where applicable. +.TP 4 +.B Clear +This command clears all bits in the bitmap image. The grid squares +will be set to the background color. Pressing C inside the bitmap +window has the same effect. +.TP 4 +.B Set +This command sets all bits in the bitmap image. The grid squares +will be set to the foreground color. Pressing S inside the bitmap +window has the same effect. +.TP 4 +.B Invert +This command inverts all bits in the bitmap image. The grid squares +will be inverted appropriately. Pressing I inside the bitmap window +has the same effect. +.TP 4 +.B Mark +This command is used to mark an area of the grid by dragging out a +rectangular shape in the highlighting color. Once the area is marked, +it can be operated on by a number of commands (see \fBUp, Down, Left, +Right, Rotate, Flip, Cut,\fP etc.) Only one marked area can be present +at any time. If you attempt to mark another area, the old mark will +vanish. The same effect can be achieved by pressing\fB +Shift-MouseButton1\fP and dragging out a rectangle in the grid window. +Pressing\fB Shift-MouseButton2\fP will mark the entire grid area. +.TP 4 +.B Unmark +This command will cause the marked area to vanish. The same effect can +be achieved by pressing\fB Shift-MouseButton3\fP. +.TP 4 +.B Copy +This command is used to copy an area of the grid from one location to +another. If there is no marked grid area displayed,\fB Copy\fP +behaves just like\fB Mark\fP described above. Once there is a marked +grid area displayed in the highlighting color, this command has two +alternative behaviors. If you click a mouse button inside the marked +area, you will be able to drag the rectangle that represents the +marked area to the desired location. After you release the mouse +button, the area will be copied. If you click outside the marked +area,\fB Copy\fP will assume that you wish to mark a different region of +the bitmap image, thus it will behave like\fB Mark\fP again. +.TP 4 +.B Move +This command is used to move an area of the grid from one location to +another. Its behavior resembles the behavior of\fB Copy\fP command, +except that the marked area will be moved instead of copied. +.TP 4 +.B Flip Horizontally +This command will flip the bitmap image with respect to the horizontal axes. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing H inside the bitmap window has the +same effect. +.TP 4 +.B Up +This command moves the bitmap image one pixel up. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing UpArrow inside the bitmap window has the +same effect. +.TP 4 +.B Flip Vertically +This command will flip the bitmap image with respect to the vertical axes. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing V inside the bitmap window has the +same effect. +.TP 4 +.B Left +This command moves the bitmap image one pixel to the left. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing LeftArrow inside the bitmap window has +the same effect. +.TP 4 +.B Fold +This command will fold the bitmap image so that the opposite corners +become adjacent. This is useful when creating bitmap images for +tiling. Pressing F inside the bitmap window has the same effect. +.TP 4 +.B Right +This command moves the bitmap image one pixel to the right. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing RightArrow inside the bitmap window +has the same effect. +.TP 4 +.B Rotate Left +This command rotates the bitmap image 90 degrees to the left (counter +clockwise.) +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing L inside the bitmap window has the +same effect. +.TP 4 +.B Down +This command moves the bitmap image one pixel down. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing DownArrow inside the bitmap window +has the same effect. +.TP 4 +.B Rotate Right +This command rotates the bitmap image 90 degrees to the right (clockwise.) +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing R inside the bitmap window has the +same effect. +.TP 4 +.B Point +This command will change the grid squares underneath the mouse pointer if +a mouse button is being pressed down. If you drag the mouse button +continuously, the line may not be continuous, depending on the speed of your +system and frequency of mouse motion events. +.TP 4 +.B Curve +This command will change the grid squares underneath the mouse pointer if +a mouse button is being pressed down. If you drag the mouse button +continuously, it will make sure that the line is continuous. If your system +is slow or\fI bitmap\fP receives very few mouse motion events, it might +behave quite strangely. +.TP 4 +.B Line +This command will change the gird squares in a line between two squares. +Once you press a mouse button in the grid window,\fI bitmap\fP will +highlight the line from the square where the mouse button was initially +pressed to the square where the mouse pointer is located. By releasing the +mouse button you will cause the change to take effect, and the highlighted +line will disappear. +.TP 4 +.B Rectangle +This command will change the gird squares in a rectangle between two squares. +Once you press a mouse button in the grid window,\fI bitmap\fP will +highlight the rectangle from the square where the mouse button was initially +pressed to the square where the mouse pointer is located. By releasing the +mouse button you will cause the change to take effect, and the highlighted +rectangle will disappear. +.TP 4 +.B Filled Rectangle +This command is identical to\fB Rectangle\fP, except at the end the +rectangle will be filled rather than outlined. +.TP 4 +.B Circle +This command will change the gird squares in a circle between two squares. +Once you press a mouse button in the grid window,\fI bitmap\fP will +highlight the circle from the square where the mouse button was initially +pressed to the square where the mouse pointer is located. By releasing the +mouse button you will cause the change to take effect, and the highlighted +circle will disappear. +.TP 4 +.B Filled Circle +This command is identical to\fB Circle\fP, except at the end the +circle will be filled rather than outlined. +.TP 4 +.B Flood Fill +This command will flood fill the connected area underneath the mouse +pointer when you click on the desired square. Diagonally adjacent +squares are not considered to be connected. +.TP 4 +.B Set Hot Spot +This command designates one square in the grid as the hot spot if this +bitmap image is to be used for defining a cursor. Pressing a mouse button +in the desired square will cause a diamond shape to be displayed. +.TP 4 +.B Clear Hot Spot +This command removes any designated hot spot from the bitmap image. +.TP 4 +.B Undo +This command will undo the last executed command. It has depth one, +that is, pressing\fB Undo\fP after\fB Undo\fP will undo itself. +.SH FILE MENU +The File menu commands can be accessed by pressing the File button and +selecting the appropriate menu entry, or by pressing Ctrl key with +another key. These commands deal with files and global bitmap +parameters, such as size, basename, filename etc. +.TP 4 +.B New +This command will clear the editing area and prompt for the name of +the new file to be edited. It will not load in the new file. +.TP 4 +.B Load +This command is used to load a new bitmap file into the bitmap editor. +If the current image has not been saved, user will be asked whether to +save or ignore the changes. The editor can edit only one file at a +time. If you need interactive editing, run a number of editors and +use cut and paste mechanism as described below. +.TP 4 +.B Insert +This command is used to insert a bitmap file into the image +being currently edited. After being prompted for the filename, +click inside the grid window and drag the outlined rectangle to the +location where you want to insert the new file. +.TP 4 +.B Save +This command will save the bitmap image. It will not prompt for the +filename unless it is said to be <none>. If you leave the filename +undesignated or \-, the output will be piped to stdout. +.TP 4 +.B Save As +This command will save the bitmap image after prompting for a new +filename. It should be used if you want to change the filename. +.TP 4 +.B Resize +This command is used to resize the editing area to the new number of +pixels. The size should be entered in the WIDTHxHEIGHT format. The +information in the image being edited will not be lost unless the new +size is smaller that the current image size. The editor was not +designed to edit huge files. +.TP 4 +.B Rescale +This command is used to rescale the editing area to the new width and +height. The size should be entered in the WIDTHxHEIGHT format. It will +not do antialiasing and information will be lost if you rescale to the +smaller sizes. Feel free to add you own algorithms for better rescaling. +.TP 4 +.B Filename +This command is used to change the filename without changing the basename +nor saving the file. If you specify \- for a filename, the output will +be piped to stdout. +.TP 4 +.B Basename +This command is used to change the basename, if a different one from +the specified filename is desired. +.TP 4 +.B Quit +\This command will terminate the bitmap application. If the file was +not saved, user will be prompted and asked whether to save the image +or not. This command is preferred over killing the process. +.SH EDIT MENU +The Edit menu commands can be accessed by pressing the Edit button and +selecting the appropriate menu entry, or by pressing Meta key with +another key. These commands deal with editing facilities such as +grid, axes, zooming, cut and paste, etc. +.TP 4 +.B Image +This command will display the image being edited and its inverse in its +actual size in a separate window. The window can be moved away to continue +with editing. Pressing the left mouse button in the image window will +cause it to disappear from the screen. +.TP 4 +.B Grid +This command controls the grid in the editing area. If the grid spacing +is below the value specified by gridTolerance resource (8 by default), +the grid will be automatically turned off. It can be enforced by explicitly +activating this command. +.TP 4 +.B Dashed +This command controls the stipple for drawing the grid lines. The stipple +specified by dashes resource can be turned on or off by activating this +command. +.TP 4 +.B Axes +This command controls the highlighting of the main axes of the image +being edited. The actual lines are not part of the image. They are +provided to aid user when constructing symmetrical images, or whenever +having the main axes highlighted helps your editing. +.TP 4 +.B Stippled +This command controls the stippling of the highlighted areas of the +bitmap image. The stipple specified by stipple resource can be turned on +or off by activating this command. +.TP 4 +.B Proportional +This command controls the proportional mode. If the proportional mode +is on, width and height of all image squares are forced to be equal, +regardless of the proportions of the bitmap window. +.TP 4 +.B Zoom +This command controls the zoom mode. If there is a marked area of the +image already displayed, bitmap will automatically zoom into it. Otherwise, +user will have to highlight an area to be edited in the zoom mode and +bitmap will automatically switch into it. One can use all the editing +commands and other utilities in the zoom mode. When you zoom out, undo +command will undo the whole zoom session. +.TP 4 +.B Cut +This commands cuts the contents of the highlighted image area into the +internal cut and paste buffer. +.TP 4 +.B Copy +This command copies the contents of the highlighted image area into the +internal cut and paste buffer. +.TP 4 +.B Paste +This command will check if there are any other bitmap applications with +a highlighted image area, or if there is something in the internal cut +and paste buffer and copy it to the image. To place the copied image, +click in the editing window and drag the outlined image to the position +where you want to place i, and then release the button. +.SH CUT AND PASTE +Bitmap supports two cut and paste mechanisms; the internal cut and +paste and the global X selection cut and paste. The internal cut and +paste is used when executing copy and move drawing commands and also +cut and copy commands from the edit menu. The global X selection cut +and paste is used whenever there is a highlighted area of a bitmap +image displayed anywhere on the screen. To copy a part of image from +another bitmap editor simply highlight the desired area by using the +Mark command or pressing the shift key and dragging the area with the +left mouse button. When the selected area becomes highlighted, any +other applications (such as xterm, etc.) that use primary selection +will discard their selection values and unhighlight the appropriate +information. Now, use the Paste command for the Edit menu or control +mouse button to copy the selected part of image into another (or the +same) bitmap application. If you attempt to do this without a visible +highlighted image area, the bitmap will fall back to the internal cut +and paste buffer and paste whatever was there stored at the moment. +.SH WIDGETS +Below is the widget structure of the \fIbitmap\fP +application. Indentation indicates hierarchical structure. The +widget class name is given first, followed by the widget instance +name. All widgets except the bitmap widget are from the standard +Athena widget set. +.sp +.nf + Bitmap bitmap + TransientShell image + Box box + Label normalImage + Label invertedImage + TransientShell input + Dialog dialog + Command okay + Command cancel + TransientShell error + Dialog dialog + Command abort + Command retry + TransientShell qsave + Dialog dialog + Command yes + Command no + Command cancel + Paned parent + Form formy + MenuButton fileButton + SimpleMenu fileMenu + SmeBSB new + SmeBSB load + SmeBSB insert + SmeBSB save + SmeBSB saveAs + SmeBSB resize + SmeBSB rescale + SmeBSB filename + SmeBSB basename + SmeLine line + SmeBSB quit + MenuButton editButton + SimpleMenu editMenu + SmeBSB image + SmeBSB grid + SmeBSB dashed + SmeBSB axes + SmeBSB stippled + SmeBSB proportional + SmeBSB zoom + SmeLine line + SmeBSB cut + SmeBSB copy + SmeBSB paste + Label status + Pane pane + Bitmap bitmap + Form form + Command clear + Command set + Command invert + Toggle mark + Command unmark + Toggle copy + Toggle move + Command flipHoriz + Command up + Command flipVert + Command left + Command fold + Command right + Command rotateLeft + Command down + Command rotateRight + Toggle point + Toggle curve + Toggle line + Toggle rectangle + Toggle filledRectangle + Toggle circle + Toggle filledCircle + Toggle floodFill + Toggle setHotSpot + Command clearHotSpot + Command undo +.fi +.SH COLORS +If you would like bitmap to be viewable in color, include the following +in the #ifdef COLOR section of the file you read with xrdb: +.sp 1 +*customization: \-color +.sp 1 +.br +This will cause bitmap to pick up the colors in the app-defaults color +customization file: +.sp 1 + <XRoot>/lib/X11/app-defaults/Bitmap-color +.sp 1 +where <XRoot> refers to the root of the X11 install tree. +.fi +.SH BITMAP WIDGET +Bitmap widget is a stand-alone widget for editing raster images. It +is not designed to edit large images, although it may be used in that +purpose as well. It can be freely incorporated with other +applications and used as a standard editing tool. The following are +the resources provided by the bitmap widget. +.sp +.nf +Bitmap Widget + +Header file Bitmap.h +Class bitmapWidgetClass +Class Name Bitmap +Superclass Bitmap + + +All the Simple Widget resources plus .\|.\|. +.ta 1.6i 3.2i 4.8i + +Name Class Type Default Value + +foreground Foreground Pixel XtDefaultForeground +highlight Highlight Pixel XtDefaultForeground +framing Framing Pixel XtDefaultForeground +gridTolerance GridTolerance Dimension 8 +size Size String 32x32 +dashed Dashed Boolean True +grid Grid Boolean True +stippled Stippled Boolean True +proportional Proportional Boolean True +axes Axes Boolean False +squareWidth SquareWidth Dimension 16 +squareHeight SquareHeight Dimension 16 +margin Margin Dimension 16 +xHot XHot Position NotSet (\-1) +yHot YHot Position NotSet (\-1) +button1Function Button1Function DrawingFunction Set +button2Function Button2Function DrawingFunction Invert +button3Function Button3Function DrawingFunction Clear +button4Function Button4Function DrawingFunction Invert +button5Function Button5Function DrawingFunction Invert +filename Filename String None ("") +basename Basename String None ("") +.fi + +.SH AUTHOR +Davor Matic, MIT X Consortium @@ -0,0 +1,191 @@ +/* $Xorg: bmtoa.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1988, 1993, 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. + +*/ + +/* + * bmtoa - bitmap to ascii filter + * Author: Jim Fulton, MIT X Consortium + */ + +#include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xos.h> + +#include <X11/Xmu/Drawing.h> + +extern char *malloc(); +extern char *mktemp(); + +char *ProgramName; + + +static void usage () +{ + fprintf (stderr, "usage: %s [-options ...] [filename]\n\n", + ProgramName); + fprintf (stderr, + "where options include:\n"); + fprintf (stderr, + " -chars cc chars to use for 0 and 1 bits, respectively\n"); + fprintf (stderr, "\n"); + exit (1); +} + +static char *copy_stdin () +{ +#ifdef WIN32 + static char tmpfilename[] = "/temp/bmtoa.XXXXXX"; +#else + static char tmpfilename[] = "/tmp/bmtoa.XXXXXX"; +#endif + char buf[BUFSIZ]; + FILE *fp; + int nread, nwritten; + + if (mktemp (tmpfilename) == NULL) { + fprintf (stderr, + "%s: unable to genererate temporary file name for stdin.\n", + ProgramName); + exit (1); + } + fp = fopen (tmpfilename, "w"); + while (1) { + buf[0] = '\0'; + nread = fread (buf, 1, sizeof buf, stdin); + if (nread <= 0) break; + nwritten = fwrite (buf, 1, nread, fp); + if (nwritten != nread) { + fprintf (stderr, + "%s: error copying stdin to file (%d of %d chars)\n", + ProgramName, nwritten, nread); + (void) fclose (fp); + (void) unlink (tmpfilename); + exit (1); + } + } + (void) fclose (fp); + return tmpfilename; +} + +main (argc, argv) + int argc; + char **argv; +{ + char *filename = NULL; + int isstdin = 0; + char *chars = "-#"; + int i; + unsigned int width, height; + unsigned char *data; + int x_hot, y_hot; + int status; + + ProgramName = argv[0]; + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (arg[0] == '-') { + switch (arg[1]) { + case '\0': + filename = NULL; + continue; + case 'c': + if (++i >= argc) usage (); + chars = argv[i]; + continue; + default: + usage (); + } + } else { + filename = arg; + } + } + + if (strlen (chars) != 2) { + fprintf (stderr, + "%s: bad character list \"%s\", must have exactly 2 characters\n", + ProgramName, chars); + exit (1); + } + + if (!filename) { + filename = copy_stdin (); + isstdin = 1; + } + + status = XmuReadBitmapDataFromFile (filename, &width, &height, &data, + &x_hot, &y_hot); + if (isstdin) (void) unlink (filename); /* don't need it anymore */ + if (status != BitmapSuccess) { + fprintf (stderr, "%s: unable to read bitmap from file \"%s\"\n", + ProgramName, isstdin ? "(stdin)" : filename); + exit (1); + } + + print_scanline (width, height, data, chars); + exit (0); +} + +print_scanline (width, height, data, chars) + unsigned int width, height; + unsigned char *data; + char *chars; +{ + char *scanline = (char *) malloc (width + 1); + unsigned char *dp = data; + int row, column; + static unsigned char masktable[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; + int padded = ((width & 7) != 0); + + if (!scanline) { + fprintf (stderr, "%s: unable to allocate %d bytes for scanline\n", + ProgramName, width + 1); + exit (1); + } + + for (row = 0; row < height; row++) { + for (column = 0; column < width; column++) { + int i = (column & 7); + + if (*dp & masktable[i]) { + putchar (chars[1]); + } else { + putchar (chars[0]); + } + + if (i == 7) dp++; + } + putchar ('\n'); + if (padded) dp++; + } + return; +} + |