Link with C++ linker
[oweals/cde.git] / cde / programs / dticon / main.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 /* $TOG: main.c /main/11 1999/09/17 13:25:57 mgreess $ */
24 /*********************************************************************
25 *  (c) Copyright 1993, 1994 Hewlett-Packard Company
26 *  (c) Copyright 1993, 1994 International Business Machines Corp.
27 *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
28 *  (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
29 *      Novell, Inc.
30 **********************************************************************/
31 /*-----------------------------------------------------------*/
32 /* This is the project main program file.                    */
33 /* You may add application dependent source code             */
34 /* at the appropriate places.                                */
35 /*-----------------------------------------------------------*/
36 #include <stdio.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <locale.h>
41 #include <sys/param.h>
42
43 #include <X11/Intrinsic.h>
44 #include <Xm/Protocols.h>
45 #include <Xm/DialogS.h>
46 #include <Xm/MessageB.h>
47 #include <Xm/MwmUtil.h>
48 #include <Dt/EnvControlP.h>
49 #include <Dt/UserMsg.h>
50 #include "externals.h"
51 #include "main.h"
52
53 #ifdef __TOOLTALK
54 #include <Tt/tttk.h>
55 int ttMark;
56 int tt_tmpfile_fd = -1;
57 static int undeclared = 0;
58 static Tt_message local_msg = (Tt_message) 0;
59 void DieFromToolTalkError( );
60 Tt_message ProcessToolTalkMessage( );
61 Tt_message ProcessToolTalkMediaMessage( );
62 extern void ProcessAppArgs();
63 void send_tt_saved();
64 #define dticon_ptype "DT_Icon_Editor"
65 #endif
66
67 #define ERROR           -1
68 #define NO_ERROR        0
69
70 static XtResource resources[] = {
71   {"useMessaging", "UseMessaging", XmRBoolean, sizeof (Boolean),
72     XtOffset (ApplicationDataPtr, useBMS), XmRImmediate, (XtPointer)False,
73   },
74   {"session", "Session", XmRString, sizeof (char *),
75     XtOffset (ApplicationDataPtr, session), XmRImmediate, (XtPointer)NULL,
76   },
77   {"bmSuffix", "BmSuffix", XmRString, sizeof (char *),
78     XtOffset (ApplicationDataPtr, bmSuffix), XmRImmediate, (XtPointer)".bm",
79   },
80   {"pmSuffix", "PmSuffix", XmRString, sizeof (char *),
81     XtOffset (ApplicationDataPtr, pmSuffix), XmRImmediate, (XtPointer)".pm",
82   },
83   {"maxIconWidth", "MaxIconWidth", XmRInt, sizeof (int),
84     XtOffset (ApplicationDataPtr, maxIconWidth), XmRImmediate,
85     (caddr_t)MAX_ICON_WIDTH,
86   },
87   {"maxIconHeight", "MaxIconHeight", XmRInt, sizeof (int),
88     XtOffset (ApplicationDataPtr, maxIconHeight), XmRImmediate,
89     (caddr_t)MAX_ICON_HEIGHT,
90   },
91   {"useFileFilter", "UseFileFilter", XmRBoolean, sizeof (Boolean),
92     XtOffset (ApplicationDataPtr, useFileFilter), XmRImmediate, (XtPointer)True,
93   },
94   {"useFileLists", "UseFileLists", XmRBoolean, sizeof (Boolean),
95     XtOffset (ApplicationDataPtr, useFileLists), XmRImmediate, (XtPointer)True,
96   },
97 };
98
99 static XrmOptionDescRec option_list[] =
100 {
101    {"-noMessaging", "useMessaging", XrmoptionNoArg, (caddr_t)"FALSE"},
102    {"-session", "session", XrmoptionSepArg, NULL},
103    {"-bmSuffix", "bmSuffix", XrmoptionSepArg, NULL},
104    {"-pmSuffix", "pmSuffix", XrmoptionSepArg, NULL},
105    {"-maxIconWidth", "maxIconWidth", XrmoptionSepArg, (caddr_t)MAX_ICON_WIDTH},
106    {"-maxIconHeight", "maxIconHeight",XrmoptionSepArg,(caddr_t)MAX_ICON_HEIGHT},
107    {"-noFileFilter", "useFileFilter", XrmoptionNoArg, (caddr_t)"FALSE"},
108    {"-noFileLists", "useFileLists", XrmoptionNoArg, (caddr_t)"FALSE"},
109    {"-useFileFilter", "useFileFilter", XrmoptionNoArg, (caddr_t)"TRUE"},
110    {"-useFileLists", "useFileLists", XrmoptionNoArg, (caddr_t)"TRUE"},
111 };
112
113
114 extern Widget mainForm, iconForm, fileMenu_quit_pb;
115 extern void GetSessionInfo();
116 extern char start_file[];
117 extern char dummy[];
118
119
120 /*-----------------------------------------------------------*/
121 /* Insert application global declarations here               */
122 /*-----------------------------------------------------------*/
123
124 XtAppContext AppContext;
125 Widget       TopLevel;
126 Widget       dticonShell;
127 char        *execName, *progName;
128 char msgID[120];
129
130
131
132
133 /*-----------------------------------------------------------*/
134 /* User has selected window manager close button... verify   */
135 /* close desired if data has not been saved.                 */
136 /*-----------------------------------------------------------*/
137 static void
138 CloseCB (
139         Widget w,
140         XtPointer clientData,
141         XtPointer callbackArg )
142 {
143     DialogFlag = QUIT;
144     XtCallCallbacks (fileMenu_quit_pb, XmNactivateCallback, NULL);
145 }
146
147
148 /*-----------------------------------------------------------*/
149 /* Session is ending, save session information               */
150 /*-----------------------------------------------------------*/
151 static void
152 SaveSessionCB (
153         Widget w,
154         XtPointer clientData,
155         XtPointer callbackArg )
156 {
157 #ifdef DEBUG
158   if (debug)
159     stat_out("SaveSessionCB\n");
160 #endif
161
162     SaveSession();
163 }
164
165
166
167 /*-----------------------------------------------------------*/
168 /*-----------------------------------------------------------*/
169 /* main                                                      */
170 /*-----------------------------------------------------------*/
171 /*-----------------------------------------------------------*/
172 int
173 main(
174         int argc,
175         char *argv[] )
176 {
177         /*-----------------------------------------------------------*/
178         /* Declarations.                                             */
179         /*-----------------------------------------------------------*/
180         Widget  w, d;
181         int n;
182         Arg args[20];
183         Atom xa_WM_DELETE_WINDOW, xa_WM_SAVE_YOURSELF;
184         char *tmpPtr=NULL;
185         static char *untitledStr = NULL;
186         char *p=NULL;
187         char *tmpp=NULL;
188
189 #ifdef __TOOLTALK
190     int ttFd;
191     char * procId;
192     Tt_status ttRc;
193     char * sessionString;
194 #endif
195
196         /*-----------------------------------------------------------*/
197         /* Interface function declaration                            */
198         /*-----------------------------------------------------------*/
199         Widget  create_dtIconShell();
200         Widget  create_newIconDialog();
201         Widget  create_queryDialog();
202         Widget  create_stdErrDialog();
203         Widget  create_fileIODialog();
204         void    GetMarginData();
205
206
207         /* ------------------------*/
208         /*      Initialize program      */
209         /*------------------------------*/
210         _DtEnvControl(DT_ENV_SET); /* set up environment variables */
211
212         XtSetLanguageProc(NULL, NULL, NULL);
213
214         execName = argv[0];
215         if (progName=strrchr(argv[0], '/'))
216             progName++;
217         else
218             progName = argv[0];
219
220
221         TopLevel = XtAppInitialize(&AppContext, CLASS_NAME,
222                                 option_list, XtNumber(option_list),
223                                 &argc, argv, NULL, NULL, NULL);
224
225         XtGetApplicationResources(TopLevel, &xrdb, resources,
226                                       XtNumber(resources), NULL, 0);
227
228         GetSessionInfo();
229
230
231
232         /*------------------------------------------------------------*/
233         /*    Insert initialization code for your application here    */
234         /*------------------------------------------------------------*/
235
236
237         /*------------------------------------------------------------------*/
238         /*  Create and popup the first window of the interface.  The        */
239         /*  return value can be used in the popdown or destroy functions.   */
240         /*------------------------------------------------------------------*/
241         w = create_dtIconShell();
242         dticonShell = w;
243         d = create_fileIODialog();
244         d = create_newIconDialog();
245         d = create_queryDialog();
246         d = create_stdErrDialog();
247         Create_Gfx_Labels(Foreground, Background);
248         AssignHelpCallbacks();
249
250         XtRealizeWidget (TopLevel);
251         XtMapWidget (TopLevel);
252
253         GetMarginData();
254
255         /* */
256         /*  Since I can't change the .msg files I'll have to force
257             it here.
258         */
259     last_fname[0] = '\0';
260     if (!untitledStr)
261       untitledStr = GETSTR(2,20, "UNTITLED");
262     strcpy(last_fname, untitledStr);
263     strcat(last_fname, ".m.pm");
264     ChangeTitle();
265         /* */
266
267         ParseAppArgs(argc, argv);
268         if (start_file[0] != '\0')
269         {
270            /* strip off path portion of name if there is one */
271            tmpPtr = strrchr(start_file,'/');
272            if (tmpPtr != NULL)
273                XtSetArg(args[0], XmNiconName, tmpPtr+1);
274            else
275                XtSetArg(args[0], XmNiconName, start_file);
276            XtSetValues(dtIconShell, args, 1);
277         }
278         n = 0;
279         XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
280         XtSetValues(mainForm, args, n);
281         XtSetValues(iconForm, args, n);
282
283         /*------------------------------------------------------------------*/
284         /*   Catch window close event and call "File...Exit" callback.      */
285         /*------------------------------------------------------------------*/
286         xa_WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
287         XmAddWMProtocolCallback(dtIconShell, xa_WM_DELETE_WINDOW, CloseCB,
288                                 NULL);
289
290         /*------------------------------------------------------------------*/
291         /*   Register for save and restore.                                 */
292         /*------------------------------------------------------------------*/
293         xa_WM_SAVE_YOURSELF = XInternAtom(dpy, "WM_SAVE_YOURSELF", False);
294         XmAddWMProtocolCallback(dtIconShell, xa_WM_SAVE_YOURSELF,
295                                 SaveSessionCB, NULL);
296
297 #ifdef __TOOLTALK
298     ttMark = tt_mark( );
299     p = (char *)getenv("TT_SESSION");
300     if (!p || strlen(p)==0) {
301     tt_default_session_set( tt_X_session( XDisplayString( dpy )));}
302
303     procId = ttdt_open( &ttFd, "dticon", "CDE", "1.0", 1 );
304     ttRc = tt_ptr_error(procId);
305     tmpPtr = GETSTR(8, 8, "Could not connect to ToolTalk:\n%s\nExiting ...");
306     DieFromToolTalkError( dticonShell, tmpPtr, ttRc );
307
308     ttRc = ttmedia_ptype_declare( dticon_ptype, 0,
309                                   ProcessToolTalkMediaMessage, NULL, 0);
310     DieFromToolTalkError( dticonShell, "ttmedia_ptype_declare: %s", ttRc );
311
312     ttRc = ttmedia_ptype_declare( dticon_ptype, 1000,
313                                   ProcessToolTalkMediaMessage, NULL, 0);
314     DieFromToolTalkError( dticonShell, "ttmedia_ptype_declare: %s", ttRc );
315
316     ttRc = ttmedia_ptype_declare( dticon_ptype, 2000,
317                                   ProcessToolTalkMediaMessage, NULL, 1);
318     DieFromToolTalkError( dticonShell, "ttmedia_ptype_declare: %s", ttRc );
319
320     tttk_Xt_input_handler(NULL, 0, 0);
321
322     ttRc = tt_ptr_error(ttdt_session_join( tt_default_session( ),
323                                           ProcessToolTalkMessage,
324                                           (Widget) 0, NULL, 1));
325     DieFromToolTalkError( dticonShell, "ttdt_session_join: %s", ttRc );
326
327     XtAppAddInput( AppContext, ttFd, (XtPointer)XtInputReadMask,
328                         tttk_Xt_input_handler, 0 );
329     if (!undeclared) tt_ptype_undeclare(dticon_ptype);
330     tt_release(ttMark);
331 #endif
332
333
334         /*-------------------------*/
335         /*   Enter the event loop  */
336         /*-------------------------*/
337         {
338             XEvent event;
339
340             for (;;) {
341                 XtAppNextEvent(AppContext, &event);
342                 if ((GraphicsOp == S_GRAB) &&
343                     ((event.type == ButtonPress)  ||
344                      (event.type == MotionNotify) ||
345                      (event.type == ButtonRelease)))
346                   Do_ButtonOp(&event);
347                 else
348                 {
349                     if ((GraphicsOp == POLYGON || GraphicsOp == POLYLINE) &&
350                           (event.type == ButtonPress))
351                     {
352                         if (event.xbutton.window != tablet_win)
353                             EndPolyOp();
354                     }
355                     XtDispatchEvent(&event);
356                 }
357             }
358         }
359 }
360
361 #ifdef __TOOLTALK
362
363 static void
364 ExitCB (Widget dialog, XtPointer client_data, XtPointer call_data)
365 {
366     exit((int) client_data);
367 }
368
369 void
370 DieFromToolTalkError(Widget parent, char *errfmt, Tt_status status)
371 {
372     Arg          args[10];
373     Widget       dialog, dialogShell;
374     char        *errmsg, *statmsg, *title;
375     XmString     xms_errmsg, xms_ok, xms_title;
376     int          n;
377
378     if (! tt_is_err(status)) return;
379
380     statmsg = tt_status_message(status);
381     errmsg = XtMalloc(strlen(errfmt) + strlen(statmsg) + 2);
382     sprintf(errmsg, errfmt, statmsg);
383
384     xms_ok = GETXMSTR(8,6, "OK");
385     xms_errmsg = XmStringCreateLocalized(errmsg);
386     xms_title = GETXMSTR(8,2, "Icon Editor - Error");
387
388     n = 0;
389     XtSetArg(args[n], XmNautoUnmanage, False); n++;
390     XtSetArg(args[n], XmNokLabelString, xms_ok); n++;
391     XtSetArg(args[n], XmNdialogTitle, xms_title); n++;
392     XtSetArg(args[n], XmNmessageString, xms_errmsg); n++;
393     XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
394
395     dialog = XmCreateErrorDialog(parent, "IconEditorError", args, n);
396     XtAddCallback(dialog, XmNokCallback, ExitCB, (XtPointer) status);
397     XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
398     XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
399
400     /*
401      * Disable the frame menu from dialog since we don't want the user
402      * to be able to close dialogs with the frame menu
403      */
404     dialogShell = XtParent(dialog);
405     n = 0;
406     XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MENU); n++;
407     XtSetValues(dialogShell, args, n);
408     XtManageChild(dialog);
409     XtRealizeWidget(dialogShell);
410
411     _DtSimpleError(CLASS_NAME, DtFatalError, NULL, errmsg);
412
413     XtFree(errmsg);
414     XmStringFree(xms_ok);
415     XmStringFree(xms_errmsg);
416     XmStringFree(xms_title);
417
418     while (TRUE)
419       XtAppProcessEvent(XtWidgetToApplicationContext(dialog), XtIMAll);
420 }
421
422
423 Tt_message ProcessToolTalkMediaMessage( Tt_message      msg,
424                                         void*           cdata,
425                                         Tttk_op         op,
426                                         Tt_status       diag,
427                                         unsigned char*  contents,
428                                         int             len,
429                                         char*           file,
430                                         char*           doc)
431 {
432 int mark = tt_mark();
433 int tmplen=0;
434 int tt_tmpMaskfile_fd = -1;
435 char mask_file[MAX_FNAME];
436 char *tmp = NULL;
437 char *tmp1 = NULL;
438
439 if (tt_message_status(msg) == TT_WRN_START_MESSAGE) tt_message_reply(msg);
440
441
442   switch(op) {
443     case TTME_COMPOSE:
444         /*
445          * At this time, we don't handle composing new icons.
446          * Fail any such requests.
447          */
448         tt_message_fail(msg);
449         break;
450     case TTME_DISPLAY:
451         /*
452          * At this time, we don't handle displaying icons
453          * without editing them.
454          * Fail any such requests.
455          */
456         tt_message_fail(msg);
457         break;
458     case TTME_EDIT:
459
460         /*
461          * Undeclare the ptype so that this process will
462          * not service any more TT requests.
463          */
464
465         tt_ptype_undeclare(dticon_ptype);
466         undeclared = 1;
467
468         if (tt_message_status(msg) != TT_WRN_START_MESSAGE)
469         {
470           /*
471            * A message came in while we were already up
472            * and running -- reject it so that another dticon
473            * process will be started up to service this
474            * request.
475            */
476
477           tt_message_reject(msg);
478         }
479         else if (edit_notifier(NULL, msg, 0))
480         {
481            strcpy( msgID, tt_message_arg_val(msg, 1) );
482
483            if (file)
484            {
485                    /*
486                     * Icon data is in a file
487                    */
488                    strcpy(start_file, file);
489            }
490            else
491            {
492              /*
493               * Icon data is in a buffer -- write it
494               * to a /tmp file.
495              */
496              unsigned char* buf;
497              int blen;
498              int wlen;
499
500              if (tt_message_arg_bval(msg, 0,
501                                      &buf, &blen) != TT_OK)
502              {
503                 tt_message_fail(msg);
504                 edit_notifier(NULL, 0, 1);
505              }
506              else
507              {
508                 (void) tmpnam(start_file);
509                 if( (buf) && (!strncmp((char *)buf, "/* XPM */", 9)) )
510                 {
511                    /* Format XPM */
512                    tt_tmpfile_fd =
513                            open(start_file,
514                                 O_CREAT | O_WRONLY | O_NDELAY,
515                                 0666);
516                    if (tt_tmpfile_fd && (wlen =
517                                  write(tt_tmpfile_fd,
518                                        buf, blen)) == blen)
519                    {
520                       (void) close(tt_tmpfile_fd);
521                       param_flag[AUTO_FILE] = True;
522                       argsNeedProcessed = True;
523                    }
524                    else {
525                            tt_message_fail(msg);
526                            edit_notifier(NULL, 0, 1);
527                         }
528                 }
529                 else
530                 {
531                    /* Format XBM */
532                    /* assume two buffers.... */
533                    tmp = strchr((char *)buf, ';');
534                    tmp ++;
535                    tmplen=blen - strlen(tmp);
536
537                      /* read XBM file first*/
538                      /* Grab the first buffer. */
539                      tt_tmpfile_fd =
540                              open(start_file,
541                                   O_CREAT | O_WRONLY | O_NDELAY,
542                                   0666);
543
544                      if (tt_tmpfile_fd && (wlen =
545                                    write(tt_tmpfile_fd,
546                                          buf, tmplen)) == tmplen)
547                      {
548                         (void) close(tt_tmpfile_fd);
549                         param_flag[AUTO_FILE] = True;
550                         argsNeedProcessed = True;
551                      }
552                      else
553                      {
554                              tt_message_fail(msg);
555                             edit_notifier(NULL, 0, 1);
556                      }
557
558                    /* Try to find the second buffer. */
559                    tmp ++;
560                    if(tmp) tmp1=strchr(tmp, ';');
561
562                    if (tmp1)
563                    {
564                       /* we have a mask */
565                       /* construct the name of the mask file */
566                       strcpy(mask_file, start_file);
567                       strcat(mask_file, "_m\0");
568                       tt_tmpMaskfile_fd =
569                             open(mask_file,
570                             O_CREAT | O_WRONLY | O_NDELAY,
571                             0666);
572                       /* Read the mask fro the seconf buffer. */
573                       if (tt_tmpMaskfile_fd && (wlen =
574                       write(tt_tmpMaskfile_fd,
575                             tmp, strlen(tmp))) == strlen(tmp))
576                       {
577                          (void) close(tt_tmpMaskfile_fd);
578                          param_flag[AUTO_FILE] = True;
579                          argsNeedProcessed = True;
580                       }
581                       else {
582                               tt_message_fail(msg);
583                               edit_notifier(NULL, 0, 1);
584                            }
585                    }
586                 } /* else XBM Format */
587              }
588            }
589         }
590     break;
591   }
592
593   tt_release(mark);
594   return (Tt_message) 0;
595 }
596
597 int
598 edit_notifier(char* fname, Tt_message msg, int clear)
599 {
600         /*
601          * Triple-mode function that either (1) saves the message
602          * so it can be replied to later, (2) replies to a
603          * previously-saved message, or (3) clears its state.
604          */
605
606         if (clear) {
607                 if (local_msg != (Tt_message) 0) {
608                         tt_message_reply(local_msg);
609                         tt_message_destroy(local_msg);
610                 }
611                 local_msg = (Tt_message) 0;
612
613                 return 1;
614         }
615
616         if (fname && !msg) {
617
618                 /*
619                  * Not currently used, DELETE THIS COMMENT if it
620                  * is ever needed.
621                  */
622
623                 if (local_msg != (Tt_message) 0) {
624                         /*
625                          * Set the filename arg to the new, passed-in
626                          * file name, and reply to the message.
627                          */
628                         tt_message_arg_val_set(local_msg, 0, fname);
629                         tt_message_reply(local_msg);
630                         local_msg = (Tt_message) 0;
631                 }
632                 return 1;
633         }
634         else if (!fname && msg) {
635                 /*
636                  * Just store the message for a later reply.  If
637                  * we already have a stored message, return a failure
638                  * status (0) and reject the incoming message.
639                  */
640                 if (local_msg != (Tt_message) 0) {
641                         tt_message_reject(msg);
642                         return 0;
643                 }
644                 else {
645                         local_msg = msg;
646                         return 1;
647                 }
648         }
649         else {
650                 /*
651                  * The caller is confused.
652                  */
653                 tt_message_reject(msg);
654                 return 0;
655         }
656 }
657
658
659 void
660 send_tt_saved()
661 {
662         int mark;
663         int fd;
664         int fdm;
665         int len=0;
666         int Mlen=0;
667         int rlen=0;
668         char* buffer=NULL;
669         char* Fbuffer=NULL;
670         char* Mbuffer=NULL;
671         struct stat statbuf;        /* Information on a file. */
672         Tt_status ttstat;
673         Tt_message msg;
674
675         mark = tt_mark();
676         msg = tt_message_create();
677         tt_message_address_set(msg, TT_HANDLER);
678         tt_message_handler_set(msg, tt_message_sender(local_msg));
679         tt_message_class_set(msg, TT_NOTICE);
680         tt_message_scope_set(msg, TT_SESSION);
681         tt_message_session_set(msg, tt_default_session());
682         tt_message_op_set(msg, "Saved");
683
684         /* Read the base file regardless of format */
685         fd = open(last_fname, O_RDONLY | O_NDELAY);
686         len = lseek(fd, 0, SEEK_END);
687         (void) lseek(fd, 0, SEEK_SET);
688         Fbuffer = XtMalloc(len + 1);
689         if ((rlen = read(fd, Fbuffer, len)) != len)
690         {
691         /* didn't read whole file! */
692         printf("dtcreate: Only read %d of %d bytes of icon file!\n", rlen, len);
693         }
694         (void) close(fd);
695         Fbuffer[len]='\0';
696
697         rlen = 0;
698         /* Handle the XBM format */
699         if( (fileFormat != FORMAT_XPM) && (stat(dummy, &statbuf) == 0) )
700         {
701            /* Read the mask file if one exists */
702            fdm = open(dummy, O_RDONLY | O_NDELAY);
703            Mlen = lseek(fdm, 0, SEEK_END);
704            (void) lseek(fdm, 0, SEEK_SET);
705            Mbuffer = XtMalloc(Mlen + 1);
706            if ((rlen = read(fdm, Mbuffer, Mlen)) != Mlen)
707            {
708                /* didn't read whole file! */
709                printf(
710                 "dtcreate: Only read %d of %d bytes of icon file!\n",
711                 rlen, Mlen);
712            }
713            (void) close(fdm);
714            Mbuffer[Mlen] ='\0';
715
716            /* Double buffer the base and mask */
717            buffer = XtMalloc(strlen(Fbuffer)+strlen(Mbuffer)+1);
718            strcpy(buffer, Fbuffer);
719            buffer[strlen(Fbuffer)] ='\0';
720            strcat(buffer, Mbuffer);
721            buffer[strlen(Fbuffer)+strlen(Mbuffer)+1] ='\0';
722            XtFree(Mbuffer);
723         }
724         else
725         {
726            /* No mask/bm just pass the pm file */
727              buffer = XtMalloc(len + 1);
728              strcpy(buffer, Fbuffer);
729              buffer[len+1] ='\0';
730         }
731
732         tt_message_barg_add(msg, TT_IN, tt_message_arg_type(local_msg, 0),
733                             (void *) buffer, Mlen+len+1);
734         tt_message_arg_add(msg, TT_IN, "string", msgID);
735
736         ttstat = tt_message_send(msg);
737         tt_message_destroy(msg);
738         tt_release(mark);
739
740         XtFree(Fbuffer);
741         XtFree(buffer);
742 }
743
744
745 Tt_message ProcessToolTalkMessage(Tt_message msg,
746                                   void* cdata,
747                                   Tt_message contract)
748 {
749         int mark = tt_mark();
750         char* op = tt_message_op(msg);
751
752         if (!strcmp(op, "Quit")) {
753                 /*
754                  * Do any necessary cleanup here, call
755                  * tt_message_reply(), and quit.
756                  * Since this is not currently implemented here,
757                  * the message will just be failed for now.
758                  */
759                 tt_message_fail(msg);
760         }
761         /*
762          * The messages that must interact with the X environment
763          * are not supported currently.  If a realized,
764          * mappedWhenManaged top-level widget were passed to
765          * ttdt_session_join(), they would be handled automatically.
766          * Since that is not the case, they are passed to this
767          * callback, and could be implemented here if desired
768          * (if so, be sure to change tt_message_reject to
769          * tt_message_reply!).
770          */
771         else {
772                 tt_message_reject(msg);
773         }
774
775         tt_release(mark);
776         return (Tt_message) 0;
777 }
778
779 #endif
780
781
782 /******************************************************************************
783 NAME:           handle_dialog_child( wgt, manage_func )
784
785 INPUT:          Widget  wgt                     - the dialogShellWidget
786                 void    (*manage_func)()        - either XtManageChild
787                                                   or XtUnmanageChild
788
789 RETURN:         int                             - NO_ERROR if successfull
790                                                   ERROR otherwise
791
792 DESCRIPTION:    Handles the popping up or popping down of dialog shells
793                 by managing or unmanaging their children.
794
795 CREATION:       Visual Edge Software            Sept 19/91
796 -----------------------------------------------------------------------------*/
797 static  int     handle_dialog_child( Widget wgt, void (*manage_func)() )
798 {
799         int     i, num_children;
800         Widget  *children;
801
802         XtVaGetValues( wgt,
803                        XmNnumChildren, &num_children,
804                        XmNchildren, &children,
805                        NULL );
806
807         /* We manage/unmanage the first rectObj child in the list.
808          * Note that the check for rectObjClass is necessary since some
809          * implementations of Motif add protocol children to the dialogShell.
810          */
811
812         for (i = 0; i < num_children; i++)
813         {
814                 if ( XtIsSubclass( children[i], rectObjClass ) )
815                 {
816                         (*manage_func)(children[i]);
817                         return ( NO_ERROR );
818                 }
819         }
820
821         return ( ERROR );
822 }
823
824 /******************************************************************************
825 NAME:           PopupInterface( wgt, grab_flag )
826
827 INPUT:          Widget          wgt             - Widget to popup
828                 XtGrabKind      grab_flag       - grab flag
829
830 RETURN:         int                     ERROR or NO_ERROR
831
832 DESCRIPTION:    Popups up an interface. The widget should be a toplevel widget.
833                 Note that special handling is required for dialogShells since
834                 those are popped up by managing their children if they have
835                 some.
836                 The grab_flag could be any of:
837                                 no_grab (XtGrabNone)
838                                 nonexclusive_grab (XtGrabNonexclusive)
839                                 exclusive_grab (XtGrabExclusive)
840
841 CREATION:       Visual Edge Software            April 6 1991
842 -----------------------------------------------------------------------------*/
843 int     PopupInterface( Widget wgt, XtGrabKind grab_flag )
844 {
845
846         if ( XtIsSubclass( wgt, xmDialogShellWidgetClass ) )
847         {
848                 if ( handle_dialog_child( wgt, XtManageChild ) == ERROR )
849                         XtPopup( wgt, grab_flag );
850         }
851         else
852         {
853                 XtPopup( wgt, grab_flag );
854         }
855
856         return ( NO_ERROR );
857 }