home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-386-Vol-2of3.iso
/
c
/
cwikwidg.zip
/
cwikwidget
/
Cmap
/
Cmap.c
next >
Wrap
C/C++ Source or Header
|
1992-04-04
|
25KB
|
872 lines
/*
* Copyright 1992 John L. Cwikla
*
* 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 appears in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of John L. Cwikla or
* University of Illinois not be used in advertising or publicity
* pertaining to distribution of the software without specific, written
* prior permission. John L. Cwikla and University of Illinois make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
* John L. Cwikla and University of Illinois disclaim all warranties with
* regard to this software, including all implied warranties of
* merchantability and fitness, in no event shall John L. Cwikla or
* University of Illinois be liable for any special, indirect or
* consequential damages or any damages whatsoever resulting from loss of
* use, data or profits, whether in an action of contract, negligence or
* other tortious action, arising out of or in connection with the use or
* performance of this software.
*
* Author:
* John L. Cwikla
* Materials Research Laboratory Center for Computation
* University Of Illinois at Urbana-Champaign
* 104 S. Goodwin
* Urbana, IL 61801
*
* cwikla@uimrl7.mrl.uiuc.edu
*/
/*
** Cmap Widget
*/
/*
** Resources: Type: Default: Comment:
**
** XtNmargin : integer : 5 : minimum margin around widget picture and label
** XtNselected : integer : 0 : current box for selection and values
** XtNchangeCallback : callback : NULL : callback when any new box is chosen
** XtNfont : string : XtDefaultFont : fontname for label
** XtNforeground : pixel : XtDefautlForeground : pixel value for selected box and label
** XtNboxWidth : integer : 0 : maximum box width (0 for calculate/resize)
** XtNboxHeight : integer : 0 : maximum box height (0 for calculate/resize)
**
*/
#include <X11/Xos.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <math.h>
#include <varargs.h>
#include "CmapP.h"
#include "Cmap.h"
/* For actions */
#if NeedFunctionProtoTypes
static void Left(CmapWidget _w, XEvent *_event, String *_argv, int *_argc);
static void Right(CmapWidget _w, XEvent *_event, String *_argv, int *_argc);
static void Up(CmapWidget _w, XEvent *_event, String *_argv, int *_argc);
static void Down(CmapWidget _w, XEvent *_event, String *_argv, int *_argc);
static void Select(CmapWidget _w, XEvent *_event, String *_argv, int *_argc);
#else
static void Left();
static void Right();
static void Up();
static void Down();
static void Select();
#endif
/* For widget internals */
#if NeedFunctionProtoTypes
static void Initialize(CmapWidget _request, CmapWidget _new);
static void Realize(CmapWidget _w, XtValueMask *_xvm, XSetWindowAttributes *_xswa);
static void Resize(CmapWidget _w);
static void Destroy(CmapWidget _w);
static void Redisplay(CmapWidget _w, XEvent *_event, Region _region);
static Boolean SetValues(CmapWidget _current, CmapWidget _request, CmapWidget _new);
static void MyXtWarning();
#else
static void Initialize();
static void Realize();
static void Resize();
static void Destroy();
static void Redisplay();
static Boolean SetValues();
static void MyXtWarning();
#endif
/* For Misc */
#if NeedFunctionProtoTypes
static int XYtoBox(CmapWidget _w, int _x, int _y);
static void ReString(CmapWidget _w);
static void DrawLabel(CmapWidget _w, GC _gc);
static void DrawSelected(CmapWidget _w, int _boxNumber);
static void DrawBox(CmapWidget _w, int _boxNumber);
#else
static int XYtoBox();
static void ReString();
static void DrawLabel();
static void DrawSelected();
static void DrawBox();
#endif
static char CmapTranslations[] =
"<Key>h: left()\n\
<Key>l: right()\n\
<Key>k: up()\n\
<Key>j: down()\n\
<Btn1Down>: select()\n\
<Btn1Motion>: select()";
static XtActionsRec CmapActions[] =
{
{ "left", Left },
{ "right", Right },
{ "up", Up },
{ "down", Down },
{ "select", Select}
};
#define RGB_STRING "R:%d G:%d B:%d (%d of %d)"
#define CMAP_MINBOXWIDTH 5
#define CMAP_MINBOXHEIGHT 5
#define BOXtoX(w, b) (((b) % w->cmap.numX) * w->cmap.realBoxWidth + w->cmap.drawPos.x)
#define BOXtoY(w, b) (((b) / w->cmap.numX) * w->cmap.realBoxHeight + w->cmap.drawPos.y)
#define ROW(w, a) ((a) / w->cmap.numX)
#define COL(w, a) ((a) % w->cmap.numX)
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#define TheOffset(field) XtOffset(CmapWidget, cmap.field)
static XtResource CmapResources[] =
{
{XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
TheOffset(font), XtRString, (caddr_t)XtDefaultFont},
{XtNchangeCallback, XtCCallback, XtRCallback, sizeof(caddr_t),
TheOffset(changeCallback), XtRCallback, (caddr_t)NULL},
{XtNmargin, XtCMargin, XtRInt, sizeof(int),
TheOffset(margin), XtRImmediate, (caddr_t)5},
{XtNselected, XtCSelected, XtRInt, sizeof(int),
TheOffset(selected), XtRImmediate, (caddr_t)0},
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
TheOffset(foreground), XtRString, (caddr_t)XtDefaultForeground},
{XtNboxWidth, XtCBoxWidth, XtRInt, sizeof(int),
TheOffset(boxWidth), XtRImmediate, (caddr_t)0},
{XtNboxHeight, XtCBoxHeight, XtRInt, sizeof(int),
TheOffset(boxHeight), XtRImmediate, (caddr_t)0},
{XtNfirstIndex, XtCFirstIndex, XtRInt, sizeof(int),
TheOffset(firstIndex), XtRImmediate, (caddr_t)0},
{XtNlastIndex, XtCLastIndex, XtRInt, sizeof(int),
TheOffset(lastIndex), XtRImmediate, (caddr_t)LastIndexDefault}
};
#undef TheOffset
CmapClassRec cmapClassRec =
{
{ /* CoreClassPart */
(WidgetClass)&widgetClassRec, /* superclass */
"Cmap", /* class_name */
sizeof(CmapRec), /* widget_size */
NULL, /* class_initialize */
NULL, /* class_part_initialize */
FALSE, /* class_init */
Initialize, /* initialize */
NULL, /* initialize_hook */
Realize, /* realize */
CmapActions, /* actions */
XtNumber(CmapActions), /* num_actions */
CmapResources, /* resources */
XtNumber(CmapResources), /* num_resources */
NULLQUARK, /* xrm_class */
TRUE, /* compress_motion */
TRUE, /* compress_exposure */
TRUE, /* compress_enterleave */
TRUE, /* visible_intress */
Destroy, /* destroy */
Resize, /* resize */
Redisplay, /* expose */
SetValues, /* set_values */
NULL, /* set_values_hook */
XtInheritSetValuesAlmost, /* set_values_almost */
NULL, /* get_values_hook */
NULL, /* accept_focus */
XtVersion, /* version */
NULL, /* callback_private */
CmapTranslations, /* tm_translations */
NULL,
NULL,
NULL,
},
{
0 /* empty */
}
};
WidgetClass cmapWidgetClass = (WidgetClass) &cmapClassRec;
#define CMAP _new->cmap
#define CORE _new->core
static void Initialize(_request, _new)
CmapWidget _request;
CmapWidget _new;
{
Display *display;
XColor color;
display = XtDisplay(_new);
if (CMAP.font == (XFontStruct *)NULL)
{
if ((CMAP.font = XLoadQueryFont(display, "fixed")) == NULL)
if ((CMAP.font = XLoadQueryFont(display, "9x15")) == NULL)
MyXtWarning("CmapWidget: Fonts %s and %s not found.", "fixed", "9x15");
}
if (CMAP.margin < 0)
{
MyXtWarning("CmapWidget: Margin (%d) cannot be negative. Margin set to 0.", CMAP.margin);
CMAP.margin = 0;
}
if (CMAP.boxWidth < 0)
{
MyXtWarning("CmapWidget: BoxWidth (%d) cannot be negative. BoxWidth set to 0.", CMAP.boxWidth);
CMAP.boxWidth = 0;
}
if (CMAP.boxHeight < 0)
{
MyXtWarning("CmapWidget: BoxHeight (%d) cannot be negative. BoxHeight set to 0.", CMAP.boxHeight);
CMAP.boxHeight = 0;
}
if (CMAP.firstIndex < 0)
{
MyXtWarning("CmapWidget: FirstIndex (%d) cannot be negative. FirstIndex set to 0.", CMAP.firstIndex);
CMAP.firstIndex = 0;
}
CMAP.availColors = XDisplayCells(display, DefaultScreen(display));
if (CMAP.lastIndex == LastIndexDefault)
CMAP.lastIndex = CMAP.availColors-1;
if (CMAP.lastIndex < CMAP.firstIndex)
{
MyXtWarning("CmapWidget: LastIndex (%d) cannot be less than FirstIndex (%d). LastIndex set to %d.",
CMAP.lastIndex, CMAP.firstIndex, CMAP.firstIndex+1);
CMAP.lastIndex = CMAP.firstIndex + 1;
}
if (CMAP.lastIndex > CMAP.availColors-1)
{
MyXtWarning("CmapWidget: LastIndex (%d) cannot be more than greatest index (%d). LastIndex set to %d.",
CMAP.lastIndex, CMAP.availColors-1, CMAP.availColors-1);
CMAP.lastIndex = CMAP.availColors-1;
}
CMAP.usedColors = MIN(CMAP.lastIndex-CMAP.firstIndex+1, CMAP.availColors);
CMAP.numX = (int)floor(sqrt((double)(CMAP.usedColors)));
CMAP.numY = CMAP.usedColors/CMAP.numX + (CMAP.usedColors % CMAP.numX ? 1 : 0);
if (CMAP.selected > CMAP.usedColors)
{
MyXtWarning("CmapWidget: Selected pixel (%d) is greater than %d. Selected set to %d.",
CMAP.selected, CMAP.usedColors-1, CMAP.usedColors-1);
CMAP.selected = CMAP.usedColors-1;
}
if (CMAP.selected < 0)
{
MyXtWarning("CmapWidget: Selected pixel cannot be negative! Selected set to 0.");
CMAP.selected = 0;
}
color.pixel = CMAP.selected+CMAP.firstIndex;
XQueryColor(display, CORE.colormap, &color);
CMAP.selectedColor = color;
sprintf(CMAP.label, RGB_STRING, color.red, color.green,
color.blue, CMAP.selected+1, CMAP.usedColors);
CMAP.labelHeight = CMAP.font->ascent + CMAP.font->descent;
CMAP.labelWidth = XTextWidth(CMAP.font, CMAP.label, strlen(CMAP.label));
if (_request->core.width == 0)
CORE.width = MAX ((CMAP.boxWidth ? CMAP.boxWidth : CMAP_MINBOXWIDTH) * CMAP.numX, CMAP.labelWidth)
+ 2 * CMAP.margin;
if (_request->core.height == 0)
CORE.height = (CMAP.boxHeight ? CMAP.boxHeight : CMAP_MINBOXHEIGHT) * CMAP.numY + CMAP.margin
+ CMAP.labelHeight + 2 * CMAP.margin;
Resize(_new);
}
#undef CMAP
#undef CORE
static void Realize(_w, _xvm, _xswa)
CmapWidget _w;
XtValueMask *_xvm;
XSetWindowAttributes *_xswa;
{
XGCValues gcValues;
/* Call the Realize procedure (XtInheritRealize) */
(*cmapWidgetClass->core_class.superclass->core_class.realize)((Widget)_w, _xvm, _xswa);
/* Now we can create our GC's */
gcValues.foreground = _w->cmap.selected;
_w->cmap.gc = XCreateGC(XtDisplay(_w), XtWindow(_w), GCForeground, &gcValues);
/* This one is read only */
gcValues.foreground = _w->cmap.foreground;
gcValues.font = _w->cmap.font->fid;
_w->cmap.foregroundGC = XtGetGC((Widget)_w, GCFont | GCForeground, &gcValues);
/* This one is read only */
gcValues.foreground = _w->core.background_pixel;
_w->cmap.eraseGC = XtGetGC((Widget)_w, GCFont | GCForeground, &gcValues);
}
static void Resize(_w)
CmapWidget _w;
{
int marginX, marginY;
marginX = 2 * _w->cmap.margin;
marginY = 2 * _w->cmap.margin;
_w->cmap.realBoxWidth = (_w->core.width - marginX)/_w->cmap.numX;
_w->cmap.realBoxHeight = (_w->core.height - marginY - (_w->cmap.labelHeight + _w->cmap.margin)) /
_w->cmap.numY;
if (_w->cmap.boxWidth)
if (_w->cmap.realBoxWidth > _w->cmap.boxWidth)
_w->cmap.realBoxWidth = _w->cmap.boxWidth;
if (_w->cmap.boxHeight)
if (_w->cmap.realBoxHeight > _w->cmap.boxHeight)
_w->cmap.realBoxHeight = _w->cmap.boxHeight;
marginX += (_w->core.width - marginX) - (_w->cmap.numX * _w->cmap.realBoxWidth);
marginY += (_w->core.height - marginY) - (_w->cmap.numY * _w->cmap.realBoxHeight + _w->cmap.margin + _w->cmap.labelHeight);
_w->cmap.drawPos.y = marginY / 2;
_w->cmap.drawPos.x = marginX / 2;
_w->cmap.labelPos.x = (_w->core.width/2) - (_w->cmap.labelWidth)/2;
_w->cmap.labelPos.y = _w->cmap.drawPos.y + (_w->cmap.numY * _w->cmap.realBoxHeight) + _w->cmap.font->ascent
+ _w->cmap.margin;
}
static void Destroy(_w)
CmapWidget _w;
{
XFreeGC(XtDisplay(_w), _w->cmap.gc);
XtReleaseGC((Widget)_w, _w->cmap.foregroundGC);
XtReleaseGC((Widget)_w, _w->cmap.eraseGC);
XFreeFont(XtDisplay(_w),_w->cmap.font);
XtRemoveAllCallbacks((Widget)_w, XtNchangeCallback);
}
static void DrawLabel(_w, _gc)
CmapWidget _w;
GC _gc;
{
XDrawString(XtDisplay(_w), XtWindow(_w), _gc,
_w->cmap.labelPos.x, _w->cmap.labelPos.y,
_w->cmap.label, strlen(_w->cmap.label));
}
static void DrawSelected(_w, _boxNumber)
CmapWidget _w;
int _boxNumber;
{
int x, y;
XRectangle rect[2];
x = BOXtoX(_w, _boxNumber);
y = BOXtoY(_w, _boxNumber);
rect[0].x = x;
rect[0].y = y;
rect[0].width = (unsigned short)MAX(0, _w->cmap.realBoxWidth - 1);
rect[0].height = (unsigned short)MAX(0, _w->cmap.realBoxHeight - 1);
rect[1].x = x + 2;
rect[1].y = y + 2;
rect[1].width = (unsigned short)MAX(0, _w->cmap.realBoxWidth - 5);
rect[1].height = (unsigned short)MAX(0, _w->cmap.realBoxHeight - 5);
XDrawRectangles(XtDisplay(_w), XtWindow(_w), _w->cmap.foregroundGC,
rect, 2);
XDrawRectangle(XtDisplay(_w), XtWindow(_w), _w->cmap.eraseGC,
x+1, y+1,
MAX(0, _w->cmap.realBoxWidth - 3),
MAX(0, _w->cmap.realBoxHeight - 3));
}
static void DrawBox(_w, _boxNumber)
CmapWidget _w;
int _boxNumber;
{
int x, y;
XSetForeground(XtDisplay(_w), _w->cmap.gc, _boxNumber+_w->cmap.firstIndex);
x = BOXtoX(_w, _boxNumber);
y = BOXtoY(_w, _boxNumber);
XFillRectangle(XtDisplay(_w), XtWindow(_w), _w->cmap.gc,
x, y,
_w->cmap.realBoxWidth, _w->cmap.realBoxHeight);
}
static void Redisplay(_w, _event, _region)
CmapWidget _w;
XEvent *_event;
Region _region;
{
int i,j;
int scol, ecol;
int srow, erow;
XRectangle rect;
XClipBox(_region, &rect);
if (_w->core.visible)
{
XFillRectangle(XtDisplay(_w), XtWindow(_w), _w->cmap.eraseGC, rect.x, rect.y,
rect.width, rect.height);
rect.x = MAX(rect.x, _w->cmap.drawPos.x);
rect.y = MAX(rect.y, _w->cmap.drawPos.y);
rect.width = MIN(rect.x+rect.width, _w->cmap.drawPos.x+_w->cmap.numX*_w->cmap.realBoxWidth-1);
rect.height = MIN(rect.y+rect.height, _w->cmap.drawPos.y+_w->cmap.numY*_w->cmap.realBoxHeight-1);
if(!( (rect.x >= rect.width) || (rect.y >= rect.height)))
{
scol = COL(_w, XYtoBox(_w, rect.x, rect.y));
ecol = COL(_w, XYtoBox(_w, rect.width, rect.y));
srow = ROW(_w, XYtoBox(_w, rect.x, rect.y));
erow = ROW(_w, XYtoBox(_w, rect.x, rect.height));
i = scol;
j = srow;
for(;i<=ecol; i++)
{
for(;(j<=erow) && ((i+_w->cmap.numX*j)<_w->cmap.usedColors);j++)
DrawBox(_w, i + j*_w->cmap.numX);
j = srow;
}
}
DrawLabel(_w, _w->cmap.eraseGC);
DrawLabel(_w, _w->cmap.foregroundGC);
DrawSelected(_w, _w->cmap.selected);
}
XFlush(XtDisplay(_w));
}
#define CMAP _new->cmap
static Boolean SetValues(_current, _request, _new)
CmapWidget _current;
CmapWidget _request;
CmapWidget _new;
{
Boolean redisplay = FALSE;
Boolean newErase = FALSE;
Boolean newSelected = FALSE;
Display *display = XtDisplay(_new);
XGCValues gcValues;
int gcMask = GCFont;
if (CMAP.margin < 0)
{
MyXtWarning("CmapWidget: Margin (%d) cannot be negative. Margin set to 0.", CMAP.margin);
CMAP.margin = 0;
}
if (CMAP.boxWidth < 0)
{
MyXtWarning("CmapWidget: BoxWidth (%d) cannot be negative. BoxWidth set to 0.", CMAP.boxWidth);
CMAP.boxWidth = 0;
}
if (CMAP.boxHeight < 0)
{
MyXtWarning("CmapWidget: BoxHeight (%d) cannot be negative. BoxHeight set to 0.", CMAP.boxHeight);
CMAP.boxHeight = 0;
}
if (CMAP.font == (XFontStruct *)NULL)
{
if ((CMAP.font = XLoadQueryFont(display, "fixed")) == NULL)
if ((CMAP.font = XLoadQueryFont(display, "9x15")) == NULL)
MyXtWarning("CmapWidget: Fonts %s and %s not found.", "fixed", "9x15");
newSelected = TRUE;
redisplay = TRUE;
}
if (_new->core.background_pixel != _current->core.background_pixel)
{
gcValues.foreground = gcValues.background = _new->core.background_pixel;
gcMask |= (GCForeground | GCBackground);
newErase = TRUE;
redisplay = TRUE;
}
if (CMAP.foreground != _current->cmap.foreground)
newSelected = TRUE;
if (CMAP.selected != _current->cmap.selected)
{
if (CMAP.selected < 0)
{
MyXtWarning("CmapWidget: Selected pixel cannot be negative! Selected set to 0.");
CMAP.selected = 0;
}
if (CMAP.lastIndex == LastIndexDefault)
CMAP.lastIndex = CMAP.availColors-1;
if (CMAP.lastIndex < CMAP.firstIndex)
{
MyXtWarning("CmapWidget: LastIndex (%d) cannot be less than FirstIndex (%d). LastIndex set to %d.",
CMAP.lastIndex, CMAP.firstIndex, CMAP.firstIndex+1);
CMAP.lastIndex = CMAP.firstIndex + 1;
}
if (CMAP.lastIndex > CMAP.availColors-1)
{
MyXtWarning("CmapWidget: LastIndex (%d) cannot be more than greatest index (%d). LastIndex set to %d.",
CMAP.lastIndex, CMAP.availColors-1, CMAP.availColors-1);
CMAP.lastIndex = CMAP.availColors-1;
}
CMAP.usedColors = MIN(CMAP.lastIndex-CMAP.firstIndex+1, CMAP.availColors);
CMAP.numX = (int)floor(sqrt((double)(CMAP.usedColors)));
CMAP.numY = CMAP.usedColors / CMAP.numX + (CMAP.usedColors % CMAP.numX ? 1 : 0);
if (CMAP.selected > CMAP.usedColors-1)
{
MyXtWarning("CmapWidget: Selected pixel (%d) is greater than %d. Selected set to %d.",
CMAP.selected, CMAP.usedColors-1, CMAP.usedColors-1);
CMAP.selected = CMAP.lastIndex;
}
if (CMAP.selected < 0)
{
MyXtWarning("CmapWidget: Selected pixel (%d) cannot be negative. Selected set to 0.",
CMAP.selected);
CMAP.selected = 0;
}
DrawLabel(_current, _current->cmap.eraseGC);
CMAP.selectedColor.pixel = CMAP.selected+CMAP.firstIndex;
XQueryColor(display, _new->core.colormap, &CMAP.selectedColor);
ReString(_new);
DrawLabel(_new, CMAP.foregroundGC);
DrawBox(_new, _current->cmap.selected);
DrawSelected(_new, CMAP.selected);
XFlush(XtDisplay(_new));
}
if (CMAP.font->fid != _current->cmap.font->fid)
{
XFreeFont(display, _current->cmap.font);
XSetFont(display, CMAP.foregroundGC, CMAP.font->fid);
ReString(_new);
newSelected = TRUE;
newErase = TRUE;
redisplay = TRUE;
}
gcValues.font = CMAP.font->fid;
if (newErase)
{
XtReleaseGC((Widget)_new, CMAP.eraseGC);
_new->cmap.eraseGC = XtGetGC((Widget)_new, gcMask, &gcValues);
}
if (newSelected)
{
XtReleaseGC((Widget)_new, CMAP.foregroundGC);
gcValues.foreground = CMAP.foreground;
_new->cmap.foregroundGC = XtGetGC((Widget)_new, GCFont | GCForeground, &gcValues);
}
if ((CMAP.boxHeight != _current->cmap.boxHeight) ||
(CMAP.boxWidth != _current->cmap.boxWidth))
{
Resize(_new);
redisplay = TRUE;
}
return redisplay;
}
#undef CMAP
static void ReString(_w)
CmapWidget _w;
{
sprintf(_w->cmap.label, RGB_STRING, _w->cmap.selectedColor.red, _w->cmap.selectedColor.green,
_w->cmap.selectedColor.blue, _w->cmap.selected+1, _w->cmap.usedColors);
_w->cmap.labelHeight = _w->cmap.font->ascent + _w->cmap.font->descent;
_w->cmap.labelWidth = XTextWidth(_w->cmap.font, _w->cmap.label, strlen(_w->cmap.label));
_w->cmap.labelPos.x = (_w->core.width/2) - (_w->cmap.labelWidth)/2;
_w->cmap.labelPos.y = _w->cmap.drawPos.y + (_w->cmap.numY * _w->cmap.realBoxHeight) + _w->cmap.font->ascent +
_w->cmap.margin;
}
static int XYtoBox(_w, _x, _y)
CmapWidget _w;
int _x;
int _y;
{
int trux, truy;
int twidth, theight;
int x, y;
trux = _x - _w->cmap.drawPos.x;
truy = _y - _w->cmap.drawPos.y;
twidth = _w->cmap.numX * _w->cmap.realBoxWidth;
theight = _w->cmap.numY * _w->cmap.realBoxHeight;
if ((trux < 0) || (truy < 0) || (trux >= twidth) || (truy >= theight))
return -1;
return trux/_w->cmap.realBoxWidth +
truy/_w->cmap.realBoxHeight * _w->cmap.numX;
}
static void Left(_w, _event, _argv, _argc)
CmapWidget _w;
XEvent *_event;
String *_argv;
int *_argc;
{
int box;
Arg warg;
CmapCallbackStruct ccs;
if (*_argc != 0)
MyXtWarning("CmapWidget: Left takes no paramaters.");
box = ((_w->cmap.selected - 1) < 0) ? _w->cmap.usedColors - 1 : _w->cmap.selected - 1;
XtSetArg(warg, XtNselected, box);
XtSetValues((Widget)_w, &warg, 1);
ccs.reason = CMAP_LEFT;
ccs.event = _event;
ccs.color = _w->cmap.selectedColor;
XtCallCallbacks((Widget)_w, XtNchangeCallback, &ccs);
}
static void Right(_w, _event, _argv, _argc)
CmapWidget _w;
XEvent *_event;
String *_argv;
int *_argc;
{
int box;
Arg warg;
CmapCallbackStruct ccs;
if (*_argc != 0)
MyXtWarning("CmapWidget: Right takes no paramaters.");
box = ((_w->cmap.selected + 1) == _w->cmap.usedColors ) ? 0 : _w->cmap.selected + 1;
XtSetArg(warg, XtNselected, box);
XtSetValues((Widget)_w, &warg, 1);
ccs.reason = CMAP_RIGHT;
ccs.event = _event;
ccs.color = _w->cmap.selectedColor;
XtCallCallbacks((Widget)_w, XtNchangeCallback, &ccs);
}
static void Up(_w, _event, _argv, _argc)
CmapWidget _w;
XEvent *_event;
String *_argv;
int *_argc;
{
int box;
Arg warg;
CmapCallbackStruct ccs;
if (*_argc != 0)
MyXtWarning("CmapWidget: Up takes no paramaters.");
box = _w->cmap.selected - _w->cmap.numX;
if (box < 0)
{
box += _w->cmap.numX * (_w->cmap.numY+1) + 1;
while (box > _w->cmap.usedColors-1)
box -= _w->cmap.numX;
}
XtSetArg(warg, XtNselected, box);
XtSetValues((Widget)_w, &warg, 1);
ccs.reason = CMAP_UP;
ccs.event = _event;
ccs.color = _w->cmap.selectedColor;
XtCallCallbacks((Widget)_w, XtNchangeCallback, &ccs);
}
static void Down(_w, _event, _argv, _argc)
CmapWidget _w;
XEvent *_event;
String *_argv;
int *_argc;
{
int box;
Arg warg;
CmapCallbackStruct ccs;
if (*_argc != 0)
MyXtWarning("CmapWidget: Down takes no paramaters.");
box = _w->cmap.selected + _w->cmap.numX;
if (box >= _w->cmap.usedColors)
{
box -= _w->cmap.numX * (_w->cmap.numY+1) + 1;
while (box < 0)
box += _w->cmap.numX;
}
XtSetArg(warg, XtNselected, box);
XtSetValues((Widget)_w, &warg, 1);
ccs.reason = CMAP_DOWN;
ccs.event = _event;
ccs.color = _w->cmap.selectedColor;
XtCallCallbacks((Widget)_w, XtNchangeCallback, &ccs);
}
static void Select(_w, _event, _argv, _argc)
CmapWidget _w;
XEvent *_event;
String *_argv;
int *_argc;
{
int box;
int x, y;
Arg warg;
CmapCallbackStruct ccs;
switch (_event->type)
{
case ButtonPress:
case ButtonRelease:
x = ((XButtonEvent *)_event)->x;
y = ((XButtonEvent *)_event)->y;
break;
case KeyPress:
case KeyRelease:
x = ((XKeyEvent *)_event)->x;
y = ((XKeyEvent *)_event)->y;
break;
case MotionNotify:
x = ((XMotionEvent *)_event)->x;
y = ((XMotionEvent *)_event)->y;
break;
default: return; break;
}
if ((box = XYtoBox(_w, x, y)) < 0)
return;
if (box ==_w->cmap.selected)
return;
if (box > _w->cmap.usedColors-1)
return;
XtSetArg(warg, XtNselected, box);
XtSetValues((Widget)_w, &warg, 1);
ccs.reason = CMAP_SELECT;
ccs.event = _event;
ccs.color = _w->cmap.selectedColor;
XtCallCallbacks((Widget)_w, XtNchangeCallback, &ccs);
}
#define MAXSTRING 300
static void MyXtWarning(_format, va_alist)
char *_format;
va_dcl /* stupid define already has a ; on it */
{
va_list parms;
char dest[MAXSTRING];
va_start(parms);
vsprintf(dest, _format, parms);
va_end(parms);
XtWarning(dest);
}
/* External routines */
/* If you have
** an application that plays with the colormap, you
** must verify that the label is correct for that
** color (ie, the r,g,b values are correct.
** * NOTE * The event is NULL in the callback.
*/
void CmapVerifySelectedColor(_w, _notify)
Widget _w;
Boolean _notify;
{
XColor color;
CmapWidget cw;
if (!(XtIsCmap(_w)))
{
MyXtWarning("Widget passed to CmapVerifySelectedColor is not a Cmap widget!");
return;
}
cw = (CmapWidget)_w;
color.pixel = cw->cmap.selected;
XQueryColor(XtDisplay(cw), cw->core.colormap, &color);
DrawLabel(cw, cw->cmap.eraseGC);
cw->cmap.selectedColor = color;
ReString(cw);
DrawLabel(cw, cw->cmap.foregroundGC);
if (_notify)
{
CmapCallbackStruct ccs;
ccs.event = (XEvent *)NULL;
ccs.color = color;
ccs.reason = CMAP_VERIFY;
XtCallCallbacks(_w, XtNchangeCallback, &ccs);
}
}
/*
** Currently selected box in colormap.
** If the widget is not a Cmap widget, the returned value is undefined
*/
XColor CmapGetSelected(_w)
Widget _w;
{
if (!XtIsCmap(_w))
{
XColor xc;
MyXtWarning("Widget passed to CmapGetSelected is not a Cmap widget!");
return xc;
}
return ((CmapWidget)_w)->cmap.selectedColor;
}