summaryrefslogtreecommitdiff
path: root/Build/source/texk/xdvik/gui/xlwradio.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/xdvik/gui/xlwradio.c')
-rw-r--r--Build/source/texk/xdvik/gui/xlwradio.c677
1 files changed, 677 insertions, 0 deletions
diff --git a/Build/source/texk/xdvik/gui/xlwradio.c b/Build/source/texk/xdvik/gui/xlwradio.c
new file mode 100644
index 00000000000..27bb14c3eb2
--- /dev/null
+++ b/Build/source/texk/xdvik/gui/xlwradio.c
@@ -0,0 +1,677 @@
+/* adapted from xlwradio.c in the XEmacs distribution.
+ Changes are Copyright (C) 2002-2004 the xdvik development team.
+
+ Note SU: This widget doesn't work with Xaw3d, and I have little
+ inclination to make it work - the design would need to be utterly
+ different, e.g. the radio would need to be a diamond instead of a
+ circle, since 3d-shadowed circles don't look circular; colormap
+ issues would need to be settled, etc. And besides, I don't like Xaw3d ;)
+
+ So instead, the caller should just do:
+
+ myWidget = XtVaCreateManagedWidget("foo",
+ #ifdef XAW
+ radioWidgetClass,
+ #else
+ toggleWidgetClass,
+ #endif
+ ... arglist ...);
+
+ Feel free to submit patches if you want this implemented.
+
+ Original copyright follows:
+*/
+
+/* Radio Widget for XEmacs.
+ Copyright (C) 1999 Edward A. Falk
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Synched up with: Radio.c 1.1 */
+
+/*
+ * Radio.c - Radio button widget
+ *
+ * Author: Edward A. Falk
+ * falk@falconer.vip.best.com
+ *
+ * Date: June 30, 1997
+ *
+ *
+ * Overview: This widget is identical to the Toggle widget in behavior,
+ * but completely different in appearance. This widget looks like a small
+ * diamond-shaped button with a label to the right.
+ *
+ * To make this work, we subclass the Toggle widget to inherit its behavior
+ * and to inherit the label-drawing function from which Toggle is
+ * subclassed. We then completely replace the Expose, Set, Unset
+ * and Highlight member functions.
+ *
+ * The Set and Unset actions are slightly unorthodox. In Toggle's
+ * ClassInit function, Toggle searches the Command actions list and
+ * "steals" the Set and Unset functions, caching pointers to them in its
+ * class record. It then calls these functions from its own ToggleSet
+ * and Toggle actions.
+ *
+ * We, in turn, override the Set() and Unset() actions in our own ClassRec.
+ */
+
+#include "xdvi-config.h"
+#include "xdvi.h"
+#include "xdvi-debug.h"
+#include "util.h"
+#include "xaw_bitmaps.h" /* bitmaps for radio/checkbuttons */
+
+#include "xlwradioP.h"
+
+#ifndef MOTIF /* entire file */
+
+#include <stdio.h>
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xaw/Text.h>
+#include <X11/Xaw/AsciiText.h>
+/* #include "../src/xmu.h" */
+
+#define BOX_SIZE 16
+#define PIXMAP_OFFSET 2 /* additional space between pixmap and label */
+
+#ifndef UNUSED
+# define UNUSED(x) ((void)(x))
+#endif
+
+#ifndef MAX
+# define MAX(i, j) ( (i) > (j) ? (i) : (j) )
+#endif
+
+
+#define rclass(w) ((RadioWidgetClass)((w)->core.widget_class))
+
+
+#ifdef _ThreeDP_h
+#define swid(rw) ((rw)->threeD.shadow_width)
+#else
+#define swid(rw) ((rw)->core.border_width)
+#endif
+
+#define bsize(rw) (rclass(rw)->radio_class.dsize)
+#define bs(rw) (bsize(rw) + PIXMAP_OFFSET + 2*swid(rw))
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* The translations table from Toggle do not need to be
+ * overridden by Radio
+ */
+
+
+/* Member functions */
+
+static void RadioInit (Widget, Widget, ArgList, Cardinal *);
+static void RadioExpose (Widget, XEvent *, Region);
+static void RadioResize (Widget);
+static void RadioDestroy (Widget);
+static void RadioClassInit (void);
+static void RadioClassPartInit (WidgetClass);
+static Boolean RadioSetValues (Widget, Widget, Widget, ArgList, Cardinal *);
+static void DrawDiamond (Widget);
+static XtGeometryResult RadioQueryGeometry (Widget, XtWidgetGeometry *,
+ XtWidgetGeometry *);
+
+/* Action procs */
+
+static void RadioHighlight (Widget, XEvent *, String *, Cardinal *);
+static void RadioUnhighlight (Widget, XEvent *, String *, Cardinal *);
+
+/* internal privates */
+
+static void RadioSize (RadioWidget, Dimension *, Dimension *);
+
+/* The actions table from Toggle is almost perfect, but we need
+ * to override Highlight, Set, and Unset.
+ */
+
+static XtActionsRec actionsList[] =
+{
+ {"highlight", RadioHighlight},
+ {"unhighlight", RadioUnhighlight},
+};
+
+#define offset(field) XtOffset(RadioWidget, radio.field)
+
+static XtResource resources[] = {
+ {XtNisRadio, XtCIsRadio, XtRBoolean, sizeof(Boolean),
+ offset(isRadio), XtRImmediate, (XtPointer)True },
+};
+#undef offset
+
+#define SuperClass ((ToggleWidgetClass)&toggleClassRec)
+
+RadioClassRec radioClassRec = {
+ {
+ (WidgetClass) SuperClass, /* superclass */
+ "Radio", /* class_name */
+ sizeof(RadioRec), /* size */
+ RadioClassInit, /* class_initialize */
+ RadioClassPartInit, /* class_part_initialize */
+ FALSE, /* class_inited */
+ RadioInit, /* initialize */
+ NULL, /* initialize_hook */
+ XtInheritRealize, /* realize */
+ actionsList, /* actions */
+ XtNumber(actionsList), /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* resource_count */
+ NULLQUARK, /* xrm_class */
+ TRUE, /* compress_motion */
+ TRUE, /* compress_exposure */
+ TRUE, /* compress_enterleave */
+ FALSE, /* visible_interest */
+ RadioDestroy, /* destroy */
+ RadioResize, /* resize */
+ RadioExpose, /* expose */
+ RadioSetValues, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ XtInheritTranslations, /* tm_table */
+ RadioQueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL /* extension */
+ }, /* CoreClass fields initialization */
+ {
+ XtInheritChangeSensitive /* change_sensitive */
+#ifndef HAVE_OLD_XAW
+ , NULL
+#endif
+ }, /* SimpleClass fields initialization */
+#ifdef _ThreeDP_h
+ {
+ XtInheritXaw3dShadowDraw /* field not used */
+ }, /* ThreeDClass fields initialization */
+#endif
+ {
+ 0 /* field not used */
+ }, /* LabelClass fields initialization */
+ {
+ 0 /* field not used */
+ }, /* CommandClass fields initialization */
+ {
+ RadioSet, /* Set Procedure. */
+ RadioUnset, /* Unset Procedure. */
+ NULL /* extension. */
+ }, /* ToggleClass fields initialization */
+ {
+ BOX_SIZE,
+ DrawDiamond, /* draw procedure */
+ None, /* selected radiobutton */
+ None, /* unselected radiobutton */
+ None, /* selected menubutton */
+ None, /* unselected menubutton */
+ NULL /* extension. */
+ } /* RadioClass fields initialization */
+};
+
+ /* for public consumption */
+WidgetClass radioWidgetClass = (WidgetClass) &radioClassRec;
+
+
+
+
+
+
+/****************************************************************
+ *
+ * Class Methods
+ *
+ ****************************************************************/
+
+static void
+RadioClassInit (void)
+{
+ XawInitializeWidgetSet();
+}
+
+static void
+RadioClassPartInit (WidgetClass class)
+{
+ RadioWidgetClass c = (RadioWidgetClass) class;
+ RadioWidgetClass super = (RadioWidgetClass)c->core_class.superclass;
+
+ if( c->radio_class.drawDiamond == NULL ||
+ c->radio_class.drawDiamond == XtInheritDrawDiamond )
+ {
+ c->radio_class.drawDiamond = super->radio_class.drawDiamond;
+ }
+
+}
+
+
+
+
+static void
+RadioInit (Widget request,
+ Widget new,
+ ArgList args,
+ Cardinal *num_args)
+{
+ RadioWidget rw = (RadioWidget) new;
+ RadioWidget rw_req = (RadioWidget) request;
+ Dimension w,h;
+
+ UNUSED(args);
+ UNUSED(num_args);
+
+ /* FIXME: should pixmap initialization be here?? */
+
+ /* Select initial size for the widget */
+ if( rw_req->core.width == 0 || rw_req->core.height == 0 ) {
+ RadioSize(rw, &w,&h);
+ if( rw_req->core.width == 0 )
+ rw->core.width = w;
+ if( rw_req->core.height == 0 )
+ rw->core.height = h;
+ rw->core.widget_class->core_class.resize(new);
+ }
+ /*
+ FIXME: access to XtWindow(rw) fails in the init method, so
+ I moved the bitmap creation here -- is there a better way??
+ */
+ /* create pixmaps */
+ rclass(rw)->radio_class.sel_radio
+ = XCreateBitmapFromData(XtDisplay(rw), RootWindowOfScreen(XtScreen(rw)),
+ (char *)button_radio_on_bits, BUTTON_BITMAP_W, BUTTON_BITMAP_H);
+ rclass(rw)->radio_class.unsel_radio
+ = XCreateBitmapFromData(XtDisplay(rw), RootWindowOfScreen(XtScreen(rw)),
+ (char *)button_radio_off_bits, BUTTON_BITMAP_W, BUTTON_BITMAP_H);
+ rclass(rw)->radio_class.sel_menu
+ = XCreateBitmapFromData(XtDisplay(rw), RootWindowOfScreen(XtScreen(rw)),
+ (char *)button_check_on_bits, BUTTON_BITMAP_W, BUTTON_BITMAP_H);
+ rclass(rw)->radio_class.unsel_menu
+ = XCreateBitmapFromData(XtDisplay(rw), RootWindowOfScreen(XtScreen(rw)),
+ (char *)button_check_off_bits, BUTTON_BITMAP_W, BUTTON_BITMAP_H);
+}
+
+/* Function Name: RadioDestroy
+ * Description: Destroy Callback for radio widget.
+ * Arguments: w - the radio widget that is being destroyed.
+ * Returns: none.
+ */
+
+static void
+RadioDestroy (Widget w)
+{
+ RadioWidget rw = (RadioWidget)w;
+ /* de-allocate bitmaps */
+ XFreePixmap(XtDisplay(w), rclass(rw)->radio_class.sel_radio);
+ XFreePixmap(XtDisplay(w), rclass(rw)->radio_class.unsel_radio);
+ XFreePixmap(XtDisplay(w), rclass(rw)->radio_class.sel_menu);
+ XFreePixmap(XtDisplay(w), rclass(rw)->radio_class.unsel_menu);
+}
+
+
+/* React to size change from manager. Label widget will compute some internal
+ * stuff, but we need to override. This code requires knowledge of the
+ * internals of the Label widget.
+ */
+
+static void
+RadioResize (Widget w)
+{
+ RadioWidget rw = (RadioWidget)w;
+
+ /* call parent resize proc */
+ SuperClass->core_class.resize(w);
+
+ /* override label offset */
+
+ switch( rw->label.justify ) {
+ case XtJustifyLeft:
+ rw->label.label_x += (bs(rw) + rw->label.internal_width);
+ break;
+ case XtJustifyRight:
+ break;
+ case XtJustifyCenter:
+ default:
+ rw->label.label_x += (bs(rw) + rw->label.internal_width)/2;
+ break;
+ }
+}
+
+
+/*
+ * Repaint the widget window.
+ */
+
+static void
+RadioExpose (Widget w,
+ XEvent *event,
+ Region region)
+{
+ RadioWidget rw = (RadioWidget) w;
+ Display *dpy = XtDisplay(w);
+ Window win = XtWindow(w);
+ GC gc;
+ Pixmap left_bitmap;
+ extern WidgetClass labelWidgetClass;
+
+ /* Note: the Label widget examines the region to decide if anything
+ * needs to be drawn. I'm not sure that this is worth the effort,
+ * but it bears thinking on.
+ */
+
+ /* Command widget may sometimes override the label GC in order
+ * to draw inverse video. We don't use inverse video, so we need
+ * to restore the label's normal GC.
+ */
+ rw->label.normal_GC = rw->command.normal_GC;
+
+
+ /* Let label widget draw the label. If there was an lbm_x
+ * field, we could let Label draw the bitmap too. But there
+ * isn't, so we need to temporarily remove the bitmap and
+ * draw it ourself later.
+ */
+ left_bitmap = rw->label.left_bitmap;
+ rw->label.left_bitmap = None;
+ labelWidgetClass->core_class.expose(w,event,region);
+ rw->label.left_bitmap = left_bitmap;
+
+ /* now manually draw the left bitmap. TODO: 3-d look, xaw-xpm */
+ gc = XtIsSensitive(w) ? rw->label.normal_GC : rw->label.gray_GC;
+ if( left_bitmap != None && rw->label.lbm_width > 0 )
+ {
+ /* TODO: handle pixmaps */
+ XCopyPlane(dpy, left_bitmap, win, gc,
+ 0,0, rw->label.lbm_width, rw->label.lbm_height,
+ (int) rw->label.internal_width*2 + bs(rw),
+ (int) rw->label.internal_height + rw->label.lbm_y,
+ 1UL);
+ }
+ DrawDiamond(w);
+ /* Finally, the button itself */
+ ((RadioWidgetClass)(w->core.widget_class))->radio_class.drawDiamond(w);
+}
+
+
+
+
+/************************************************************
+ *
+ * Set specified arguments into widget
+ *
+ ***********************************************************/
+
+
+/* ARGSUSED */
+static Boolean
+RadioSetValues (Widget current,
+ Widget request,
+ Widget new,
+ ArgList args,
+ Cardinal *num_args)
+{
+ RadioWidget oldrw = (RadioWidget) current;
+ RadioWidget newrw = (RadioWidget) new;
+
+ UNUSED(request);
+ UNUSED(args);
+ UNUSED(num_args);
+
+ /* Need to find out if the size of the widget changed. Set new size
+ * if it did and resize is permitted. One way to determine of the
+ * widget changed size would be to scan the args list. Another way
+ * is to compare the old and new widgets and see if any of several
+ * size-related fields have been changed. The Label widget chose the
+ * former method, but I choose the latter.
+ */
+
+ if( newrw->label.resize &&
+ ( newrw->core.width != oldrw->core.width ||
+ newrw->core.height != oldrw->core.height ||
+ newrw->core.border_width != oldrw->core.border_width ) )
+ {
+ RadioSize(newrw, &newrw->core.width, &newrw->core.height);
+ }
+
+ /* The label set values routine can resize the widget. We need to
+ * recalculate if this is true.
+ */
+ if (newrw->label.label_x != oldrw->label.label_x)
+ {
+ RadioResize (new);
+ }
+ return FALSE;
+}
+
+static XtGeometryResult
+RadioQueryGeometry (Widget w,
+ XtWidgetGeometry *intended,
+ XtWidgetGeometry *preferred)
+{
+ RadioWidget rw = (RadioWidget) w;
+
+ preferred->request_mode = CWWidth | CWHeight;
+ RadioSize(rw, &preferred->width, &preferred->height);
+
+ if ( ((intended->request_mode & (CWWidth | CWHeight))
+ == (CWWidth | CWHeight)) &&
+ intended->width == preferred->width &&
+ intended->height == preferred->height)
+ return XtGeometryYes;
+ else if (preferred->width == w->core.width &&
+ preferred->height == w->core.height)
+ return XtGeometryNo;
+ else
+ return XtGeometryAlmost;
+}
+
+
+
+
+
+/************************************************************
+ *
+ * Action Procedures
+ *
+ ************************************************************/
+
+/*
+ * Draw the highlight border around the widget. The Command widget
+ * did this by drawing through a mask. We do it by just drawing the
+ * border.
+ */
+
+static void
+DrawHighlight (Widget w,
+ GC gc)
+{
+ RadioWidget rw = (RadioWidget)w;
+ XRectangle rects[4];
+ Dimension ht = rw->command.highlight_thickness;
+
+ if( ht <= 0 ||
+ ht > rw->core.width/2 ||
+ ht > rw->core.height/2 )
+ return;
+
+ if( ! XtIsRealized(w) )
+ return;
+
+ rects[0].x = 0; rects[0].y = 0;
+ rects[0].width = rw->core.width; rects[0].height = ht;
+ rects[1].x = 0; rects[1].y = rw->core.height - ht;
+ rects[1].width = rw->core.width; rects[1].height = ht;
+ rects[2].x = 0; rects[2].y = ht;
+ rects[2].width = ht; rects[2].height = rw->core.height - ht*2;
+ rects[3].x = rw->core.width - ht; rects[3].y = ht;
+ rects[3].width = ht; rects[3].height = rw->core.height - ht*2;
+ XFillRectangles( XtDisplay(w), XtWindow(w), gc, rects, 4);
+}
+
+static void
+RadioHighlight (Widget w,
+ XEvent *event,
+ String *params,
+ Cardinal *num_params)
+{
+ RadioWidget rw = (RadioWidget)w;
+ UNUSED(event);
+ UNUSED(params);
+ UNUSED(num_params);
+
+ DrawHighlight(w, rw->command.normal_GC);
+}
+
+
+static void
+RadioUnhighlight (Widget w,
+ XEvent *event,
+ String *params,
+ Cardinal *num_params)
+{
+ RadioWidget rw = (RadioWidget)w;
+ UNUSED(event);
+ UNUSED(params);
+ UNUSED(num_params);
+
+ DrawHighlight(w, rw->command.inverse_GC);
+}
+
+
+void
+RadioSet (Widget w,
+ XEvent *event,
+ String *params,
+ Cardinal *num_params)
+{
+ RadioWidget rw = (RadioWidget)w;
+ RadioWidgetClass class = (RadioWidgetClass) w->core.widget_class;
+
+ UNUSED(event);
+ UNUSED(params);
+ UNUSED(num_params);
+
+ if( rw->command.set )
+ return;
+
+ rw->command.set = TRUE;
+ if( XtIsRealized(w) )
+ class->radio_class.drawDiamond(w);
+}
+
+
+void
+RadioUnset (Widget w,
+ XEvent *event,
+ String *params,
+ Cardinal *num_params)
+{
+ RadioWidget rw = (RadioWidget)w;
+ RadioWidgetClass class = (RadioWidgetClass) w->core.widget_class;
+
+ UNUSED(event);
+ UNUSED(params);
+ UNUSED(num_params);
+
+ if( ! rw->command.set )
+ return;
+
+ rw->command.set = FALSE;
+ if( XtIsRealized(w) )
+ class->radio_class.drawDiamond(w);
+}
+
+
+
+
+/************************************************************
+ *
+ * Internal Procedures
+ *
+ ************************************************************/
+
+
+/* Size of widget. Width is size of box plus width of border around
+ * box plus width of label plus three margins plus the size of the left
+ * bitmap, if any. Height is max(box,bitmap,label) plus two margins.
+ */
+
+static void
+RadioSize (RadioWidget rw,
+ Dimension *w,
+ Dimension *h)
+{
+ *w = rw->label.label_width + bs(rw) + LEFT_OFFSET(rw) +
+ 3 * rw->label.internal_width;
+ *h = MAX( rw->label.label_height, bs(rw) ) +
+ 2 * rw->label.internal_width;
+}
+
+
+static void
+DrawDiamond(Widget w)
+{
+ RadioWidget rw = (RadioWidget) w;
+ Display *dpy = XtDisplay(w);
+ Window win = XtWindow(w);
+
+ Position x = rw->label.internal_width;
+ Position y = rw->core.height/2;
+ GC gc = XtIsSensitive(w) ? rw->command.normal_GC : rw->label.gray_GC;
+ Pixmap selected, unselected;
+
+ if (rw->radio.isRadio) { /* it's a radio button */
+ selected = rclass(rw)->radio_class.sel_radio;
+ unselected = rclass(rw)->radio_class.unsel_radio;
+ }
+ else {
+ selected = rclass(rw)->radio_class.sel_menu;
+ unselected = rclass(rw)->radio_class.unsel_menu;
+ }
+
+ ASSERT(selected != None, "");
+ ASSERT(unselected != None, "");
+
+ if(rw->command.set) {
+ XCopyPlane(dpy, selected, win, gc,
+ 0, 0, BUTTON_BITMAP_H, BUTTON_BITMAP_W,
+ x, y - BUTTON_BITMAP_H / 2, 1L);
+ }
+ else {
+ XCopyPlane(dpy, unselected, win, gc,
+ 0, 0, BUTTON_BITMAP_H, BUTTON_BITMAP_W,
+ x, y - BUTTON_BITMAP_H / 2, 1L);
+ }
+}
+
+
+#else
+/* silence `empty compilation unit' warnings */
+static void bar(void); static void foo() { bar(); } static void bar(void) { foo(); }
+#endif /* MOTIF */