Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtappbuilder / src / ab / ui_msg.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23
24 /*
25  *      $XConsortium: ui_msg.c /main/3 1995/11/06 17:56:14 rswiston $
26  *
27  * @(#)ui_msg.c 1.17 09 Mar 1995      cde_app_builder/src/ab
28  *
29  *      RESTRICTED CONFIDENTIAL INFORMATION:
30  *
31  *      The information in this document is subject to special
32  *      restrictions in a confidential disclosure agreement between
33  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34  *      document outside HP, IBM, Sun, USL, SCO, or Univel without
35  *      Sun's specific written approval.  This document and all copies
36  *      and derivative works thereof must be returned or destroyed at
37  *      Sun's request.
38  *
39  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40  *
41  */
42
43
44 /*
45  ***********************************************************************
46  * ui_msg.c - User-Interface MessageDialog support functions
47  *      
48  *
49  ***********************************************************************
50  */
51 #include <stdio.h>
52 #include <Xm/Xm.h>
53 #include <Xm/MessageB.h>
54 #include <Xm/SelectioB.h>
55 #include <Xm/PushB.h>
56 #include <Xm/TextF.h>
57 #include <ab_private/ab.h>
58 #include <ab_private/objxm.h>
59 #include <ab_private/ui_util.h>
60
61
62 /*************************************************************************
63 **                                                                      **
64 **       Private Function Declarations                                  **
65 **                                                                      **
66 **************************************************************************/
67
68 static Widget   create_message_dlg(
69                     Widget      parent,
70                     unsigned char dlg_type,
71                     STRING      title,
72                     STRING      msg,
73                     STRING      ok_label,
74                     STRING      cancel_label,
75                     STRING      help_label,
76                     unsigned char default_button_type
77                 );
78
79 static void     destroyCB(
80                     Widget      widget,
81                     XtPointer   client_data,
82                     XtPointer   call_data
83                 );
84 static void     modal_dlgCB(
85                     Widget      widget,
86                     XtPointer   client_data,
87                     XtPointer   call_data
88                 );
89
90 static Widget   create_prompt_dlg(
91                     Widget      parent,
92                     STRING      title,
93                     STRING      label,
94                     STRING      ok_label,
95                     STRING      cancel_label,
96                     STRING      help_label,
97                     unsigned char default_button_type
98                 );
99
100 static void     prompt_ok_modal_dlgCB(
101                     Widget                        widget,
102                     XtPointer                     client_data,
103                     XmSelectionBoxCallbackStruct  *call_data
104                 );
105 static void     prompt_cancel_modal_dlgCB(
106                     Widget                        widget,
107                     XtPointer                     client_data,
108                     XmSelectionBoxCallbackStruct  *call_data
109                 );
110 static void     prompt_close_modal_dlg(
111                     Widget      widget,
112                     XtPointer   client_data,
113                     XtPointer   call_data
114                 );
115
116 /*************************************************************************
117 **                                                                      **
118 **       Data                                                           **
119 **                                                                      **
120 **************************************************************************/
121
122 /*************************************************************************
123 **                                                                      **
124 **       Function Definitions                                           **
125 **                                                                      **
126 **************************************************************************/
127 /*
128  * Popup a simple InfoMessage Dialog with "OK" & "Help" 
129  * buttons (the dialog will be destroyed on pop-down)
130  */
131 void
132 ui_popup_info_message(
133     Widget      parent,
134     STRING      title,
135     STRING      msg
136 )
137 {
138     ui_popup_message(parent, XmDIALOG_INFORMATION, title, msg, 
139                         "OK", NULL, 
140                         NULL, NULL,
141                         "Help", NULL,
142                         XmDIALOG_OK_BUTTON);
143 }
144
145 /*
146  * Popup a Message Dialog
147  * (the dialog will be destroyed after popdown)
148  */
149 void
150 ui_popup_message(
151     Widget         parent,
152     unsigned char  msg_type,
153     STRING         title,
154     STRING         msg,
155     STRING         ok_label,
156     XtCallbackProc ok_callback,
157     STRING         cancel_label,
158     XtCallbackProc cancel_callback,
159     STRING         help_label,
160     XtCallbackProc help_callback,
161     unsigned char  default_button_type
162 )
163 {
164     Widget      msg_dlg;
165
166     msg_dlg = create_message_dlg(parent, msg_type, title, msg, 
167                                  ok_label, cancel_label, help_label,
168                                  default_button_type);
169
170     /* Add Callbacks if necessary */
171     if (ok_callback != NULL)
172         XtAddCallback(msg_dlg, XmNokCallback, ok_callback, NULL);
173     if (cancel_callback != NULL)
174         XtAddCallback(msg_dlg, XmNcancelCallback, cancel_callback, NULL);
175     if (help_callback != NULL)
176         XtAddCallback(msg_dlg, XmNhelpCallback, help_callback, NULL);
177
178     XtManageChild(msg_dlg);
179     ui_win_front(msg_dlg);
180  
181 }
182
183 /*
184  * Popup an Application-MODAL MessageDialog. 
185  * Return an "answer" corresponding to the Dialog Button
186  * that the user pressed:
187  *      UI_ANSWER_OK, UI_ANSWER_CANCEL, UI_ANSWER_HELP
188  */
189 UI_MODAL_ANSWER
190 ui_popup_modal_message(
191     Widget         parent,
192     unsigned char  msg_type,
193     STRING         title,
194     STRING         msg,
195     STRING         ok_label,
196     STRING         cancel_label,
197     STRING         help_label,
198     unsigned char  default_button_type,
199     Widget         *modal_dlg_pane_out_ptr
200 )
201 {
202     XtAppContext           app;
203     Widget                 modal_dlg_pane = NULL;
204     UI_MODAL_ANSWER        answer;
205     XtCallbackRec ok_callback[] = {
206             {(XtCallbackProc)modal_dlgCB, (XtPointer) UI_ANSWER_OK},
207             {(XtCallbackProc) NULL, (XtPointer) NULL}
208     };
209     XtCallbackRec cancel_callback[] = { 
210             {(XtCallbackProc)modal_dlgCB, (XtPointer) UI_ANSWER_CANCEL}, 
211             {(XtCallbackProc) NULL, (XtPointer) NULL} 
212     };
213     XtCallbackRec help_callback[] = {
214             {(XtCallbackProc)modal_dlgCB, (XtPointer) UI_ANSWER_HELP},
215             {(XtCallbackProc) NULL, (XtPointer) NULL}
216     };
217
218
219     modal_dlg_pane = create_message_dlg(parent, msg_type, title, msg, 
220                                 ok_label, cancel_label, help_label,
221                                 default_button_type);
222
223     XtVaSetValues(modal_dlg_pane,
224                 XmNdialogStyle,    XmDIALOG_FULL_APPLICATION_MODAL,
225                 XmNokCallback,     &ok_callback,
226                 XmNcancelCallback, &cancel_callback,
227                 XmNhelpCallback,   &help_callback,
228                 XmNuserData,       &answer,
229                 NULL);
230
231     answer = UI_ANSWER_NONE;
232
233     /* Popup Modal MessageDialog and wait for answer */
234     XtManageChild(modal_dlg_pane);
235     ui_win_front(modal_dlg_pane);
236     app = XtDisplayToApplicationContext(XtDisplay(modal_dlg_pane));
237     while (answer == UI_ANSWER_NONE)
238         XtAppProcessEvent(app, XtIMAll);
239
240
241     if (modal_dlg_pane_out_ptr != NULL)
242     {
243         (*modal_dlg_pane_out_ptr) = modal_dlg_pane;
244     }
245     return(answer);
246 }
247
248
249 static void
250 modal_dlgCB(
251     Widget      widget,
252     XtPointer   client_data,
253     XtPointer   call_data
254 )
255 {
256     UI_MODAL_ANSWER     op = (UI_MODAL_ANSWER)client_data;
257     UI_MODAL_ANSWER     *answerp = NULL;
258
259     XtVaGetValues(widget, XmNuserData, &answerp, NULL);
260
261     /* Will cause Modal dialog to return */
262     *answerp = op;
263
264 }
265
266 static Widget
267 create_message_dlg(
268     Widget      parent,
269     unsigned char  msg_type,
270     STRING         title,
271     STRING         msg,
272     STRING         ok_label,
273     STRING         cancel_label,
274     STRING         help_label,
275     unsigned char  default_button_type
276 )
277 {
278     Widget      msg_dlg;
279     Widget      shell;
280     Widget      button;
281     XmString    c_xmlabel, ok_xmlabel, h_xmlabel;
282     Arg         arg[12];
283     int         n = 0;
284
285     /* We want to parent the Dialog off of a Shell
286      * so walk up the tree to find the parent's shell
287      * ancestor...
288      */  
289     shell = ui_get_ancestor_shell(parent);
290
291     msg_dlg = XmCreateMessageDialog(shell,
292                         "ab_message_dialog",
293                         NULL, 0);
294
295     /* We don't want a "Cancel" button */
296     if (cancel_label == NULL)
297     {
298         button = XmMessageBoxGetChild(msg_dlg, XmDIALOG_CANCEL_BUTTON);
299         XtUnmanageChild(button);
300     }   
301     else
302     {   
303         c_xmlabel = XmStringCreateLocalized(cancel_label);
304         XtSetArg(arg[n], XmNcancelLabelString, c_xmlabel); n++;
305     }   
306     if (ok_label == NULL)
307     {
308         button = XmMessageBoxGetChild(msg_dlg, XmDIALOG_OK_BUTTON);
309         XtUnmanageChild(button);
310     }   
311     else
312     {   
313         ok_xmlabel = XmStringCreateLocalized(ok_label);
314         XtSetArg(arg[n], XmNokLabelString, ok_xmlabel); n++;
315     }   
316     if (help_label == NULL)
317     {
318         button = XmMessageBoxGetChild(msg_dlg, XmDIALOG_HELP_BUTTON);
319         XtUnmanageChild(button);
320     }
321     else
322     {
323         h_xmlabel = XmStringCreateLocalized(help_label);
324         XtSetArg(arg[n], XmNhelpLabelString, h_xmlabel); n++;
325     }
326     XtSetArg(arg[n], XmNmessageAlignment, XmALIGNMENT_CENTER);  n++;
327     XtSetArg(arg[n], XmNdialogType,       msg_type);            n++;
328     XtSetValues(msg_dlg, arg, n);
329  
330     /* Free XmStrings if they were allocated */
331     if (cancel_label != NULL)
332         XmStringFree(c_xmlabel);
333     if (ok_label != NULL)
334         XmStringFree(ok_xmlabel);
335     if (help_label != NULL)
336         XmStringFree(h_xmlabel);
337  
338     /* In case there are newlines in message, we must use the built-in
339      * Motif converter available in Varargs.
340      */
341     XtVaSetValues(msg_dlg,
342             XtVaTypedArg,  XmNdialogTitle,
343                         XtRString, title, strlen(title)+1,
344             XtVaTypedArg,  XmNmessageString,
345                         XtRString, msg, strlen(msg)+1,
346             XmNmessageAlignment,  XmALIGNMENT_CENTER,
347             XmNdefaultButtonType, default_button_type,
348             NULL);
349  
350     XtAddCallback(XtParent(msg_dlg), XtNpopdownCallback, destroyCB, (XtPointer)1);
351  
352     return(msg_dlg);
353
354 }
355
356
357 static void
358 destroyCB(
359     Widget      widget,
360     XtPointer   client_data,
361     XtPointer   call_data
362 )
363 {
364     int    yes = (int)client_data;
365
366    /* REMIND: aim,1/29/94 - temp. fix for prompt dialog crashing */
367     if (yes == 1)
368         XtDestroyWidget(widget);
369 }
370
371 /* note: the caller has to destroy the dialog when it's not needed anymore */
372 static Widget
373 create_prompt_dlg(
374     Widget      parent,
375     STRING      title,
376     STRING      label,
377     STRING      ok_label,
378     STRING      cancel_label,
379     STRING      help_label,
380     unsigned char default_button_type
381 )
382 {
383     Widget      prompt_dlg;
384     Widget      shell;
385     Widget      button, default_button;
386     XmString    c_xmlabel, ok_xmlabel, h_xmlabel;
387     Arg         arg[12];
388     int         n = 0;
389  
390     /* We want to parent the Dialog off of a Shell
391      * so walk up the tree to find the parent's shell
392      * ancestor...
393      */
394     shell = ui_get_ancestor_shell(parent);
395  
396     XtSetArg(arg[n], XmNautoUnmanage, FALSE); n++;
397     prompt_dlg = XmCreatePromptDialog(shell,
398                         "ab_prompt_dialog",
399                         arg, n);
400  
401     n = 0;
402     /* We don't want a "Cancel" button */
403     if (cancel_label == NULL)
404     {
405         button = XmSelectionBoxGetChild(prompt_dlg, XmDIALOG_CANCEL_BUTTON);
406         XtUnmanageChild(button);
407     }
408     else
409     {
410         c_xmlabel = XmStringCreateLocalized(cancel_label);
411         XtSetArg(arg[n], XmNcancelLabelString, c_xmlabel); n++;
412     }
413     if (ok_label == NULL)
414     {
415         button = XmSelectionBoxGetChild(prompt_dlg, XmDIALOG_OK_BUTTON);
416         XtUnmanageChild(button);
417     }
418     else
419     {
420         ok_xmlabel = XmStringCreateLocalized(ok_label);
421         XtSetArg(arg[n], XmNokLabelString, ok_xmlabel); n++;
422     }
423     if (help_label == NULL)
424     {    
425         button = XmSelectionBoxGetChild(prompt_dlg, XmDIALOG_HELP_BUTTON);
426         XtUnmanageChild(button);
427     }
428     else
429     {
430         h_xmlabel = XmStringCreateLocalized(help_label);
431         XtSetArg(arg[n], XmNhelpLabelString, h_xmlabel); n++;
432     }
433     XtSetValues(prompt_dlg, arg, n);
434
435     /* Free XmStrings if they were allocated */
436     if (cancel_label != NULL)
437         XmStringFree(c_xmlabel);
438     if (ok_label != NULL)
439         XmStringFree(ok_xmlabel);
440     if (help_label != NULL)
441         XmStringFree(h_xmlabel);
442  
443     switch (default_button_type)
444     {
445         case XmDIALOG_CANCEL_BUTTON:
446             default_button = XmSelectionBoxGetChild(prompt_dlg,
447                                 XmDIALOG_CANCEL_BUTTON);
448             break;
449         case XmDIALOG_OK_BUTTON:
450             default_button = XmSelectionBoxGetChild(prompt_dlg,
451                                 XmDIALOG_OK_BUTTON);
452             break;
453         case XmDIALOG_HELP_BUTTON:
454             default_button = XmSelectionBoxGetChild(prompt_dlg,
455                                 XmDIALOG_HELP_BUTTON);
456             break;
457         default:
458             default_button = NULL;
459             break;
460     }
461
462     /* In case there are newlines in message, we must use the built-in
463      * Motif converter available in Varargs.
464      */
465     XtVaSetValues(prompt_dlg,
466             XtVaTypedArg,  XmNdialogTitle,
467                         XtRString, title, strlen(title)+1,
468             XtVaTypedArg, XmNselectionLabelString,
469                         XtRString, label, strlen(label),
470             XmNdefaultButton, default_button,
471             NULL);
472
473     return(prompt_dlg);
474 }
475
476 /*
477  * Popup a Prompt Dialog
478  * (the dialog will be destroyed after popdown)
479  *
480  * does not participate with ab window protocol
481  */
482 void
483 ui_popup_prompt(
484     Widget              parent,
485     STRING              title,
486     STRING              label,
487     STRING              initial_text,
488     STRING              ok_label,
489     XtCallbackProc      ok_callback,
490     XtPointer           ok_clientData,
491     STRING              cancel_label,
492     XtCallbackProc      cancel_callback,
493     XtPointer           cancel_clientData,
494     STRING              help_label,
495     XtCallbackProc      help_callback,
496     XtPointer           help_clientData,
497     unsigned char       default_button_type
498 )
499 {
500     Widget              prompt_dlg, textf;
501
502     prompt_dlg = create_prompt_dlg(parent, title, label,
503                                  ok_label, cancel_label, help_label,
504                                  default_button_type);
505
506     /* Add Callbacks if necessary */
507     if (ok_callback != NULL)
508         XtAddCallback(prompt_dlg, XmNokCallback, ok_callback, ok_clientData);
509     if (cancel_callback != NULL)
510         XtAddCallback(prompt_dlg, XmNcancelCallback, cancel_callback, cancel_clientData);
511     if (help_callback != NULL)
512         XtAddCallback(prompt_dlg, XmNhelpCallback, help_callback, help_clientData);
513     /* destroy the dialog after popdown */
514     XtAddCallback(XtParent(prompt_dlg), XtNpopdownCallback, destroyCB, (XtPointer)1);
515
516     XtManageChild(prompt_dlg);
517     ui_win_front(prompt_dlg);
518
519     if ( initial_text != NULL )
520     {
521         textf = XmSelectionBoxGetChild(prompt_dlg, XmDIALOG_TEXT);
522         XmTextFieldSetString(textf, initial_text);
523         XmTextFieldSetSelection(textf, 0, strlen(initial_text), CurrentTime);
524         XmProcessTraversal(textf, XmTRAVERSE_CURRENT);
525     }
526 }
527
528 static void
529 prompt_ok_modal_dlgCB(
530     Widget                        widget,
531     XtPointer                     client_data,
532     XmSelectionBoxCallbackStruct  *call_data
533 )
534 {
535     UI_MODAL_ANSWER     *answerp = NULL;
536     Prompt_Info_Rec     *prompt_info = NULL;
537     Widget              textf = NULL;
538
539     XtVaGetValues(widget, XmNuserData, &prompt_info, NULL);
540     *(prompt_info->seln_str) =(STRING)objxm_xmstr_to_str(call_data->value);
541     answerp = (UI_MODAL_ANSWER *)client_data;
542
543     textf = XmSelectionBoxGetChild(widget, XmDIALOG_TEXT); 
544     if ( prompt_info->verify_proc(textf, prompt_info) )
545     {
546         /* We want to popdown the prompt dialog first before setting
547          * answerp, because that will cause ui_popup_modal_prompt() to
548          * return to the routine which is calling it. 
549          */
550         ui_win_show(widget, False, NULL);
551         *answerp = UI_ANSWER_OK;
552     }
553 }
554
555 static void
556 prompt_cancel_modal_dlgCB(
557     Widget                        widget,
558     XtPointer                     client_data,
559     XmSelectionBoxCallbackStruct  *call_data
560 )
561 {
562     UI_MODAL_ANSWER     *answerp = NULL;
563     Prompt_Info_Rec     *prompt_info = NULL;
564
565     XtVaGetValues(widget, XmNuserData, &prompt_info, NULL);
566     *(prompt_info->seln_str) =(STRING)objxm_xmstr_to_str(call_data->value);
567     answerp = (UI_MODAL_ANSWER *)client_data;
568
569     /* We want to popdown the prompt dialog first before setting
570      * answerp, because that will cause ui_popup_modal_prompt() to
571      * return to the routine which is calling it.
572      */
573     ui_win_show(widget, False, NULL);
574     *answerp = UI_ANSWER_CANCEL;
575 }
576
577 /* This routine is called when "Close is selected from
578  * the Motif window manager menu.  It behaves the same
579  * way as if the user pressed the "Cancel" button.
580  */ 
581 static void
582 prompt_close_modal_dlg(
583     Widget      widget,
584     XtPointer   client_data,
585     XtPointer   call_data
586 )
587 {
588     UI_MODAL_ANSWER     *answerp = NULL;
589
590     answerp = (UI_MODAL_ANSWER *)client_data;
591     *answerp = UI_ANSWER_CANCEL;
592 }
593
594 UI_MODAL_ANSWER
595 ui_popup_modal_prompt(
596     Widget              parent,
597     STRING              title,
598     STRING              label,
599     STRING              initial_text,
600     STRING              ok_label,
601     STRING              cancel_label,
602     STRING              help_label,
603     DtbObjectHelpData   help_data,
604     unsigned char       default_button_type,
605     STRING              *seln_str,
606     ModalPromptVerifyProc verify_proc,
607     XtPointer           client_data
608 )
609 {
610     XtAppContext                app;
611     static UI_MODAL_ANSWER      answer;
612     Prompt_Info_Rec             prompt_info = {NULL, NULL, NULL};
613     Widget                      modal_prompt = NULL;
614     
615     XtCallbackRec ok_callback[] = {
616             {(XtCallbackProc)prompt_ok_modal_dlgCB, (XtPointer) NULL},
617             {(XtCallbackProc) NULL, (XtPointer) NULL}
618     };   
619     XtCallbackRec cancel_callback[] = {
620             {(XtCallbackProc)prompt_cancel_modal_dlgCB, (XtPointer) NULL},
621             {(XtCallbackProc) NULL, (XtPointer) NULL}
622     };
623  
624     modal_prompt = create_prompt_dlg(parent, title, label, ok_label, 
625                         cancel_label, help_label, 
626                         default_button_type);
627
628     answer = UI_ANSWER_NONE;
629     ok_callback[0].closure = (XtPointer) &answer;
630     cancel_callback[0].closure = (XtPointer) &answer;
631
632     /* participate with the ab window protocol */
633     ab_register_window(modal_prompt, AB_WIN_MODAL, WindowUp, parent,
634         AB_WPOS_STACK_CENTER, prompt_close_modal_dlg, (XtPointer) &answer);
635     
636     prompt_info.verify_proc = verify_proc;
637     prompt_info.client_data = client_data;
638     prompt_info.seln_str = seln_str;
639  
640     XtVaSetValues(modal_prompt,
641                 XmNdialogStyle,    XmDIALOG_PRIMARY_APPLICATION_MODAL,
642                 XmNokCallback,     &ok_callback,
643                 XmNcancelCallback, &cancel_callback,
644                 XmNuserData,       &prompt_info,
645                 NULL);
646     if (!util_strempty(help_label) && (help_data != NULL))
647     {
648         XtAddCallback(modal_prompt, 
649                 XmNhelpCallback, dtb_help_dispatch, 
650                 help_data);
651     }
652
653     /* Popup Modal MessageDialog and wait for answer */
654     ab_show_window(modal_prompt);
655     ui_win_front(modal_prompt);
656
657     /* Set the initial text for the prompt dialog */
658     if ( initial_text != NULL )
659     {
660         Widget  textf;
661         
662         textf = XmSelectionBoxGetChild(modal_prompt, XmDIALOG_TEXT);
663         XmTextFieldSetString(textf, initial_text);
664         XmTextFieldSetSelection(textf, 0, strlen(initial_text), CurrentTime);
665         XmProcessTraversal(textf, XmTRAVERSE_CURRENT);
666     }
667
668     app = XtDisplayToApplicationContext(XtDisplay(modal_prompt));
669     while (answer == UI_ANSWER_NONE)
670     {
671         XtAppProcessEvent(app, XtIMAll);
672     }
673
674     /*
675     ** Destroy the dialog, we are done with it. 
676     */
677     XtDestroyWidget(modal_prompt);
678     return(answer);
679 }