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