Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dticon / process.c
1 /* $TOG: process.c /main/7 1999/08/16 11:03:31 mgreess $ */
2 /********************************************************************
3 *  (c) Copyright 1993, 1994 Hewlett-Packard Company
4 *  (c) Copyright 1993, 1994 International Business Machines Corp.
5 *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
6 *  (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
7 *      Novell, Inc.
8 **********************************************************************/
9 /******************************************************************************
10  **  Program:           dticon.c
11  **
12  **  Description:       X11-based multi-color icon editor
13  **
14  **  File:              process.c, which contains the following subroutines or
15  **                     functions:
16  **                       Process_New()
17  **                       Process_Open()
18  **                       Process_Save()
19  **                       Process_SaveAs()
20  **                       Process_Quit()
21  **                       Process_Query_OK()
22  **                       Process_Query_Cancel()
23  **                       Process_Size_OK()
24  **                       Eval_NewSize()
25  **                       Process_Size_Cancel()
26  **                       Process_StdErr_OK()
27  **                       Process_Undo()
28  **                       Process_Cut()
29  **                       Process_Copy()
30  **                       Process_Paste()
31  **                       Process_Scale()
32  **                       Process_Resize()
33  **                       Process_AddHotspot()
34  **                       Process_DeleteHotspot()
35  **                       Process_Clear()
36  **                       Process_RotateLeft()
37  **                       Process_RotateRight()
38  **                       Process_FlipV()
39  **                       Process_FlipH()
40  **                       Process_GridState()
41  **                       Process_DropCheckOp()
42  **                       Do_DropCheckOp()
43  **                       Process_DropOp()
44  **                       Do_Paste()
45  **                       Do_DropOp()
46  **
47  ******************************************************************************
48  **
49  **  Copyright Hewlett-Packard Company, 1990, 1991, 1992.
50  **  All rights are reserved.  Copying or reproduction of this program,
51  **  except for archival purposes, is prohibited without prior written
52  **  consent of Hewlett-Packard Company.
53  **
54  **  Hewlett-Packard makes no representations about the suitibility of this
55  **  software for any purpose.  It is provided "as is" without express or
56  **  implied warranty.
57  **
58  *****************************************************************************
59 */
60 #include <Xm/Xm.h>
61 #include <Xm/XmP.h>
62 #include <Xm/TextF.h>
63 #include "externals.h"
64 #include <string.h>
65
66 #include <Xm/DragC.h>
67 #include <Dt/Dnd.h>
68
69 #include <Dt/HelpDialog.h>
70 #include "main.h"
71
72 #ifdef __TOOLTALK
73 #include <Tt/tttk.h>
74 extern void ReplyToMessage( );
75 extern Tt_message replyMsg;
76 #endif
77
78 static void Do_DropCheckOp(DtDndTransferCallback);
79 static void Do_DropOp(void);
80
81 extern Widget optionsMenu_grid;
82 Widget editMenu_paste_pb;
83 Widget editMenu_cut_pb;
84 Widget editMenu_copy_pb;
85 Widget editMenu_rotate_pb;
86 Widget editMenu_flip_pb;
87 Widget editMenu_scale_pb;
88 Widget editMenu_undo_pb;
89 extern Widget newWidthText, newHeightText;
90
91 extern GC scratch_gc;
92 extern char dummy[];
93
94 Boolean Write_File( char * );
95 Boolean Read_File( char * );
96
97 extern void Process_SaveAs(void);
98 extern void Eval_NewSize(int, int);
99 extern void Process_Copy(XImage **, XImage **);
100 extern void Process_Resize(void);
101
102 /*-----------------------------------------------------------*/
103 /* Insert application global declarations here               */
104 /*-----------------------------------------------------------*/
105 static char     undo_file[MAX_FNAME];          /* save the file name after new */
106 char dropFileName[MAX_FNAME];
107 int SaveMeNot = TRUE;     /* used to flag a save as for existing file */
108 int SavedOnce = False;
109 int  NewFlag = False;             /* use for undo after new */
110
111 /***************************************************************************
112  *                                                                         *
113  * Routine:   Process_New                                                  *
114  *                                                                         *
115  * Purpose:   Process the selection of the NEW button in the 'File'        *
116  *            pulldown menu.  If the 'Dirty' flag is set, changes have     *
117  *            been made to the drawing tablet since the last save, which   *
118  *            would be lost by quitting.  Notify the user of this and      *
119  *            allow them the chance to change their minds.  If they do     *
120  *            not, pop-up the NewIconDialog for the user to select new     *
121  *            dimensions (if desired) for the new icon.                    *
122  *                                                                         *
123  ***************************************************************************/
124 void
125 Process_New( void )
126 {
127   DialogFlag = NEW;
128   if (Dirty)
129     DoQueryDialog( GETSTR(16,16, "The current icon has not been saved.\n\nYour changes will be lost.") );
130   else {
131     Process_Resize();
132     DialogFlag = NONE; }
133 }
134
135 /***************************************************************************
136  *                                                                         *
137  * Routine:   Process_Open                                                 *
138  *                                                                         *
139  * Purpose:   Process the selection of the OPEN button in the 'File'       *
140  *            pulldown menu.  If the 'Dirty' flag is set, changes have     *
141  *            been made to the drawing tablet since the last save, which   *
142  *            would be lost by quitting.  Notify the user of this and      *
143  *            allow them the chance to change their minds.  If they do     *
144  *            not, pop-up the FileSelectionDialog for the user to select   *
145  *            the new file to be loaded.                                   *
146  *                                                                         *
147  ***************************************************************************/
148
149 void
150 Process_Open( void )
151 {
152   DialogFlag = OPEN;
153   fileIOMode = FILE_READ;
154   if (Dirty)
155     DoQueryDialog( GETSTR(16,16, "The current icon has not been saved.\nYour changes will be lost.") );
156   else
157   {
158     XtManageChild(fileIODialog);
159     SetFileIODialogInfo();
160   }
161 }
162
163
164 /***************************************************************************
165  *                                                                         *
166  * Routine:   Process_Save                                                 *
167  *                                                                         *
168  * Purpose:   Process the selection of the SAVE button in the 'File'       *
169  *            pulldown menu.  This automatically saves the current icon    *
170  *            to the same file it was loaded from, or saved to the last    *
171  *            time.  If this file was created 'from scratch' and no        *
172  *            previous save operation has taken place, selecting this      *
173  *            operation behaves the same way that the SAVE_AS operation    *
174  *            behaves.                                                     *
175  *                                                                         *
176  ***************************************************************************/
177
178 void
179 Process_Save( void )
180 {
181   static char *untitledStr = NULL;
182   static char newName[MAX_FNAME];
183   char *tmp1 = NULL;
184   char *tmp2 = NULL;
185   int c;
186
187   DialogFlag = SAVE;
188   fileIOMode = FILE_WRITE;
189
190   untitledStr = GETSTR(2,20, "UNTITLED");
191   tmp1= strrchr(last_fname, '/');
192   if (tmp1) {
193      c = tmp1[1];
194      tmp2 = strchr(tmp1, c);
195      strcpy(newName, tmp2);
196   }
197   if (strncmp(newName, untitledStr, 8) == 0 || last_fname[0] == NULL) Process_SaveAs();
198   else
199  {
200   if (SavedOnce == True)
201   {
202     if (!Write_File(last_fname))
203       DoErrorDialog( GETSTR(16,4, "Unable to write data to file") );
204     else
205       Dirty = False;
206   }
207   else
208     Process_SaveAs();
209  }
210 }
211
212
213 /***************************************************************************
214  *                                                                         *
215  * Routine:   Process_SaveAs                                               *
216  *                                                                         *
217  * Purpose:   Process the selection of the SAVE_AS button in the 'File'    *
218  *            pulldown menu.  This pops-up the FileSelectionDialog which   *
219  *            prompts the user to select the file in which to save the     *
220  *            current icon.                                                *
221  *                                                                         *
222  ***************************************************************************/
223
224 void
225 Process_SaveAs( void )
226 {
227   DialogFlag = SAVE_AS;
228   fileIOMode = FILE_WRITE;
229   XtManageChild(fileIODialog);
230   SetFileIODialogInfo();
231 }
232
233
234 /***************************************************************************
235  *                                                                         *
236  * Routine:   Process_Quit                                                 *
237  *                                                                         *
238  * Purpose:   Process the selection of the QUIT button in the 'File'       *
239  *            pulldown menu.  If the 'Dirty' flag is set, changes have     *
240  *            been made to the drawing tablet since the last save, which   *
241  *            would be lost by quitting.  Notify the user of this and      *
242  *            allow them the chance to change their minds.                 *
243  *                                                                         *
244  ***************************************************************************/
245
246 void
247 Process_Quit( void )
248 {
249   extern int ttMark;
250   extern int tt_tmpfile_fd;
251
252   DialogFlag = QUIT;
253   if (Dirty)
254     DoQueryDialog( GETSTR(16,16, "The current icon has not been saved.\nYour changes will be lost.") );
255   else {
256 #ifdef __TOOLTALK
257   edit_notifier(NULL, 0, 1);
258   ttdt_session_quit( 0, 0, 1 );
259   ttdt_close( 0, 0, 1 );
260   tt_release( ttMark );
261   if (tt_tmpfile_fd != -1) {
262      unlink(last_fname);
263      if (fileFormat != FORMAT_XPM ) {
264         unlink(dummy);
265      } /* if */
266   } /* if */
267 #endif
268 exit(0);
269 } /* else */
270 }
271
272 /*****************************************************************************/
273
274 void
275 Process_Query_OK( void )
276 {
277   extern int ttMark;
278   extern int tt_tmpfile_fd;
279
280   switch (DialogFlag) {
281     case QUIT :
282 #ifdef __TOOLTALK
283   edit_notifier(NULL, 0, 1);
284   ttdt_session_quit( 0, 0, 1 );
285   ttdt_close( 0, 0, 1 );
286   tt_release( ttMark );
287   if (tt_tmpfile_fd != -1) {
288      unlink(last_fname);
289      if (fileFormat != FORMAT_XPM ) {
290         unlink(dummy);}
291   }
292 #endif
293                   exit(0);
294     break;
295     case NEW  : Process_Resize();
296                 DialogFlag= NONE;
297     break;
298     case OPEN :   XtManageChild(fileIODialog);
299                   SetFileIODialogInfo();
300     break;
301     case SAVE_AS : SaveMeNot = False;
302                    Do_FileIO(NULL, NULL, NULL);
303     break;
304     case GRAB :   Do_GrabOp();
305     break;
306     case DROP :   Do_DropOp();
307     break;
308    } /* switch */
309    XSync(dpy, 0);
310 }
311
312 void
313 Process_Query_Cancel( void )
314 {
315   DialogFlag = NONE;
316 }
317
318 void
319 Process_Size_OK( void )
320 {
321   char *widthStr, *heightStr;
322   int new_width, new_height;
323
324   XtUnmanageChild(newIconDialog);
325   widthStr = XmTextFieldGetString(newWidthText);
326   heightStr = XmTextFieldGetString(newHeightText);
327   new_width = atoi(widthStr);
328   new_height = atoi(heightStr);
329   Eval_NewSize(new_width, new_height);
330   DialogFlag = NONE;
331 }
332
333 void
334 Eval_NewSize(
335         int width,
336         int height )
337 {
338   char old_width[10], old_height[10];
339   int flag;
340
341   if ((width < 1) || (width > xrdb.maxIconWidth) ||
342       (height < 1) || (height > xrdb.maxIconHeight)) {
343     sprintf(old_width, "%d", icon_width);
344     XmTextFieldSetString(newWidthText, old_width);
345     sprintf(old_height, "%d", icon_height);
346     XmTextFieldSetString(newHeightText, old_height);
347     DoErrorDialog(GETSTR(16,10,"Invalid width and/or\nheight specified"));
348    }
349   else {
350
351     if (DialogFlag == NEW)
352       flag = DO_NOT_SAVE;
353     else
354       flag = DO_SAVE;
355
356     Backup_Icons();    /* for undo */
357     Init_Icons(width, height, flag);
358
359    }
360 }
361
362 void
363 Process_Size_Cancel( void )
364 {
365   DialogFlag = NONE;
366   XtUnmanageChild(newIconDialog);
367 }
368
369 void
370 Process_StdErr_OK( void )
371 {
372   DialogFlag = NONE;
373   XtUnmanageChild(stdErrDialog);
374 }
375
376
377 /***************************************************************************
378  *                                                                         *
379  * Routine:   Process_Undo                                                 *
380  *                                                                         *
381  * Purpose:   Process the selection of the 'Undo' button in the 'Edit'     *
382  *            pulldown menu.  If no previous icon state is available,      *
383  *            notify the user via a pop-up error dialog.  Otherwise,       *
384  *            reverse the Backup_Icon() function behavior, update the      *
385  *            tablet to reflect the change, and set the UndoFlag to        *
386  *            False (indicating that no further undo ops. are possible).   *
387  *                                                                         *
388  ***************************************************************************/
389
390 void
391 Process_Undo( void )
392 {
393   if (UndoFlag) {
394     if ((icon_width != backup_width) || (icon_height != backup_height))
395       Init_Icons(backup_width, backup_height, DO_NOT_SAVE);
396     XCopyArea(dpy, prev_color_icon, color_icon,
397  Color_gc, 0, 0, icon_width, icon_height, 0, 0);
398     XCopyArea(dpy, prev_mono_icon, mono_icon,
399  Mono_gc, 0, 0, icon_width, icon_height, 0, 0);
400     if (XtWindow(iconImage))
401       XCopyArea(dpy, color_icon, XtWindow(iconImage), Color_gc,
402  0, 0, icon_width, icon_height, 0, 0);
403     if (XtWindow(monoImage))
404       XCopyArea(dpy, mono_icon, XtWindow(monoImage), Mono_gc,
405  0, 0, icon_width, icon_height, 0, 0);
406     Repaint_Exposed_Tablet();
407     UndoFlag = False;
408     Dirty = True;
409     XtSetSensitive( editMenu_undo_pb, False);
410
411   if ( NewFlag == TRUE ){
412     NewFlag = False;
413     strcpy(last_fname, undo_file);
414     last_fname[strlen(last_fname)] = '\0';
415     ChangeTitle();}
416    }
417   else
418     DoErrorDialog( GETSTR(16,8,"There is no previous\nimage available") );
419 }
420
421 void
422 Process_Cut( void )
423 {
424   Process_Copy(&CutCopy, &CutCopy_mono);
425   if (Selected) {
426     Backup_Icons();
427     XSetForeground(dpy, scratch_gc, Transparent);
428     XFillRectangle(dpy, color_icon, scratch_gc, select_box.x, select_box.y,
429  select_box.width, select_box.height);
430     XFillRectangle(dpy, mono_icon, scratch_gc, select_box.x, select_box.y,
431  select_box.width, select_box.height);
432     XFillRectangle(dpy, XtWindow(iconImage), scratch_gc,
433  select_box.x, select_box.y, select_box.width, select_box.height);
434     XFillRectangle(dpy, XtWindow(monoImage), scratch_gc,
435  select_box.x, select_box.y, select_box.width, select_box.height);
436     Transfer_Back_Image(select_box.x, select_box.y,
437    (select_box.x+select_box.width),
438    (select_box.y+select_box.height), FILL);
439  XtSetSensitive( editMenu_paste_pb, True);
440    }
441 }
442
443 void
444 Process_Copy(
445  XImage **img,
446  XImage **img_mono )
447 {
448   if (Selected) {
449     *img = XGetImage(dpy, color_icon, select_box.x, select_box.y,
450  select_box.width, select_box.height, AllPlanes, format);
451     *img_mono = XGetImage(dpy, mono_icon, select_box.x, select_box.y,
452  select_box.width, select_box.height, AllPlanes, format);
453  XtSetSensitive( editMenu_paste_pb, True);
454    }
455   else
456     DoErrorDialog( GETSTR(16,12, "No area has been selected") );
457 }
458
459 void
460 Process_Paste( void )
461 {
462   if (CutCopy) {
463     Backup_Icons();
464     Backup_G_Op = GraphicsOp;
465     GraphicsOp  = S_PASTE;
466     FirstRigid = True;
467     /* grayout unusable stuff */
468     XtSetSensitive( editMenu_cut_pb, False);
469     XtSetSensitive( editMenu_copy_pb, False);
470     XtSetSensitive(editMenu_rotate_pb, False);
471     XtSetSensitive(editMenu_flip_pb,  False);
472     XtSetSensitive(editMenu_scale_pb,  False);
473     XSync(dpy, 0);
474    }
475   else
476     DoErrorDialog(GETSTR(16,14, "No area was previously\ncut or copied"));
477 }
478
479 void
480 Process_Scale( void )
481 {
482   if (Selected) {
483     Backup_Icons();
484     Backup_G_Op = GraphicsOp;
485     GraphicsOp  = S_SCALE_1;
486     FirstRigid = True;
487    }
488   else
489     DoErrorDialog( GETSTR(16,12, "No area has been selected") );
490 }
491
492 void
493 Process_Resize( void )
494 {
495   int flag;
496   char old_width[10], old_height[10];
497   static char *untitledStr = NULL;
498
499   if ( DialogFlag == NEW ) {
500     strcpy(undo_file, last_fname);
501     last_fname[0] = '\0';
502     SavedOnce = False;
503     Backup_Icons();    /* for undo */
504     flag = DO_NOT_SAVE;
505     Init_Icons(icon_width, icon_height, flag);
506     if (!untitledStr)
507       untitledStr = GETSTR(2,20, "UNTITLED");
508     strcpy(last_fname, untitledStr);
509     strcat(last_fname, ".m.pm");
510     last_fname[strlen(last_fname)] = '\0';
511     ChangeTitle();
512     Repaint_Exposed_Tablet();
513     Dirty = False;
514     NewFlag = TRUE;
515     }
516   else{
517     sprintf(old_width, "%d", icon_width);
518     XmTextFieldSetString(newWidthText, old_width);
519     sprintf(old_height, "%d", icon_height);
520     XmTextFieldSetString(newHeightText, old_height);
521     XtManageChild(newIconDialog);
522     XmProcessTraversal(newWidthText, XmTRAVERSE_CURRENT);
523     XmTextFieldSetSelection(newWidthText, 0, 3, CurrentTime); }
524 }
525
526 /***************************************************************************
527  *                                                                         *
528  * Routine:   Process_Clear                                                *
529  *                                                                         *
530  * Purpose:   Process the selection of the 'Clear' button in the 'Edit'    *
531  *            pulldown menu.  This should be undo'able, just like a normal *
532  *            graphics ops., so back up the icons before wiping out their  *
533  *            contents.  After painting them to transparent, copy the      *
534  *            contents of the color icon back onto the tablet.             *
535  *                                                                         *
536  ***************************************************************************/
537
538 void
539 Process_Clear( void )
540 {
541   Backup_Icons();
542   XSetForeground(dpy, scratch_gc, Transparent);
543   XFillRectangle(dpy, color_icon, scratch_gc, 0, 0, icon_width, icon_height);
544   XFillRectangle(dpy, mono_icon, scratch_gc, 0, 0, icon_width, icon_height);
545   if (XtWindow(iconImage))
546     XCopyArea(dpy, color_icon, XtWindow(iconImage), scratch_gc,
547  0, 0, icon_width, icon_height, 0, 0);
548   if (XtWindow(monoImage))
549     XCopyArea(dpy, mono_icon, XtWindow(monoImage), scratch_gc,
550  0, 0, icon_width, icon_height, 0, 0);
551   Repaint_Exposed_Tablet();
552   Dirty = False;
553 }
554 /***************************************************************************
555  *                                                                         *
556  * Routine:   Process_GrabImage                                            *
557  *                                                                         *
558  * Purpose:   You're a computer programmer.  *YOU* figure out what it does.*
559  *                                                                         *
560  ***************************************************************************/
561
562 void
563 Process_GrabImage( void )
564 {
565   DialogFlag = GRAB;
566   if (Dirty)
567     DoQueryDialog( GETSTR(16,16, "The current icon has not been saved.\nYour changes will be lost.") );
568   else
569     Do_GrabOp();
570 }
571
572
573 /***************************************************************************
574  *                                                                         *
575  * Routine:   Process_AddHotspot                                           *
576  *                                                                         *
577  * Purpose:   Process the selection of the 'Add Hotspot' button in the     *
578  *            'Edit' pulldown menu.  Save the current graphics ops. flag   *
579  *            and set the flag to S_HOTSPOT.  The actual [x,y] location    *
580  *            selection for the hotspot will occur in the event processing *
581  *            loop for the tablet.                                         *
582  *                                                                         *
583  ***************************************************************************/
584
585 void
586 Process_AddHotspot( void )
587 {
588   Backup_G_Op = GraphicsOp;
589   GraphicsOp  = S_HOTSPOT;
590 }
591
592
593 /***************************************************************************
594  *                                                                         *
595  * Routine:   Process_DeleteHotspot                                        *
596  *                                                                         *
597  * Purpose:   Process the selection of the 'Delete Hotspot' button in the  *
598  *            'Edit' pulldown menu.  Set the X and Y hot values to -1, set *
599  *            the hotSpot flag to FALSE, and repaint the exposed portion   *
600  *            of the tablet (to remove the visible hotspot indicator).     *
601  *                                                                         *
602  ***************************************************************************/
603
604 void
605 Process_DeleteHotspot( void )
606 {
607   X_Hot = -1;
608   Y_Hot = -1;
609   hotSpot = False;
610   Repaint_Exposed_Tablet();
611 }
612
613 void
614 Process_RotateLeft( void )
615 {
616   XImage *color_img, *mono_img;
617
618   Process_Copy(&color_img, &mono_img);
619   /* Turn off Paste since no area is available to Paste */
620   XtSetSensitive( editMenu_paste_pb, False);
621   if (Selected) {
622     Backup_Icons();
623     Rotate = XGetImage(dpy, root, 0, 0, color_img->height, color_img->width,
624     AllPlanes, format);
625     Rotate_mono = XGetImage(dpy, root, 0, 0, mono_img->height, mono_img->width,
626     AllPlanes, format);
627     Block_Rotate(color_img, Rotate, ROTATE_L);
628     Block_Rotate(mono_img, Rotate_mono, ROTATE_L);
629     XDestroyImage(color_img);
630     XDestroyImage(mono_img);
631     Backup_G_Op = GraphicsOp;
632     GraphicsOp  = S_ROTATE;
633     FirstRigid = True;
634    }
635 }
636
637 void
638 Process_RotateRight( void )
639 {
640   XImage *color_img, *mono_img;
641
642   Process_Copy(&color_img, &mono_img);
643   /* Turn off Paste since no area is available to Paste */
644   XtSetSensitive( editMenu_paste_pb, False);
645   if (Selected) {
646     Backup_Icons();
647     Rotate = XGetImage(dpy, root, 0, 0, color_img->height, color_img->width,
648     AllPlanes, format);
649     Rotate_mono = XGetImage(dpy, root, 0, 0, mono_img->height, mono_img->width,
650     AllPlanes, format);
651     Block_Rotate(color_img, Rotate, ROTATE_R);
652     Block_Rotate(mono_img, Rotate_mono, ROTATE_R);
653     XDestroyImage(color_img);
654     XDestroyImage(mono_img);
655     Backup_G_Op = GraphicsOp;
656     GraphicsOp  = S_ROTATE;
657     FirstRigid = True;
658    }
659 }
660
661
662 /***************************************************************************
663  *                                                                         *
664  * Routine:   Process_FlipV                                                *
665  *                                                                         *
666  * Purpose:   Process the selection of the 'Vertical' button in the 'Edit' *
667  *            ->'Flip Area' pulldown menu.  This should be undo'able,      *
668  *            just like a normal graphics ops., so back up the icons       *
669  *            first, then call Mirror_Image(), with the flag VERTICAL.     *
670  *            If no area is SELECTED, map the error dialog with the        *
671  *            appropriate message.                                         *
672  *                                                                         *
673  ***************************************************************************/
674
675 void
676 Process_FlipV( void )
677 {
678   if (Selected) {
679     Backup_Icons();
680     Mirror_Image(VERTICAL);
681    }
682   else
683     DoErrorDialog( GETSTR(16,12, "No area has been selected") );
684 }
685
686
687 /***************************************************************************
688  *                                                                         *
689  * Routine:   Process_FlipH                                                *
690  *                                                                         *
691  * Purpose:   Process the selection of the 'Horizontal' button in the      *
692  *            'Edit'->'Flip Area' pulldown menu.  This should be undo'able,*
693  *            just like a normal graphics ops., so back up the icons       *
694  *            first, then call Mirror_Image(), with the flag HORIZONTAL.   *
695  *            If no area is SELECTED, map the error dialog with the        *
696  *            appropriate message.                                         *
697  *                                                                         *
698  ***************************************************************************/
699
700 void
701 Process_FlipH( void )
702 {
703   if (Selected) {
704     Backup_Icons();
705     Mirror_Image(HORIZONTAL);
706    }
707   else
708     DoErrorDialog( GETSTR(16,12, "No area has been selected") );
709 }
710
711
712 /***************************************************************************
713  *                                                                         *
714  * Routine:   Process_GridState                                            *
715  *                                                                         *
716  * Purpose:   Process the selection of the 'Visible Grid' button in the    *
717  *            'Options' pulldown menu.  Set the GridEnabled internal flag  *
718  *            to reflect the current state of the toggle.  If the value is *
719  *            different from the previous value, repaint the tablet.       *
720  *                                                                         *
721  ***************************************************************************/
722
723 void
724 Process_GridState( void )
725 {
726   Arg args[10];
727   int i;
728   Boolean new_val;
729
730   i = 0;
731   XtSetArg(args[i], XmNset, &new_val); i++;
732   XtGetValues(optionsMenu_grid, args, i);
733 #ifdef DEBUG
734   if (debug) {
735     stat_out("Toggling tablet grid ");
736     switch (new_val) {
737       case True   : stat_out("ON\n");
738       break;
739       case False  : stat_out("OFF\n");
740       break;
741      }
742    }
743 #endif
744   if (new_val != GridEnabled) {
745     GridEnabled = new_val;
746     Repaint_Exposed_Tablet();
747    }
748 }
749 /***************************************************************************
750  *                                                                         *
751  * Routine:   ConvertDropName                                              *
752  *                                                                         *
753  * Purpose:  Convert the "object" received from bms to a full path name    *
754  *           note:  I am making BIG assumptions about the format of the    *
755  *                  file I am getting from dtfile. "<host> - <path>"      *
756  * WARNING:  I have used an Xe function directly (XeIsLocalHostP), rather  *
757  *           than include Dt/Connect.h, which was causing bad things to    *
758  *           happen at build time, probably because dticon is not ansi-   *
759  *           clean (it tried to get c++ version of /usr/include/stdlib.h?) *
760  *           It's simply too late to clean up the ansi... (the bell tolls) *
761  *                                                                         *
762  ***************************************************************************/
763 static char *
764 ConvertDropName( char *objects)
765 {
766     char *host;
767     char *path;
768     char *fullName;
769     char *tmp;
770     char *netfile;
771
772     host = objects;
773     tmp = strchr(objects,' ');
774     if (tmp==NULL)      /* shouldn't happen */
775       return (strdup(strchr(objects, '/')));
776
777     /* check if same host */
778     tmp[0] = '\0';
779     if ((Boolean)XeIsLocalHostP(host))
780     {
781         tmp[0] = ' ';
782         return (strdup(strchr(objects, '/')));
783     }
784
785     /* different host... get full path name */
786     path = tmp+3;      /* skip past the " - " */
787
788     /* Convert to a valid name on the local host. */
789     netfile = tt_host_file_netfile(host, path);
790     fullName = tt_netfile_file(netfile);
791     tt_free(netfile);
792
793     tmp[0] = ' ';      /* put back the " " after host name */
794     return (fullName);
795 }
796
797
798 /***************************************************************************
799  *                                                                         *
800  * Routine:   Process_DropCheckOp                                          *
801  *                                                                         *
802  * Purpose:   Validate the drag-n-drop operation that just occured on the  *
803  *            tablet window.                                               *
804  *                                                                         *
805  ***************************************************************************/
806
807 void
808 Process_DropCheckOp(
809  Widget w,
810  XtPointer client_data,
811  XtPointer call_data)
812 {
813   DtDndTransferCallback transferInfo = (DtDndTransferCallback) call_data;
814
815   /* save name in global array for later (Do_DropOp function) */
816   /*
817    * REMIND:  Need to address case of multiple file names - here and
818    *   elsewhere in the code. This continues with the assumption
819    *  that there is only one file name transfered.
820    */
821   if (transferInfo->dropData->numItems > 0)
822   {
823     strncpy (dropFileName, transferInfo->dropData->data.files[0],
824       MAX_FNAME);
825   }
826   else
827     dropFileName[0] = '\0';
828
829   Do_DropCheckOp(transferInfo);
830
831 #ifdef DEBUG
832   if (debug) {
833     stat_out("      file-name = %s\n", dropFileName);
834    }
835 #endif
836
837 }
838
839 extern Widget  formatMenu_xpm_tb, formatMenu_xbm_tb;
840 extern int successFormat, x_hot, y_hot;
841 extern unsigned int width_ret, height_ret;
842
843 /***************************************************************************
844  *                                                                         *
845  * Routine:   Do_DropCheckOp                                               *
846  *                                                                         *
847  * Purpose:   Verify the drag-n-drop operation that just occured on the    *
848  *            tablet window.                                               *
849  *                                                                         *
850  ***************************************************************************/
851
852 static void
853 Do_DropCheckOp(
854  DtDndTransferCallback transferInfo)
855 {
856
857 #ifdef DEBUG
858   if (debug) {
859     stat_out("    Doing DROP OPERATION :\n");
860     stat_out("    name is = %s\n", dropFileName);
861    }
862 #endif
863
864   if (dropFileName[0] != '\0')
865   {
866     if (!Read_File(dropFileName))
867     {
868        DoErrorDialog( GETSTR(16,2,
869       "The file cannot be accessed\nor contains invalid data") );
870       transferInfo->status = DtDND_FAILURE;
871     }
872     else
873     {
874       transferInfo->status = DtDND_SUCCESS;
875     } /* else */
876   } /* if */
877 }
878
879 void
880 Process_DropOp(
881  Widget w,
882         XtPointer client_data,
883         XtPointer call_data)
884 {
885       DialogFlag = DROP;
886
887       if (Dirty)
888         DoQueryDialog( GETSTR(16,16, "The current icon has not been saved.\n\nYour changes will be lost.") );
889       else  {
890             Do_DropOp();}
891 }
892
893 static void
894 Do_DropOp(void)
895 {
896       if (successFormat == FORMAT_XPM)
897       {
898         X_Hot = xpm_ReadAttribs.x_hotspot;
899         Y_Hot = xpm_ReadAttribs.y_hotspot;
900         Display_XPMFile(xpm_ReadAttribs.width, xpm_ReadAttribs.height);
901       }
902       else if (successFormat == FORMAT_XBM)
903       {
904         X_Hot = x_hot;
905         Y_Hot = y_hot;
906         Display_XBMFile(width_ret, height_ret);
907       }
908
909       Dirty = False;
910 }
911
912 /***************************************************************************
913  *                                                                         *
914  * Routine:   Do_Paste                                                     *
915  *                                                                         *
916  * Purpose:   Paste the CutCopy image at the tablet location specified by  *
917  *            the [x,y] parameters in the call.                            *
918  *                                                                         *
919  ***************************************************************************/
920
921 void
922 Do_Paste(
923         int x,
924         int y )
925 {
926   XImage *color_img, *mono_img;
927
928   if (GraphicsOp == S_PASTE) {
929     color_img = CutCopy;
930     mono_img  = CutCopy_mono;
931    }
932   else if (GraphicsOp == S_ROTATE) {
933     color_img = Rotate;
934     mono_img  = Rotate_mono;
935    }
936   else {
937     color_img = Scale;
938     mono_img  = Scale_mono;
939    }
940
941   if (GraphicsOp == S_PASTE)
942   {
943     GraphicsOp = S_WAIT_RELEASE;
944   }
945   else
946   {
947     GraphicsOp = Backup_G_Op;
948     if (Backup_G_Op == SELECT)
949       Start_HotBox(CONTINUE);
950     Backup_G_Op = NULL;
951   }
952
953   XPutImage(dpy, color_icon, Color_gc, color_img, 0, 0, x, y,
954   color_img->width, color_img->height);
955   XPutImage(dpy, mono_icon, Mono_gc, mono_img, 0, 0, x, y,
956   mono_img->width, mono_img->height);
957   XCopyArea(dpy, color_icon, XtWindow(iconImage), Color_gc,
958   x, y, color_img->width, color_img->height, x, y);
959   XCopyArea(dpy, mono_icon, XtWindow(monoImage), Mono_gc,
960   x, y, mono_img->width, mono_img->height, x, y);
961   Transfer_Back_Image(x, y, x+color_img->width, y+color_img->height, FILL);
962 }
963