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