#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/Xmu/SysUtil.h>
#include <X11/Xatom.h>
#include <X11/Xfuncs.h>
#include <X11/Xos.h>
#include "BitmapP.h"
#include "Bitmap.h"
#include <stdio.h>
#include <math.h>
#define min(x, y) ((((int)(x)) < (int)(y)) ? (x) : (y))
#define max(x, y) ((((int)(x)) > (int)(y)) ? (x) : (y))
Boolean DEBUG;
#define DefaultGridTolerance 8
#define DefaultBitmapSize "16x16"
#define FallbackBitmapWidth 16
#define FallbackBitmapHeight 16
#define DefaultGrid TRUE
#define DefaultDashed TRUE
#define DefaultStippled TRUE
#define DefaultProportional TRUE
#define DefaultAxes FALSE
#define DefaultMargin 16
#define DefaultSquareWidth 16
#define DefaultSquareHeight 16
#define DefaultFilename ""
#define Offset(field) XtOffsetOf(BitmapRec, bitmap.field)
static XtResource resources[] = {
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
Offset(foreground_pixel), XtRString, XtDefaultForeground},
{XtNhighlight, XtCHighlight, XtRPixel, sizeof(Pixel),
Offset(highlight_pixel), XtRString, XtDefaultForeground},
{XtNframe, XtCFrame, XtRPixel, sizeof(Pixel),
Offset(frame_pixel), XtRString, XtDefaultForeground},
{XtNgridTolerance, XtCGridTolerance, XtRDimension, sizeof(Dimension),
Offset(grid_tolerance), XtRImmediate, (XtPointer) DefaultGridTolerance},
{XtNsize, XtCSize, XtRString, sizeof(String),
Offset(size), XtRImmediate, (XtPointer) DefaultBitmapSize},
{XtNdashed, XtCDashed, XtRBoolean, sizeof(Boolean),
Offset(dashed), XtRImmediate, (XtPointer) DefaultDashed},
{XtNgrid, XtCGrid, XtRBoolean, sizeof(Boolean),
Offset(grid), XtRImmediate, (XtPointer) DefaultGrid},
{XtNstippled, XtCStippled, XtRBoolean, sizeof(Boolean),
Offset(stippled), XtRImmediate, (XtPointer) DefaultStippled},
{XtNproportional, XtCProportional, XtRBoolean, sizeof(Boolean),
Offset(proportional), XtRImmediate, (XtPointer) DefaultProportional},
{XtNaxes, XtCAxes, XtRBoolean, sizeof(Boolean),
Offset(axes), XtRImmediate, (XtPointer) DefaultAxes},
{XtNsquareWidth, XtCSquareWidth, XtRDimension, sizeof(Dimension),
Offset(squareW), XtRImmediate, (XtPointer) DefaultSquareWidth},
{XtNsquareHeight, XtCSquareHeight, XtRDimension, sizeof(Dimension),
Offset(squareH), XtRImmediate, (XtPointer) DefaultSquareHeight},
{XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension),
Offset(margin), XtRImmediate, (XtPointer) DefaultMargin},
{XtNxHot, XtCXHot, XtRPosition, sizeof(Position),
Offset(hot.x), XtRImmediate, (XtPointer) NotSet},
{XtNyHot, XtCYHot, XtRPosition, sizeof(Position),
Offset(hot.y), XtRImmediate, (XtPointer) NotSet},
{XtNbutton1Function, XtCButton1Function, XtRButtonFunction, sizeof(int),
Offset(button_function[0]), XtRImmediate, (XtPointer) Set},
{XtNbutton2Function, XtCButton2Function, XtRButtonFunction, sizeof(int),
Offset(button_function[1]), XtRImmediate, (XtPointer) Invert},
{XtNbutton3Function, XtCButton3Function, XtRButtonFunction, sizeof(int),
Offset(button_function[2]), XtRImmediate, (XtPointer) Clear},
{XtNbutton4Function, XtCButton4Function, XtRButtonFunction, sizeof(int),
Offset(button_function[3]), XtRImmediate, (XtPointer) Clear},
{XtNbutton5Function, XtCButton5Function, XtRButtonFunction, sizeof(int),
Offset(button_function[4]), XtRImmediate, (XtPointer) Clear},
{XtNfilename, XtCFilename, XtRString, sizeof(String),
Offset(filename), XtRImmediate, (XtPointer) DefaultFilename},
{XtNbasename, XtCBasename, XtRString, sizeof(String),
Offset(basename), XtRImmediate, (XtPointer) DefaultFilename},
{XtNdashes, XtCDashes, XtRBitmap, sizeof(Pixmap),
Offset(dashes), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
{XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap),
Offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
};
#undef Offset
static XtActionsRec actions[] =
{
{"mark", (XtActionProc)BWTMark},
{"mark-all", (XtActionProc)BWTMarkAll},
{"unmark", (XtActionProc)BWTUnmark},
{"paste", (XtActionProc)BWTPaste},
{"bw-debug", (XtActionProc)BWDebug},
{"abort", (XtActionProc)BWAbort},
{"store-to-buffer", (XtActionProc)BWStoreToBuffer},
{"change-notify", (XtActionProc)BWChangeNotify},
{"set-changed", (XtActionProc)BWSetChanged},
{"up", (XtActionProc)BWUp},
{"down", (XtActionProc)BWDown},
{"left", (XtActionProc)BWLeft},
{"right", (XtActionProc)BWRight},
{"fold", (XtActionProc)BWFold},
{"flip-horiz", (XtActionProc)BWFlipHoriz},
{"flip-vert", (XtActionProc)BWFlipVert},
{"rotate-right", (XtActionProc)BWRotateRight},
{"rotate-left", (XtActionProc)BWRotateLeft},
{"set", (XtActionProc)BWSet},
{"clear", (XtActionProc)BWClear},
{"invert", (XtActionProc)BWInvert},
{"undo", (XtActionProc)BWUndo},
{"redraw", (XtActionProc)BWRedraw},
};
static char translations1[] =
"\
Shift<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 BWRequestRec requests[] =
{
{MarkRequest, sizeof(BWStatus),
TwoPointsEngage, (XtPointer) BWDrawRectangle,
TwoPointsTerminateTimed, (XtPointer) BWSelect,
NULL, (XtPointer) NULL},
{RestoreRequest, sizeof(BWStatus),
OnePointEngage, (XtPointer) BWDragStored,
OnePointTerminate, (XtPointer) BWRestore,
NULL, (XtPointer) NULL},
{ImmediateCopyRequest, sizeof(BWStatus),
OnePointEngage, (XtPointer) BWDragMarked,
OnePointTerminate, (XtPointer) BWCopy,
NULL, (XtPointer) NULL},
{ImmediateMoveRequest, sizeof(BWStatus),
OnePointEngage, (XtPointer) BWDragMarked,
OnePointTerminate, (XtPointer) BWMove,
NULL, (XtPointer) NULL},
{CopyRequest, sizeof(BWStatus),
DragOnePointEngage, (XtPointer) Paste,
DragOnePointTerminate, (XtPointer) ImmediateCopyRequest,
Interface, (XtPointer) BWUnmark},
{MoveRequest, sizeof(BWStatus),
DragOnePointEngage, (XtPointer) Paste,
DragOnePointTerminate, (XtPointer) ImmediateMoveRequest,
Interface, (XtPointer) BWUnmark},
{PointRequest, sizeof(BWStatus),
DragOnePointEngage, (XtPointer) BWDrawPoint,
DragOnePointTerminate, (XtPointer) BWDrawPoint,
NULL, (XtPointer) NULL},
{CurveRequest, sizeof(BWStatus),
DragTwoPointsEngage, (XtPointer) BWBlindLine,
DragTwoPointsTerminate, (XtPointer) BWBlindLine,
NULL, (XtPointer) NULL},
{LineRequest, sizeof(BWStatus),
TwoPointsEngage, (XtPointer) BWDrawLine,
TwoPointsTerminate, (XtPointer) BWDrawLine,
NULL, (XtPointer) NULL},
{RectangleRequest, sizeof(BWStatus),
TwoPointsEngage, (XtPointer) BWDrawRectangle,
TwoPointsTerminate, (XtPointer) BWDrawRectangle,
NULL, (XtPointer) NULL},
{FilledRectangleRequest, sizeof(BWStatus),
TwoPointsEngage, (XtPointer) BWDrawRectangle,
TwoPointsTerminate, (XtPointer) BWDrawFilledRectangle,
NULL, (XtPointer) NULL},
{CircleRequest, sizeof(BWStatus),
TwoPointsEngage, (XtPointer) BWDrawCircle,
TwoPointsTerminate, (XtPointer) BWDrawCircle,
NULL, (XtPointer) NULL},
{FilledCircleRequest, sizeof(BWStatus),
TwoPointsEngage, (XtPointer) BWDrawCircle,
TwoPointsTerminate, (XtPointer) BWDrawFilledCircle,
NULL, (XtPointer) NULL},
{FloodFillRequest, sizeof(BWStatus),
OnePointEngage, (XtPointer) NULL,
OnePointTerminate, (XtPointer) BWFloodFill,
NULL, (XtPointer) NULL},
{HotSpotRequest, sizeof(BWStatus),
OnePointEngage, (XtPointer) BWDrawHotSpot,
OnePointTerminate, (XtPointer) BWDrawHotSpot,
NULL, (XtPointer) NULL},
{ZoomInRequest, sizeof(BWStatus),
TwoPointsEngage, (XtPointer) BWDrawRectangle,
TwoPointsTerminate, (XtPointer) BWZoomIn,
NULL, (XtPointer) NULL},
};
static void ClassInitialize(void);
static void Initialize(Widget wrequest, Widget wnew,
ArgList argv, Cardinal *argc);
static void Redisplay(Widget w, XEvent *event, Region region);
static void Resize(Widget w);
static void Destroy(Widget w);
static void Refresh(BitmapWidget BW, Position x, Position y,
Dimension width, Dimension height);
static Boolean SetValues(Widget old, Widget request, Widget new,
ArgList args, Cardinal *num_args);
BitmapClassRec bitmapClassRec = {
{
(WidgetClass) &simpleClassRec,
"Bitmap",
sizeof(BitmapRec),
ClassInitialize,
NULL,
FALSE,
Initialize,
NULL,
XtInheritRealize,
actions,
XtNumber(actions),
resources,
XtNumber(resources),
NULLQUARK,
TRUE,
FALSE,
TRUE,
TRUE,
Destroy,
Resize,
Redisplay,
SetValues,
NULL,
XtInheritSetValuesAlmost,
NULL,
NULL,
XtVersion,
NULL,
NULL ,
XtInheritQueryGeometry,
XtInheritDisplayAccelerator,
NULL,
},
{
XtInheritChangeSensitive,
},
{
targets,
XtNumber(targets),
requests,
XtNumber(requests),
}
};
WidgetClass bitmapWidgetClass = (WidgetClass) &bitmapClassRec;
void
BWDebug(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
DEBUG ^= True;
}
Pixmap
BWGetPixmap(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return GetPixmap(BW, BW->bitmap.zoom.image);
}
Pixmap
BWGetUnzoomedPixmap(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
GC gc;
Pixmap pix;
if (BW->bitmap.zooming) {
pix = XCreatePixmap(XtDisplay(w), XtWindow(w),
BW->bitmap.zoom.image->width,
BW->bitmap.zoom.image->height, 1);
if (!(gc = XCreateGC(XtDisplay(w), pix,
(unsigned long) 0, (XGCValues *) 0)))
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 *
GetImage(BitmapWidget BW, Pixmap pixmap)
{
Window root;
int x, y;
unsigned int width, height, border_width, depth;
XImage *source, *image;
XGetGeometry(XtDisplay(BW), pixmap, &root, &x, &y,
&width, &height, &border_width, &depth);
source = XGetImage(XtDisplay(BW), pixmap, x, y, width, height,
1, XYPixmap);
image = ConvertToBitmapImage(BW, source);
return image;
}
XImage *
CreateBitmapImage(BitmapWidget BW, char *data,
Dimension width, Dimension height)
{
XImage *image = XCreateImage(XtDisplay(BW),
DefaultVisual(XtDisplay(BW),
DefaultScreen(XtDisplay(BW))),
1, XYBitmap, 0,
data, width, height,
8, ((int)width + 7) / 8);
image->height = height;
image->width = width;
image->depth = 1;
image->xoffset = 0;
image->format = XYBitmap;
image->data = (char *)data;
image->byte_order = LSBFirst;
image->bitmap_unit = 8;
image->bitmap_bit_order = LSBFirst;
image->bitmap_pad = 8;
image->bytes_per_line = ((int)width + 7) / 8;
return image;
}
void
DestroyBitmapImage(XImage **image)
{
if (image) {
if (*image) {
if ((*image)->data)
XtFree((*image)->data);
XtFree((char *)*image);
}
*image = NULL;
}
}
#if 0
XImage *
BWGetImage(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
BitmapWidget BW = (BitmapWidget) w;
return BW->bitmap.image;
}
#endif
void
BWChangeNotify(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.notify)
(*BW->bitmap.notify)(w, NULL, NULL, NULL);
}
void
BWNotify(Widget w, XtActionProc proc)
{
BitmapWidget BW = (BitmapWidget) w;
BW->bitmap.notify = proc;
}
void
BWSetChanged(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
BW->bitmap.changed = True;
}
Boolean
BWQueryChanged(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return BW->bitmap.changed;
}
void
BWClearChanged(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
BW->bitmap.changed = False;
}
Boolean
BWQueryStored(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return (BW->bitmap.storage != NULL);
}
Boolean
BWQueryStippled(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return BW->bitmap.stippled;
}
static void
RedrawStippled(BitmapWidget BW)
{
XExposeEvent event;
event.type = Expose;
event.display = XtDisplay((Widget)BW);
event.window = XtWindow((Widget)BW);
event.x = 0;
event.y = 0;
event.width = BW->core.width;
event.height = BW->core.height;
event.count = 0;
BWRedrawMark((Widget)BW);
BW->bitmap.stipple_change_expose_event = True;
XtDispatchEvent((XEvent *)&event);
BW->bitmap.stipple_change_expose_event = False;
}
void
BWSwitchStippled(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
RedrawStippled(BW);
BW->bitmap.stippled ^= True;
XSetFillStyle(XtDisplay(BW), BW->bitmap.highlighting_gc,
(BW->bitmap.stippled ? FillStippled : FillSolid));
RedrawStippled(BW);
}
void
BWSelect(Widget w, Position from_x, Position from_y,
Position to_x, Position to_y, Time btime)
{
BWMark(w, from_x, from_y, to_x, to_y);
BWGrabSelection(w, btime);
}
Boolean
BWQueryAxes(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return BW->bitmap.axes;
}
void
BWSwitchAxes(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
BW->bitmap.axes ^= True;
BWHighlightAxes(w);
}
void
BWAxes(Widget w, Boolean _switch)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.axes != _switch)
BWSwitchAxes(w);
}
void
BWRedrawAxes(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.axes)
BWHighlightAxes(w);
}
#if 0
void
BWPutImage(BitmapWidget w, Display *display, Drawable drawable, GC gc,
Position x, Position y)
{
BitmapWidget BW = (BitmapWidget) w;
XPutImage(display, drawable, gc, BW->bitmap.image,
0, 0, x, y, BW->bitmap.image->width, BW->bitmap.image->height);
}
#endif
static String
StripFilename(String filename)
{
char *begin = strrchr(filename, '/');
char *end, *result;
int length;
if (filename) {
begin = (begin ? begin + 1 : filename);
end = strchr(begin, '.');
length = (end ? (end - begin) : strlen (begin));
result = (char *) XtMalloc (length + 1);
strncpy (result, begin, length);
result [length] = '\0';
return (result);
}
else
return (NULL);
}
static int
XmuWriteBitmapDataToFile(String filename, String basename,
int width, int height, char *datap,
int x_hot, int y_hot)
{
FILE *file;
int i, data_length;
data_length = Length(width, height);
if(!filename || !strcmp(filename, "") || !strcmp(filename, "-")) {
file = stdout;
filename = "dummy";
}
else
file = fopen(filename, "w+");
if (!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;
}
static void
CvtStringToButtonFunction(XrmValuePtr args,
Cardinal *num_args,
XrmValuePtr from_val,
XrmValuePtr to_val)
{
static int button_function;
char lower_name[80];
XmuCopyISOLatin1Lowered (lower_name, (char*)from_val->addr);
if (!strcmp(lower_name, XtClear)) {
button_function = Clear;
to_val->addr = (XPointer) &button_function;
to_val->size = sizeof(button_function);
return;
}
if (!strcmp(lower_name, XtSet)) {
button_function = Set;
to_val->addr = (XPointer) &button_function;
to_val->size = sizeof(button_function);
return;
}
if (!strcmp(lower_name, XtInvert)) {
button_function = Invert;
to_val->addr = (XPointer) &button_function;
to_val->size = sizeof(button_function);
return;
}
XtStringConversionWarning(from_val->addr, XtRButtonFunction);
button_function = Clear;
to_val->addr = (XPointer) &button_function;
to_val->size = sizeof(button_function);
}
static void
ClassInitialize(void)
{
char *tm_table = XtMalloc(strlen(translations1) + strlen(translations2) + 1);
strcpy(tm_table, translations1);
strcat(tm_table, translations2);
bitmapClassRec.core_class.tm_table = tm_table;
XawInitializeWidgetSet();
XtAddConverter(XtRString, XtRButtonFunction, CvtStringToButtonFunction,
NULL, 0);
DEBUG = False;
}
static void
SetSizeFromSizeResource(BitmapWidget bw)
{
if (BWParseSize(bw->bitmap.size,
&bw->bitmap.width,
&bw->bitmap.height)
==
False) {
bw->bitmap.width = FallbackBitmapWidth;
bw->bitmap.height = FallbackBitmapHeight;
XtWarning("Cannot parse the size resource. BitmapWidget");
}
}
static void
Initialize(Widget wrequest, Widget wnew, ArgList argv, Cardinal *argc)
{
BitmapWidget new = (BitmapWidget) wnew;
XGCValues values;
XtGCMask mask;
char *image_data, *buffer_data;
new->bitmap.stipple_change_expose_event = False;
new->bitmap.notify = NULL;
new->bitmap.cardinal = 0;
new->bitmap.current = 0;
new->bitmap.fold = False;
new->bitmap.changed = False;
new->bitmap.zooming = False;
new->bitmap.selection.own = False;
new->bitmap.selection.limbo = False;
new->bitmap.request_stack = (BWRequestStack *)
XtMalloc(sizeof(BWRequestStack));
new->bitmap.request_stack[0].request = NULL;
new->bitmap.request_stack[0].call_data = NULL;
new->bitmap.request_stack[0].trap = False;
SetSizeFromSizeResource(new);
new->core.width = new->bitmap.width * new->bitmap.squareW +
2 * new->bitmap.margin;
new->core.height = new->bitmap.height * new->bitmap.squareH +
2 * new->bitmap.margin;
new->bitmap.hot.x = new->bitmap.hot.y = NotSet;
new->bitmap.buffer_hot.x = new->bitmap.buffer_hot.y = NotSet;
new->bitmap.mark.from_x = new->bitmap.mark.from_y = NotSet;
new->bitmap.mark.to_x = new->bitmap.mark.to_y = NotSet;
new->bitmap.buffer_mark.from_x = new->bitmap.buffer_mark.from_y = NotSet;
new->bitmap.buffer_mark.to_x = new->bitmap.buffer_mark.to_y = NotSet;
values.foreground = new->bitmap.foreground_pixel;
values.background = new->core.background_pixel;
values.foreground ^= values.background;
values.function = GXxor;
mask = GCForeground | GCBackground | GCFunction;
new->bitmap.drawing_gc = XCreateGC(XtDisplay(new),
RootWindow(XtDisplay(new),
DefaultScreen(XtDisplay(new))),
mask, &values);
values.foreground = new->bitmap.highlight_pixel;
values.background = new->core.background_pixel;
values.foreground ^= values.background;
values.function = GXxor;
mask = GCForeground | GCBackground | GCFunction;
if (new->bitmap.stipple != XtUnspecifiedPixmap)
{
values.stipple = new->bitmap.stipple;
mask |= GCStipple | GCFillStyle;
}
values.fill_style = (new->bitmap.stippled ? FillStippled : FillSolid);
new->bitmap.highlighting_gc = XCreateGC(XtDisplay(new),
RootWindow(XtDisplay(new),
DefaultScreen(XtDisplay(new))),
mask, &values);
values.foreground = new->bitmap.frame_pixel;
values.background = new->core.background_pixel;
values.foreground ^= values.background;
mask = GCForeground | GCBackground | GCFunction;
if (new->bitmap.dashes != XtUnspecifiedPixmap)
{
values.stipple = new->bitmap.dashes;
mask |= GCStipple | GCFillStyle;
}
values.fill_style = (new->bitmap.dashed ? FillStippled : FillSolid);
new->bitmap.frame_gc = XCreateGC(XtDisplay(new),
RootWindow(XtDisplay(new),
DefaultScreen(XtDisplay(new))),
mask, &values);
values.foreground = new->bitmap.highlight_pixel;
values.background = new->core.background_pixel;
values.foreground ^= values.background;
mask = GCForeground | GCBackground | GCFunction;
new->bitmap.axes_gc = XCreateGC(XtDisplay(new),
RootWindow(XtDisplay(new),
DefaultScreen(XtDisplay(new))),
mask, &values);
image_data = CreateCleanData(Length(new->bitmap.width,
new->bitmap.height));
buffer_data = CreateCleanData(Length(new->bitmap.width,
new->bitmap.height));
new->bitmap.storage = NULL;
new->bitmap.image = CreateBitmapImage(new,
image_data,
new->bitmap.width,
new->bitmap.height);
new->bitmap.buffer = CreateBitmapImage(new,
buffer_data,
new->bitmap.width,
new->bitmap.height);
{
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((Widget)new);
}
Boolean
BWParseSize(String size, Dimension *width, Dimension *height)
{
int x, y;
unsigned int w, h;
int status;
status = XParseGeometry(size, &x, &y, &w, &h);
if (status & (WidthValue | HeightValue)) {
*width = (Dimension) w;
*height = (Dimension) h;
return True;
}
else return False;
}
Boolean
BWQueryMarked(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y);
}
static void
FixMark(BitmapWidget BW)
{
if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) {
BW->bitmap.mark.from_x = min(BW->bitmap.mark.from_x,
BW->bitmap.image->width);
BW->bitmap.mark.from_y = min(BW->bitmap.mark.from_y,
BW->bitmap.image->height);
BW->bitmap.mark.to_x = min(BW->bitmap.mark.to_x,
BW->bitmap.image->width);
BW->bitmap.mark.to_y = min(BW->bitmap.mark.to_y,
BW->bitmap.image->height);
if((BW->bitmap.mark.from_x == BW->bitmap.mark.from_y) &&
(BW->bitmap.mark.to_x == BW->bitmap.mark.to_y))
BW->bitmap.mark.from_x =
BW->bitmap.mark.from_y =
BW->bitmap.mark.to_x =
BW->bitmap.mark.to_y = NotSet;
}
}
int
BWStoreFile(Widget w, String filename, String *basename)
{
BitmapWidget BW = (BitmapWidget) w;
int status;
unsigned char *storage_data;
unsigned int width, height;
int x_hot, y_hot;
status = XmuReadBitmapDataFromFile(filename, &width, &height,
&storage_data, &x_hot, &y_hot);
if (status == BitmapSuccess) {
DestroyBitmapImage(&BW->bitmap.storage);
BW->bitmap.storage = CreateBitmapImage(BW, (char *)storage_data, width, height);
return BitmapSuccess;
}
else
XtWarning(" read file failed. BitmapWidget");
return status;
}
String
BWUnparseStatus(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
XmuSnprintf(BW->bitmap.status, sizeof(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(Widget w, String str)
{
BitmapWidget BW = (BitmapWidget) w;
if (str) {
XtFree(BW->bitmap.filename);
BW->bitmap.filename = XtNewString( str);
}
}
void
BWChangeBasename(Widget w, String str)
{
BitmapWidget BW = (BitmapWidget) w;
if (str) {
XtFree(BW->bitmap.basename);
BW->bitmap.basename = XtNewString(str);
}
}
int
BWReadFile(Widget w, String filename, String 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((Widget)BW);
if (BW->core.visible) {
XClearArea(XtDisplay(BW), XtWindow(BW),
0, 0,
BW->core.width, BW->core.height,
True);
}
return BitmapSuccess;
}
else
XtWarning(" read file failed. BitmapWidget");
return status;
}
#if 0
void
BWSetImage(Widget w, XImage *image)
{
BitmapWidget BW = (BitmapWidget) w;
XImage *buffer;
char *buffer_data;
buffer_data = CreateCleanData(Length(image->width, image->height));
buffer = CreateBitmapImage(BW, buffer_data,
(Dimension) image->width,
(Dimension) image->height);
TransferImageData(BW->bitmap.image, buffer);
DestroyBitmapImage(&BW->bitmap.image);
DestroyBitmapImage(&BW->bitmap.buffer);
BW->bitmap.image = image;
BW->bitmap.buffer = buffer;
BW->bitmap.width = image->width;
BW->bitmap.height = image->height;
Resize((Widget)BW);
if (BW->core.visible) {
XClearArea(XtDisplay(BW), XtWindow(BW),
0, 0,
BW->core.width, BW->core.height,
True);
}
}
#endif
int
BWWriteFile(Widget w, String filename, String 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(Widget w, String *str)
{
BitmapWidget BW = (BitmapWidget) w;
*str = XtNewString(BW->bitmap.filename);
return *str;
}
String
BWGetFilepath(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(Widget w, String *str)
{
BitmapWidget BW = (BitmapWidget) w;
*str = XtNewString(BW->bitmap.basename);
return *str;
}
static void
FixHotSpot(BitmapWidget BW)
{
if (!QueryInBitmap(BW, BW->bitmap.hot.x, BW->bitmap.hot.y))
BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet;
}
static void
ZoomOut(BitmapWidget BW)
{
CopyImageData(BW->bitmap.image, BW->bitmap.zoom.image,
0, 0,
BW->bitmap.image->width - 1,
BW->bitmap.image->height - 1,
BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y);
DestroyBitmapImage(&BW->bitmap.image);
DestroyBitmapImage(&BW->bitmap.buffer);
BW->bitmap.image = BW->bitmap.zoom.image;
BW->bitmap.buffer = BW->bitmap.zoom.buffer;
BW->bitmap.width = BW->bitmap.image->width;
BW->bitmap.height = BW->bitmap.image->height;
BW->bitmap.fold = BW->bitmap.zoom.fold;
BW->bitmap.changed |= BW->bitmap.zoom.changed;
BW->bitmap.grid = BW->bitmap.zoom.grid;
if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) {
BW->bitmap.hot.x += BW->bitmap.zoom.at_x;
BW->bitmap.hot.y += BW->bitmap.zoom.at_y;
}
else
BW->bitmap.hot = BW->bitmap.zoom.hot;
BW->bitmap.mark.from_x = NotSet;
BW->bitmap.mark.from_y = NotSet;
BW->bitmap.mark.to_x = NotSet;
BW->bitmap.mark.to_y = NotSet;
BW->bitmap.zooming = False;
}
void
BWZoomOut(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.zooming) {
ZoomOut(BW);
Resize((Widget)BW);
if (BW->core.visible)
XClearArea(XtDisplay(BW), XtWindow(BW),
0, 0,
BW->core.width, BW->core.height,
True);
}
}
void
BWZoomMarked(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
BWZoomIn(w,
BW->bitmap.mark.from_x, BW->bitmap.mark.from_y,
BW->bitmap.mark.to_x, BW->bitmap.mark.to_y);
}
void
BWZoomIn(Widget w,
Position from_x, Position from_y,
Position to_x, Position to_y)
{
BitmapWidget BW = (BitmapWidget) w;
XImage *image, *buffer;
Dimension width, height;
char *image_data, *buffer_data;
if (BW->bitmap.zooming)
ZoomOut(BW);
QuerySwap(from_x, to_x);
QuerySwap(from_y, to_y);
from_x = max(0, from_x);
from_y = max(0, from_y);
to_x = min(BW->bitmap.width - 1, to_x);
to_y = min(BW->bitmap.height - 1, to_y);
width = to_x - from_x + 1;
height = to_y - from_y + 1;
image_data = CreateCleanData(Length(width, height));
buffer_data = CreateCleanData(Length(width, height));
image = CreateBitmapImage(BW, image_data, width, height);
buffer = CreateBitmapImage(BW, buffer_data, width, height);
CopyImageData(BW->bitmap.image, image, from_x, from_y, to_x, to_y, 0, 0);
CopyImageData(BW->bitmap.buffer, buffer, from_x, from_y, to_x, to_y, 0, 0);
BW->bitmap.zoom.image = BW->bitmap.image;
BW->bitmap.zoom.buffer = BW->bitmap.buffer;
BW->bitmap.zoom.at_x = from_x;
BW->bitmap.zoom.at_y = from_y;
BW->bitmap.zoom.fold = BW->bitmap.fold;
BW->bitmap.zoom.changed = BW->bitmap.changed;
BW->bitmap.zoom.hot = BW->bitmap.hot;
BW->bitmap.zoom.grid = BW->bitmap.grid;
BW->bitmap.image = image;
BW->bitmap.buffer = buffer;
BW->bitmap.width = width;
BW->bitmap.height = height;
BW->bitmap.changed = False;
BW->bitmap.hot.x -= from_x;
BW->bitmap.hot.y -= from_y;
BW->bitmap.mark.from_x = NotSet;
BW->bitmap.mark.from_y = NotSet;
BW->bitmap.mark.to_x = NotSet;
BW->bitmap.mark.to_y = NotSet;
BW->bitmap.zooming = True;
BW->bitmap.grid = True;
FixHotSpot(BW);
Resize((Widget)BW);
if (BW->core.visible)
XClearArea(XtDisplay(BW), XtWindow(BW),
0, 0,
BW->core.width, BW->core.height,
True);
}
void
BWRescale(Widget w, Dimension width, Dimension height)
{
BitmapWidget BW = (BitmapWidget) w;
XImage *image, *buffer;
char *buffer_data;
if (BW->bitmap.zooming)
ZoomOut(BW);
image = ScaleBitmapImage(BW, BW->bitmap.image,
(double) width / (double) BW->bitmap.image->width,
(double) height / (double) BW->bitmap.image->height);
buffer_data = CreateCleanData(Length(image->width, image->height));
buffer = CreateBitmapImage(BW, buffer_data,
(Dimension) image->width,
(Dimension) image->height);
TransferImageData(BW->bitmap.buffer, buffer);
DestroyBitmapImage(&BW->bitmap.image);
DestroyBitmapImage(&BW->bitmap.buffer);
BW->bitmap.image = image;
BW->bitmap.buffer = buffer;
BW->bitmap.width = image->width;
BW->bitmap.height = image->height;
FixHotSpot(BW);
FixMark(BW);
Resize((Widget)BW);
if (BW->core.visible)
XClearArea(XtDisplay(BW), XtWindow(BW),
0, 0,
BW->core.width, BW->core.height,
True);
}
Boolean
BWQueryZooming(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return BW->bitmap.zooming;
}
static void
ResizeGrid(BitmapWidget BW, Dimension width, Dimension height)
{
XImage *image, *buffer;
char *image_data, *buffer_data;
if (BW->bitmap.zooming)
ZoomOut(BW);
image_data = CreateCleanData(Length(width, height));
buffer_data = CreateCleanData(Length(width, height));
image = CreateBitmapImage(BW, image_data, width, height);
buffer = CreateBitmapImage(BW, buffer_data, width, height);
TransferImageData(BW->bitmap.image, image);
TransferImageData(BW->bitmap.buffer, buffer);
DestroyBitmapImage(&BW->bitmap.image);
DestroyBitmapImage(&BW->bitmap.buffer);
BW->bitmap.image = image;
BW->bitmap.buffer = buffer;
BW->bitmap.width = width;
BW->bitmap.height = height;
FixHotSpot(BW);
FixMark(BW);
}
void
BWResize(Widget w, Dimension width, Dimension height)
{
BitmapWidget BW = (BitmapWidget) w;
ResizeGrid(BW, width, height);
Resize((Widget)BW);
if (BW->core.visible)
XClearArea(XtDisplay(BW), XtWindow(BW),
0, 0,
BW->core.width, BW->core.height,
True);
}
static void
Destroy(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
XFreeGC(XtDisplay(w), BW->bitmap.drawing_gc);
XFreeGC(XtDisplay(w), BW->bitmap.highlighting_gc);
XFreeGC(XtDisplay(w), BW->bitmap.frame_gc);
XFreeGC(XtDisplay(w), BW->bitmap.axes_gc);
BWRemoveAllRequests(w);
XtFree(BW->bitmap.filename);
XtFree(BW->bitmap.basename);
}
static void
Resize(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
Dimension squareW, squareH;
squareW = max(1, ((int)BW->core.width - 2 * (int)BW->bitmap.margin) /
(int)BW->bitmap.width);
squareH = max(1, ((int)BW->core.height - 2 * (int)BW->bitmap.margin) /
(int)BW->bitmap.height);
if (BW->bitmap.proportional)
BW->bitmap.squareW = BW->bitmap.squareH = min(squareW, squareH);
else {
BW->bitmap.squareW = squareW;
BW->bitmap.squareH = squareH;
}
BW->bitmap.horizOffset = max((Position)BW->bitmap.margin,
(Position)(BW->core.width -
BW->bitmap.width *
BW->bitmap.squareW) / 2);
BW->bitmap.vertOffset = max((Position)BW->bitmap.margin,
(Position)(BW->core.height -
BW->bitmap.height *
BW->bitmap.squareH) / 2);
BW->bitmap.grid &= ((BW->bitmap.squareW > BW->bitmap.grid_tolerance) &&
(BW->bitmap.squareH > BW->bitmap.grid_tolerance));
}
static void
Redisplay(Widget w, XEvent *event, Region region)
{
BitmapWidget BW = (BitmapWidget) w;
if(event->type == Expose
&&
BW->core.visible)
if (BW->bitmap.stipple_change_expose_event == False)
Refresh(BW,
event->xexpose.x, event->xexpose.y,
event->xexpose.width, event->xexpose.height);
}
void
BWClip(Widget w, Position x, Position y, Dimension width, Dimension height)
{
Position from_x, from_y,
to_x, to_y;
BitmapWidget BW = (BitmapWidget) w;
XRectangle rectangle;
from_x = InBitmapX(BW, x);
from_y = InBitmapY(BW, y);
to_x = InBitmapX(BW, x + width);
to_y = InBitmapY(BW, y + height);
QuerySwap(from_x, to_x);
QuerySwap(from_y, to_y);
from_x = max(0, from_x);
from_y = max(0, from_y);
to_x = min(BW->bitmap.width - 1, to_x);
to_y = min(BW->bitmap.height - 1, to_y);
rectangle.x = InWindowX(BW, from_x);
rectangle.y = InWindowY(BW, from_y);
rectangle.width = InWindowX(BW, to_x + 1) - InWindowX(BW, from_x);
rectangle.height = InWindowY(BW, to_y + 1) - InWindowY(BW, from_y);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.highlighting_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.drawing_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.frame_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.axes_gc,
0, 0,
&rectangle, 1,
Unsorted);
}
void
BWUnclip(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
XRectangle rectangle;
rectangle.x = InWindowX(BW, 0);
rectangle.y = InWindowY(BW, 0);
rectangle.width = InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0);
rectangle.height = InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.highlighting_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.drawing_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.frame_gc,
0, 0,
&rectangle, 1,
Unsorted);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.axes_gc,
0, 0,
&rectangle, 1,
Unsorted);
}
static void
Refresh(BitmapWidget BW, Position x, Position y,
Dimension width, Dimension height)
{
XRectangle rectangle;
rectangle.x = min(x, InWindowX(BW, InBitmapX(BW, x)));
rectangle.y = min(y, InWindowY(BW, InBitmapY(BW, y)));
rectangle.width = max(x + width,
InWindowX(BW, InBitmapX(BW, x + width)+1)) - rectangle.x;
rectangle.height = max(y + height,
InWindowY(BW, InBitmapY(BW, y + height)+1)) - rectangle.y;
XClearArea(XtDisplay(BW), XtWindow(BW),
rectangle.x, rectangle.y,
rectangle.width, rectangle.height,
False);
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.frame_gc,
0, 0,
&rectangle, 1,
Unsorted);
XDrawRectangle(XtDisplay(BW), XtWindow(BW),
BW->bitmap.frame_gc,
InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1,
InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
BWClip((Widget) BW, x, y, width, height);
BWRedrawGrid((Widget) BW, x, y, width, height);
BWRedrawSquares((Widget) BW, x, y, width, height);
BWRedrawMark((Widget) BW);
BWRedrawHotSpot((Widget) BW);
BWRedrawAxes((Widget) BW);
BWUnclip((Widget) BW);
}
Boolean
BWQueryGrid(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return BW->bitmap.grid;
}
void
BWSwitchGrid(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
BW->bitmap.grid ^= TRUE;
BWDrawGrid(w,
0, 0,
BW->bitmap.image->width - 1, BW->bitmap.image->height - 1);
}
void
BWGrid(Widget w, Boolean _switch)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.grid != _switch)
BWSwitchGrid(w);
}
Boolean
BWQueryDashed(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return (BW->bitmap.dashed);
}
void
BWSwitchDashed(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
XRectangle rectangle;
BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1);
rectangle.x = 0;
rectangle.y = 0;
rectangle.width = BW->core.width;
rectangle.height = BW->core.height;
XSetClipRectangles(XtDisplay(BW),
BW->bitmap.frame_gc,
0, 0,
&rectangle, 1,
Unsorted);
XDrawRectangle(XtDisplay(BW), XtWindow(BW),
BW->bitmap.frame_gc,
InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1,
InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
BW->bitmap.dashed ^= True;
XSetFillStyle(XtDisplay(BW), BW->bitmap.frame_gc,
(BW->bitmap.dashed ? FillStippled : FillSolid));
XDrawRectangle(XtDisplay(BW), XtWindow(BW),
BW->bitmap.frame_gc,
InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1,
InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
BWUnclip(w);
BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1);
}
void
BWDashed(Widget w, Boolean _switch)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.dashed != _switch)
BWSwitchDashed(w);
}
static Boolean
SetValues(Widget old, Widget request, Widget new,
ArgList args, Cardinal *num_args)
{
BitmapWidget oldbw = (BitmapWidget) old;
BitmapWidget newbw = (BitmapWidget) new;
Boolean resize = False;
Boolean redisplay = False;
#define NE(field) (oldbw->field != newbw->field)
if (NE(bitmap.grid))
BWSwitchGrid(old);
if (NE(bitmap.dashed))
BWSwitchDashed(old);
if (NE(bitmap.axes))
BWSwitchAxes(old);
if (NE(bitmap.stippled))
BWSwitchStippled(old);
if (NE(bitmap.proportional))
resize = True;
if (NE(bitmap.filename) || NE(bitmap.basename) || NE(bitmap.size))
BWChangeNotify(old);
if (NE(bitmap.filename)) {
if (newbw->bitmap.filename) {
XtFree(oldbw->bitmap.filename);
newbw->bitmap.filename = XtNewString(newbw->bitmap.filename);
}
else
newbw->bitmap.filename = oldbw->bitmap.filename;
}
if (NE(bitmap.basename)) {
if (newbw->bitmap.basename) {
XtFree(oldbw->bitmap.basename);
newbw->bitmap.basename = XtNewString(newbw->bitmap.basename);
}
else
newbw->bitmap.basename = oldbw->bitmap.basename;
}
if (NE(bitmap.size)) {
Dimension width, height;
if (BWParseSize(newbw->bitmap.size, &width, &height)) {
ResizeGrid(newbw, width, height);
resize = True;
}
}
if (NE(bitmap.margin) ||
NE(bitmap.grid_tolerance) ||
NE(bitmap.squareW) ||
NE(bitmap.squareH) ||
NE(core.height) ||
NE(core.width))
resize = True;
if (NE(bitmap.hot.x) || NE(bitmap.hot.y))
BWSetHotSpot(old, newbw->bitmap.hot.x, newbw->bitmap.hot.y);
if (NE(bitmap.foreground_pixel) || NE(core.background_pixel)) {
XSetForeground(XtDisplay(new),
newbw->bitmap.drawing_gc,
newbw->bitmap.foreground_pixel
^
newbw->core.background_pixel);
redisplay = True;
}
if (NE(bitmap.frame_pixel) || NE(core.background_pixel)) {
XSetForeground(XtDisplay(new),
newbw->bitmap.frame_gc,
newbw->bitmap.frame_pixel
^
newbw->core.background_pixel);
redisplay = True;
}
if (NE(bitmap.dashes)) {
XSetStipple(XtDisplay(new),
newbw->bitmap.frame_gc,
newbw->bitmap.dashes);
redisplay = True;
}
if (NE(bitmap.highlight_pixel) || NE(core.background_pixel)) {
RedrawStippled(newbw);
XSetForeground(XtDisplay(new),
newbw->bitmap.highlighting_gc,
newbw->bitmap.highlight_pixel
^
newbw->core.background_pixel);
RedrawStippled(newbw);
}
if (NE(bitmap.stipple)) {
RedrawStippled(newbw);
XSetStipple(XtDisplay(new),
newbw->bitmap.highlighting_gc,
newbw->bitmap.stipple);
RedrawStippled(newbw);
}
if (resize) Resize((Widget)newbw);
return (redisplay || resize);
#undef NE
}
Boolean
BWQueryProportional(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
return (BW->bitmap.proportional);
}
void
BWSwitchProportional(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
BW->bitmap.proportional ^= True;
Resize((Widget)BW);
if (BW->core.visible)
XClearArea(XtDisplay(BW), XtWindow(BW),
0, 0,
BW->core.width, BW->core.height,
True);
}
#if 0
void
BWProportional(Widget w, Boolean _switch)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.proportional != _switch)
BWSwitchProportional(w);
}
#endif
void
BWTPaste(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
BitmapWidget BW = (BitmapWidget) w;
BWRequestSelection(w, event->xbutton.time, TRUE);
if (!BWQueryStored(w))
return;
BWEngageRequest(w, RestoreRequest, False,
(char *)&(event->xbutton.state), sizeof(int));
OnePointHandler(w,
(BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status,
event, NULL);
}
void
BWTMark(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
BitmapWidget BW = (BitmapWidget) w;
BWEngageRequest(w, MarkRequest, False,
(char *)&(event->xbutton.state), sizeof(int));
TwoPointsHandler(w,
(BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status,
event, NULL);
}
void
BWTMarkAll(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
BWMarkAll(w);
BWGrabSelection(w, event->xkey.time);
}
void
BWTUnmark(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
BWUnmark(w);
}