2
* Button.c, vi: tabstop=4
4
* Copyright (C) 1998 Rasca Gmelch, Berlin
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Library General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Library General Public License for more details.
17
* You should have received a copy of the GNU Library General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
#define __FILE__ "Button.c"
27
#include <X11/StringDefs.h>
28
#include <X11/IntrinsicP.h>
29
#include <Xw/ButtonP.h>
31
#define offset(field) XtOffsetOf (XwButtonRec, field)
35
static XtResource resources [] = {
37
{ XtNactiveColor, XtCActiveColor, XtRPixel, sizeof(Pixel),
38
offset(button.active_pixel), XtRString, "white" },
39
{ XtNpopupAtMouse, XtCPopupAtMouse, XtRBoolean, sizeof(Boolean),
40
offset(button.popup_at_mouse), XtRString, (XtPointer)"False" },
41
{ XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
42
offset(button.notify_callbacks), XtRCallback, (XtPointer)NULL },
43
{ XtNmenuName, XtCMenuName, XtRString, sizeof(String),
44
offset(button.menu_name), XtRImmediate, NULL },
45
{ XtNbitmap, XtCBitmap, XtRPixmap, sizeof(Pixmap),
46
offset(button.pic), XtRImmediate, (XtPointer)None },
47
{ XtNaccel, XtCAccel, XtRString, sizeof(String),
48
offset(button.accel), XtRImmediate, "set() notify() unset()" },
50
{ XtNlabel, XtCLabel, XtRString, sizeof(String),
51
offset (label.label), XtRImmediate, NULL },
53
{ XtNshadowType, XtCShadowType, XtRInt, sizeof(int),
54
offset(base.shadow_type), XtRImmediate, (XtPointer)XtShadowUp },
58
* action function declarations
61
Highlight (Widget, XEvent*, String*, Cardinal *),
62
Unhighlight (Widget, XEvent*, String*, Cardinal *),
63
Focus (Widget, XEvent*, String*, Cardinal *),
64
Reset (Widget, XEvent*, String*, Cardinal *),
65
Set (Widget, XEvent*, String*, Cardinal *),
66
Notify (Widget, XEvent*, String*, Cardinal *),
67
Unset (Widget, XEvent*, String*, Cardinal *),
68
Tab (Widget, XEvent*, String*, Cardinal *),
69
Popup (Widget, XEvent*, String*, Cardinal *),
70
GetFocus (Widget, XEvent*, String*, Cardinal *),
71
GetPointer (Widget, XEvent*, String*, Cardinal *);
76
static XtActionsRec actions [] =
78
{"highlight", Highlight },
79
{"unhighlight", Unhighlight },
85
{"get-focus", GetFocus },
86
{"get-pointer", GetPointer },
87
{"tab", Tab }, /* execute the XtNtabCallback functions */
88
{"popup", Popup }, /* don't forget to set XtNmenuName */
92
* default translation table
94
static char defaultTranslations [] = "\
95
<EnterWindow>: highlight(in)\n\
96
<LeaveWindow>: reset()\n\
97
<FocusIn>: focus(in)\n\
98
<FocusOut>: focus(out)\n\
100
<Btn1Up>: notify() unset() get-focus()\n\
101
<Btn3Down>: set() popup() reset()\n\
102
Shift<Key>Tab: tab(prev)\n\
103
<Key>Tab: tab(next)\n\
104
<Key>Return: set() notify() unset()";
107
* method function declarations
111
ClassInitialize (void),
112
ClassPartInitialize (WidgetClass wc),
113
Initialize (Widget treq, Widget tnew, ArgList args, Cardinal *nums),
116
Redisplay (Widget w, XEvent *event, Region region);
118
SetValues (Widget, Widget, Widget, ArgList, Cardinal*),
119
AcceptFocus(Widget, Time*);
124
static void DrawButton (Widget w);
127
* class record initialization
129
#define BaseClass ((WidgetClass)&xwBaseClassRec)
130
#define SuperClass ((WidgetClass)&xwLabelClassRec)
131
#define ThisClass ((WidgetClass)&xwButtonClassRec)
132
XwButtonClassRec xwButtonClassRec = {
134
/* core_class fields */
135
/* superclass */ SuperClass,
136
/* class_name */ "XwButton",
137
/* widget_size */ sizeof(XwButtonRec),
138
/* class_initialize */ ClassInitialize,
139
/* class_part_initialize */ ClassPartInitialize,
140
/* class_inited */ False,
141
/* initialize */ Initialize,
142
/* initialize_hook */ NULL,
143
/* realize */ XtInheritRealize,
144
/* actions */ actions,
145
/* num_actions */ XtNumber(actions),
146
/* resources */ resources,
147
/* num_resources */ XtNumber(resources),
148
/* xrm_class */ NULLQUARK,
149
/* compress_motion */ True,
150
/* compress_exposure */ XtExposeCompressMultiple,
151
/* compress_enterleave */ True,
152
/* visible_interest */ True,
153
/* destroy */ Destroy,
155
/* expose */ Redisplay,
156
/* set_values */ SetValues,
157
/* set_values_hook */ NULL,
158
/* set_values_almost */ XtInheritSetValuesAlmost,
159
/* get_values_hook */ NULL,
160
/* accept_focus */ AcceptFocus,
161
/* version */ XtVersion,
162
/* callback_private */ NULL,
163
/* tm_table */ defaultTranslations,
164
/* query_geometry */ XtInheritQueryGeometry,
165
/* display_accelerator */ XtInheritDisplayAccelerator,
168
{ /* base_class fields */
170
XtInheritFocusAction,
171
XtInheritGetFocusAction,
173
{ /* label_class fields */
176
{ /* button_class fields */
182
WidgetClass xwButtonWidgetClass = ThisClass;
186
* method function definitions
188
#define Margin(w) (int)(w->base.shadow_width + w->label.margin)
189
#define FontHeight(f) (int)(f->max_bounds.ascent + f->max_bounds.descent)
190
#define FontAscent(f) (int)(f->max_bounds.ascent)
191
#define FontDescent(f) (int)(f->max_bounds.descent)
192
#define TextWidth(f,s) XTextWidth (f,s,strlen(s))
195
RegAccel (XwButtonWidget bw) {
202
printf ("%s: RegAccel (%s) label=%s accel=%s\n", __FILE__, ((Widget)bw)->core.name,
203
bw->label.label, bw->button.accel);
205
if (bw->label.underline_pos > -1) {
206
pos = bw->label.label + bw->label.underline_pos;
207
if (*(pos+1) != '&') {
208
sprintf (transl_str, "<Key>%c: %s", *(pos+1), bw->button.accel);
209
tlt = XtParseTranslationTable (transl_str);
210
XtAugmentTranslations ((Widget)bw, tlt);
211
sprintf (transl_str, "Alt<Key>%c: %s", *(pos+1), bw->button.accel);
212
acc = XtParseAcceleratorTable (transl_str);
213
bw->core.accelerators = acc;
221
InitGC (XwButtonWidget w)
226
gc_vals.fill_style = FillSolid;
227
gc_vals.foreground = w->core.background_pixel;
228
gc_mask = GCFillStyle | GCForeground;
229
w->button.std_bg_gc = XtGetGC ((Widget) w, gc_mask, &gc_vals);
230
gc_vals.foreground = w->button.active_pixel;
231
w->button.focus_bg_gc = XtGetGC ((Widget) w, gc_mask, &gc_vals);
233
gc_vals.background = w->button.active_pixel;
234
gc_vals.foreground = w->base.foreground_pixel;
235
gc_vals.font = w->label.font->fid;
236
gc_mask = GCBackground | GCForeground | GCFont;
237
w->button.focusGC = XtGetGC ((Widget)w, gc_mask, &gc_vals);
244
Initialize (Widget treq, Widget tnew, ArgList args, Cardinal *num_args)
246
XwButtonWidget new = (XwButtonWidget) tnew;
248
printf ("%s: Initialize (%s)\n", __FILE__, new->core.name);
250
if (new->button.pic) {
252
unsigned int width, height, bw;
254
XGetGeometry (XtDisplay (new), new->button.pic, &root, &x, &y,
255
&width, &height, &bw, &new->button.pic_depth);
257
printf ("%s: pixmap x=%d y=%d depth=%d\n",
258
__FILE__,x, y, new->button.pic_depth);
260
new->core.width = width + 2 * Margin(new);
261
new->button.pic_width = width;
262
new->core.height = height + 2 * Margin(new);
263
new->button.pic_height = height;
266
new->button.set = False;
268
new->button.bgGC = new->button.std_bg_gc;
275
ClassInitialize (void)
277
XtRegisterGrabAction (Popup, True,
278
ButtonPressMask | ButtonReleaseMask,
279
GrabModeAsync, GrabModeAsync);
286
ClassPartInitialize (WidgetClass wc)
288
XwButtonWidgetClass c = (XwButtonWidgetClass) wc;
289
if (c->button_class.draw_button == XtInheritDrawButton)
290
c->button_class.draw_button = DrawButton;
291
if (c->button_class.popup_menu == XtInheritPopupMenu)
292
c->button_class.popup_menu = Popup;
299
SetValues (Widget curr, Widget req, Widget reply, ArgList args, Cardinal *nargs)
301
Boolean redraw = False;
302
XwButtonWidget bw = (XwButtonWidget) curr;
303
XwButtonWidget new = (XwButtonWidget) reply;
305
if (bw->button.set != new->button.set) {
308
if (bw->core.sensitive != new->core.sensitive) {
309
if (new->core.sensitive == False) {
310
new->button.bgGC = new->button.std_bg_gc;
314
if (bw->label.text != new->label.text) {
318
if (bw->button.pic != new->button.pic) {
322
XGetGeometry (XtDisplay (new), new->button.pic, &root, &x, &y,
323
&new->button.pic_width, &new->button.pic_height,
324
&bw, &new->button.pic_depth);
328
printf ("%s: SetValues (%s ..) redraw=%d\n", __FILE__, new->core.name, (int)redraw);
337
XwButtonWidget bw = (XwButtonWidget) w;
339
printf ("%s: Destroy (%s)\n", __FILE__, w->core.name);
341
XtReleaseGC (w, bw->button.std_bg_gc);
342
XtReleaseGC (w, bw->button.focus_bg_gc);
357
Redisplay (Widget w, XEvent *event, Region region)
359
XwButtonWidget bw = (XwButtonWidget) w;
362
printf ("%s: Redisplay (%s) ul_pos=%d x=%d y=%d len=%d oa=%d\n", __FILE__, w->core.name,
363
bw->label.underline_pos, bw->label.underline_x,
364
bw->label.underline_y, bw->label.underline_len, bw->core.height);
367
if (bw->base.shadow_width > 0)
368
(*BaseClass->core_class.expose)(w, event, region);
374
AcceptFocus (Widget w, Time *t)
377
printf ("%s: AcceptFocus (%s)\n", __FILE__, w->core.name);
379
if (!XtIsRealized(w))
383
if (!XtIsSensitive(w))
390
* action function definitions
395
Highlight (Widget w, XEvent *event, String *params, Cardinal *num_params)
397
XwButtonWidget bw = (XwButtonWidget) w;
399
printf ("%s: Highlight(%s) event=%d\n",__FILE__,bw->label.text,event->type);
401
if (bw->core.sensitive) {
402
bw->label.textGC = bw->button.focusGC;
403
bw->button.bgGC = bw->button.focus_bg_gc;
410
Unhighlight (Widget w, XEvent *event, String *params, Cardinal *num_params)
412
XwButtonWidget bw = (XwButtonWidget) w;
414
printf ("%s: Unhighlight(%s) event=%d\n", __FILE__,
415
bw->label.text, event->type);
417
bw->label.textGC = bw->label.sensitiveGC;
418
bw->button.bgGC = bw->button.std_bg_gc;
426
Reset (Widget w, XEvent *event, String *params, Cardinal *num_params)
428
XwButtonWidget bw = (XwButtonWidget) w;
430
printf ("%s: Reset(%s)\n", __FILE__, bw->label.text);
432
if (bw->button.set) {
433
Unset (w, event, params, num_params);
435
Unhighlight (w, event, params, num_params);
440
Notify (Widget w, XEvent *event, String *params, Cardinal *num_params)
442
XwButtonWidget bw = (XwButtonWidget) w;
444
printf ("%s: Notify(%s)\n", __FILE__, bw->label.text);
447
XtCallCallbackList (w, bw->button.notify_callbacks, (XtPointer)event);
454
Set (Widget w, XEvent *event, String *params, Cardinal *num_params)
456
XwButtonWidget bw = (XwButtonWidget) w;
458
printf ("%s: Set (%s, ..)\n", __FILE__, bw->label.text);
463
bw->button.set = True;
464
if (XtIsRealized(w)) {
465
XtVaSetValues (w, XtNshadowType, XtShadowDown, NULL);
471
Unset (Widget w, XEvent *event, String *params, Cardinal *num_params)
473
XwButtonWidget bw = (XwButtonWidget) w;
476
printf ("%s: Unset(%s)\n", __FILE__, bw->label.text);
480
bw->button.set = False;
482
XtVaSetValues (w, XtNshadowType, XtShadowUp, NULL);
488
GetFocus (Widget w, XEvent *event, String *params, Cardinal *num_params)
491
printf ("%s: GetFocus(%s)\n", __FILE__, XtName(w));
493
(*xwButtonClassRec.base_class.getfocus_action)(w,event, params, num_params);
499
GetPointer (Widget w, XEvent *event, String *params, Cardinal *num_params)
502
printf ("%s: GetPointer(%s)\n", __FILE__, ((XwButtonWidget)w)->label.text);
504
XWarpPointer (XtDisplay(w), None, XtWindow(w),
505
0, 0, 0, 0, w->core.width/2, w->core.height/2);
509
* for usage as menu-button
512
Popup (Widget w, XEvent *event, String *params, Cardinal *num_params)
514
XwButtonWidget bw = (XwButtonWidget) w;
516
printf ("%s: Popup ('%s')\n", __FILE__, bw->label.text);
518
/* check if button is used as menu button .. */
519
if (bw->button.menu_name) {
522
menu = XtNameToWidget (w, bw->button.menu_name);
524
menu = XtNameToWidget (XtParent(w), bw->button.menu_name);
527
printf ("%s: Popup ('..') menu=%s\n", __FILE__, bw->button.menu_name);
529
if (!XtIsRealized(menu))
530
XtRealizeWidget(menu);
531
XtTranslateCoords (w, 0, 0, &x, &y);
532
if (bw->button.popup_at_mouse && (event->type & ButtonPress)) {
533
y += event->xbutton.y;
534
x += event->xbutton.x;
536
y = y + w->core.height + 2 * w->core.border_width;
538
XtVaSetValues (menu, XtNx, x, XtNy, y, NULL);
539
XtPopupSpringLoaded (menu);
550
Tab (Widget w, XEvent *event, String *params, Cardinal *num_params)
553
fprintf (stderr, "%s: Tab_action()\n", __FILE__);
555
(*xwButtonClassRec.base_class.tab_action)(w, event, params, num_params);
561
Focus (Widget w, XEvent *event, String *params, Cardinal *num_params)
563
(*xwButtonClassRec.base_class.focus_action)(w, event, params, num_params);
571
DrawButton (Widget w)
573
XwButtonWidget bw = (XwButtonWidget) w;
575
if (!XtIsRealized(w))
578
XFillRectangle (XtDisplay (w), XtWindow(w), bw->button.bgGC,
579
ShadowWidth(bw), ShadowWidth(bw),
580
bw->core.width - (2*ShadowWidth(bw)),
581
bw->core.height - (2*ShadowWidth(bw)));
583
printf ("%s: DrawButton(%s)\n", __FILE__, w->core.name);
585
if (!bw->button.pic) {
586
(*xwButtonClassRec.label_class.draw_label)(w);
589
printf ("%s: DrawButton(%s) depth=%d\n", __FILE__, w->core.name,
590
bw->button.pic_depth);
592
if (bw->button.pic_depth < 2)
593
XCopyPlane (XtDisplay(w), bw->button.pic, XtWindow(w),
595
0, 0, bw->button.pic_width, bw->button.pic_height,
596
Margin(bw), Margin(bw), 1L);
598
XCopyArea (XtDisplay(w), bw->button.pic, XtWindow(w),
600
0, 0, bw->button.pic_width, bw->button.pic_height,
601
Margin(bw), Margin(bw));