home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute these examples for any
- purpose and without fee is hereby granted, provided that the above
- copyright notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting documentation,
- and that the name of Digital not be used in advertising or publicity
- pertaining to distribution of the software without specific, written
- prior permission.
-
- DIGITAL AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL DIGITAL 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.
-
- ******************************************************************/
-
- #include <string.h> /* Needed for string manipulation */
- #include <X11/IntrinsicP.h> /* Intrinsics header file */
- #include <X11/StringDefs.h> /* Resource string definitions */
- #include "PushbuttoP.h" /* Pushbutton private header file */
-
- static void InsPixel(), InsPixmap();
-
- #define Offset(field) XtOffsetOf(PushbuttonRec, pushbutton.field)
-
- static XtResource resources[] = {
- {XtNcallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
- Offset(callback), XtRCallback, (XtPointer) NULL},
- {"pri.vate", "Pri.vate", XtRBoolean, sizeof(Boolean),
- Offset(use_insens_pixel), XtRImmediate, (XtPointer) TRUE},
- {XtNinsensitiveForeground, XtCForeground, XtRPixel, sizeof(Pixel),
- Offset(insensitive_foreground),
- XtRCallProc, (XtPointer) InsPixel},
- {XtNinsensitivePixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
- Offset(insensitive_pixmap),
- XtRCallProc, (XtPointer) InsPixmap},
- {XtNhighlightBorder, XtCBorderWidth,
- XtRDimension, sizeof(Dimension),
- Offset(highlight_border), XtRImmediate, (XtPointer) 1},
- {XtNaccelString, XtCAccelString, XtRString, sizeof(String),
- XtOffsetOf(PushbuttonRec, label.accel_string),
- XtRString, NULL},
- {XtNacceleratorString, XtCAcceleratorString,
- XtRString, sizeof(String),
- Offset(accelerator_string), XtRString, NULL},
- {XtNborderWidth, XtCBorderWidth,
- XtRDimension, sizeof(Dimension),
- XtOffsetOf(PushbuttonRec, core.border_width),
- XtRImmediate, (XtPointer) 1},
- };
-
- #undef Offset
-
- static void InsPixel(w, offset, value)
- Widget w;
- int offset; /* Not used */
- XrmValue *value;
- {
- PushbuttonWidget p = (PushbuttonWidget) w;
-
- /* Any value will work; it won't be used */
- value->addr = (caddr_t) &p->label.foreground;
- p->pushbutton.use_insens_pixel = FALSE;
- }
-
- /* Return a 2x2 pixmap with the foreground at 50% */
-
- static Pixmap GetPixmap(pw)
- PushbuttonWidget pw;
- {
- static char bits[] = {0x01, 0x02};
-
- return XCreatePixmapFromBitmapData(XtDisplay(pw),
- RootWindowOfScreen(XtScreen(pw)), bits, 2, 2,
- pw->label.foreground, pw->core.background_pixel,
- pw->core.depth);
- }
-
- static void InsPixmap(w, offset, value)
- Widget w;
- int offset; /* Not used */
- XrmValue *value;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
- static Pixmap pixmap;
-
- if (pw->pushbutton.use_insens_pixel) pixmap = None;
- else pixmap = GetPixmap(pw);
-
- value->addr = (caddr_t) &pixmap;
- }
-
- static char defaultTranslations[] =
- "<EnterWindow> : highlight() \n\
- <LeaveWindow> : unhighlight() \n\
- <Btn1Down> : invert() \n\
- <Btn1Up> : notify() uninvert()";
-
- static void Highlight(), Unhighlight(), Invert(), Uninvert(), Notify();
-
- static XtActionsRec actions[] = {
- {"highlight", Highlight},
- {"unhighlight", Unhighlight},
- {"invert", Invert},
- {"uninvert", Uninvert},
- {"notify", Notify},
- };
-
- /* Forward declarations */
-
- static void Initialize(), DisplayAccelerator(), Destroy(), Redisplay();
- static Boolean SetValues();
-
- /* Class record declaration */
-
- PushbuttonClassRec pushbuttonClassRec = {
- /* Core class part */
- {
- /* superclass */ (WidgetClass) &labelClassRec,
- /* class_name */ "Pushbutton",
- /* widget_size */ sizeof(PushbuttonRec),
- /* class_initialize */ NULL,
- /* 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 */ XtExposeCompressMultiple,
- /* compress_enterleave */ TRUE,
- /* visible_interest */ FALSE,
- /* destroy */ NULL,
- /* resize */ XtInheritResize,
- /* expose */ Redisplay,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* accept_focus */ NULL,
- /* version */ XtVersion,
- /* callback offsets */ NULL,
- /* tm_table */ defaultTranslations,
- /* query_geometry */ XtInheritQueryGeometry,
- /* display_accelerator */ DisplayAccelerator,
- /* extension */ NULL
- },
- /* Label class part */
- {
- /* select_text */ InheritSelectText,
- /* extension */ NULL
- },
- /* Pushbutton class part */
- {
- /* extension */ NULL
- }
- };
-
- /* Class record pointer */
-
- WidgetClass pushbuttonWidgetClass = (WidgetClass) &pushbuttonClassRec;
-
- static void Highlight(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
-
- if (!pw->pushbutton.highlighted) {
- pw->pushbutton.highlighted = TRUE;
- if (XtIsRealized(w)) {
- XClearWindow(XtDisplay(w), XtWindow(w));
- (*(XtClass(w)->core_class.expose))(w, event, NULL);
- }
- }
- }
-
- static void Unhighlight(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
-
- if (pw->pushbutton.highlighted) {
- pw->pushbutton.highlighted = FALSE;
- if (XtIsRealized(w)) {
- XClearWindow(XtDisplay(w), XtWindow(w));
- (*(XtClass(w)->core_class.expose))(w, event, NULL);
- }
- }
- }
-
- static void Invert(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
-
- if (!pw->pushbutton.inverted) {
- pw->pushbutton.inverted = TRUE;
- pw->label.current_gc = pw->pushbutton.inverted_gc;
- if (XtIsRealized(w)) {
- XClearWindow(XtDisplay(w), XtWindow(w));
- (*(XtClass(w)->core_class.expose))(w, event, NULL);
- }
- }
- }
-
- static void Uninvert(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
-
- if (pw->pushbutton.inverted) {
- pw->pushbutton.inverted = FALSE;
- if (XtIsSensitive(w)) {
- pw->label.current_gc = pw->label.gc;
- } else pw->label.current_gc = pw->pushbutton.insensitive_gc;
-
- if (XtIsRealized(w)) {
- XClearWindow(XtDisplay(w), XtWindow(w));
- (*(XtClass(w)->core_class.expose))(w, event, NULL);
- }
- }
- }
-
- static void Notify(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
-
- /* If event is a button event, and the event's window is the
- widget's window, we were invoked normally. Make sure
- the pointer is really in the window */
-
- if (event != NULL && event->type == ButtonRelease &&
- event->xany.window == XtWindow(w)) {
- XButtonEvent *b = &event->xbutton;
- if (b->x < 0 || b->y < 0 ||
- b->x >= w->core.width || b->y >= w->core.height) return;
- }
-
- XtCallCallbackList(pw, pw->pushbutton.callback, NULL);
- }
-
- static GC GetInvertedGC(pw)
- PushbuttonWidget pw;
- {
- XGCValues values;
-
- values.foreground = pw->core.background_pixel;
- values.font = pw->label.font->fid;
- return XtGetGC((Widget) pw, GCForeground | GCFont, &values);
- }
-
- static GC GetInsensitiveGC(pw)
- PushbuttonWidget pw;
- {
- XGCValues values;
-
- values.font = pw->label.font->fid;
-
- if (pw->pushbutton.use_insens_pixel) {
- values.foreground = pw->pushbutton.insensitive_foreground;
- return XtGetGC((Widget) pw, GCForeground | GCFont, &values);
- } else {
- values.tile = pw->pushbutton.insensitive_pixmap;
- values.fill_style = FillTiled;
- return XtGetGC((Widget) pw,
- GCTile | GCFont | GCFillStyle, &values);
- }
- }
-
- static void Initialize(req, new)
- Widget req, new;
- {
- PushbuttonWidget pw = (PushbuttonWidget) new;
-
- pw->pushbutton.insensitive_gc = GetInsensitiveGC(pw);
- pw->pushbutton.inverted_gc = GetInvertedGC(pw);
- pw->pushbutton.accelerator_string =
- XtNewString(pw->pushbutton.accelerator_string);
-
- pw->pushbutton.highlighted = pw->pushbutton.inverted = FALSE;
-
- if (!XtIsSensitive(pw)) {
- pw->label.current_gc = pw->pushbutton.insensitive_gc;
- }
- }
-
- static Boolean SetValues(old, req, new, args, num_args)
- Widget old, req, new;
- ArgList args;
- Cardinal *num_args;
- {
- PushbuttonWidget oldpw = (PushbuttonWidget) old;
- PushbuttonWidget newpw = (PushbuttonWidget) new;
-
- #define NE(field) (oldpw->field != newpw->field)
-
- /* If insensitive fields or button's font has changed,
- update insensitive GC */
-
- if (NE(pushbutton.insensitive_foreground)) {
- newpw->pushbutton.use_insens_pixel = TRUE;
- }
-
- if (NE(pushbutton.insensitive_pixmap)) {
- if (newpw->pushbutton.insensitive_pixmap == None) {
- newpw->pushbutton.insensitive_pixmap = GetPixmap(newpw);
- }
- newpw->pushbutton.use_insens_pixel = FALSE;
- }
-
- if (NE(pushbutton.insensitive_foreground) ||
- NE(pushbutton.insensitive_pixmap) || NE(label.font->fid)) {
- XtReleaseGC(newpw, oldpw->pushbutton.insensitive_gc);
- newpw->pushbutton.insensitive_gc = GetInsensitiveGC(newpw);
-
- if (newpw->label.current_gc ==
- oldpw->pushbutton.insensitive_gc) {
- newpw->label.current_gc = newpw->pushbutton.insensitive_gc;
- }
- }
-
- /* If background or font has changed, update inverted GC */
-
- if (NE(core.background_pixel) || NE(label.font->fid)) {
- XtReleaseGC(newpw, oldpw->pushbutton.inverted_gc);
- newpw->pushbutton.inverted_gc = GetInvertedGC(newpw);
-
- if (newpw->pushbutton.inverted) {
- newpw->label.current_gc = newpw->pushbutton.inverted_gc;
- }
- }
-
- /* If sensitivity changing, adjust appearance */
-
- if (NE(core.sensitive) || NE(core.ancestor_sensitive)) {
- if (XtIsSensitive(newpw)) { /* Just made sensitive */
- newpw->label.current_gc = newpw->label.gc;
-
- } else { /* Just made insensitive */
- newpw->label.current_gc =
- newpw->pushbutton.insensitive_gc;
-
- /* If currently highlighted, will never receive
- leave event to unhighlight, so unhighlight */
- newpw->pushbutton.highlighted = FALSE;
- }
- }
-
- /* If current graphics context has changed, inverted
- and foreground has changed, or highlighted and highlight
- width has changed, redisplay */
-
- return NE(label.current_gc) ||
- (NE(label.foreground) && newpw->pushbutton.inverted) ||
- (NE(pushbutton.highlight_border) &&
- newpw->pushbutton.highlighted);
- #undef NE
- }
-
- static void Destroy(w)
- Widget w;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
-
- /* Release the GCs */
-
- XtReleaseGC(w, pw->pushbutton.insensitive_gc);
- XtReleaseGC(w, pw->pushbutton.inverted_gc);
-
- XtFree(pw->pushbutton.accelerator_string);
- XtFree(pw->label.accel_string);
- }
-
- static void Redisplay(w, event, region)
- Widget w;
- XEvent *event;
- Region region;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
- int offset;
-
- /* If inverted, fill background with the foreground color */
-
- if (pw->pushbutton.inverted) {
- XFillRectangle(XtDisplay(w), XtWindow(w), pw->label.gc,
- 0, 0, pw->core.width, pw->core.height);
- }
-
- /* If highlighted, draw highlighting border */
-
- if (pw->pushbutton.highlighted) {
- offset = pw->pushbutton.highlight_border / 2;
- XDrawRectangle(XtDisplay(w), XtWindow(w), pw->label.current_gc,
- offset, offset,
- pw->core.width - pw->pushbutton.highlight_border,
- pw->core.height - pw->pushbutton.highlight_border);
- }
-
- /* Make Label redisplay the string */
-
- (*pushbuttonWidgetClass->core_class.superclass->core_class.expose)
- (w, event, region);
- }
-
- static void DisplayAccelerator(w, string)
- Widget w;
- String string;
- {
- PushbuttonWidget pw = (PushbuttonWidget) w;
- Arg args[1];
-
- if (pw->pushbutton.accelerator_string != NULL) {
- XtSetArg(args[0], XtNaccelString,
- pw->pushbutton.accelerator_string);
- XtSetValues(w, args, 1);
- }
- }
-