2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $TOG: utils.c /main/9 1998/09/24 12:32:05 samborn $ */
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
30 **********************************************************************/
31 /******************************************************************************
34 ** Description: X11-based multi-color icon editor
36 ** File: utils.c, which contains the following subroutines or
38 ** Create_Gfx_Labels()
45 ** Repaint_Exposed_Tablet()
48 ** Transfer_Back_Image()
56 ** Switch_FillSolids()
69 ******************************************************************************
71 ** Copyright 1991 by 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.
76 ** Hewlett-Packard makes no representations about the suitibility of this
77 ** software for any purpose. It is provided "as is" without express or
80 ******************************************************************************/
83 #include <X11/cursorfont.h>
84 #include <Xm/Protocols.h>
87 #include <Xm/MessageB.h>
88 #include <Xm/VendorSEP.h>
89 #include <Dt/UserMsg.h>
92 #include "externals.h"
94 /* Copied from Xm/BaseClassI.h */
95 extern XmWidgetExtData _XmGetWidgetExtData(
97 #if NeedWidePrototypes
98 unsigned int extType) ;
100 unsigned char extType) ;
101 #endif /* NeedWidePrototypes */
103 #include "pixmaps/Circle.pm"
104 #include "pixmaps/CircleSolid.pm"
105 #include "pixmaps/Connected.pm"
106 #include "pixmaps/ConnectedClosed.pm"
107 #include "pixmaps/ConnecClosedSolid.pm"
108 #include "pixmaps/Ellipse.pm"
109 #include "pixmaps/EllipseSolid.pm"
110 #include "pixmaps/Eraser.pm"
111 #include "pixmaps/Rectangle.pm"
112 #include "pixmaps/RectangleSolid.pm"
113 #include "pixmaps/PaintBucket.pm"
114 #include "pixmaps/Pencil.pm"
115 #include "pixmaps/Line.pm"
116 #include "pixmaps/SelectArea.pm"
118 #include "bitmaps/q_mark.xbm"
120 extern Widget color_pb1, color_pb2, color_pb3, color_pb4,
121 color_pb5, color_pb6, color_pb7, color_pb8;
122 extern Widget grey_pb1, grey_pb2, grey_pb3, grey_pb4,
123 grey_pb5, grey_pb6, grey_pb7, grey_pb8;
124 extern Widget fgColorToggle, bgColorToggle, tsColorToggle,
125 bsColorToggle, selectColorToggle,
126 transparentColorToggle;
127 extern Widget pointButton, floodButton, lineButton, polylineButton,
128 rectangleButton, polygonButton, circleButton,
129 ellipseButton, eraseButton, selectButton;
130 extern Widget viewport, tablet, tabletBorder, tabletFrame;
131 extern Widget iconForm, iconSize, monoLabel;
132 extern Widget fillToggle, magMenu_8x_tb;
133 extern Widget formatMenu_xbm_tb, formatMenu_xpm_tb;
134 extern Widget optionsMenu_grid, menu1, queryDialog, stdErrDialog;
135 extern Widget tablet_wid;
136 extern Window tablet_win;
138 static int jskXerrorDebug();
139 static int jskXerrorIODebug();
141 Widget editMenu_undo_pb;
143 void GetSessionInfo( void );
144 void Set_Gfx_Labels( Boolean );
149 int PixelTableLookup(
152 extern void *Process_DropCheckOp(
156 extern void *Process_DropOp(
160 extern void Repaint_Tablet(Window, int, int, int, int);
161 extern void Init_Widget_List(void);
162 extern void Init_Pen_Colors(Widget);
163 extern void Init_Color_Table(void);
164 extern void RegisterDropSites(void);
165 extern void Abort(char *);
166 extern void DoErrorDialog(char *);
168 char dash_list[2] = {1,1};
170 char start_file[256];
174 Position x_margin, y_margin;
175 Pixmap pointPix, floodPix, linePix, polylinePix, rectPix;
176 Pixmap polygonPix, circlePix, ellipsePix, eraserPix, selectPix;
177 Pixmap rectSolidPix, circleSolidPix, polygonSolidPix, ellipseSolidPix;
178 extern int successFormat, x_hot, y_hot;
179 extern unsigned int width_ret, height_ret;
181 /* Structure used on a save session to see if a dt is iconic */
188 /***************************************************************************
190 * Routine: Create_Gfx_Labels *
192 * Purpose: Initialize all the global variables used by the icon editor. *
194 ***************************************************************************/
203 Pixmap q_markPix, mask;
205 depth = XDefaultDepth(dpy, screen);
208 pointPix = XCreatePixmapFromBitmapData(dpy, root,
209 point_bits, point_width, point_height,
211 floodPix = XCreatePixmapFromBitmapData(dpy, root,
212 flood_bits, flood_width, flood_height,
214 linePix = XCreatePixmapFromBitmapData(dpy, root,
215 line_bits, line_width, line_height,
217 polylinePix = XCreatePixmapFromBitmapData(dpy, root,
218 polyline_bits, polyline_width, polyline_height,
220 rectPix = XCreatePixmapFromBitmapData(dpy, root,
221 rectangle_bits, rectangle_width, rectangle_height,
223 polygonPix = XCreatePixmapFromBitmapData(dpy, root,
224 polygon_bits, polygon_width, polygon_height,
226 circlePix = XCreatePixmapFromBitmapData(dpy, root,
227 circle_bits, circle_width, circle_height,
229 ellipsePix = XCreatePixmapFromBitmapData(dpy, root,
230 ellipse_bits, ellipse_width, ellipse_height,
232 eraserPix = XCreatePixmapFromBitmapData(dpy, root,
233 eraser_bits, eraser_width, eraser_height,
235 selectPix = XCreatePixmapFromBitmapData(dpy, root,
236 select_bits, select_width, select_height,
240 xpm_ReadAttribs.valuemask = READ_FLAGS;
241 xpm_ReadAttribs.colorsymbols = colorSymbols;
242 xpm_ReadAttribs.numsymbols = NUM_PENS;
244 status = _DtXpmCreatePixmapFromData(dpy, root, Circle, &circlePix, &mask,
246 if (status != XpmSuccess) Abort(GETSTR(10,2, "Cannot initialize button icon for circle"));
247 status = _DtXpmCreatePixmapFromData(dpy, root, CircleSolid, &circleSolidPix,
248 &mask, &xpm_ReadAttribs);
249 if (status != XpmSuccess) Abort(GETSTR(10,4, "Cannot initialize button icon for solid circle"));
250 status = _DtXpmCreatePixmapFromData(dpy, root, Connected, &polylinePix, &mask,
252 if (status != XpmSuccess) Abort(GETSTR(10,6, "Cannot initialize button icon for polyline"));
253 status = _DtXpmCreatePixmapFromData(dpy, root, ConnectedClosed, &polygonPix,
254 &mask, &xpm_ReadAttribs);
255 if (status != XpmSuccess) Abort(GETSTR(10,8, "Cannot initialize button icon for polygon"));
256 status = _DtXpmCreatePixmapFromData(dpy, root, ConnecClosedSolid,
257 &polygonSolidPix, &mask, &xpm_ReadAttribs);
258 if (status != XpmSuccess) Abort(GETSTR(10,10, "Cannot initialize button icon for solid polygon"));
259 status = _DtXpmCreatePixmapFromData(dpy, root, Ellipse, &ellipsePix, &mask,
261 if (status != XpmSuccess) Abort(GETSTR(10,12, "Cannot initialize button icon for ellipse"));
262 status = _DtXpmCreatePixmapFromData(dpy, root, EllipseSolid, &ellipseSolidPix,
263 &mask, &xpm_ReadAttribs);
264 if (status != XpmSuccess) Abort(GETSTR(10,14, "Cannot initialize button icon for solid ellipse"));
265 status = _DtXpmCreatePixmapFromData(dpy, root, Eraser, &eraserPix, &mask,
267 if (status != XpmSuccess) Abort(GETSTR(10,16, "Cannot initialize button icon for eraser"));
268 status = _DtXpmCreatePixmapFromData(dpy, root, Line, &linePix, &mask,
270 if (status != XpmSuccess) Abort(GETSTR(10,18, "Cannot initialize button icon for line"));
271 status = _DtXpmCreatePixmapFromData(dpy, root, PaintBucket, &floodPix, &mask,
273 if (status != XpmSuccess) Abort(GETSTR(10,20, "Cannot initialize button icon for flood"));
274 status = _DtXpmCreatePixmapFromData(dpy, root, Pencil, &pointPix, &mask,
276 if (status != XpmSuccess) Abort(GETSTR(10,22, "Cannot initialize button icon for point"));
277 status = _DtXpmCreatePixmapFromData(dpy, root, Rectangle, &rectPix, &mask,
279 if (status != XpmSuccess) Abort(GETSTR(10,24, "Cannot initialize button icon for rectangle"));
280 status = _DtXpmCreatePixmapFromData(dpy, root, RectangleSolid, &rectSolidPix,
281 &mask, &xpm_ReadAttribs);
282 if (status != XpmSuccess) Abort(GETSTR(10,26, "Cannot initialize button icon for solid rectangle"));
283 status = _DtXpmCreatePixmapFromData(dpy, root, SelectArea, &selectPix, &mask,
285 if (status != XpmSuccess) Abort(GETSTR(10,28, "Cannot initialize button icon for select"));
287 q_markPix = XCreatePixmapFromBitmapData(dpy, root,
288 (char*)q_mark_bits, q_mark_width, q_mark_height,
292 XtSetArg(args[i], XmNlabelPixmap, pointPix); i++;
293 XtSetValues(pointButton, args, i);
295 XtSetArg(args[i], XmNlabelPixmap, linePix); i++;
296 XtSetValues(lineButton, args, i);
298 XtSetArg(args[i], XmNlabelPixmap, eraserPix); i++;
299 XtSetValues(eraseButton, args, i);
301 XtSetArg(args[i], XmNlabelPixmap, floodPix); i++;
302 XtSetValues(floodButton, args, i);
304 XtSetArg(args[i], XmNlabelPixmap, polylinePix); i++;
305 XtSetValues(polylineButton, args, i);
307 XtSetArg(args[i], XmNlabelPixmap, selectPix); i++;
308 XtSetValues(selectButton, args, i);
310 XtSetArg(args[i], XmNlabelPixmap, q_markPix); i++;
311 XtSetValues(queryDialog, args, i);
313 Set_Gfx_Labels(HOLLOW);
316 /***************************************************************************
318 * Routine: Init_Editor *
320 * Purpose: Initialize all the global variables, states, widgets, etc, *
321 * for the icon editor. This is a long, messy, somewhat *
322 * rambling routine. *
324 ***************************************************************************/
335 /*** window ID of tablet ***/
338 /*** Nothing needs to be saved, yet ***/
341 /*** Initial Graphics states, pen color, etc. ***/
343 CurrentColor = COLOR1;
344 ColorBlock = STATIC_COLOR;
349 /*** file I/O related globals ***/
350 last_fname[0] = '\0';
354 XSetErrorHandler(jskXerrorDebug);
355 XSetIOErrorHandler(jskXerrorIODebug);
357 /*** Xlib-related globals ***/
358 dpy = XtDisplay(wid);
360 root = DefaultRootWindow(dpy);
361 screen = DefaultScreen(dpy);
362 screen_ptr = XtScreen(wid);
363 black_pixel = BlackPixel(dpy, screen);
364 white_pixel = WhitePixel(dpy, screen);
365 Cmap = DefaultColormap(dpy, screen);
367 /*** initialize global pixel table data ***/
368 pixelTable.pixelTableSize = 0;
369 pixelTable.numItems = 0;
370 pixelTable.lastFound = 0;
371 pixelTable.item = NULL;
373 /*** Initialize the GCs used by the app. ***/
374 Color_gc = XCreateGC(dpy, root, 0, 0);
375 Mono_gc = XCreateGC(dpy, root, 0, 0);
376 Grid_gc = XCreateGC(dpy, root, 0, 0);
377 Erase_gc = XCreateGC(dpy, root, 0, 0);
378 Flicker_gc = XCreateGC(dpy, root, 0, 0);
379 scratch_gc = XCreateGC(dpy, root, 0, 0);
380 XSetState(dpy, Flicker_gc, black_pixel, white_pixel, GXinvert,
381 (DefaultDepthOfScreen(XtScreen(wid)) > 8) ? AllPlanes : 0x01);
382 XSetSubwindowMode(dpy, Flicker_gc, IncludeInferiors);
383 XSetDashes(dpy, Grid_gc, 0, dash_list, 2);
384 XSetLineAttributes(dpy, Grid_gc, 0, LineDoubleDash, CapButt, JoinMiter);
386 /*** Initialize the widget variables ***/
389 /*** Initialize the pen colors and the internal color table ***/
390 Init_Pen_Colors(wid);
392 XSetForeground(dpy, Erase_gc, Transparent);
394 /*** configure the color and mono icons to their initial size ***/
395 Init_Icons(icon_width, icon_height, DO_NOT_SAVE);
398 DtInitialize (dpy, wid, progName, progName);
400 /*** Drop site registration must occur after DtInitialize() ***/
404 multiClickTime = XtGetMultiClickTime(dpy);
406 /*** Now, do all the tedious widget initialization ***/
408 XtSetArg(args[i], XmNset, True); i++;
409 XtSetValues(StaticWid[CurrentColor], args, i);
410 XtSetValues(GraphicOpsWid[GraphicsOp], args, i);
411 XtSetValues(magMenu_8x_tb, args, i);
412 XtSetValues(optionsMenu_grid, args, i);
413 XtSetValues(formatMenu_xpm_tb, args, i);
415 XtSetArg(args[i], XmNbackground, Transparent); i++;
416 XtSetValues(tablet_wid, args, i);
417 XtSetValues(tabletBorder, args, i);
418 XSetForeground(dpy, Color_gc, StaticPen[0]);
419 XSetForeground(dpy, Mono_gc, StaticMono[0]);
421 XtSetArg(args[i], XmNset, FillSolids); i++;
422 XtSetValues(fillToggle, args, i);
424 XtSetArg(args[i], XmNclipWindow, &clip_wid); i++;
425 XtGetValues(viewport, args, i);
432 stat_out("DEFAULT TIME-OUT VALUE IS %d MILLISECONDS\n", multiClickTime);
433 stat_out("****CLIP WINDOW WIDGET = %d\n", clip_wid);
434 stat_out(" TABLET OFFSETS [x,y] = [%d,%d]\n", x_margin, y_margin);
439 XtSetArg(args[i], XmNbackground, Transparent); i++;
440 XtSetValues(clip_wid, args, i);
442 XtSetArg(args[i], XmNset, False); i++;
443 XtSetValues(floodButton, args, i);
444 XtSetValues(lineButton, args, i);
445 XtSetValues(polylineButton, args, i);
446 XtSetValues(rectangleButton, args, i);
447 XtSetValues(polygonButton, args, i);
448 XtSetValues(circleButton, args, i);
449 XtSetValues(ellipseButton, args, i);
450 XtSetValues(eraseButton, args, i);
451 XtSetValues(selectButton, args, i);
453 XtSetArg(args[i], XmNset, True); i++;
454 XtSetValues(pointButton, args, i);
458 /***************************************************************************
460 * Routine: GetMarginData *
462 * Purpose: We need to get margin data AFTER these widgets are realized *
463 * in order to get valid data... so do it here *
465 ***************************************************************************/
468 GetMarginData( void )
477 stat_out("****** Getting margin data: x=%d y=%d\n", x_margin, y_margin);
481 XtSetArg(args[i], XmNx, &lx); i++;
482 XtSetArg(args[i], XmNy, &ly); i++;
483 XtGetValues(tabletFrame, args, i);
487 XtSetArg(args[i], XmNx, &lx); i++;
488 XtSetArg(args[i], XmNy, &ly); i++;
489 XtGetValues(tablet_wid, args, i);
495 stat_out("****** margin data: x=%d y=%d\n", x_margin, y_margin);
501 /***************************************************************************
503 * Routine: New_MagFactor *
505 * Purpose: The user has just selected a new magnification factor for *
506 * the fat pixels on the tablet. Update the MagFactor global *
507 * variable and reapaint the visible portion of the tablet to *
508 * reflect the change. *
510 ***************************************************************************/
521 stat_out("****** Changing MagFactor to %d\n", new_value);
524 MagFactor = new_value;
526 XtSetArg(args[i], XmNwidth, (icon_width*MagFactor)); i++;
527 XtSetArg(args[i], XmNheight, (icon_height*MagFactor)); i++;
528 XtSetValues(tablet_wid, args, i);
531 /* This code does not seem to be needed and since it slows down
532 the grid drawing I'll take it out */
533 /*Repaint_Exposed_Tablet();*/
537 /***************************************************************************
539 * Routine: New_FileFormat *
541 * Purpose: Update the fileFormat value to reflect the user's current *
542 * choice of default file output formats. *
544 ***************************************************************************/
553 stat_out("****** Changing Output File Format to ");
555 case FORMAT_XPM : stat_out("XPM\n");
557 case FORMAT_XBM : stat_out("XBM\n");
559 default : stat_out("UNKNOWN\n");
565 fileFormat = new_value;
570 /***************************************************************************
572 * Routine: Icon_Coords *
574 * Purpose: Convert a set of [x,y] values (acquired from the tablet) *
575 * into the equivalent [x,y] values they represent on the *
576 * actual icon being created/modified. *
578 ***************************************************************************/
587 *fat_x = normal_x / MagFactor;
588 *fat_y = normal_y / MagFactor;
592 /***************************************************************************
594 * Routine: Tablet_Coords *
596 * Purpose: Convert a set of fat [x,y] values back into raw [x,y] values *
597 * which map to the top-left corner of the fat pixel value. *
599 ***************************************************************************/
608 *raw_x = fat_x * MagFactor;
609 *raw_y = fat_y * MagFactor;
613 /***************************************************************************
615 * Routine: Quantize *
617 * Purpose: Adjust a set of [x,] values so that they mark the top-left *
618 * corner (or the middle, depending on the 'center' flag) of *
619 * whatever 'fat' pixel they map onto. This will insure that *
620 * any operation involving rubberband lines leaps from fat *
621 * pixel center to fat pixel center, providing a clear visual *
622 * indicator of which pixel currently contains the line/point. *
624 ***************************************************************************/
637 if ((lx%MagFactor) != 0)
638 lx = (lx / MagFactor) * MagFactor;
639 if ((ly%MagFactor) != 0)
640 ly = (ly / MagFactor) * MagFactor;
650 /***************************************************************************
652 * Routine: Repaint_Exposed_Tablet *
654 * Purpose: Repaint the rectangular section of the tablet currently *
655 * visible in the clipping area widget of the scrolled window *
656 * widget. To do this, we get the current width and height *
657 * of the clipping area widget, the current width and height *
658 * of the drawing area manager widget (the clipping area *
659 * widget's immediate child), and the x and y position of the *
660 * drawing area manager widget. This will allow us to cal- *
661 * culate what portion of the tablet (drawn button widget) is *
662 * currently visible in the clipping area widget. We then *
663 * request th Repaint_Tablet() routine to repaint that portion *
664 * of the drawn button. *
666 ***************************************************************************/
669 Repaint_Exposed_Tablet( void )
674 Dimension c_width, c_height, t_width, t_height;
677 XtSetArg(args[i], XmNwidth, &c_width); i++;
678 XtSetArg(args[i], XmNheight, &c_height); i++;
679 XtGetValues(clip_wid, args, i);
681 XtSetArg(args[i], XmNx, &t_x); i++;
682 XtSetArg(args[i], XmNy, &t_y); i++;
683 XtSetArg(args[i], XmNwidth, &t_width); i++;
684 XtSetArg(args[i], XmNheight, &t_height); i++;
685 XtGetValues(tabletBorder, args, i);
691 if (t_x < 0) t_x = 0;
692 if (t_y < 0) t_y = 0;
694 Repaint_Tablet(tablet_win, t_x, t_y, c_width, c_height);
698 /***************************************************************************
700 * Routine: Repaint_Tablet *
702 * Purpose: Repaint the rectangular section of the tablet described by *
703 * the [x,y,width,height] values in the XRectangle. *
705 ***************************************************************************/
718 scratch_img = XGetImage(dpy, color_icon, 0, 0, icon_width, icon_height,
722 stat_out("****** Repaint_Tablet: x,y=%d,%d w,h=%d,%d\n", x,y,width,height);
725 for (i=x; i<x+width+MagFactor; i+=MagFactor)
726 for (j=y; j<y+height+MagFactor; j+=MagFactor) {
727 Icon_Coords(i, j, &lx, &ly);
728 if ((lx >= 0) && (lx < icon_width) &&
729 (ly >= 0) && (ly < icon_height)) {
730 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, lx, ly));
731 XFillRectangle(dpy, tablet_win, scratch_gc,
732 lx*MagFactor, ly*MagFactor, MagFactor, MagFactor);
734 if ((lx == X_Hot) && (ly == Y_Hot)) {
735 XDrawLine(dpy, tablet_win, Grid_gc,
736 lx*MagFactor, ly*MagFactor+MagFactor, lx*MagFactor+MagFactor, ly*MagFactor);
737 XDrawLine(dpy, tablet_win, Grid_gc,
738 lx*MagFactor, ly*MagFactor, lx*MagFactor+MagFactor, ly*MagFactor+MagFactor);
743 Quantize(&x, &y, False);
744 width += (MagFactor*2);
745 height += (MagFactor*2);
748 Draw the grid if Enabled....
751 for (i=x; i<=x+width+MagFactor; i+=MagFactor)
752 XDrawLine(dpy, win, Grid_gc, i, y, i, (y+height));
753 for (i=y; i<=y+height+MagFactor; i+=MagFactor)
754 XDrawLine(dpy, win, Grid_gc, x, i, (x+width), i);
758 XDestroyImage(scratch_img);
762 /***************************************************************************
764 * Routine: Paint_Tile *
766 * Purpose: Paint a single rectangular tile of size MagFactor x *
767 * MagFactor with the color supplied in the passed GC. *
768 * The X and Y parameters are coordinates for the 1:1 *
769 * sized icon, and not direct coordinates for the tablet. *
771 ***************************************************************************/
779 XFillRectangle(dpy, tablet_win, gc,
780 x*MagFactor, y*MagFactor, MagFactor, MagFactor);
783 XDrawRectangle(dpy, tablet_win, Grid_gc,
784 x*MagFactor, y*MagFactor, MagFactor, MagFactor);
787 if ((x == X_Hot) && (y == Y_Hot)) {
788 XDrawLine(dpy, tablet_win, Grid_gc,
789 x*MagFactor, y*MagFactor+MagFactor, x*MagFactor+MagFactor, y*MagFactor);
790 XDrawLine(dpy, tablet_win, Grid_gc,
791 x*MagFactor, y*MagFactor, x*MagFactor+MagFactor, y*MagFactor+MagFactor);
796 /***************************************************************************
798 * Routine: Transfer_Back_Image *
800 * Purpose: Paint a single rectangular tile of size MagFactor x *
801 * MagFactor with the color supplied in the passed GC. *
802 * The [x,y] coordinate pairs are both icon coordinates, *
803 * not tablet coordinates. *
805 ***************************************************************************/
815 int min_x, min_y, max_x, max_y, i, j;
820 stat_out("Entering Transfer_Back_Image\n");
821 stat_out("Values are x1:%d, y1:%d, x2:%d, y2:%d, flag = ",
823 stat_out(" icon size is width:%d, height:%d\n", icon_width, icon_height);
825 case HOLLOW : stat_out("HOLLOW\n");
827 case FILL : stat_out("FILL\n");
829 default : stat_out("UNKNOWN\n");
835 min_x = ((x1 < x2) ? x1 : x2);
836 min_y = ((y1 < y2) ? y1 : y2);
837 max_x = ((x1 > x2) ? x1 : x2);
838 max_y = ((y1 > y2) ? y1 : y2);
840 /*** make sure max_x and max_y are within icon ***/
841 if (max_x >= icon_width)
842 max_x = icon_width-1;
843 if (max_y >= icon_height)
844 max_y = icon_height-1;
846 scratch_img = XGetImage(dpy, color_icon, 0, 0, icon_width, icon_height,
848 /*** do the entire rectangular area... ***/
850 for (i = min_x; i <= max_x; i++)
851 for (j = min_y; j <= max_y; j++) {
852 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, i, j));
853 Paint_Tile(i, j, scratch_gc);
856 /*** ...or just do the border of rectangle ***/
858 for (i = min_x; i <= max_x; i++) {
859 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, i, min_y));
860 Paint_Tile(i, min_y, scratch_gc);
862 for (i = min_x; i <= max_x; i++) {
863 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, i, max_y));
864 Paint_Tile(i, max_y, scratch_gc);
866 for (i = min_y; i <= max_y; i++) {
867 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, min_x, i));
868 Paint_Tile(min_x, i, scratch_gc);
870 for (i = min_y; i <= max_y; i++) {
871 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, max_x, i));
872 Paint_Tile(max_x, i, scratch_gc);
875 XDestroyImage(scratch_img);
879 stat_out("Leaving Transfer_Back_Image\n");
885 /***************************************************************************
887 * Routine: Init_Widget_list *
889 * Purpose: Initialize all the pen color widgets into 2 widget ID *
890 * arrays, to simplify referencing them later. *
892 ***************************************************************************/
895 Init_Widget_List( void )
899 GraphicOpsWid[POINT] = pointButton;
900 GraphicOpsWid[FLOOD] = floodButton;
901 GraphicOpsWid[LINE] = lineButton;
902 GraphicOpsWid[POLYLINE] = polylineButton;
903 GraphicOpsWid[RECTANGLE] = rectangleButton;
904 GraphicOpsWid[POLYGON] = polygonButton;
905 GraphicOpsWid[CIRCLE] = circleButton;
906 GraphicOpsWid[ELLIPSE] = ellipseButton;
907 GraphicOpsWid[ERASER] = eraseButton;
908 GraphicOpsWid[SELECT] = selectButton;
910 DynamicWid[BG_COLOR-BG_COLOR] = bgColorToggle;
911 DynamicWid[FG_COLOR-BG_COLOR] = fgColorToggle;
912 DynamicWid[TS_COLOR-BG_COLOR] = tsColorToggle;
913 DynamicWid[BS_COLOR-BG_COLOR] = bsColorToggle;
914 DynamicWid[SELECT_COLOR-BG_COLOR] = selectColorToggle;
915 DynamicWid[TRANS_COLOR-BG_COLOR] = transparentColorToggle;
917 StaticWid[COLOR1] = color_pb1;
918 StaticWid[COLOR2] = color_pb2;
919 StaticWid[COLOR3] = color_pb3;
920 StaticWid[COLOR4] = color_pb4;
921 StaticWid[COLOR5] = color_pb5;
922 StaticWid[COLOR6] = color_pb6;
923 StaticWid[COLOR7] = color_pb7;
924 StaticWid[COLOR8] = color_pb8;
925 StaticWid[GREY1] = grey_pb1;
926 StaticWid[GREY2] = grey_pb2;
927 StaticWid[GREY3] = grey_pb3;
928 StaticWid[GREY4] = grey_pb4;
929 StaticWid[GREY5] = grey_pb5;
930 StaticWid[GREY6] = grey_pb6;
931 StaticWid[GREY7] = grey_pb7;
932 StaticWid[GREY8] = grey_pb8;
938 /***************************************************************************
940 * Routine: Init_Pen_Colors *
942 * Purpose: Initialize all the pen colors (both Static and Dynamic) and *
943 * set the appropriate fg/bg colors for each pen button widget *
946 ***************************************************************************/
956 int i, j, pixelTableIndex;
959 XtSetArg(arg[i], XmNbackground, &Background); i++;
960 XtGetValues(wid, arg, i);
961 XmGetColors(screen_ptr, Cmap, Background, &Foreground, &TopShadow,
962 &BottomShadow, &Select);
966 stat_out("Return from XmGetColors()\n");
969 /*** Set FOREGROUND Button fg/bg colors ***/
971 XtSetArg(arg[i], XmNbackground, Foreground); i++;
972 pixelTableIndex = PixelTableLookup (Foreground, False);
973 if (PIXEL_TABLE_MONO(pixelTableIndex) == white_pixel) {
974 XtSetArg(arg[i], XmNforeground, black_pixel); i++;
977 XtSetArg(arg[i], XmNforeground, white_pixel); i++;
979 XtSetValues(fgColorToggle, arg, i);
981 /*** Set BACKGROUND Button fg/bg colors ***/
983 XtSetArg(arg[i], XmNbackground, Background); i++;
984 XtSetArg(arg[i], XmNforeground, Foreground); i++;
985 XtSetValues(bgColorToggle, arg, i);
987 /*** Set TOP_SHADOW Button fg/bg colors ***/
989 XtSetArg(arg[i], XmNbackground, TopShadow); i++;
990 if (TopShadow == Foreground) /* B & W */
991 { XtSetArg(arg[i], XmNforeground, Background); i++; }
993 { XtSetArg(arg[i], XmNforeground, Foreground); i++; }
994 XtSetValues(tsColorToggle, arg, i);
996 /*** Set BOTTOM_SHADOW Button fg/bg colors ***/
998 XtSetArg(arg[i], XmNbackground, BottomShadow); i++;
999 if (BottomShadow == Foreground) /* B & W */
1000 { XtSetArg(arg[i], XmNforeground, Background); i++; }
1002 { XtSetArg(arg[i], XmNforeground, Foreground); i++; }
1003 XtSetValues(bsColorToggle, arg, i);
1005 /*** Set SELECT Button fg/bg colors ***/
1007 XtSetArg(arg[i], XmNbackground, Select); i++;
1008 XtSetArg(arg[i], XmNforeground, Foreground); i++;
1009 XtSetValues(selectColorToggle, arg, i);
1011 /*** Set TRANSPARENT Button fg/bg colors ***/
1013 XtSetArg(arg[i], XmNbackground, &Transparent); i++;
1014 XtSetArg(arg[i], XmNforeground, &transFg); i++;
1015 XtGetValues(menu1, arg, i);
1017 XtSetArg(arg[i], XmNbackground, Transparent); i++;
1018 XtSetArg(arg[i], XmNforeground, transFg); i++;
1019 XtSetValues(transparentColorToggle, arg, i);
1021 /*** Store the colors in the dynamic array ***/
1023 DynamicPen[BG_COLOR-BG_COLOR] = Background;
1024 DynamicPen[FG_COLOR-BG_COLOR] = Foreground;
1025 DynamicPen[TS_COLOR-BG_COLOR] = TopShadow;
1026 DynamicPen[BS_COLOR-BG_COLOR] = BottomShadow;
1027 DynamicPen[SELECT_COLOR-BG_COLOR] = Select;
1028 DynamicPen[TRANS_COLOR-BG_COLOR] = Transparent;
1032 stat_out("Backgrounds set for all 6 dynamic colors\n");
1035 /*** STUB *********************************************************/
1036 DynamicMono[BG_COLOR-BG_COLOR] = black_pixel;
1037 DynamicMono[FG_COLOR-BG_COLOR] = white_pixel;
1038 DynamicMono[TS_COLOR-BG_COLOR] = white_pixel;
1039 DynamicMono[BS_COLOR-BG_COLOR] = black_pixel;
1040 DynamicMono[SELECT_COLOR-BG_COLOR] = white_pixel;
1041 DynamicMono[TRANS_COLOR-BG_COLOR] = Transparent;
1043 for (i=0; i<NUM_STATICS; i++) {
1044 /*** Init the 16 color values ***/
1045 status = XParseColor(dpy, Cmap, color_table[i][5], &exact_def);
1047 sprintf(err_str, "%s %d",
1048 GETSTR(10,30, "Unable to parse static color no."), i+1);
1051 status = XAllocColor(dpy, Cmap, &exact_def);
1053 sprintf(err_str, "%s %d",
1054 GETSTR(10,32, "Unable to allocate static color no."), i+1);
1057 StaticPen[i] = exact_def.pixel;
1059 XtSetArg(arg[j], XmNbackground, StaticPen[i]); j++;
1060 XtSetValues(StaticWid[i], arg, j);
1061 /*** Init the 16 monochrome values ***/
1062 status = XParseColor(dpy, Cmap, color_table[i][2], &exact_def);
1064 sprintf(err_str, "%s %d",
1065 GETSTR(10,30, "Unable to parse static color no."), i+1);
1068 status = XAllocColor(dpy, Cmap, &exact_def);
1070 sprintf(err_str, "%s %d",
1071 GETSTR(10,32, "Unable to allocate static color no."), i+1);
1074 StaticMono[i] = exact_def.pixel;
1076 /******************************************************************/
1080 /***************************************************************************
1082 * Routine: Init_Color_Table *
1084 * Purpose: Complete initialization of the color_table used to specify *
1085 * color naming conventions when writing out XPM files. Then *
1086 * initialize the name and pixel fields for all the elements *
1087 * of the global array colorSymbols. *
1089 ***************************************************************************/
1092 Init_Color_Table( void )
1098 cmap_size = XDisplayCells(dpy, screen);
1101 for (i=NUM_STATICS; i<NUM_STATICS+5; i++) {
1102 if (DynamicMono[i-NUM_STATICS] == black_pixel)
1103 color_table[i][2] = black_string;
1105 color_table[i][2] = white_string;
1106 cval.pixel = DynamicPen[i-NUM_STATICS];
1107 XQueryColor(dpy, Cmap, &cval);
1108 sprintf(dynamic_c_str[i-NUM_STATICS], "#%04X%04X%04X",
1109 cval.red, cval.green, cval.blue);
1110 color_table[i][5] = dynamic_c_str[i-NUM_STATICS];
1112 color_table[NUM_PENS-1][2] = none_string;
1114 cval.pixel = DynamicPen[TRANS_COLOR-BG_COLOR];
1115 XQueryColor(dpy, Cmap, &cval);
1116 sprintf(dynamic_c_str[NUM_DYNAMICS-1], "#%04X%04X%04X",
1117 cval.red, cval.green, cval.blue);
1118 color_table[NUM_PENS-1][5] = dynamic_c_str[NUM_DYNAMICS-1];
1123 stat_out("XPM Color Table initialized:\n");
1124 for (i=0; i<(NUM_PENS); i++)
1125 stat_out(" %s %18s %18s\n", color_table[i][0], color_table[i][1],
1130 colorSymbols = (XpmColorSymbol *) XtMalloc(NUM_PENS * sizeof(XpmColorSymbol));
1132 Abort(GETSTR(10,38, "No memory(0)"));
1133 for (i=0; i<NUM_STATICS; i++) {
1134 colorSymbols[i].name = (char *) XtMalloc(strlen(color_table[i][1]) +1);
1135 if (!colorSymbols[i].name)
1136 Abort(GETSTR(10,40, "No memory(1)"));
1137 strcpy(colorSymbols[i].name, color_table[i][1]);
1138 colorSymbols[i].value = "";
1139 colorSymbols[i].pixel = StaticPen[i];
1141 for (i=NUM_STATICS; i<NUM_STATICS+NUM_DYNAMICS; i++) {
1142 colorSymbols[i].name = (char *) XtMalloc(strlen(color_table[i][1]) +1);
1143 if (!colorSymbols[i].name)
1144 Abort(GETSTR(10,42, "No memory(2)"));
1145 strcpy(colorSymbols[i].name, color_table[i][1]);
1146 colorSymbols[i].value = "";
1147 colorSymbols[i].pixel = DynamicPen[i-NUM_STATICS];
1152 stat_out("%d Color Symbols installed:\n", NUM_PENS);
1153 for (i=0; i<NUM_PENS; i++) {
1154 stat_out(" %d - %s | %s | %d\n", (i+1), colorSymbols[i].name,
1155 colorSymbols[i].value, colorSymbols[i].pixel);
1160 /*** now comes the ugly part, initialize the .colorTable field ***/
1161 /*** in xpm_WriteAttribs. This should remain constant for the ***/
1162 /*** life of the executable, and so only needs to be initialized ***/
1165 colorTable = (char ***) calloc(NUM_PENS, sizeof(char **));
1166 xpm_WriteAttribs.colorTable = (XpmColor*)colorTable;
1167 xpm_WriteAttribs.pixels = (Pixel *) calloc(NUM_PENS, sizeof(Pixel));
1168 if (!xpm_WriteAttribs.colorTable)
1169 Abort(GETSTR(10,44, "No memory(3)"));
1170 for (i=0; i<NUM_PENS; i++) {
1171 colorTable[i] = (char **) calloc(6, sizeof(char *));
1173 Abort(GETSTR(10,46, "No memory(4)"));
1175 for (i=0; i<NUM_PENS; i++) {
1176 xpm_WriteAttribs.pixels[i] = colorSymbols[i].pixel;
1177 for (j=0; j<6; j++) {
1178 if (color_table[i][j] && strlen(color_table[i][j]) > 0) {
1179 colorTable[i][j] = (char *) XtMalloc(strlen(color_table[i][j])+1);
1180 if (!colorTable[i][j])
1181 Abort(GETSTR(10,48, "No memory(5)"));
1182 strcpy(colorTable[i][j], color_table[i][j]);
1186 xpm_WriteAttribs.ncolors = NUM_PENS;
1187 xpm_WriteAttribs.hints_cmt = hints_cmt;
1188 xpm_WriteAttribs.colors_cmt = colors_cmt;
1189 xpm_WriteAttribs.pixels_cmt = pixels_cmt;
1190 xpm_WriteAttribs.mask_pixel = 0x80000000;
1194 Dump_AttribStruct(&xpm_WriteAttribs);
1199 /***************************************************************************
1201 * Routine: Size_IconForm *
1203 * Purpose: Given new dimensions for the Color and Mono icon widgets, *
1204 * calculate and set the new overall dimensions for the icon *
1205 * form widget (iconForm) which holds both of them and their *
1208 ***************************************************************************/
1217 Dimension label1_w, label1_h, label2_w, label2_h;
1218 Dimension form_width, form_height, junk;
1219 XmString label1_str, label2_str;
1220 XmFontList label_fontlist;
1225 stat_out("Entering Size_IconForm\n");
1228 /*********************************************************************
1229 * Before re-sizing the 2 icons (up or down), make sure their parent *
1230 * form's width is at least wide enough to fully show the two label *
1231 * gadgets (iconSize and monoLabel). If the icon widths are smaller *
1232 * than this, set offsets to center them on the space provided. *
1233 *********************************************************************/
1235 /*********************************************************************
1236 * First, get the minimum usable widths for the two label gadgets, *
1237 * and their current heights. *
1238 *********************************************************************/
1240 XtSetArg(args[i], XmNfontList, &label_fontlist); i++;
1241 XtSetArg(args[i], XmNlabelString, &label1_str); i++;
1242 XtGetValues(iconSize, args, i);
1244 XtSetArg(args[i], XmNlabelString, &label2_str); i++;
1245 XtGetValues(monoLabel, args, i);
1247 XmStringExtent(label_fontlist, label1_str, &label1_w, &junk);
1248 XmStringExtent(label_fontlist, label2_str, &label2_w, &junk);
1250 XtSetArg(args[i], XmNheight, &label1_h); i++;
1251 XtGetValues(iconSize, args, i);
1253 XtSetArg(args[i], XmNheight, &label2_h); i++;
1254 XtGetValues(monoLabel, args, i);
1256 /*********************************************************************
1257 * If the min. width for either label gadget is greater than the *
1258 * current icon widths, use half the difference between the two *
1259 * widths as a left and right offset for the two icon (drawn button) *
1261 *********************************************************************/
1262 if ((label1_w > width) || (label2_w > width))
1263 diff = (Position) (((label1_w > label2_w) ? label1_w : label2_w)
1269 XtSetArg(args[i], XmNleftOffset, diff); i++;
1270 XtSetValues(iconImage, args, i);
1271 XtSetValues(monoImage, args, i);
1273 /*********************************************************************
1274 * The overall form dimensions should be as follows: the form width *
1275 * will be the greater of the icon widths, or the widths of the two *
1276 * label gadgets. The form height will be the sum of the two icon *
1277 * heights, plus the sum of heights of the two label gadgets, plus *
1278 * the vertical offset between the bottom of the first label and the *
1279 * top of the second icon. *
1280 *********************************************************************/
1282 XtSetArg(args[i], XmNtopOffset, &top_offset); i++;
1283 XtGetValues(monoImage, args, i);
1284 form_width = max(width, (Dimension)max(label1_w, label2_w));
1285 form_height = (height*2) + label1_h + label2_h + top_offset;
1288 stat_out(" form_width = %d (of %d,%d,%d)\n", form_width, width, label1_w,
1290 stat_out(" form_height = %d\n", form_height);
1294 XtSetArg(args[i], XmNwidth, form_width); i++;
1295 XtSetArg(args[i], XmNheight, form_height); i++;
1296 XtSetValues(iconForm, args, i);
1300 stat_out("Leaving Size_IconForm\n");
1305 /***************************************************************************
1307 * Routine: Init_Icons *
1309 * Purpose: Initialize new color and mono icons at program start-up *
1310 * and at the following times: *
1311 * o When 'New' is selected from the 'File' pull-down menu. *
1312 * o When 'Resize Icon' is selected from the 'Edit' pull-down *
1314 * o When 'Load' is selected from the 'File' pull-down menu, *
1315 * and a new file is read in. *
1316 * o When 'Grab Screen Image' is selected from the 'Edit' *
1317 * pull-down menu, and the image is loaded into the editor. *
1319 * This routine sizes the iconImage, monoImage, and tablet *
1320 * widgets to the new dimensions (*MagFactor, and +1 in the *
1321 * case of the tablet widget). It also creates the application-*
1322 * internal Pixmaps associated with the iconImage and monoImage.*
1323 * If the 'saveFlag' flag is 'True', it is assumed that the *
1324 * current icons are being resized and that there are existing *
1325 * images that need to be retained. In this case, the new *
1326 * Pixmaps are created and the old Pixmaps are copied onto the *
1327 * new ones, before the old Pixmaps are freed. *
1329 ***************************************************************************/
1338 Pixmap tmp_color, tmp_mono;
1341 int i, x_offset, y_offset;
1346 stat_out("Entering Init_Icons: flag=%d\n", saveFlag);
1347 stat_out(" Init_Icons: color=%x mono=%x\n", color_icon, mono_icon);
1353 /*** App. init or 'New Icon' ***/
1356 XFreePixmap(dpy, color_icon);
1358 XFreePixmap(dpy, mono_icon);
1360 /*** Resizing the existing icon ***/
1363 tmp_color = color_icon;
1365 tmp_mono = mono_icon;
1370 color_icon = XCreatePixmap(dpy, root, width, height,
1371 DefaultDepth(dpy, screen));
1372 mono_icon = XCreatePixmap(dpy, root, width, height,
1373 DefaultDepth(dpy, screen));
1375 if ((color_icon == 0) || (mono_icon == 0))
1376 Abort(GETSTR(10,50, "Cannot initialize application icon storage"));
1378 XSetForeground(dpy, scratch_gc, Transparent);
1379 XFillRectangle(dpy, color_icon, scratch_gc, 0, 0, width, height);
1380 XFillRectangle(dpy, mono_icon, scratch_gc, 0, 0, width, height);
1382 sprintf(text, "%d x %d", width, height);
1384 local_str = XmStringCreateLocalized(text);
1385 XtSetArg(args[i], XmNlabelString, local_str); i++;
1386 XtSetValues(iconSize, args, i);
1387 XmStringFree(local_str);
1390 XtSetArg(args[i], XmNwidth, width); i++;
1391 XtSetArg(args[i], XmNheight, height); i++;
1392 XtSetValues(iconImage, args, i);
1393 XtSetValues(monoImage, args, i);
1395 /*********************************************************************
1396 * Call Size_IconForm() to re-do the layout of the iconForm widget, *
1397 * which contains the iconImage, iconSize, monoImage, and monoLabel *
1399 *********************************************************************/
1401 Size_IconForm(width, height);
1404 XCopyArea(dpy, tmp_color, color_icon, Color_gc, 0, 0,
1405 icon_width, icon_height, x_offset, y_offset);
1406 XCopyArea(dpy, tmp_mono, mono_icon, Mono_gc, 0, 0,
1407 icon_width, icon_height, x_offset, y_offset);
1409 XFreePixmap(dpy, tmp_color);
1411 XFreePixmap(dpy, tmp_mono);
1414 if (XtWindow(iconImage))
1415 XCopyArea(dpy, color_icon, XtWindow(iconImage), Color_gc,
1416 0, 0, width, height, 0, 0);
1417 if (XtWindow(monoImage))
1418 XCopyArea(dpy, mono_icon, XtWindow(monoImage), Mono_gc,
1419 0, 0, width, height, 0, 0);
1421 XtSetArg(args[i], XmNwidth, ((width*MagFactor)+1)); i++;
1422 XtSetArg(args[i], XmNheight, ((height*MagFactor)+1)); i++;
1423 XtSetValues(tablet_wid, args, i);
1426 icon_height = height;
1428 /* This code does not seem to be needed and since it slows down
1429 the grid drawing I'll take it out for now*/
1432 Repaint_Exposed_Tablet();
1437 stat_out("Leaving Init_Icons\n");
1444 XtPointer client_data,
1445 XtPointer call_data)
1447 DtDndTransferCallback transferInfo = (DtDndTransferCallback) call_data;
1449 if (transferInfo->reason == DtCR_DND_TRANSFER &&
1450 transferInfo->operation == XmDROP_COPY) {
1452 Process_DropCheckOp(w, client_data, call_data);
1454 transferInfo->status = DtDND_FAILURE;
1461 XtPointer client_data,
1462 XtPointer call_data)
1464 DtDndDropAnimateCallbackStruct *animateInfo =
1465 (DtDndDropAnimateCallbackStruct *) call_data;
1467 if (animateInfo->reason == DtCR_DND_DROP_ANIMATE) {
1469 Process_DropOp(w, client_data, call_data);
1473 /***************************************************************************
1475 * Routine: RegisterDropSites *
1477 * Purpose: Register the tablet as a valid drop zone. *
1479 ***************************************************************************/
1482 RegisterDropSites( void )
1484 static XtCallbackRec transferCB[] = { {TransferCallback, NULL},
1486 static XtCallbackRec animateCB[] = { {AnimateCallback, NULL},
1492 XtSetArg(args[0], XmNclipWindow, &clipWin);
1493 XtGetValues(viewport, args, 1);
1496 * This code makes assumptions about the order of the arguments.
1497 * XmNanimationStyle is assumed to be first and
1498 * DtNregisterChildren is assumed to be last
1501 XtSetArg(args[n], XmNanimationStyle, XmDRAG_UNDER_NONE); n++; /* first */
1502 XtSetArg(args[n], DtNdropAnimateCallback, animateCB); n++;
1503 XtSetArg(args[n], DtNregisterChildren, True); n++; /* last */
1505 DtDndDropRegister(clipWin, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1506 (XtCallbackList) transferCB, args, n);
1508 DtDndDropRegister(tabletBorder, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1509 (XtCallbackList) transferCB, args, n);
1511 DtDndDropRegister(tabletFrame, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1512 (XtCallbackList) transferCB, args, n);
1514 DtDndDropRegister(tablet, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1515 (XtCallbackList) transferCB, args, n - 1);
1518 * Once the drag and drop library is fixed, the following calls
1519 * will not be necessary. Currently the dnd library does not pass on
1520 * Motif resource values, in this case XmNanimationStyle.
1523 XmDropSiteUpdate(clipWin, args, 1);
1524 XmDropSiteUpdate(tabletBorder, args, 1);
1525 XmDropSiteUpdate(tabletFrame, args, 1);
1526 XmDropSiteUpdate(tablet, args, 1);
1529 /***************************************************************************
1533 * Purpose: Print a fatal error message and then exit. *
1535 ***************************************************************************/
1542 _DtSimpleError (progName, DtError, NULL, str, NULL);
1547 /***************************************************************************
1549 * Routine: stat_out *
1551 * Purpose: Generate a debug message to stderr. Flush stdout, and then *
1552 * print the message(s) to stderr and flush stderr. By doing *
1553 * an fflush after each fprintf, we can always determin where *
1554 * in the code the process is running. The stat_out() routine *
1555 * is invoked like printf() with up to 7 arguments. It is *
1556 * source-code identical to the outl() routine used in the xwd *
1557 * and xwud utilities which are part of standard X11. *
1559 *X11***********************************************************************/
1572 /* static char str[1024]; */
1575 fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
1578 /* sprintf(str, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
1579 _DtSimpleError ("dticon-stat_out", DtError, NULL, str, NULL);*/
1582 /***************************************************************************
1584 * Routine: PixelTableClear *
1586 * Purpose: Reset the pixel table to force subsequent lookups to get *
1587 * new pixel information. Do not free up space for table. *
1589 *X11***********************************************************************/
1593 pixelTable.numItems = 0;
1594 pixelTable.lastFound = 0;
1597 /***************************************************************************
1599 * Routine: PixelTableLookup *
1601 * Purpose: Return index into the Pixel Table for the pixel passed in. *
1602 * If the pixel passed in isn't already in the table, it will *
1603 * be added. This may require allocating a larger pixel table. *
1604 * In order to clear the Pixel Table (which should be done each *
1605 * time a new image is being processed in order to get current *
1606 * pixel data) call PixelTableClear(). *
1608 * For performance, save the last lookup result, and check it *
1609 * first. This should improve performance unless image is very *
1610 * "dithered". The allocNew parameter will be set if the image *
1611 * was grabbed from screen. In this case, each "screen" pixel *
1612 * will need a new pixel allocated for it. *
1614 *X11***********************************************************************/
1623 /** first, check to see if the last lookup was for the same pixel **/
1624 if (pixelTable.lastFound < pixelTable.numItems)
1625 if (pixelTable.item[pixelTable.lastFound].xcolor.pixel == pixelIn)
1626 return pixelTable.lastFound;
1628 /** look through table to see if there is an entry for this pixel **/
1629 for (i=0; i<pixelTable.numItems; i++)
1631 if (pixelTable.item[i].xcolor.pixel == pixelIn)
1633 pixelTable.lastFound = i;
1639 /** No entry for this pixel, create one **/
1642 /** Allocate larger table if needed **/
1643 if (pixelTable.numItems == pixelTable.pixelTableSize)
1645 pixelTable.pixelTableSize += PIXEL_TABLE_INC;
1646 pixelTable.item = (PixelTableItem *)XtRealloc((char *)pixelTable.item,
1647 sizeof(PixelTableItem)*pixelTable.pixelTableSize);
1650 /** Get color information for pixelIn **/
1651 i = pixelTable.numItems;
1652 pixelTable.numItems++;
1654 pixelTable.item[i].xcolor.pixel = pixelIn;
1655 XQueryColor(dpy, Cmap, &(pixelTable.item[i].xcolor));
1657 /*--- < ESTABLISH THE GREYSCALE IMAGE > ---*/
1658 /*--- The NTSC formula for converting an RGB value into the ---*/
1659 /*--- corresponding grayscale value is: ---*/
1660 /*--- luminosity = .299 red + .587 green + .114 blue ---*/
1662 grayValue = ( (int)((pixelTable.item[i].xcolor.red*299) +
1663 (pixelTable.item[i].xcolor.green*587) +
1664 (pixelTable.item[i].xcolor.blue*114)) / 1000) >> 8;
1666 if (grayValue < GAMMA_CUTOFF)
1667 pixelTable.item[i].mono = black_pixel;
1669 pixelTable.item[i].mono = white_pixel;
1671 /** Allocate new color cell if needed (use old for mono conversion) **/
1674 tmpXColor.red = pixelTable.item[i].xcolor.red;
1675 tmpXColor.green = pixelTable.item[i].xcolor.green;
1676 tmpXColor.blue = pixelTable.item[i].xcolor.blue;
1678 if (!XAllocColor(dpy, Cmap, &tmpXColor))
1680 /* for lack of something better, use the old color cell */
1681 pixelTable.item[i].newCell = pixelTable.item[i].xcolor.pixel;
1682 DoErrorDialog(GETSTR(10,62,"Operation failed.\nColormap is full"));
1685 pixelTable.item[i].newCell = tmpXColor.pixel;
1688 pixelTable.lastFound = i;
1693 /***************************************************************************
1695 * Routine: Switch_FillSolids *
1697 * Purpose: Toggles the state of the global FillSolids flag, based on *
1698 * the XmNset resource for the fillToggle widget. *
1700 *X11***********************************************************************/
1703 Switch_FillSolids( void )
1709 XtSetArg(args[i], XmNset, &FillSolids); i++;
1710 XtGetValues(fillToggle, args, i);
1712 Set_Gfx_Labels(FILL);
1714 Set_Gfx_Labels(HOLLOW);
1717 stat_out("Fill_Solids toggle = %s\n", (FillSolids? "True" : "False"));
1722 /***************************************************************************
1724 * Routine: Select_New_Pen *
1726 * Purpose: Changes the fg color of the pen GC, based on the parameter *
1729 *X11***********************************************************************/
1735 int new_block, new_pen;
1738 new_block = STATIC_COLOR;
1742 new_block = DYNAMIC_COLOR;
1743 new_pen = n - BG_COLOR;
1747 stat_out("**** n = %d, new_block = %d, new_pen = %d\n", n,
1748 new_block, new_pen);
1752 /*** if the new choice is the current pen, re-set it and return ***/
1753 if ((new_block == ColorBlock) && (new_pen == CurrentColor)) {
1754 if (new_block == STATIC_COLOR)
1755 XmToggleButtonSetState(StaticWid[new_pen], True, False);
1757 XmToggleButtonSetState(DynamicWid[new_pen], True, False);
1761 /*** un-set the previous choice ***/
1762 if (ColorBlock == STATIC_COLOR)
1763 XmToggleButtonSetState(StaticWid[CurrentColor], False, False);
1765 XmToggleButtonSetState(DynamicWid[CurrentColor], False, False);
1769 stat_out(" New pen color = %d\n", n);
1772 ColorBlock = new_block; /*** STATIC or DYNAMIC? ***/
1773 CurrentColor = new_pen; /*** index w/i the appropriate block ***/
1775 XSetForeground(dpy, Color_gc,
1776 (ColorBlock ? DynamicPen[CurrentColor] : StaticPen[CurrentColor]));
1777 XSetForeground(dpy, Mono_gc,
1778 (ColorBlock ? DynamicMono[CurrentColor] : StaticMono[CurrentColor]));
1782 /***************************************************************************
1784 * Routine: Backup_Icons *
1786 * Purpose: Copy the current contents of the color and mono icons to *
1787 * their undo storage areas, just prior to modifying them with *
1788 * the current graphics operation. *
1790 *X11***********************************************************************/
1793 Backup_Icons( void )
1795 /*** If we're backing up the tablet contents, it's dirty ***/
1796 /*** and may need to be saved to file at some point. ***/
1800 /*** if the icon sizes don't match the backup sizes, or ***/
1801 /*** either of the backup icons don't exist, create them ***/
1803 if ((icon_width != backup_width) ||
1804 (icon_height != backup_height) ||
1805 (!prev_color_icon) ||
1806 (!prev_mono_icon)) {
1807 if (prev_color_icon)
1808 XFreePixmap(dpy, prev_color_icon);
1810 XFreePixmap(dpy, prev_mono_icon);
1811 prev_color_icon = XCreatePixmap(dpy, root, icon_width, icon_height,
1812 DefaultDepth(dpy, screen));
1813 prev_mono_icon = XCreatePixmap(dpy, root, icon_width, icon_height,
1814 DefaultDepth(dpy, screen));
1815 backup_width = icon_width;
1816 backup_height = icon_height;
1819 /*** now, copy the color and mono pixmap to the backup pixmaps ***/
1821 XCopyArea(dpy, color_icon, prev_color_icon,
1822 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
1823 XCopyArea(dpy, mono_icon, prev_mono_icon,
1824 Mono_gc, 0, 0, icon_width, icon_height, 0, 0);
1826 XtSetSensitive( editMenu_undo_pb, True);
1830 /***************************************************************************
1832 * Routine: DoErrorDialog *
1834 * Purpose: Some error has just occurred in the application. Pop up *
1835 * the error dialog and display the message passed in. *
1837 *X11***********************************************************************/
1848 local_str = XmStringCreateLocalized(str);
1849 XtSetArg(arg[i], XmNmessageString, local_str);
1851 XtSetValues(stdErrDialog, arg, i);
1852 XmStringFree(local_str);
1853 XtManageChild(stdErrDialog);
1857 /***************************************************************************
1859 * Routine: DoQueryDialog *
1861 * Purpose: The user should be prompted on an action they're attempting. *
1862 * Pop up the query dialog and display the message passed in. *
1864 *X11***********************************************************************/
1873 static Widget w=NULL;
1875 XtPopup(dtIconShell, XtGrabNone);
1876 XMapRaised(XtDisplay(dtIconShell), XtWindow(dtIconShell));
1879 w = XmMessageBoxGetChild(queryDialog, XmDIALOG_CANCEL_BUTTON);
1882 local_str = XmStringCreateLocalized(str);
1883 XtSetArg(arg[i], XmNmessageString, local_str); i++;
1884 XtSetValues(queryDialog, arg, i);
1885 XmStringFree(local_str);
1886 XtManageChild(queryDialog);
1888 XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1892 /***************************************************************************
1894 * Routine: Do_GrabOp *
1896 * Purpose: Switch to GRAB mode. Grab the server and the pointer until *
1897 * the user has made a selection from the screen. The server *
1898 * and pointer are ungrabbed in Do_ButtonOp(). *
1900 * Note: Moved the server grab until the mouse button is pressed *
1901 * (beginning the screen grab) in order to give the windows *
1902 * time to repaint. This was needed specifically for the *
1903 * queryDialog used when the icon image is "Dirty". *
1905 *X11***********************************************************************/
1910 Backup_G_Op = GraphicsOp;
1911 GraphicsOp = S_GRAB;
1912 cursor = XCreateFontCursor(dpy, XC_crosshair);
1913 XGrabPointer(dpy, root, False,
1914 ButtonPressMask|PointerMotionMask|ButtonReleaseMask,
1915 GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime);
1919 /***************************************************************************
1921 * Routine: LoadGrabbedImage *
1923 * Purpose: Given an [x,y] coordinate, plus width and height, grab an *
1924 * XImage from the Root window and load it into the icon *
1927 *X11***********************************************************************/
1935 XImage *img, *mono_img;
1937 int pixelTableIndex;
1941 stat_out("LoadGrabbedImage: [%d,%d] - width: %d, height: %d\n",
1942 x, y, width, height);
1947 if (width > 0 && height > 0)
1948 img = XGetImage(dpy, root, x, y, width, height, AllPlanes, format);
1950 XUngrabPointer (dpy, CurrentTime);
1951 XUngrabServer (dpy);
1955 DoErrorDialog( GETSTR(10,60, "Screen image capture failed") );
1959 /*********************************************************************
1960 * OK, now that we've got the image, we need to convert the entire *
1961 * thing to pixels that the icon editor won't lose control over. *
1962 * To do this, we find all the pixel values in the image and request *
1963 * equivalent read-only colors in the colormap (we won't be drawing *
1964 * with any pen colors we don't already have). Once the requests to *
1965 * the Cmap have been honored, we go thru the image one more time *
1966 * and replace each old pixel with the correct new value. *
1967 * NOTE: Old code assumed 256 max colors... NOT OKAY. Added dynamic *
1968 * pixel table for color lookup, which also handles allocating *
1969 * the new read-only color. - julie *
1970 *********************************************************************/
1972 /*********************************************************************
1973 * Dup the XImage so there'll be two identical copies: one to *
1974 * update with the new color values, and one with which to create *
1975 * a monochrome equivalent. *
1976 *********************************************************************/
1977 mono_img = XSubImage(img, 0, 0, img->width, img->height);
1979 DoErrorDialog( GETSTR(10,60, "Screen image capture failed") );
1983 /* force new pixel lookup, in case pixel data has changed */
1985 for (i=0; i<img->width; i++)
1987 for (j=0; j<img->height; j++)
1989 pixelTableIndex = PixelTableLookup(XGetPixel(img, i, j), True);
1990 XPutPixel(img, i, j, PIXEL_TABLE_NEW_CELL(pixelTableIndex));
1991 XPutPixel(mono_img, i, j, PIXEL_TABLE_MONO(pixelTableIndex));
1996 Init_Icons(img->width, img->height, DO_NOT_SAVE);
1997 XPutImage(dpy, color_icon, Color_gc, img, 0, 0, 0, 0,
1998 img->width, img->height);
1999 XPutImage(dpy, mono_icon, Mono_gc, mono_img, 0, 0, 0, 0,
2000 img->width, img->height);
2003 XDestroyImage(mono_img);
2009 /***************************************************************************
2011 * Routine: ParseAppArgs *
2013 * Purpose: Parse the invocation arguments, looking for '-f' and '-x'. *
2014 * This routine is invoked once by dticon. *
2016 * Each of the args should be accompanied by a parameter. If *
2017 * one does not exist, abort dticon with the appropriate *
2018 * error message. Otherwise, store the parameter in a global *
2019 * variable for processing by ProcessAppArgs() (called once *
2022 *X11***********************************************************************/
2034 stat_out("Entering ParseAppArgs\n");
2037 for (i=0; i<NUM_PARAMS; i++)
2038 param_flag[i] = False;
2039 argsNeedProcessed = False;
2041 /*** First, figure out which arguments get used ***/
2043 /* don't process command line args if restoring from a session file */
2044 if (xrdb.session != NULL)
2045 argsNeedProcessed = True;
2048 for (i=1; i<num; i++)
2052 if (cmd_arg[0] == '-') /* process command line switches */
2058 if (strncpy(start_file, cmd[i], 255)) {
2059 param_flag[AUTO_FILE] = True;
2060 argsNeedProcessed = True;
2063 Abort(GETSTR(10,52, "Invalid use of the '-f' parameter"));
2066 Abort(GETSTR(10,52, "Invalid use of the '-f' parameter"));
2068 case 'x': if (++i < num)
2070 if (strcpy(start_size, cmd[i])) {
2071 param_flag[AUTO_SIZE] = True;
2072 argsNeedProcessed = True;
2075 Abort(GETSTR(10,54, "Invalid use of the '-x' parameter"));
2078 Abort(GETSTR(10,54, "Invalid use of the '-x' parameter"));
2088 for (i=0; i<NUM_PARAMS; i++)
2089 stat_out(" param_flag = %s\n", (param_flag[i] ? "True" : "False"));
2090 stat_out("Leaving ParseAppArgs\n");
2097 /***************************************************************************
2099 * Routine: ProcessAppArgs *
2101 * Purpose: Process the invocation arguments, '-f'and '-x' *
2103 * If '-f' exists, the following parameter should be the name *
2104 * of a file to load at application start-up. Invoke the *
2105 * Read_File() routine with that parameter. *
2107 * If '-x' exists, the following parameter should be the *
2108 * initial geometry for the icon tablet (work area). Parse *
2109 * the string with XParseGeometry and pass the results (if *
2110 * valid) to Eval_NewSize(). *
2112 *X11***********************************************************************/
2114 #define MASK (WidthValue & HeightValue)
2117 ProcessAppArgs( void )
2124 stat_out("Entering ProcessAppArgs\n");
2127 argsNeedProcessed = False;
2129 /*** Attempt to honor the arguments, in order of priority ***/
2130 /*** ('-session', '-f', '-x', in that order). ***/
2132 /*** GetSessionInfo() will already set start_file if needed **/
2134 if ( param_flag[AUTO_FILE] || (session.useSession && start_file[0] != '\0') )
2136 fileIOMode = FILE_READ;
2137 if (!Read_File(start_file))
2138 DoErrorDialog( GETSTR(16,2,
2139 "The file cannot be accessed\nor contains invalid data") );
2141 if (successFormat == FORMAT_XPM) {
2142 X_Hot = xpm_ReadAttribs.x_hotspot;
2143 Y_Hot = xpm_ReadAttribs.y_hotspot;
2144 Display_XPMFile(xpm_ReadAttribs.width, xpm_ReadAttribs.height);
2146 else if (successFormat == FORMAT_XBM) {
2149 Display_XBMFile(width_ret, height_ret);
2153 else if(param_flag[AUTO_SIZE]) {
2154 result = XParseGeometry(start_size, &x_ret, &y_ret,
2155 &width_ret, &height_ret);
2156 if ((!MASK) & result)
2157 Abort(GETSTR(10,64, "Invalid dimension parameter"));
2159 Eval_NewSize(width_ret, height_ret);
2164 stat_out("Leaving ProcessAppArgs\n");
2170 /***************************************************************************
2172 * Routine: Set_Gfx_Labels *
2174 * Purpose: Set the label pixmaps of the 'Rectangle', 'Polygon', *
2175 * 'Circle', and 'Ellipse' graphics tool toggle to either *
2176 * Solid or Hollow, depending on the flag passed in. *
2178 *X11***********************************************************************/
2187 if (flag == HOLLOW) {
2189 XtSetArg(args[i], XmNlabelPixmap, rectPix); i++;
2190 XtSetValues(rectangleButton, args, i);
2192 XtSetArg(args[i], XmNlabelPixmap, circlePix); i++;
2193 XtSetValues(circleButton, args, i);
2195 XtSetArg(args[i], XmNlabelPixmap, polygonPix); i++;
2196 XtSetValues(polygonButton, args, i);
2198 XtSetArg(args[i], XmNlabelPixmap, ellipsePix); i++;
2199 XtSetValues(ellipseButton, args, i);
2203 XtSetArg(args[i], XmNlabelPixmap, rectSolidPix); i++;
2204 XtSetValues(rectangleButton, args, i);
2206 XtSetArg(args[i], XmNlabelPixmap, circleSolidPix); i++;
2207 XtSetValues(circleButton, args, i);
2209 XtSetArg(args[i], XmNlabelPixmap, polygonSolidPix); i++;
2210 XtSetValues(polygonButton, args, i);
2212 XtSetArg(args[i], XmNlabelPixmap, ellipseSolidPix); i++;
2213 XtSetValues(ellipseButton, args, i);
2218 /***************************************************************************
2220 * Routine: jskXerrorDebug *
2222 * Purpose: This routine takes the place of the default non-fatal error *
2223 * handler normally used by the X server. If an error occurs, *
2224 * this routine simply stores the error_code in the global *
2225 * variable XErrorFlag (making it available to other sections *
2226 * of the application). Then it returns. *
2228 ***************************************************************************/
2229 #define MAX_MSG_STR 1024
2231 static int jskXerrorDebug(disp, error_event)
2233 XErrorEvent *error_event;
2235 char error_msg[MAX_MSG_STR];
2239 stat_out("\n\nX Protocol Error:\n");
2241 _DtPrintDefaultErrorSafe(disp, error_event, error_msg, MAX_MSG_STR);
2242 _DtSimpleError (progName, DtWarning, NULL, error_msg, NULL);
2249 /***************************************************************************
2251 * Routine: jskXerrorIODebug *
2253 * Purpose: This routine is needed in order to get good bfa (bba) stats *
2254 **************************************************************************/
2255 static int jskXerrorIODebug(disp)
2263 /***************************************************************************
2265 * Routine: SaveSession *
2267 * Purpose: save state information for session management *
2268 **************************************************************************/
2274 char *xa_CommandStr[3];
2275 char *tmpStr, *tmpStr2;
2277 Dimension width, height;
2278 char bufr[1024]; /* make bigger if needed */
2279 XmVendorShellExtObject vendorExt;
2280 XmWidgetExtData extData;
2282 Atom wmStateAtom, actualType;
2284 unsigned long nitems, leftover;
2289 stat_out("SaveSession\n");
2292 DtSessionSavePath(dtIconShell, &path, &name);
2294 /* Create the session file */
2295 if ((fd = creat(path, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
2297 tmpStr = GETSTR(16,24, "Couldn't save session to file");
2298 tmpStr2 = (char *)XtMalloc(strlen(tmpStr) + strlen(path)+ 3);
2299 snprintf(tmpStr2, sizeof(strlen(tmpStr) + strlen(path)+ 3), "%s: %s\n", tmpStr, path);
2300 _DtSimpleErrnoError(progName, DtError, NULL, tmpStr2, NULL);
2302 XtFree ((char *)path);
2303 XtFree ((char *)name);
2308 /* Getting the WM_STATE property to see if iconified or not */
2310 wmStateAtom = XInternAtom(dpy, "WM_STATE", False);
2312 XGetWindowProperty (dpy, XtWindow(dtIconShell), wmStateAtom, 0L,
2313 (long)BUFSIZ, False, wmStateAtom, &actualType,
2314 &actualFormat, &nitems, &leftover,
2315 (unsigned char **) &wmState);
2317 if (wmState->state == IconicState)
2318 sprintf(bufr, "*iconic: True\n");
2320 sprintf(bufr, "*iconic: False\n");
2322 /*** Get and write out the geometry info for our Window ***/
2324 x = XtX(dtIconShell);
2325 y = XtY(dtIconShell);
2326 width = XtWidth(dtIconShell);
2327 height = XtHeight(dtIconShell);
2329 /* Modify x & y to take into account window mgr frames
2330 * This is pretty bogus, but I don't know a better way to do it.
2332 extData = _XmGetWidgetExtData(dtIconShell, XmSHELL_EXTENSION);
2333 vendorExt = (XmVendorShellExtObject)extData->widget;
2334 x -= vendorExt->vendor.xOffset;
2335 y -= vendorExt->vendor.yOffset;
2337 sprintf(bufr, "%s*x: %d\n", bufr, x);
2338 sprintf(bufr, "%s*y: %d\n", bufr, y);
2339 sprintf(bufr, "%s*width: %d\n", bufr, width);
2340 sprintf(bufr, "%s*height: %d\n", bufr, height);
2341 if (last_fname[0] != '\0')
2342 sprintf(bufr, "%s*file: %s\n", bufr, last_fname);
2344 if(-1 == write (fd, bufr, strlen(bufr))) {
2345 fprintf(stderr, "write() to session failed\n");
2346 XtFree ((char *)path);
2347 XtFree ((char *)name);
2353 xa_CommandStr[n] = execName; n++;
2354 xa_CommandStr[n] = "-session"; n++;
2355 xa_CommandStr[n] = name; n++;
2357 XSetCommand(dpy, XtWindow(dtIconShell), xa_CommandStr, n);
2358 XtFree ((char *)path);
2359 XtFree ((char *)name);
2363 /* Don't exit yet, SM needs time to get the new commandStr.*/
2367 /***************************************************************************
2369 * Routine: GetSessionInfo *
2371 * Purpose: get dticon session information *
2372 **************************************************************************/
2373 #define DEFAULT_WIDTH 536
2374 #define DEFAULT_HEIGHT 477
2377 GetSessionInfo( void )
2380 char *tmpStr, *tmpStr2;
2382 XrmName xrm_name[5];
2383 XrmRepresentation rep_type;
2388 stat_out("GetSessionInfo\n");
2391 if (xrdb.session == NULL)
2393 session.useSession = False;
2397 session.useSession = True;
2399 /*** Open the resource database file ***/
2401 /* TopLevel is used because dtIconShell isn't created yet... */
2402 /* okay because it only uses it to get a display, not a window */
2403 if (DtSessionRestorePath(TopLevel, &path, xrdb.session) == False)
2404 path = xrdb.session;
2406 if ((db = XrmGetFileDatabase (path)) == NULL)
2408 tmpStr = GETSTR(16,22, "Couldn't restore session from file");
2409 tmpStr2 = (char *)XtMalloc(strlen(tmpStr) + strlen(path)+ 3);
2410 sprintf(tmpStr2, "%s: %s\n", tmpStr, path);
2411 _DtSimpleErrnoError(progName, DtError, NULL, tmpStr2, NULL);
2413 if (path != xrdb.session)
2415 session.useSession = False;
2418 if (path != xrdb.session)
2422 /*** now get the information we want from the database ***/
2423 /*** make sure values are at least somewhat reasonable ***/
2427 /* get x position */
2428 xrm_name[0] = XrmStringToQuark ("x");
2429 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2430 session.x = (Position)atoi((char *)value.addr);
2433 if (session.x < 0) session.x = 0;
2435 /* get y position */
2436 xrm_name[0] = XrmStringToQuark ("y");
2437 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2438 session.y = (Position)atoi((char *)value.addr);
2441 if (session.y < 0) session.y = 0;
2444 xrm_name[0] = XrmStringToQuark ("width");
2445 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2446 session.width = (Dimension)atoi((char *)value.addr);
2448 session.width = DEFAULT_WIDTH;
2449 if (session.width < DEFAULT_WIDTH) session.width = DEFAULT_WIDTH;
2452 xrm_name[0] = XrmStringToQuark ("height");
2453 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2454 session.height = (Dimension)atoi((char *)value.addr);
2456 session.height = DEFAULT_HEIGHT;
2457 if (session.height < DEFAULT_HEIGHT) session.height = DEFAULT_HEIGHT;
2459 /* get iconic state */
2460 xrm_name[0] = XrmStringToQuark ("iconic");
2461 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2463 if ( value.addr!=NULL && strcmp((char *)value.addr, "True")==0 )
2464 session.iconicState = IconicState;
2466 session.iconicState = NormalState;
2470 xrm_name[0] = XrmStringToQuark ("file");
2471 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2473 strncpy(start_file, value.addr, 255);
2476 start_file[0] = '\0';
2480 /***************************************************************************
2482 * Routine: ChangeTitle *
2484 * Purpose: Put the file name in the window title... *
2485 ***************************************************************************/
2490 static char *dialogTitle = NULL;
2500 name = GETSTR(12, 1, "Icon Editor");
2501 dialogTitle = XtMalloc (strlen(name) + 4);
2502 sprintf(dialogTitle, "%s - ", name);
2505 if (last_fname && *last_fname)
2507 if (name = strrchr(last_fname, '/'))
2515 tmpStr = GETSTR(10, 66, "(UNTITLED)");
2516 name = XtNewString(tmpStr);
2520 title = XtMalloc (strlen(dialogTitle) + strlen(name) + 1);
2521 sprintf(title, "%s%s", dialogTitle, name);
2524 XtSetArg(al[ac], XmNtitle, title); ac++;
2525 XtSetArg(al[ac], XmNiconName, name); ac++;
2526 XtSetValues(dtIconShell, al, ac);
2527 if(freeName == True)