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