1 # include "appFrameConfig.h"
2
3 # include <stdlib.h>
4 # include <stdio.h>
5
6 # include "appFrame.h"
7 # include "appGuiBase.h"
8 # include "guiWidgets.h"
9 # include "guiWidgetsImpl.h"
10
11 # include <appDebugon.h>
12
13 # ifdef USE_MOTIF
14
15 # include <X11/Xatom.h>
16 # include <Xm/RowColumn.h>
17 # include <Xm/Label.h>
18 # include <Xm/ToggleB.h>
19 # include <Xm/PanedW.h>
20 # include <Xm/MwmUtil.h>
21 # include <Xm/Protocols.h>
22 # include <Xm/DrawnB.h>
23 # include <Xm/Separator.h>
24 # include <Xm/ScrollBar.h>
25 # include <Xm/DrawingA.h>
26
27 /************************************************************************/
28 /* */
29 /* Destroy all children of a widget. */
30 /* */
31 /* 1) Unmanaging should be done by the Xt toolkit but is not always */
32 /* done correctly. Doing it here does no harm anyway. */
33 /* */
34 /************************************************************************/
35
appEmptyParentWidget(Widget parent)36 void appEmptyParentWidget( Widget parent )
37 {
38 WidgetList children;
39 WidgetList save;
40 Cardinal childCount;
41
42 XtVaGetValues( parent,
43 XmNchildren, &children,
44 XmNnumChildren, &childCount,
45 NULL );
46
47 if ( childCount == 0 )
48 { return; }
49
50 /* 1 */
51 XtUnmanageChildren( children, childCount );
52
53 save= (WidgetList)malloc( childCount* sizeof(Widget) );
54 if ( save )
55 {
56 int i;
57
58 for ( i= childCount- 1; i >= 0; i-- )
59 { save[i]= children[i]; }
60
61 for ( i= childCount- 1; i >= 0; i-- )
62 { XtDestroyWidget( save[i] ); }
63
64 free( save );
65 }
66
67 return;
68 }
69
70 /************************************************************************/
71 /* */
72 /* Use the text of an option and the name of the application as a */
73 /* widget title. */
74 /* */
75 /************************************************************************/
76
appSetShellTitle(APP_WIDGET shell,Widget option,const char * applicationName)77 void appSetShellTitle( APP_WIDGET shell,
78 Widget option,
79 const char * applicationName )
80 {
81 char * title;
82
83 if ( option )
84 {
85 char * s;
86
87 s= appGetTextFromMenuOption( option );
88
89 title= (char *)malloc( strlen( applicationName )+ 1+ strlen( s )+ 1 );
90 sprintf( title, "%s %s", applicationName, s );
91
92 appFreeTextFromMenuOption( s );
93 }
94 else{ title= strdup( applicationName ); }
95
96 XtVaSetValues( shell,
97 XmNtitle, title,
98 NULL );
99
100 free( title );
101 }
102
103 /************************************************************************/
104 /* */
105 /* 1) Remember te initial size of a shell as its minimum size. */
106 /* */
107 /* 2) Remember te initial size of a shell as its minimum and its */
108 /* maximum size. This event handler can be used to prevent the */
109 /* user from resizing a dialog. E.G. because KDE does not listen */
110 /* to the window manager hints about this. On the other hand some */
111 /* window managers (mwm on vms!) cause this event handler to be */
112 /* called too early. That results in dialogs that are MUCH too */
113 /* small. */
114 /* */
115 /************************************************************************/
116
117 /* 1 */
appSetSizeAsMinimum(Widget w,void * through,XEvent * event,Boolean * pRefused)118 void appSetSizeAsMinimum( Widget w,
119 void * through,
120 XEvent * event,
121 Boolean * pRefused )
122 {
123 XConfigureEvent * cevent= &(event->xconfigure);
124
125 if ( cevent->type != ConfigureNotify )
126 { return; }
127
128 XtVaSetValues( w, XmNminWidth, cevent->width,
129 XmNminHeight, cevent->height,
130 NULL );
131
132 XtRemoveEventHandler( w, StructureNotifyMask, False,
133 appSetSizeAsMinimum, through );
134
135 *pRefused= 1;
136
137 return;
138 }
139
140 /* 2 */
141 # define FIX_SIZE 0
142 # if FIX_SIZE
appFixSize(Widget w,void * through,XEvent * event,Boolean * pRefused)143 static void appFixSize( Widget w,
144 void * through,
145 XEvent * event,
146 Boolean * pRefused )
147 {
148 XConfigureEvent * cevent= &(event->xconfigure);
149
150 if ( cevent->type != ConfigureNotify )
151 { return; }
152
153 XtVaSetValues( w, XmNminWidth, cevent->width,
154 XmNmaxWidth, cevent->width,
155 XmNminHeight, cevent->height,
156 XmNmaxHeight, cevent->height,
157 NULL );
158
159 XtRemoveEventHandler( w, StructureNotifyMask, False,
160 appFixSize, through );
161
162 *pRefused= 1;
163
164 return;
165 }
166 # endif
167
168 /************************************************************************/
169 /* */
170 /* Names of the X11 events. */
171 /* */
172 /************************************************************************/
173
174 const char * const APP_X11EventNames[]=
175 {
176 "0", "1", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
177 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
178 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
179 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
180 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
181 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
182 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
183 "ClientMessage", "MappingNotify"
184 };
185
186
appMakeToggleInRow(APP_WIDGET row,const char * text,APP_TOGGLE_CALLBACK_T callback,void * through,int col,int colspan)187 APP_WIDGET appMakeToggleInRow( APP_WIDGET row,
188 const char * text,
189 APP_TOGGLE_CALLBACK_T callback,
190 void * through,
191 int col,
192 int colspan )
193 {
194 Arg al[20];
195 int ac= 0;
196
197 XmString labelString;
198 Widget toggle;
199
200 if ( ! text )
201 { text= ""; }
202
203 labelString= XmStringCreateLocalized( (char *)text );
204
205 ac= 0;
206 XtSetArg( al[ac], XmNlabelString, labelString ); ac++;
207 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
208 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
209 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_POSITION ); ac++;
210 XtSetArg( al[ac], XmNleftPosition, col ); ac++;
211 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_POSITION ); ac++;
212 XtSetArg( al[ac], XmNrightPosition, col+ colspan ); ac++;
213
214 XtSetArg( al[ac], XmNtopOffset, 0 ); ac++;
215 XtSetArg( al[ac], XmNbottomOffset, 0 ); ac++;
216 XtSetArg( al[ac], XmNleftOffset, 0 ); ac++;
217 XtSetArg( al[ac], XmNrightOffset, 0 ); ac++;
218
219 XtSetArg( al[ac], XmNrecomputeSize, True ); ac++;
220
221 XtSetArg( al[ac], XmNmarginTop, TBrmargT ); ac++;
222
223 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_BEGINNING ); ac++;
224
225 toggle= XmCreateToggleButton( row, WIDGET_NAME, al, ac );
226
227 if ( callback )
228 { XtAddCallback( toggle, XmNvalueChangedCallback, callback, through ); }
229
230 XmStringFree( labelString );
231
232 XtManageChild( toggle );
233
234 return toggle;
235 }
236
appMakeImageInColumn(APP_WIDGET * pLabel,APP_WIDGET column,APP_BITMAP_IMAGE pixmap,APP_BITMAP_MASK mask)237 void appMakeImageInColumn( APP_WIDGET * pLabel,
238 APP_WIDGET column,
239 APP_BITMAP_IMAGE pixmap,
240 APP_BITMAP_MASK mask )
241 {
242 Widget label;
243
244 Arg al[20];
245 int ac= 0;
246
247 ac= 0;
248 XtSetArg( al[ac], XmNlabelType, XmPIXMAP ); ac++;
249 XtSetArg( al[ac], XmNskipAdjust, True ); ac++;
250 XtSetArg( al[ac], XmNrecomputeSize, True ); ac++;
251 XtSetArg( al[ac], XmNallowResize, True ); ac++;
252 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_BEGINNING ); ac++;
253
254 XtSetArg( al[ac], XmNlabelPixmap, pixmap ); ac++;
255
256 label= XmCreateLabel( column, WIDGET_NAME, al, ac );
257
258 XtManageChild( label );
259
260 appMotifTurnOfSashTraversal( column );
261
262 *pLabel= label; return;
263 }
264
appMakeColumnToggle(Widget * pToggle,Widget column,XtCallbackProc callback,void * through,const char * labelText,int set)265 void appMakeColumnToggle( Widget * pToggle,
266 Widget column,
267 XtCallbackProc callback,
268 void * through,
269 const char * labelText,
270 int set )
271 {
272 Widget toggle;
273
274 XmString labelString= (XmString)0;
275
276 Arg al[20];
277 int ac= 0;
278
279 if ( labelText )
280 { labelString= XmStringCreateLocalized( (char *)labelText ); }
281
282 ac= 0;
283 XtSetArg( al[ac], XmNskipAdjust, True ); ac++;
284 XtSetArg( al[ac], XmNrecomputeSize, True ); ac++;
285 XtSetArg( al[ac], XmNalignment, XmALIGNMENT_BEGINNING ); ac++;
286 XtSetArg( al[ac], XmNset, set ); ac++;
287
288 XtSetArg( al[ac], XmNmarginTop, TBcmargT ); ac++;
289 XtSetArg( al[ac], XmNmarginHeight, TBcmargH ); ac++;
290
291 if ( labelString )
292 { XtSetArg( al[ac], XmNlabelString, labelString ); ac++; }
293
294 toggle= XmCreateToggleButton( column, WIDGET_NAME, al, ac );
295
296 if ( callback )
297 { XtAddCallback( toggle, XmNvalueChangedCallback, callback, through ); }
298
299 if ( labelString )
300 { XmStringFree( labelString ); }
301
302 XtManageChild( toggle );
303
304 *pToggle= toggle;
305 }
306
appMakeColumnDrawing(Widget * pButton,Widget column,XtCallbackProc exposeCallback,XtCallbackProc pushedCallback,void * through,int width)307 void appMakeColumnDrawing( Widget * pButton,
308 Widget column,
309 XtCallbackProc exposeCallback,
310 XtCallbackProc pushedCallback,
311 void * through,
312 int width )
313 {
314 Widget button;
315
316 Arg al[20];
317 int ac= 0;
318
319 XmString labelString= XmStringCreateLocalized( (char *)" " );
320
321 ac= 0;
322 XtSetArg( al[ac], XmNskipAdjust, True ); ac++;
323 XtSetArg( al[ac], XmNrecomputeSize, True ); ac++;
324 XtSetArg( al[ac], XmNwidth, width ); ac++;
325
326 XtSetArg( al[ac], XmNmarginTop, 1 ); ac++;
327 XtSetArg( al[ac], XmNmarginHeight, 4 ); ac++;
328
329 XtSetArg( al[ac], XmNlabelString, labelString ); ac++;
330
331 button= XmCreateDrawnButton( column, WIDGET_NAME, al, ac );
332
333 if ( exposeCallback )
334 {
335 XtAddCallback( button, XmNexposeCallback, exposeCallback, through );
336 }
337
338 if ( pushedCallback )
339 {
340 XtAddCallback( button, XmNactivateCallback, pushedCallback, through );
341 }
342
343 XtManageChild( button );
344
345 XmStringFree( labelString );
346
347 *pButton= button;
348 }
349
350 /************************************************************************/
351 /* */
352 /* Make a tool with a vertical organisation. */
353 /* */
354 /************************************************************************/
355
appMakeVerticalTool(APP_WIDGET * pShell,APP_WIDGET * pPaned,EditApplication * ea,APP_BITMAP_IMAGE iconPixmap,APP_BITMAP_MASK iconMask,int userResizable,APP_WIDGET option,APP_CLOSE_CALLBACK_T closeCallback,void * through)356 void appMakeVerticalTool( APP_WIDGET * pShell,
357 APP_WIDGET * pPaned,
358 EditApplication * ea,
359 APP_BITMAP_IMAGE iconPixmap,
360 APP_BITMAP_MASK iconMask,
361 int userResizable,
362 APP_WIDGET option,
363 APP_CLOSE_CALLBACK_T closeCallback,
364 void * through )
365 {
366 Widget shell;
367 Widget paned;
368
369 Arg al[20];
370 int ac= 0;
371
372 MwmHints hints;
373
374 hints.flags= MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS;
375
376 hints.functions= MWM_FUNC_MOVE |
377 MWM_FUNC_MINIMIZE |
378 MWM_FUNC_CLOSE ;
379 hints.decorations= MWM_DECOR_BORDER |
380 MWM_DECOR_TITLE |
381 MWM_DECOR_MENU |
382 MWM_DECOR_MINIMIZE ;
383
384 if ( userResizable )
385 {
386 hints.functions |= MWM_FUNC_RESIZE;
387 hints.decorations |= MWM_DECOR_RESIZEH;
388 }
389
390 ac=0;
391 XtSetArg( al[ac], XmNdeleteResponse, XmDO_NOTHING ); ac++;
392 XtSetArg( al[ac], XmNinput, True ); ac++;
393 XtSetArg( al[ac], XmNallowShellResize, True ); ac++;
394 XtSetArg( al[ac], XmNuseAsyncGeometry, True ); ac++;
395 XtSetArg( al[ac], XmNwaitForWm, False ); ac++; /* LessTif BUG */
396 XtSetArg( al[ac], XmNwmTimeout, 0 ); ac++; /* LessTif BUG */
397 XtSetArg( al[ac], XmNmwmDecorations, hints.decorations ); ac++;
398 XtSetArg( al[ac], XmNmwmFunctions, hints.functions ); ac++;
399
400 if ( iconPixmap )
401 { XtSetArg( al[ac], XmNiconPixmap, iconPixmap ); ac++; }
402
403 # ifdef USE_X11_R5
404 shell= XtAppCreateShell( ea->eaApplicationName, WIDGET_NAME,
405 applicationShellWidgetClass,
406 XtDisplay( ea->eaToplevel.atTopWidget ), al, ac );
407 # else
408 shell= XtAppCreateShell( ea->eaApplicationName, WIDGET_NAME,
409 topLevelShellWidgetClass,
410 XtDisplay( ea->eaToplevel.atTopWidget ), al, ac );
411 # endif
412
413 XtAddEventHandler( shell, StructureNotifyMask, False,
414 appSetSizeAsMinimum, through );
415
416 appSetShellTitle( shell, option, ea->eaApplicationName );
417
418 # if FIX_SIZE
419 See above.
420 if ( ! userResizable )
421 {
422 XtAddEventHandler( shell, StructureNotifyMask, False,
423 appFixSize, through );
424 }
425 # endif
426
427 appSetCloseCallback( shell, ea, closeCallback, through );
428
429 ac= 0;
430 XtSetArg( al[ac], XmNsashWidth, 1 ); ac++;
431 XtSetArg( al[ac], XmNsashHeight, 1 ); ac++;
432 XtSetArg( al[ac], XmNseparatorOn, False ); ac++;
433 XtSetArg( al[ac], XmNmarginWidth, PWmargW ); ac++;
434 XtSetArg( al[ac], XmNmarginHeight, PWmargH ); ac++;
435 XtSetArg( al[ac], XmNspacing, PWspacing ); ac++;
436 paned= XmCreatePanedWindow( shell, WIDGET_NAME, al, ac );
437
438 XtManageChild( paned );
439
440 *pShell= shell, *pPaned= paned; return;
441 }
442
443 /************************************************************************/
444 /* */
445 /* For debugging purposes: Give widgets a name of the form file(line) */
446 /* for where they are made. */
447 /* */
448 /************************************************************************/
449
appWidgetName(char * file,int line)450 char * appWidgetName( char * file,
451 int line )
452 {
453 static char ** names;
454 static int nameCount;
455
456 char ** freshNames;
457 char * freshName;
458
459 int i;
460
461 freshNames= (char **)realloc( names, ( nameCount+ 1 )* sizeof(char *) );
462 if ( ! freshNames )
463 { XDEB(freshNames); return file; }
464 names= freshNames;
465
466 freshName= (char *)malloc( strlen( file )+ 11 );
467 if ( ! freshName )
468 { XDEB(freshName); return file; }
469
470 sprintf( freshName, "%s(%d)", file, line );
471
472 for ( i= 0; i < nameCount; freshNames++, i++ )
473 {
474 if ( ! strcmp( freshNames[0], freshName ) )
475 { free( freshName ); return freshNames[0]; }
476 }
477
478 names[nameCount++]= freshName;
479
480 return freshName;
481 }
482
483 /************************************************************************/
484 /* */
485 /* Insert a column in a top level widget (Window) */
486 /* */
487 /************************************************************************/
488
appGuiInsertColumnInWindow(APP_WIDGET * pColumn,APP_WIDGET parent)489 void appGuiInsertColumnInWindow( APP_WIDGET * pColumn,
490 APP_WIDGET parent )
491 {
492 APP_WIDGET column;
493
494 Arg al[20];
495 int ac= 0;
496
497 ac= 0;
498 XtSetArg( al[ac], XmNsashWidth, 1 ); ac++;
499 XtSetArg( al[ac], XmNsashHeight, 1 ); ac++;
500 XtSetArg( al[ac], XmNseparatorOn, False ); ac++;
501 XtSetArg( al[ac], XmNmarginWidth, 0 ); ac++;
502 XtSetArg( al[ac], XmNmarginHeight, 0 ); ac++;
503 XtSetArg( al[ac], XmNspacing, 0 ); ac++;
504
505 column= XmCreatePanedWindow( parent, WIDGET_NAME, al, ac );
506
507 XtManageChild( column );
508
509 *pColumn= column; return;
510 }
511
512 /************************************************************************/
513 /* */
514 /* Insert a menubar as the first row of a column. */
515 /* */
516 /************************************************************************/
517
appGuiInsertMenubarInColumn(APP_WIDGET * pMenubar,APP_WIDGET parent)518 void appGuiInsertMenubarInColumn( APP_WIDGET * pMenubar,
519 APP_WIDGET parent )
520 {
521 Widget menuBar;
522
523 Arg al[20];
524 int ac= 0;
525
526 ac= 0;
527 XtSetArg( al[ac], XmNskipAdjust, True ); ac++;
528 XtSetArg( al[ac], XmNallowResize, True ); ac++;
529 XtSetArg( al[ac], XmNtraversalOn, False ); ac++;
530 XtSetArg( al[ac], XmNresizeHeight, True ); ac++;
531
532 menuBar= XmCreateMenuBar( parent, WIDGET_NAME, al, ac );
533
534 XtManageChild( menuBar );
535
536 *pMenubar= menuBar; return;
537 }
538
539 /************************************************************************/
540 /* */
541 /* Insert a separator as a row of a column. */
542 /* */
543 /************************************************************************/
544
appGuiInsertSeparatorInColumn(APP_WIDGET * pSeparator,APP_WIDGET column)545 void appGuiInsertSeparatorInColumn( APP_WIDGET * pSeparator,
546 APP_WIDGET column )
547 {
548 Arg al[20];
549 int ac= 0;
550
551 *pSeparator= XmCreateSeparator( column, WIDGET_NAME, al, ac );
552
553 XtManageChild( *pSeparator );
554
555 return;
556 }
557
558 /************************************************************************/
559 /* */
560 /* Change the label/state of a toggle button. */
561 /* */
562 /************************************************************************/
563
appGuiSetToggleLabel(APP_WIDGET toggle,const char * text)564 void appGuiSetToggleLabel( APP_WIDGET toggle,
565 const char * text )
566 {
567 XmString labelString;
568
569 labelString= XmStringCreateLocalized( (char *)text );
570 XtVaSetValues( toggle,
571 XmNlabelString, labelString,
572 NULL );
573
574 XmStringFree( labelString );
575 }
576
appGuiSetToggleState(APP_WIDGET toggle,int set)577 void appGuiSetToggleState( APP_WIDGET toggle,
578 int set )
579 {
580 XmToggleButtonSetState( toggle, set != 0, False );
581 }
582
appGuiGetToggleState(APP_WIDGET toggle)583 int appGuiGetToggleState( APP_WIDGET toggle )
584 {
585 return XmToggleButtonGetState( toggle ) != 0;
586 }
587
appGuiGetToggleStateFromCallbackMotif(void * voidcbs)588 int appGuiGetToggleStateFromCallbackMotif( void * voidcbs )
589 {
590 XmToggleButtonCallbackStruct * cbs;
591
592 cbs= (XmToggleButtonCallbackStruct *)voidcbs;
593
594 return cbs->set;
595 }
596
597 /************************************************************************/
598 /* */
599 /* Enable/Disable a widget. */
600 /* */
601 /* NOTE that for text edit boxes there is a different routine. */
602 /* */
603 /************************************************************************/
604
guiEnableWidget(APP_WIDGET w,int on_off)605 void guiEnableWidget( APP_WIDGET w,
606 int on_off )
607 {
608 XtSetSensitive( w, on_off != 0 );
609 }
610
appGuiSetWidgetVisible(APP_WIDGET w,int on_off)611 void appGuiSetWidgetVisible( APP_WIDGET w,
612 int on_off )
613 {
614 APP_WIDGET parent= XtParent( w );
615
616 XtVaSetValues( w, XmNmappedWhenManaged, on_off != 0,
617 NULL );
618
619 if ( parent && XmIsRowColumn( parent ) )
620 {
621 if ( on_off )
622 { XtManageChild( w ); }
623 else{ XtUnmanageChild( w ); }
624 }
625 }
626
627 /************************************************************************/
628 /* */
629 /* Show a shell widget. Because of the RIDICULOUS and ABSURD situation */
630 /* the you cannot rely on a shell window to be visible after we tell */
631 /* it to become visible, we handle a series of events in a loop until */
632 /* it becomes visible. */
633 /* */
634 /************************************************************************/
635
appShowShellWidget(EditApplication * ea,APP_WIDGET shell)636 void appShowShellWidget( EditApplication * ea,
637 APP_WIDGET shell )
638 {
639 XtRealizeWidget( shell );
640
641 XtVaSetValues( shell, XmNinitialState, NormalState, NULL );
642 XtMapWidget( shell );
643 XRaiseWindow( XtDisplay( shell ), XtWindow( shell ) );
644
645 XSync( XtDisplay( shell ), False );
646
647 appGuiMotifWaitForWindow( shell, ea->eaContext );
648 }
649
650 /************************************************************************/
651 /* */
652 /* Hide a shell widget. Because of the RIDICULOUS and ABSURD situation */
653 /* */
654 /************************************************************************/
655
appHideShellWidget(APP_WIDGET shell)656 void appHideShellWidget( APP_WIDGET shell )
657 {
658 if ( XtIsRealized( shell ) )
659 { XtUnmapWidget( shell ); }
660 }
661
appDestroyShellWidget(APP_WIDGET shell)662 void appDestroyShellWidget( APP_WIDGET shell )
663 {
664 XtDestroyWidget( shell );
665 }
666
appGuiGetScrollbarValues(int * pValue,int * pSliderSize,APP_WIDGET scrollbar)667 void appGuiGetScrollbarValues( int * pValue,
668 int * pSliderSize,
669 APP_WIDGET scrollbar )
670 {
671 XtVaGetValues( scrollbar,
672 XmNvalue, pValue,
673 XmNsliderSize, pSliderSize,
674 NULL );
675 return;
676 }
677
appGuiSetScrollbarValues(APP_WIDGET scrollbar,int value,int sliderSize)678 void appGuiSetScrollbarValues( APP_WIDGET scrollbar,
679 int value,
680 int sliderSize )
681 {
682 const Boolean notify= False;
683
684 XmScrollBarSetValues( scrollbar, value, sliderSize, 0,0, notify );
685
686 return;
687 }
688
appGuiGetScrollbarValueFromCallback(APP_WIDGET scrollbar,void * voidcbs)689 int appGuiGetScrollbarValueFromCallback( APP_WIDGET scrollbar,
690 void * voidcbs )
691 {
692 XmScrollBarCallbackStruct * cbs= (XmScrollBarCallbackStruct *)voidcbs;
693
694 return cbs->value;
695 }
696
697 /************************************************************************/
698 /* */
699 /* Set the title of the window. */
700 /* */
701 /* See http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html */
702 /* for a better way: set _NET_WM_NAME to an UTF-8 value. */
703 /* */
704 /************************************************************************/
705
appGuiSetShellTitle(APP_WIDGET shell,const MemoryBuffer * fullTitle)706 void appGuiSetShellTitle( APP_WIDGET shell,
707 const MemoryBuffer * fullTitle )
708 {
709 XtVaSetValues( shell,
710 XmNtitle, utilMemoryBufferGetString( fullTitle ),
711 NULL );
712
713 return;
714 }
715
appGuiSetIconTitle(APP_WIDGET shell,const MemoryBuffer * iconName)716 void appGuiSetIconTitle( APP_WIDGET shell,
717 const MemoryBuffer * iconName )
718 {
719 XtVaSetValues( shell,
720 XmNiconName, utilMemoryBufferGetString( iconName ),
721 NULL );
722
723 return;
724 }
725
726 /************************************************************************/
727 /* */
728 /* Make drawing areas. Typically these are small drawings so it does */
729 /* no harm to redraw the whole drawing area after a resize. */
730 /* */
731 /************************************************************************/
732
appGuiSendExposeForResize(APP_WIDGET w,void * through,void * voidcbs)733 static void appGuiSendExposeForResize( APP_WIDGET w,
734 void * through,
735 void * voidcbs )
736 {
737 if ( XtIsRealized( w ) )
738 {
739 XClearArea( XtDisplay( w ), XtWindow( w ), 0, 0, 0, 0, True );
740 }
741 }
742
appGuiMakeDrawingAreaInColumn(APP_WIDGET * pDrawing,APP_WIDGET column,int wide,int high,int heightResizable,APP_EVENT_HANDLER_T redraw,void * through)743 void appGuiMakeDrawingAreaInColumn( APP_WIDGET * pDrawing,
744 APP_WIDGET column,
745 int wide,
746 int high,
747 int heightResizable,
748 APP_EVENT_HANDLER_T redraw,
749 void * through )
750 {
751 APP_WIDGET drawing;
752
753 Arg al[20];
754 int ac;
755
756 /*
757 XtSetArg( al[ac], XmNsensitive, False ); ac++;
758 */
759
760 ac= 0;
761 if ( high > 0 )
762 {
763 XtSetArg( al[ac], XmNheight, high ); ac++;
764 }
765
766 if ( high <= 0 || heightResizable )
767 { XtSetArg( al[ac], XmNskipAdjust, False ); ac++; }
768 else{ XtSetArg( al[ac], XmNskipAdjust, True ); ac++; }
769
770 if ( wide > 0 )
771 {
772 XtSetArg( al[ac], XmNwidth, wide ); ac++;
773 }
774 XtSetArg( al[ac], XmNtraversalOn, False ); ac++;
775 XtSetArg( al[ac], XmNnavigationType, XmNONE ); ac++;
776
777 drawing= XmCreateDrawingArea( column, WIDGET_NAME, al, ac );
778
779 if ( redraw )
780 {
781 XtAddEventHandler( drawing, ExposureMask, False, redraw, through );
782 }
783
784 XtAddCallback( drawing, XmNresizeCallback, appGuiSendExposeForResize,
785 (void *)0 );
786
787 XtManageChild( drawing );
788
789 *pDrawing= drawing;
790 }
791
792 /************************************************************************/
793 /* */
794 /* Calculate magnification factors. */
795 /* */
796 /************************************************************************/
797
appGetPixelsPerTwip(EditApplication * ea)798 void appGetPixelsPerTwip( EditApplication * ea )
799 {
800 # if 0
801 Display * display= XtDisplay( ea->eaToplevel.atTopWidget );
802 int screen= DefaultScreen( display );
803
804 double horPixPerMM;
805 double verPixPerMM;
806 double xfac;
807 double yfac;
808
809 horPixPerMM= ( (double)DisplayWidth( display, screen ) )/
810 DisplayWidthMM( display, screen );
811 verPixPerMM= ( (double)DisplayHeight( display, screen ) )/
812 DisplayHeightMM( display, screen );
813
814 xfac= ( 25.4/ ( 20.0* 72.0 ) )* horPixPerMM;
815 yfac= ( 25.4/ ( 20.0* 72.0 ) )* verPixPerMM;
816
817 ea->eaPixelsPerTwip= xfac;
818 # else
819 ea->eaPixelsPerTwip= 96.0/ ( 20* 72 );
820 # endif
821
822 return;
823 }
824
825 /************************************************************************/
826 /* */
827 /* Run a loop while the left mouse button is down. */
828 /* */
829 /************************************************************************/
830
831 typedef struct DragLoop
832 {
833 XtAppContext dlContext;
834
835 XtEventHandler dlUpHandler;
836 XtEventHandler dlMoveHandler;
837 int dlTimerInterval;
838 XtTimerCallbackProc dlTimerHandler;
839 void * dlThrough;
840
841 int dlHalted;
842 XtIntervalId dlIntervalId;
843 } DragLoop;
844
appDragTick(void * vdl,XtIntervalId * xii)845 static void appDragTick( void * vdl,
846 XtIntervalId * xii )
847 {
848 DragLoop * dl= (DragLoop *)vdl;
849
850 (*dl->dlTimerHandler)( dl->dlThrough, xii );
851
852 if ( dl->dlTimerHandler && dl->dlTimerInterval > 0 )
853 {
854 dl->dlIntervalId= XtAppAddTimeOut( dl->dlContext,
855 dl->dlTimerInterval, appDragTick, (void *)dl );
856 }
857 return;
858 }
859
appDragMouseUp(APP_WIDGET w,void * vdl,APP_EVENT * event,Boolean * pRefused)860 static void appDragMouseUp( APP_WIDGET w,
861 void * vdl,
862 APP_EVENT * event,
863 Boolean * pRefused )
864 {
865 DragLoop * dl= (DragLoop *)vdl;
866
867 if ( dl->dlUpHandler )
868 { (*dl->dlUpHandler)( w, dl->dlThrough, event, pRefused ); }
869
870 dl->dlHalted= 1;
871 }
872
873 /************************************************************************/
874 /* */
875 /* Handle a movement event, but as an optimization ignore it if the */
876 /* next even is a similar one: Apparently we are running after the */
877 /* mouse. */
878 /* */
879 /************************************************************************/
880
appDragMouseMove(APP_WIDGET w,void * vdl,APP_EVENT * event,Boolean * pRefused)881 static void appDragMouseMove( APP_WIDGET w,
882 void * vdl,
883 APP_EVENT * event,
884 Boolean * pRefused )
885 {
886 DragLoop * dl= (DragLoop *)vdl;
887 Display * display= XtDisplay( w );
888
889 if ( QLength( display ) > 0 )
890 {
891 XEvent nextEvent;
892
893 XPeekEvent( display, &nextEvent );
894
895 if ( nextEvent.type == event->type &&
896 nextEvent.xmotion.window == event->xmotion.window )
897 { return; }
898 }
899
900 if ( dl->dlMoveHandler )
901 { (*dl->dlMoveHandler)( w, dl->dlThrough, event, pRefused ); }
902 }
903
appRunDragLoop(APP_WIDGET w,EditApplication * ea,APP_EVENT * downEvent,APP_EVENT_HANDLER_T upHandler,APP_EVENT_HANDLER_T moveHandler,int timerInterval,APP_TIMER_CALLBACK timerHandler,void * through)904 void appRunDragLoop( APP_WIDGET w,
905 EditApplication * ea,
906 APP_EVENT * downEvent,
907 APP_EVENT_HANDLER_T upHandler,
908 APP_EVENT_HANDLER_T moveHandler,
909 int timerInterval,
910 APP_TIMER_CALLBACK timerHandler,
911 void * through )
912 {
913 DragLoop dl;
914
915 dl.dlContext= ea->eaContext;
916
917 dl.dlUpHandler= upHandler;
918 dl.dlMoveHandler= moveHandler;
919 dl.dlTimerInterval= timerInterval;
920 dl.dlTimerHandler= timerHandler;
921 dl.dlThrough= through;
922
923 dl.dlHalted= 0;
924 dl.dlIntervalId= (XtIntervalId)0;
925
926 if ( dl.dlTimerHandler && dl.dlTimerInterval > 0 )
927 {
928 dl.dlIntervalId= XtAppAddTimeOut( dl.dlContext,
929 dl.dlTimerInterval, appDragTick, (void *)&dl );
930 }
931
932 XtInsertEventHandler( w, ButtonReleaseMask, False,
933 appDragMouseUp, (void *)&dl, XtListHead );
934 XtInsertEventHandler( w, Button1MotionMask, False,
935 appDragMouseMove, (void *)&dl, XtListHead );
936
937 while( ! dl.dlHalted )
938 { XtAppProcessEvent( dl.dlContext, XtIMAll ); }
939
940 if ( dl.dlIntervalId )
941 { XtRemoveTimeOut( dl.dlIntervalId ); }
942
943 XtRemoveEventHandler( w, ButtonReleaseMask, False,
944 appDragMouseUp, (void *)&dl );
945 XtRemoveEventHandler( w, Button1MotionMask, False,
946 appDragMouseMove, (void *)&dl );
947 return;
948 }
949
appGuiSetFocusChangeHandler(APP_WIDGET w,APP_EVENT_HANDLER_T handler,void * through)950 void appGuiSetFocusChangeHandler( APP_WIDGET w,
951 APP_EVENT_HANDLER_T handler,
952 void * through )
953 {
954 XtAddEventHandler( w, FocusChangeMask, False, handler, through );
955 }
956
appSetDestroyCallback(APP_WIDGET shell,APP_DESTROY_CALLBACK_T destroyCallback,void * through)957 void appSetDestroyCallback( APP_WIDGET shell,
958 APP_DESTROY_CALLBACK_T destroyCallback,
959 void * through )
960 {
961 if ( destroyCallback )
962 {
963 XtAddCallback( shell, XmNdestroyCallback,
964 destroyCallback, through );
965 }
966 }
967
appSetCloseCallback(APP_WIDGET shell,EditApplication * ea,APP_CLOSE_CALLBACK_T closeCallback,void * through)968 void appSetCloseCallback( APP_WIDGET shell,
969 EditApplication * ea,
970 APP_CLOSE_CALLBACK_T closeCallback,
971 void * through )
972 {
973 if ( closeCallback && ea->eaCloseAtom > 0 )
974 {
975 XtVaSetValues( shell,
976 XmNdeleteResponse, XmDO_NOTHING,
977 NULL );
978
979 XmAddWMProtocolCallback( shell, ea->eaCloseAtom,
980 closeCallback, through );
981 }
982 }
983
appGuiFocusToWidget(APP_WIDGET w)984 void appGuiFocusToWidget( APP_WIDGET w )
985 {
986 XmProcessTraversal( w, XmTRAVERSE_CURRENT );
987 }
988
989 /************************************************************************/
990 /* */
991 /* Cope with stubborn fluxbox. */
992 /* */
993 /************************************************************************/
994
appGuiMotifSetFocusToWindow(APP_WIDGET w)995 void appGuiMotifSetFocusToWindow( APP_WIDGET w )
996 {
997 XWindowAttributes xwa;
998
999 if ( ! XtIsRealized( w ) )
1000 { return; }
1001
1002 XGetWindowAttributes( XtDisplay( w ), XtWindow( w ), &xwa );
1003
1004 if ( xwa.map_state != IsViewable )
1005 { return; }
1006
1007 XSetInputFocus( XtDisplay( w ), XtWindow( w ), RevertToNone, CurrentTime );
1008 }
1009
appGuiMotifWaitForWindow(APP_WIDGET shell,XtAppContext context)1010 void appGuiMotifWaitForWindow( APP_WIDGET shell,
1011 XtAppContext context )
1012 {
1013 const int eventCount= 350;
1014 int i;
1015
1016 for ( i= 0; i < eventCount; i++ )
1017 {
1018 if ( XtIsRealized( shell ) )
1019 {
1020 XWindowAttributes xwa;
1021
1022 XGetWindowAttributes( XtDisplay( shell ), XtWindow( shell ), &xwa );
1023 if ( xwa.map_state != IsUnmapped )
1024 { break; }
1025 }
1026
1027 XtAppProcessEvent( context, XtIMAll );
1028 }
1029
1030 if ( i >= eventCount )
1031 { LDEB(i); }
1032
1033 return;
1034 }
1035
1036 # ifdef XP_PRINTNAME
1037 # ifdef FAKE_XP
1038
XpGetContext(Display * display)1039 XPContext XpGetContext( Display * display )
1040 { return (XPContext)0; }
1041
XpGetOneAttribute(Display * display,XPContext context,XPAttributes type,char * attribute_name)1042 char *XpGetOneAttribute( Display * display,
1043 XPContext context,
1044 XPAttributes type,
1045 char * attribute_name )
1046 { return "XpGetOneAttribute"; }
1047
XpSetImageResolution(Display * display,XPContext print_context,int image_res,int * prev_res_return)1048 Bool XpSetImageResolution( Display * display,
1049 XPContext print_context,
1050 int image_res,
1051 int * prev_res_return )
1052 { *prev_res_return= 100; return False; }
1053
XpQueryExtension(Display * display,int * event_base_return,int * error_base_return)1054 Bool XpQueryExtension( Display *display,
1055 int *event_base_return,
1056 int *error_base_return )
1057 { return False; }
1058
XpStartPage(Display * display,Window window)1059 void XpStartPage( Display *display,
1060 Window window )
1061 { return; }
1062
XpEndPage(Display * display)1063 void XpEndPage( Display *display )
1064 { return; }
1065
XpEndJob(Display * display)1066 void XpEndJob( Display *display )
1067 { return; }
1068
XpGetPageDimensions(Display * display,XPContext print_context,unsigned short * width,unsigned short * height,XRectangle * reproducible_area)1069 Status XpGetPageDimensions( Display *display,
1070 XPContext print_context,
1071 unsigned short *width,
1072 unsigned short *height,
1073 XRectangle *reproducible_area )
1074 { return 0; }
1075
XpGetScreenOfContext(Display * display,XPContext print_context)1076 Screen *XpGetScreenOfContext ( Display *display,
1077 XPContext print_context )
1078 { return (Screen *)0; }
1079
XpGetDocumentData(Display * data_display,XPContext context,XPSaveProc save_proc,XPFinishProc finish_proc,XPointer client_data)1080 Status XpGetDocumentData ( Display *data_display,
1081 XPContext context,
1082 XPSaveProc save_proc,
1083 XPFinishProc finish_proc,
1084 XPointer client_data )
1085 { return 0; }
1086
XpGetPdmStartParams(Display * print_display,Window print_window,XPContext print_context,Display * video_display,Window video_window,Display ** selection_display_return,Atom * selection_return,Atom * type_return,int * format_return,unsigned char ** data_return,int * nelements_return)1087 Status XpGetPdmStartParams ( Display *print_display,
1088 Window print_window,
1089 XPContext print_context,
1090 Display *video_display,
1091 Window video_window,
1092 Display **selection_display_return,
1093 Atom *selection_return,
1094 Atom *type_return,
1095 int *format_return,
1096 unsigned char **data_return,
1097 int *nelements_return )
1098 { return 0; }
1099
XpSelectInput(Display * display,XPContext context,unsigned long event_mask)1100 void XpSelectInput ( Display *display,
1101 XPContext context,
1102 unsigned long event_mask )
1103 { return; }
1104
1105 # endif /* FAKE_XP */
1106 # endif /* XP_PRINTNAME */
1107
1108 # endif
1109