1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$TOG: DrawingA.c /main/16 1999/10/13 16:16:41 mgreess $"
26 #endif
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33
34 #include <Xm/TransltnsP.h>
35 #include <Xm/VaSimpleP.h>
36 #include "DrawingAI.h"
37 #include "GadgetUtiI.h"
38 #include "GMUtilsI.h"
39 #include "RepTypeI.h"
40 #include "TraversalI.h"
41 #include "XmI.h"
42
43
44 #define MARGIN_DEFAULT 10
45
46 #define defaultTranslations _XmDrawingA_defaultTranslations
47 #define traversalTranslations _XmDrawingA_traversalTranslations
48
49
50 /******** Static Function Declarations ********/
51
52 static void ClassInitialize( void ) ;
53 static void ClassPartInitialize(
54 WidgetClass w_class) ;
55 static void Initialize(
56 Widget rw,
57 Widget nw,
58 ArgList args,
59 Cardinal *num_args) ;
60 static void Redisplay(
61 Widget wid,
62 XEvent *event,
63 Region region) ;
64 static void Resize(
65 Widget wid) ;
66 static XtGeometryResult GeometryManager(
67 Widget w,
68 XtWidgetGeometry *request,
69 XtWidgetGeometry *reply) ;
70 static void ChangeManaged(
71 Widget wid) ;
72 static Boolean SetValues(
73 Widget cw,
74 Widget rw,
75 Widget nw,
76 ArgList args,
77 Cardinal *num_args) ;
78 static XtGeometryResult QueryGeometry(
79 Widget wid,
80 XtWidgetGeometry *intended,
81 XtWidgetGeometry *desired) ;
82 static XmNavigability WidgetNavigable(
83 Widget wid) ;
84
85 /******** End Static Function Declarations ********/
86
87
88 static XtActionsRec actionsList[] =
89 {
90 { "DrawingAreaInput", _XmDrawingAreaInput },
91 };
92
93
94 /* Resource definitions for DrawingArea
95 */
96
97 static XtResource resources[] =
98 {
99 { XmNmarginWidth,
100 XmCMarginWidth, XmRHorizontalDimension, sizeof (Dimension),
101 XtOffsetOf(XmDrawingAreaRec, drawing_area.margin_width),
102 XmRImmediate, (XtPointer) MARGIN_DEFAULT
103 },
104
105 { XmNmarginHeight,
106 XmCMarginHeight, XmRVerticalDimension, sizeof (Dimension),
107 XtOffsetOf(XmDrawingAreaRec, drawing_area.margin_height),
108 XmRImmediate, (XtPointer) MARGIN_DEFAULT
109 },
110
111 { XmNresizeCallback,
112 XmCCallback, XmRCallback, sizeof (XtCallbackList),
113 XtOffsetOf(XmDrawingAreaRec, drawing_area.resize_callback),
114 XmRImmediate, (XtPointer) NULL
115 },
116
117 { XmNexposeCallback,
118 XmCCallback, XmRCallback, sizeof (XtCallbackList),
119 XtOffsetOf(XmDrawingAreaRec, drawing_area.expose_callback),
120 XmRImmediate, (XtPointer) NULL
121 },
122
123 { XmNinputCallback,
124 XmCCallback, XmRCallback, sizeof (XtCallbackList),
125 XtOffsetOf(XmDrawingAreaRec, drawing_area.input_callback),
126 XmRImmediate, (XtPointer) NULL
127 },
128 #ifndef XM_PART_BC
129 { XmNconvertCallback,
130 XmCCallback, XmRCallback, sizeof (XtCallbackList),
131 XtOffsetOf(XmDrawingAreaRec, drawing_area.convert_callback),
132 XmRImmediate, (XtPointer) NULL
133 },
134
135 { XmNdestinationCallback,
136 XmCCallback, XmRCallback, sizeof (XtCallbackList),
137 XtOffsetOf(XmDrawingAreaRec, drawing_area.destination_callback),
138 XmRImmediate, (XtPointer) NULL
139 },
140 #endif
141
142 { XmNresizePolicy,
143 XmCResizePolicy, XmRResizePolicy, sizeof (unsigned char),
144 XtOffsetOf(XmDrawingAreaRec, drawing_area.resize_policy),
145 XmRImmediate, (XtPointer) XmRESIZE_ANY
146 },
147
148 };
149
150
151 static XmSyntheticResource syn_resources[] =
152 {
153 { XmNmarginWidth,
154 sizeof (Dimension),
155 XtOffsetOf(XmDrawingAreaRec, drawing_area.margin_width),
156 XmeFromHorizontalPixels, XmeToHorizontalPixels
157 },
158
159 { XmNmarginHeight,
160 sizeof (Dimension),
161 XtOffsetOf(XmDrawingAreaRec, drawing_area.margin_height),
162 XmeFromVerticalPixels, XmeToVerticalPixels
163 },
164 };
165
166
167
168 /****************************************************************
169 *
170 * Full class record constant
171 *
172 ****************************************************************/
173
174 static XmBaseClassExtRec baseClassExtRec = {
175 NULL,
176 NULLQUARK,
177 XmBaseClassExtVersion,
178 sizeof(XmBaseClassExtRec),
179 NULL, /* InitializePrehook */
180 NULL, /* SetValuesPrehook */
181 NULL, /* InitializePosthook */
182 NULL, /* SetValuesPosthook */
183 NULL, /* secondaryObjectClass */
184 NULL, /* secondaryCreate */
185 NULL, /* getSecRes data */
186 { 0 }, /* fastSubclass flags */
187 NULL, /* getValuesPrehook */
188 NULL, /* getValuesPosthook */
189 NULL, /* classPartInitPrehook */
190 NULL, /* classPartInitPosthook*/
191 NULL, /* ext_resources */
192 NULL, /* compiled_ext_resources*/
193 0, /* num_ext_resources */
194 FALSE, /* use_sub_resources */
195 WidgetNavigable, /* widgetNavigable */
196 NULL /* focusChange */
197 };
198
199 externaldef( xmdrawingareaclassrec) XmDrawingAreaClassRec
200 xmDrawingAreaClassRec =
201 {
202 { /* core_class fields */
203 (WidgetClass) &xmManagerClassRec, /* superclass */
204 "XmDrawingArea", /* class_name */
205 sizeof(XmDrawingAreaRec), /* widget_size */
206 ClassInitialize, /* class_initialize */
207 ClassPartInitialize, /* class_part_init */
208 FALSE, /* class_inited */
209 Initialize, /* initialize */
210 NULL, /* initialize_hook */
211 XtInheritRealize, /* realize */
212 actionsList, /* actions */
213 XtNumber(actionsList), /* num_actions */
214 resources, /* resources */
215 XtNumber(resources), /* num_resources */
216 NULLQUARK, /* xrm_class */
217 TRUE, /* compress_motion */
218 FALSE, /* compress_exposure */
219 TRUE, /* compress_enterlv */
220 FALSE, /* visible_interest */
221 NULL, /* destroy */
222 Resize, /* resize */
223 Redisplay, /* expose */
224 SetValues, /* set_values */
225 NULL, /* set_values_hook */
226 XtInheritSetValuesAlmost, /* set_values_almost */
227 NULL, /* get_values_hook */
228 NULL, /* accept_focus */
229 XtVersion, /* version */
230 NULL, /* callback_private */
231 defaultTranslations, /* tm_table */
232 QueryGeometry, /* query_geometry */
233 NULL, /* display_accelerator*/
234 (XtPointer)&baseClassExtRec, /* extension */
235 },
236 { /* composite_class fields */
237 GeometryManager, /* geometry_manager */
238 ChangeManaged, /* change_managed */
239 XtInheritInsertChild, /* insert_child */
240 XtInheritDeleteChild, /* delete_child */
241 NULL, /* extension */
242 },
243
244 { /* constraint_class fields */
245 NULL, /* resource list */
246 0, /* num resources */
247 sizeof(XmManagerConstraintRec), /* constraint size */
248 NULL, /* init proc */
249 NULL, /* destroy proc */
250 NULL, /* set values proc */
251 NULL, /* extension */
252 },
253
254 { /* manager_class fields */
255 traversalTranslations, /* translations */
256 syn_resources, /* syn_resources */
257 XtNumber (syn_resources), /* num_get_resources */
258 NULL, /* syn_cont_resources */
259 0, /* num_get_cont_resources */
260 XmInheritParentProcess, /* parent_process */
261 NULL, /* extension */
262 },
263
264 { /* drawingArea class */
265 (XtPointer) NULL, /* extension pointer */
266 }
267 };
268
269 externaldef( xmdrawingareawidgetclass) WidgetClass xmDrawingAreaWidgetClass
270 = (WidgetClass) &xmDrawingAreaClassRec ;
271
272
273
274 /****************************************************************/
275 static void
ClassInitialize(void)276 ClassInitialize( void )
277 {
278 baseClassExtRec.record_type = XmQmotif ;
279 }
280
281
282 /****************************************************************/
283 static void
ClassPartInitialize(WidgetClass w_class)284 ClassPartInitialize(
285 WidgetClass w_class )
286 {
287
288 _XmFastSubclassInit( w_class, XmDRAWING_AREA_BIT) ;
289
290 }
291
292
293 /****************************************************************
294 * Initialize. Check resizePolicy resource value
295 ****************/
296 /*ARGSUSED*/
297 static void
Initialize(Widget rw,Widget nw,ArgList args,Cardinal * num_args)298 Initialize(
299 Widget rw, /* unused */
300 Widget nw,
301 ArgList args, /* unused */
302 Cardinal *num_args ) /* unused */
303 {
304 XmDrawingAreaWidget new_w = (XmDrawingAreaWidget) nw ;
305
306 if(new_w->drawing_area.resize_policy != XmRESIZE_SWINDOW
307 && !XmRepTypeValidValue(XmRID_RESIZE_POLICY,
308 new_w->drawing_area.resize_policy,
309 (Widget) new_w) ) {
310 new_w->drawing_area.resize_policy = XmRESIZE_ANY ;
311 }
312 }
313
314
315
316 /****************************************************************
317 * General redisplay function called on exposure events.
318 ****************/
319 static void
Redisplay(Widget wid,XEvent * event,Region region)320 Redisplay(
321 Widget wid,
322 XEvent *event,
323 Region region )
324 {
325 XmDrawingAreaWidget da = (XmDrawingAreaWidget) wid ;
326 XmDrawingAreaCallbackStruct cb;
327 /****************/
328
329 cb.reason = XmCR_EXPOSE;
330 cb.event = event;
331 cb.window = XtWindow (da);
332
333 XtCallCallbackList ((Widget) da, da->drawing_area.expose_callback, &cb);
334
335 XmeRedisplayGadgets( (Widget) da, event, region);
336 }
337
338
339 /****************************************************************
340 * Invoke the application resize callbacks.
341 ****************/
342 static void
Resize(Widget wid)343 Resize(
344 Widget wid )
345 {
346 XmDrawingAreaWidget da = (XmDrawingAreaWidget) wid ;
347 XmDrawingAreaCallbackStruct cb;
348
349 cb.reason = XmCR_RESIZE;
350 cb.event = NULL;
351 cb.window = XtWindow (da);
352
353 XtCallCallbackList ((Widget) da, da->drawing_area.resize_callback, &cb);
354 }
355
356 static Widget
ObjectAtPoint(Widget wid,Position x,Position y)357 ObjectAtPoint(
358 Widget wid,
359 Position x,
360 Position y )
361 {
362 CompositeWidget cw = (CompositeWidget) wid ;
363 register int i;
364 register Widget widget;
365
366 i = cw->composite.num_children ;
367 while( i-- ) {
368 widget = cw->composite.children[i];
369
370 /* do not care for gadget only for the DA input */
371 if (XmIsGadget(widget) && XtIsManaged (widget)) {
372 if (x >= widget->core.x && y >= widget->core.y &&
373 x < widget->core.x + widget->core.width &&
374 y < widget->core.y + widget->core.height)
375 return (widget);
376 }
377 }
378
379 return (NULL);
380 }
381
382
383 /****************************************************************
384 * This function processes key and button presses and releases
385 * belonging to the DrawingArea.
386 ****************/
387 /*ARGSUSED*/
388 void
_XmDrawingAreaInput(Widget wid,XEvent * event,String * params,Cardinal * num_params)389 _XmDrawingAreaInput(
390 Widget wid,
391 XEvent *event,
392 String *params, /* unused */
393 Cardinal *num_params ) /* unused */
394 {
395 XmDrawingAreaWidget da = (XmDrawingAreaWidget) wid ;
396 XmDrawingAreaCallbackStruct cb ;
397 int x, y ;
398 Boolean button_event = True, input_on_gadget ;
399
400 if ((event->type == ButtonPress) ||
401 (event->type == ButtonRelease)) {
402 x = event->xbutton.x ;
403 y = event->xbutton.y ;
404 } else
405 if (event->type == MotionNotify) {
406 x = event->xmotion.x ;
407 y = event->xmotion.y ;
408 } else
409 if ((event->type == KeyPress) ||
410 (event->type == KeyRelease)) {
411 x = event->xkey.x ;
412 y = event->xkey.y ;
413 button_event = False ;
414 } else return ;
415 /* Unrecognized event (cannot determine x, y of pointer).*/
416
417 input_on_gadget = (ObjectAtPoint((Widget)da, x, y) != NULL);
418
419 if (!input_on_gadget && (!da->manager.active_child || button_event)) {
420 cb.reason = XmCR_INPUT ;
421 cb.event = event ;
422 cb.window = XtWindow( da) ;
423 XtCallCallbackList ((Widget) da,
424 da->drawing_area.input_callback, &cb) ;
425
426 }
427 }
428
429
430 /****************************************************************/
431 static XtGeometryResult
GeometryManager(Widget w,XtWidgetGeometry * request,XtWidgetGeometry * reply)432 GeometryManager(
433 Widget w,
434 XtWidgetGeometry *request,
435 XtWidgetGeometry *reply )
436 {
437 XmDrawingAreaWidget da;
438 /* XtGeometryHandler manager ; */
439 /****************/
440
441 da = (XmDrawingAreaWidget) w->core.parent;
442
443 /* function shared with Bulletin Board */
444 return(_XmGMHandleGeometryManager((Widget)da, w, request, reply,
445 da->drawing_area.margin_width,
446 da->drawing_area.margin_height,
447 da->drawing_area.resize_policy,
448 True)); /* no overlap checking */
449 }
450
451 /****************************************************************
452 * Re-layout children.
453 ****************/
454 static void
ChangeManaged(Widget wid)455 ChangeManaged(
456 Widget wid )
457 {
458 XmDrawingAreaWidget da = (XmDrawingAreaWidget) wid ;
459
460 /* function shared with Bulletin Board */
461 _XmGMEnforceMargin((XmManagerWidget)da,
462 da->drawing_area.margin_width,
463 da->drawing_area.margin_height,
464 False); /* use movewidget, not setvalue */
465
466 /* The first time, reconfigure only if explicit size were not given */
467
468 if (XtIsRealized((Widget)da) || (!XtWidth(da)) || (!XtHeight(da))) {
469
470 /* function shared with Bulletin Board */
471 (void)_XmGMDoLayout((XmManagerWidget)da,
472 da->drawing_area.margin_width,
473 da->drawing_area.margin_height,
474 da->drawing_area.resize_policy,
475 False); /* queryonly not specified */
476 }
477
478 XmeNavigChangeManaged((Widget) da) ;
479 }
480
481 /****************************************************************/
482 /*ARGSUSED*/
483 static Boolean
SetValues(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * num_args)484 SetValues(
485 Widget cw,
486 Widget rw, /* unused */
487 Widget nw,
488 ArgList args, /* unused */
489 Cardinal *num_args ) /* unused */
490 {
491 XmDrawingAreaWidget current = (XmDrawingAreaWidget) cw ;
492 XmDrawingAreaWidget new_w = (XmDrawingAreaWidget) nw ;
493
494 if(new_w->drawing_area.resize_policy != XmRESIZE_SWINDOW
495 && !XmRepTypeValidValue(XmRID_RESIZE_POLICY,
496 new_w->drawing_area.resize_policy,
497 (Widget) new_w) ) {
498 new_w->drawing_area.resize_policy =
499 current->drawing_area.resize_policy ;
500 }
501
502
503 /* If new margins, re-enforce them using movewidget,
504 then update the width and height so that XtSetValues does
505 the geometry request */
506 if (XtIsRealized((Widget) new_w) &&
507 (((new_w->drawing_area.margin_width !=
508 current->drawing_area.margin_width) ||
509 (new_w->drawing_area.margin_height !=
510 current->drawing_area.margin_height)))) {
511
512 /* move the child around if necessary */
513 _XmGMEnforceMargin((XmManagerWidget)new_w,
514 new_w->drawing_area.margin_width,
515 new_w->drawing_area.margin_height,
516 False); /* use movewidget, no request */
517 _XmGMCalcSize ((XmManagerWidget)new_w,
518 new_w->drawing_area.margin_width,
519 new_w->drawing_area.margin_height,
520 &new_w->core.width, &new_w->core.height);
521 }
522
523 return( False) ;
524 }
525
526
527 /****************************************************************
528 * Handle query geometry requests
529 ****************/
530 static XtGeometryResult
QueryGeometry(Widget wid,XtWidgetGeometry * intended,XtWidgetGeometry * desired)531 QueryGeometry(
532 Widget wid,
533 XtWidgetGeometry *intended,
534 XtWidgetGeometry *desired )
535 {
536 XmDrawingAreaWidget da = (XmDrawingAreaWidget) wid ;
537
538 /* function shared with Bulletin Board */
539 return(_XmGMHandleQueryGeometry(wid, intended, desired,
540 da->drawing_area.margin_width,
541 da->drawing_area.margin_height,
542 da->drawing_area.resize_policy));
543 }
544
545
546 /****************************************************************
547 * Xm private class method
548 ****************/
549
550
551 static XmNavigability
WidgetNavigable(Widget wid)552 WidgetNavigable(
553 Widget wid)
554 {
555 if( XtIsSensitive(wid)
556 && ((XmManagerWidget) wid)->manager.traversal_on )
557 {
558 XmNavigationType nav_type = ((XmManagerWidget) wid)
559 ->manager.navigation_type ;
560 Widget *children = ((XmManagerWidget) wid)->composite.children ;
561 unsigned idx = 0 ;
562
563 /* If a Drawing Area has a navigable child, and initial focus
564 is either NULL or point to this child, allow navigation to it.
565 */
566 while(idx < ((XmManagerWidget) wid)->composite.num_children) {
567 if (_XmGetNavigability(children[idx]) &&
568 ((((XmManagerWidget) wid)->manager.initial_focus == NULL) ||
569 (((XmManagerWidget) wid)->manager.initial_focus ==
570 children[idx]))){
571 if( (nav_type == XmSTICKY_TAB_GROUP)
572 || (nav_type == XmEXCLUSIVE_TAB_GROUP)
573 || ( (nav_type == XmTAB_GROUP)
574 && !_XmShellIsExclusive( wid))) {
575 return XmDESCENDANTS_TAB_NAVIGABLE ;
576 }
577 return XmDESCENDANTS_NAVIGABLE ;
578 }
579 ++idx ;
580 }
581
582 /* else just return the DA itself */
583
584 if( (nav_type == XmSTICKY_TAB_GROUP)
585 || (nav_type == XmEXCLUSIVE_TAB_GROUP)
586 || ( (nav_type == XmTAB_GROUP)
587 && !_XmShellIsExclusive( wid)) )
588 {
589 return XmTAB_NAVIGABLE ;
590 }
591 return XmCONTROL_NAVIGABLE ;
592 }
593 return XmNOT_NAVIGABLE ;
594 }
595
596
597
598
599 /****************************************************************
600 * This function creates and returns a DrawingArea widget.
601 ****************/
602 Widget
XmCreateDrawingArea(Widget p,String name,ArgList args,Cardinal n)603 XmCreateDrawingArea(
604 Widget p,
605 String name,
606 ArgList args,
607 Cardinal n )
608 {
609 /****************/
610
611 return( XtCreateWidget( name, xmDrawingAreaWidgetClass, p, args, n)) ;
612 }
613
614 Widget
XmVaCreateDrawingArea(Widget parent,char * name,...)615 XmVaCreateDrawingArea(
616 Widget parent,
617 char *name,
618 ...)
619 {
620 register Widget w;
621 va_list var;
622 int count;
623
624 Va_start(var,name);
625 count = XmeCountVaListSimple(var);
626 va_end(var);
627
628
629 Va_start(var, name);
630 w = XmeVLCreateWidget(name,
631 xmDrawingAreaWidgetClass,
632 parent, False,
633 var, count);
634 va_end(var);
635 return w;
636 }
637
638 Widget
XmVaCreateManagedDrawingArea(Widget parent,char * name,...)639 XmVaCreateManagedDrawingArea(
640 Widget parent,
641 char *name,
642 ...)
643 {
644 Widget w = NULL;
645 va_list var;
646 int count;
647
648 Va_start(var, name);
649 count = XmeCountVaListSimple(var);
650 va_end(var);
651
652 Va_start(var, name);
653 w = XmeVLCreateWidget(name,
654 xmDrawingAreaWidgetClass,
655 parent, True,
656 var, count);
657 va_end(var);
658 return w;
659 }
660