1 /*****************************************************************************
2  ** File          : display.c                                               **
3  ** Purpose       : Initialise and Realise display and query dialogs        **
4  ** Author        : Edward Groenendaal                                      **
5  ** Date          : July 1991                                               **
6  ** Documentation : Xdtm Design Folder                                      **
7  ** Related Files :                                                         **
8  ** Changes       : 30.3.92 eddyg - Took out the seggie stuff around the    **
9  **                 view file option.					    **
10  **                 18-04-92, Edward Groenendaal                            **
11  **                 Added the #if NeedFunctionPrototypes stuff              **
12  **                 June 20, 1992, Ramon Santiago                           **
13  **                 Changed all XtCreate calls to XtVaCreate calls.         **
14  **                 Changed all caddr_t to XtPointer.                       **
15  **                 Removed some lint.                                      **
16  *****************************************************************************/
17 
18 #include "xdtm.h"
19 
20 #ifndef TRUE_SYSV
21 #include <sys/file.h>    /* For access(2) */
22 #endif
23 
24 #include <X11/Shell.h>
25 #include <X11/Xaw/Label.h>
26 #include <X11/Xaw/Command.h>
27 #include <X11/Xaw/AsciiText.h>
28 #include "Xedw/XedwForm.h"
29 
30 /* Structure used to pass back the id's of the display popup's */
31 typedef struct widgets {
32   Widget popup;
33   Widget save;
34   Widget text;
35   Widget query;
36 } widgets;
37 
38 /* external and forward functions definitions */
39 extern void realize_dialog(
40 #if NeedFunctionPrototypes
41     Widget, Widget, XtGrabKind, XtEventHandler, XtPointer
42 #endif
43 );
44 extern Widget topLevel;
45 
46 public String viewfile;
47 
48 /*****************************************************************************
49  *                              init_display                                 *
50  *****************************************************************************/
51 /*ARGSUSED*/
init_display(top)52 public void init_display(top)
53 Widget top;
54 {
55   /* This procedure has been made redundant, the popup's are created
56      dynamically which is slower - but enables multiple instances. */
57 }
58 
59 /*****************************************************************************
60  *                        displaytext_callback                               *
61  *****************************************************************************/
62 #if NeedFunctionPrototypes
displaytext_callback(Widget w,widgets * display_widgets)63 void displaytext_callback(Widget w, widgets *display_widgets)
64 #else
65 void displaytext_callback(w, display_widgets)
66      Widget w;
67      widgets *display_widgets;
68 #endif
69 {
70   XtVaSetValues(
71       display_widgets->save,
72           XtNsensitive, True,
73 	  NULL ) ;
74 
75   XtRemoveCallback(w, XtNcallback, (XtCallbackProc)displaytext_callback,
76 		   display_widgets);
77 }
78 
79 /*****************************************************************************
80  *                                destroy_query                              *
81  *****************************************************************************/
82 /*ARGSUSED*/
destroy_query(w,display_widgets)83 private void destroy_query(w, display_widgets)
84 Widget w ;
85 widgets *display_widgets ;
86 {
87   /* Cancel was selected.. so just destroy the query NOT the edit popup*/
88 
89   XtDestroyWidget(display_widgets->query);
90   display_widgets->query = NULL;
91 }
92 
93 /*****************************************************************************
94  *                                destroy_view                               *
95  *****************************************************************************/
96 /*ARGSUSED*/
destroy_view(w,destroyer)97 private void destroy_view(w, destroyer)
98 Widget w ;
99 widgets *destroyer ;
100 {
101   if (destroyer->query == NULL) {
102     if (destroyer->save != NULL) {
103       /* An edit widget, check to see if a save is needed, if text is NULL
104        * we have already been called and the result was to DIE!
105        */
106       Widget wd=NULL;
107 
108       XtVaGetValues(
109           destroyer->text,
110 	      XtNtextSource, &wd,
111 	      NULL ) ;
112 
113       if (XawAsciiSourceChanged(wd) == True) {
114 	/* Make a query dialog */
115 	Widget querypopup;
116 	Widget queryform;
117 	Widget querylabel;
118 	Widget queryquit;
119 	Widget querycancel;
120 
121 	querypopup =
122 	  XtVaCreatePopupShell(
123 	      "Query",
124 	      transientShellWidgetClass,
125 	      topLevel,
126 	          NULL ) ;
127 
128 	queryform =
129 	  XtVaCreateManagedWidget(
130 	      "queryform",
131 	      xedwFormWidgetClass,
132 	      querypopup,
133 	          NULL ) ;
134 
135 	querylabel =
136 	  XtVaCreateManagedWidget(
137 	      "querylabel",
138 	      labelWidgetClass,
139 	      queryform,
140 	          XtNlabel, "File not saved! Quit anyway?",
141 		  XtNborderWidth,                        0,
142 		  XtNjustify,              XtJustifyCenter,
143 		  XtNfullWidth,                       True,
144 		  NULL ) ;
145 
146 	queryquit =
147 	  XtVaCreateManagedWidget(
148 	      "queryquit",
149 	      commandWidgetClass,
150 	      queryform,
151 	          XtNlabel,            "Quit",
152 		  XtNfromVert,     querylabel,
153 		  XtNjustify, XtJustifyCenter,
154 		  NULL ) ;
155 
156         querycancel =
157 	  XtVaCreateManagedWidget(
158 	      "querycancel",
159 	      commandWidgetClass,
160 	      queryform,
161 	          XtNlabel,          "Cancel",
162 		  XtNfromVert,     querylabel,
163 		  XtNfromHoriz,     queryquit,
164 		  XtNjustify, XtJustifyCenter,
165 		  NULL ) ;
166 
167 	destroyer->query = querypopup;
168 	XtAddCallback(queryquit,   XtNcallback, (XtCallbackProc)destroy_view,
169 		      (XtPointer)destroyer);
170 	XtAddCallback(querycancel, XtNcallback, (XtCallbackProc)destroy_query,
171 		      (XtPointer)destroyer);
172 
173 	realize_dialog(querypopup, destroyer->popup, XtGrabNonexclusive,
174 		       NULL, NULL);
175       } else {
176 	XtDestroyWidget(destroyer->popup);
177 	XtFree((char *)destroyer);
178       }
179     } else {
180       XtDestroyWidget(destroyer->popup);
181       XtFree((char *)destroyer);
182     }
183   } else {
184     /* We are returning after a 'are you sure you want to quit without saving'
185      * dialog box. Stop editing file.
186      */
187     XtDestroyWidget(destroyer->query);
188     XtDestroyWidget(destroyer->popup);
189     XtFree((char *)destroyer);
190   }
191 }
192 
193 /*****************************************************************************
194  *                              WM_destroy_view                              *
195  *****************************************************************************/
196 #if NeedFunctionPrototypes
WM_destroy_view(Widget w,XtPointer client_data,XEvent * event,Boolean * dispatch)197 private void WM_destroy_view(Widget w, XtPointer client_data,
198 				   XEvent *event, Boolean *dispatch)
199 #else
200 private void WM_destroy_view(w, client_data, event, dispatch)
201      Widget w;
202      XtPointer client_data;
203      XEvent *event;
204      Boolean *dispatch;
205 #endif
206 {
207     extern Atom protocols[2]; /* defined in dialogs.c */
208 
209     if (event->xclient.message_type == protocols[1] &&
210 	event->xclient.data.l[0] == protocols[0])
211     /* the widget got a kill signal */
212     {
213 	/* Directly call callback of `Quit' button */
214 	destroy_view(w, (Widget *)client_data);
215     }
216 }
217 
218 /*****************************************************************************
219  *                              destroy_popup                                *
220  *****************************************************************************/
221 /*ARGSUSED*/
destroy_popup(w,killme)222 private void destroy_popup(w, killme)
223 Widget w, killme;
224 {
225   XtDestroyWidget(killme);
226 }
227 
228 /*****************************************************************************
229  *                              alert_dialog                                 *
230  *****************************************************************************/
alert_dialog(label1,label2,buttonlabel)231 public void alert_dialog(label1, label2, buttonlabel)
232 String label1, label2, buttonlabel;
233 {
234 
235   Widget alertpopup;
236   Widget alertform;
237   Widget alertlabel1;
238   Widget alertlabel2 = (Widget) NULL;
239   Widget alertbutton;
240 
241   private String QueryYes = "OK";
242 
243   alertpopup =
244     XtVaCreatePopupShell(
245         "alertDialog",
246 	transientShellWidgetClass,
247 	topLevel,
248 	    NULL ) ;
249 
250   alertform =
251     XtVaCreateManagedWidget(
252 	"alertform",
253 	xedwFormWidgetClass,
254 	alertpopup,
255 	    NULL ) ;
256 
257   if (label1) {
258     alertlabel1 =
259       XtVaCreateManagedWidget(
260           "alertlabel1",
261 	  labelWidgetClass,
262 	  alertform,
263 	      XtNlabel,            label1,
264 	      XtNborderWidth,           0,
265 	      XtNjustify, XtJustifyCenter,
266 	      XtNfullWidth,          True,
267 	      NULL ) ;
268   } else {
269     fprintf(stderr, "xdtm: Programmer is a forgetfull idiot\n");
270     return;
271   }
272 
273   if (label2) {
274     alertlabel2 =
275       XtVaCreateManagedWidget(
276           "alertlabel2",
277 	  labelWidgetClass,
278 	  alertform,
279 	      XtNlabel,            label2,
280 	      XtNborderWidth,           0,
281 	      XtNjustify, XtJustifyCenter,
282 	      XtNfullWidth,          True,
283 	      XtNfromVert,    alertlabel1,
284 	      NULL ) ;
285   }
286 
287   alertbutton =
288     XtVaCreateManagedWidget(
289         "alertbutton",
290 	commandWidgetClass,
291 	alertform,
292 	    XtNlabel, (buttonlabel) ? buttonlabel : QueryYes,
293 	    XtNfromVert,  (label2) ? alertlabel2 : alertlabel1,
294 	    XtNjustify, XtJustifyCenter,
295 	    XtNfullWidth,          True,
296 	    NULL ) ;
297 
298   XtAddCallback(alertbutton, XtNcallback, (XtCallbackProc)destroy_popup,
299 		(XtPointer)alertpopup);
300 
301   if (app_data.bellonwarn) {
302       XBell(XtDisplay(alertpopup), 100);
303       XBell(XtDisplay(alertpopup), 100);
304   }
305 
306   realize_dialog(alertpopup, NULL, XtGrabNonexclusive, NULL, NULL);
307 }
308 
309 /*****************************************************************************
310  *                              displayfile                                  *
311  *****************************************************************************/
displayfile(fullname,searchto,title,grab_kind)312 public void displayfile(fullname, searchto, title, grab_kind)
313 String fullname, searchto, title;
314 XtGrabKind grab_kind;
315 {
316   /* This procedure popup's a window with the file 'fullname' contained
317    * within a text widget. When quit is selected the window is popped down.
318    *
319    * - Takes the name of the file to be viewed
320    * - Takes a string to position the initial view.
321    * - Takes a title for the window.
322    */
323 
324   Widget view_popup;
325   Widget form;
326   Widget quit_button;
327   Widget filename_label;
328   Widget view;
329   widgets *view_widgets;
330   int width, height;
331   XFontStruct *font=app_data.view_font;
332 
333   view_popup =
334     XtVaCreatePopupShell(
335         "xdtm: view file",
336 	topLevelShellWidgetClass,
337 	topLevel,
338 	    NULL ) ;
339 
340   form =
341     XtVaCreateManagedWidget(
342 	"form",
343 	xedwFormWidgetClass,
344 	view_popup,
345             XtNbottom, XtChainBottom,
346             XtNtop,       XtChainTop,
347             XtNleft,     XtChainLeft,
348             XtNright,   XtChainRight,
349             XtNhorizDistance,      5,
350             XtNvertDistance,       5,
351 	    NULL ) ;
352 
353   quit_button =
354     XtVaCreateManagedWidget(
355         "quit_button",
356 	commandWidgetClass,
357 	form,
358 	    XtNlabel,       "Quit",
359 	    XtNrubberWidth,  False,
360 	    XtNrubberHeight, False,
361             XtNresizable,    False,
362             XtNtop,     XtChainTop,
363             XtNbottom,  XtChainBottom,
364             XtNleft,    XtChainLeft,
365             XtNright,   XtChainRight,
366 	    NULL ) ;
367 
368   filename_label =
369     XtVaCreateManagedWidget(
370         "filename_label",
371 	labelWidgetClass,
372 	form,
373 	    XtNlabel, ((title != NULL) ? title : fullname),
374 	    XtNfromHoriz, quit_button,
375 	    XtNfullWidth, True,
376 	    XtNrubberHeight, False,
377             XtNtop,     XtChainTop,
378             XtNbottom,  XtChainBottom,
379             XtNleft,    XtChainLeft,
380             XtNright,   XtChainRight,
381 	    NULL ) ;
382 
383   /* Work out the height and width of the text widget */
384 
385   width =  (font->max_bounds.width * app_data.view_width);
386   height = ((font->max_bounds.ascent +
387              font->max_bounds.descent) * app_data.view_height);
388 
389   view =
390     XtVaCreateManagedWidget(
391         "view",
392 	asciiTextWidgetClass,
393 	form,
394 	    XtNstring,           fullname,
395 	    XtNeditType,         XawtextRead,
396 	    XtNtype,             XawAsciiFile,
397 	    XtNscrollHorizontal, XawtextScrollWhenNeeded,
398 	    XtNscrollVertical,   XawtextScrollAlways,
399 	    XtNwidth,            width,
400 	    XtNheight,           height,
401 	    XtNfont,             app_data.view_font,
402 	    XtNfromVert,         filename_label,
403 	    XtNfullWidth,        True,
404 	    XtNfullHeight,       True,
405             XtNtop,     XtChainTop,
406             XtNbottom,  XtChainBottom,
407             XtNleft,    XtChainLeft,
408             XtNright,   XtChainRight,
409 	    NULL ) ;
410 
411   /* The search is used for displaying HELP files at the right point */
412   if (searchto) {
413     XawTextBlock searchfor;
414     XawTextPosition foundat;
415 
416     searchfor.firstPos = 0;
417     searchfor.ptr = searchto;
418     searchfor.length = strlen(searchto);
419     searchfor.format = FMT8BIT;
420     foundat = XawTextSearch(view, XawsdRight, &searchfor);
421     if (foundat == XawTextSearchError) {
422       char uh_oh[255];
423       sprintf(uh_oh, "Couldn't find section \"%s\"!", searchto);
424       alert_dialog(uh_oh, "in help file", NULL);
425     } else {
426       XtVaSetValues(
427           view,
428 	      XtNdisplayPosition, foundat,
429 	      NULL ) ;
430       XawTextSetSelection(view, foundat, foundat+strlen(searchto));
431     }
432   }
433 
434   view_widgets = (widgets*) XtMalloc(sizeof(widgets));
435   view_widgets->popup = view_popup;
436   view_widgets->save  = NULL;
437   view_widgets->text  = view;
438   view_widgets->query = NULL;
439   XtAddCallback(quit_button, XtNcallback, (XtCallbackProc)destroy_view,
440 		(XtPointer)view_widgets);
441 
442   realize_dialog(view_popup, NULL, grab_kind,
443 		 (XtEventHandler)WM_destroy_view, (XtPointer)view_widgets);
444 
445 }
446 
447 /*****************************************************************************
448  *                               save_contents                               *
449  *****************************************************************************/
450 /*ARGSUSED*/
save_contents(w,edit_widgets)451 private void save_contents(w, edit_widgets)
452 Widget w;
453 widgets *edit_widgets;
454 {
455   Widget wd=0;
456   extern Cursor busy, left_ptr;
457 
458   XtVaSetValues(
459       edit_widgets->popup,
460           XtNcursor, busy,
461 	  NULL ) ;
462 
463   XtVaGetValues(
464       edit_widgets->text,
465           XtNtextSource,&wd,
466 	  NULL ) ;
467 
468   XawAsciiSave(wd);
469   XtSetSensitive(edit_widgets->save, False);
470 
471   XtAddCallback(wd, XtNcallback, (XtCallbackProc)displaytext_callback, (XtPointer)edit_widgets);
472 
473   XtVaSetValues(
474       edit_widgets->popup,
475           XtNcursor, left_ptr,
476 	  NULL ) ;
477 }
478 
479 /*****************************************************************************
480  *                              Editfile                                     *
481  *****************************************************************************/
editfile(fullname)482 public void editfile(fullname)
483 String fullname;
484 {
485   Widget edit_popup;
486   Widget quit_button;
487   Widget save_button;
488   Widget form;
489   Widget editwidget;
490   Widget filename_label;
491   Widget wd = NULL;
492   widgets *edit_widgets;
493   int width, height;
494   XFontStruct *font=app_data.view_font;
495 
496   /* We shall assume that the file IS writable */
497 
498   edit_popup =
499     XtVaCreatePopupShell(
500         "xdtm: edit file",
501 	topLevelShellWidgetClass,
502 	topLevel,
503 	    NULL ) ;
504 
505   form =
506     XtVaCreateManagedWidget(
507 	"form",
508 	xedwFormWidgetClass,
509 	edit_popup,
510             XtNhorizDistance,      5,
511             XtNvertDistance,       5,
512             XtNbottom, XtChainBottom,
513             XtNtop,       XtChainTop,
514             XtNleft,     XtChainLeft,
515             XtNright,   XtChainRight,
516 	    NULL ) ;
517 
518   quit_button =
519     XtVaCreateManagedWidget(
520         "quit_button",
521 	commandWidgetClass,
522 	form,
523 	    XtNlabel, "Quit",
524 	    XtNrubberWidth, False,
525 	    XtNrubberHeight, False,
526             XtNbottom, XtChainBottom,
527             XtNtop,       XtChainTop,
528             XtNleft,     XtChainLeft,
529             XtNright,   XtChainRight,
530 	    NULL ) ;
531 
532   save_button =
533     XtVaCreateManagedWidget(
534         "save_button",
535 	commandWidgetClass,
536 	form,
537 	    XtNfromHoriz,   quit_button,
538 	    XtNlabel,       "Save",
539 	    XtNrubberWidth, False,
540 	    XtNrubberHeight, False,
541 	    XtNsensitive,    False,
542             XtNbottom, XtChainBottom,
543             XtNtop,       XtChainTop,
544             XtNleft,     XtChainLeft,
545             XtNright,   XtChainRight,
546 	    NULL ) ;
547 
548   filename_label =
549     XtVaCreateManagedWidget(
550         "filename_label",
551         labelWidgetClass,
552 	form,
553 	    XtNlabel,     fullname, /* Could put editing: filename here instead */
554 	    XtNfromHoriz, save_button,
555 	    XtNfullWidth, True,
556 	    XtNrubberHeight, False,
557             XtNbottom, XtChainBottom,
558             XtNtop,       XtChainTop,
559             XtNleft,     XtChainLeft,
560             XtNright,   XtChainRight,
561 	    NULL ) ;
562 
563   width =  (font->max_bounds.width * app_data.view_width);
564   height = ((font->max_bounds.ascent +
565              font->max_bounds.descent) * app_data.view_height);
566 
567   editwidget =
568     XtVaCreateManagedWidget(
569         "editwidget",
570 	asciiTextWidgetClass,
571 	form,
572 	    XtNstring,           fullname,
573 	    XtNeditType,         XawtextEdit,
574 	    XtNtype,             XawAsciiFile,
575 	    XtNscrollHorizontal, XawtextScrollWhenNeeded,
576 	    XtNscrollVertical,   XawtextScrollAlways,
577 	    XtNwidth,            width,
578 	    XtNheight,           height,
579 	    XtNfont,             app_data.view_font,
580 	    XtNfromVert,         filename_label,
581 	    XtNfullWidth,        True,
582             XtNbottom, XtChainBottom,
583             XtNtop,       XtChainTop,
584             XtNleft,     XtChainLeft,
585             XtNright,   XtChainRight,
586 	    NULL ) ;
587 
588   XtVaGetValues(
589       editwidget,
590           XtNtextSource,&wd,
591 	  NULL ) ;
592 
593   edit_widgets = (widgets*) XtMalloc(sizeof(widgets));
594   edit_widgets->popup = edit_popup;
595   edit_widgets->save  = save_button;
596   edit_widgets->text  = editwidget;
597   edit_widgets->query = NULL;
598 
599   XtAddCallback(save_button, XtNcallback, (XtCallbackProc)save_contents,
600 		(XtPointer)edit_widgets);
601   XtAddCallback(quit_button, XtNcallback, (XtCallbackProc)destroy_view,
602 		(XtPointer)edit_widgets);
603   XtAddCallback(wd, XtNcallback, (XtCallbackProc)displaytext_callback,
604 		(XtPointer)edit_widgets);
605 
606   realize_dialog(edit_popup, NULL, XtGrabNone,
607 		 (XtEventHandler)WM_destroy_view, (XtPointer)edit_widgets);
608 }
609