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, 0x1);
381 XSetSubwindowMode(dpy, Flicker_gc, IncludeInferiors);
382 XSetDashes(dpy, Grid_gc, 0, dash_list, 2);
383 XSetLineAttributes(dpy, Grid_gc, 0, LineDoubleDash, CapButt, JoinMiter);
385 /*** Initialize the widget variables ***/
388 /*** Initialize the pen colors and the internal color table ***/
389 Init_Pen_Colors(wid);
391 XSetForeground(dpy, Erase_gc, Transparent);
393 /*** configure the color and mono icons to their initial size ***/
394 Init_Icons(icon_width, icon_height, DO_NOT_SAVE);
397 DtInitialize (dpy, wid, progName, progName);
399 /*** Drop site registration must occur after DtInitialize() ***/
403 multiClickTime = XtGetMultiClickTime(dpy);
405 /*** Now, do all the tedious widget initialization ***/
407 XtSetArg(args[i], XmNset, True); i++;
408 XtSetValues(StaticWid[CurrentColor], args, i);
409 XtSetValues(GraphicOpsWid[GraphicsOp], args, i);
410 XtSetValues(magMenu_8x_tb, args, i);
411 XtSetValues(optionsMenu_grid, args, i);
412 XtSetValues(formatMenu_xpm_tb, args, i);
414 XtSetArg(args[i], XmNbackground, Transparent); i++;
415 XtSetValues(tablet_wid, args, i);
416 XtSetValues(tabletBorder, args, i);
417 XSetForeground(dpy, Color_gc, StaticPen[0]);
418 XSetForeground(dpy, Mono_gc, StaticMono[0]);
420 XtSetArg(args[i], XmNset, FillSolids); i++;
421 XtSetValues(fillToggle, args, i);
423 XtSetArg(args[i], XmNclipWindow, &clip_wid); i++;
424 XtGetValues(viewport, args, i);
431 stat_out("DEFAULT TIME-OUT VALUE IS %d MILLISECONDS\n", multiClickTime);
432 stat_out("****CLIP WINDOW WIDGET = %d\n", clip_wid);
433 stat_out(" TABLET OFFSETS [x,y] = [%d,%d]\n", x_margin, y_margin);
438 XtSetArg(args[i], XmNbackground, Transparent); i++;
439 XtSetValues(clip_wid, args, i);
441 XtSetArg(args[i], XmNset, False); i++;
442 XtSetValues(floodButton, args, i);
443 XtSetValues(lineButton, args, i);
444 XtSetValues(polylineButton, args, i);
445 XtSetValues(rectangleButton, args, i);
446 XtSetValues(polygonButton, args, i);
447 XtSetValues(circleButton, args, i);
448 XtSetValues(ellipseButton, args, i);
449 XtSetValues(eraseButton, args, i);
450 XtSetValues(selectButton, args, i);
452 XtSetArg(args[i], XmNset, True); i++;
453 XtSetValues(pointButton, args, i);
457 /***************************************************************************
459 * Routine: GetMarginData *
461 * Purpose: We need to get margin data AFTER these widgets are realized *
462 * in order to get valid data... so do it here *
464 ***************************************************************************/
467 GetMarginData( void )
476 stat_out("****** Getting margin data: x=%d y=%d\n", x_margin, y_margin);
480 XtSetArg(args[i], XmNx, &lx); i++;
481 XtSetArg(args[i], XmNy, &ly); i++;
482 XtGetValues(tabletFrame, args, i);
486 XtSetArg(args[i], XmNx, &lx); i++;
487 XtSetArg(args[i], XmNy, &ly); i++;
488 XtGetValues(tablet_wid, args, i);
494 stat_out("****** margin data: x=%d y=%d\n", x_margin, y_margin);
500 /***************************************************************************
502 * Routine: New_MagFactor *
504 * Purpose: The user has just selected a new magnification factor for *
505 * the fat pixels on the tablet. Update the MagFactor global *
506 * variable and reapaint the visible portion of the tablet to *
507 * reflect the change. *
509 ***************************************************************************/
520 stat_out("****** Changing MagFactor to %d\n", new_value);
523 MagFactor = new_value;
525 XtSetArg(args[i], XmNwidth, (icon_width*MagFactor)); i++;
526 XtSetArg(args[i], XmNheight, (icon_height*MagFactor)); i++;
527 XtSetValues(tablet_wid, args, i);
530 /* This code does not seem to be needed and since it slows down
531 the grid drawing I'll take it out */
532 /*Repaint_Exposed_Tablet();*/
536 /***************************************************************************
538 * Routine: New_FileFormat *
540 * Purpose: Update the fileFormat value to reflect the user's current *
541 * choice of default file output formats. *
543 ***************************************************************************/
552 stat_out("****** Changing Output File Format to ");
554 case FORMAT_XPM : stat_out("XPM\n");
556 case FORMAT_XBM : stat_out("XBM\n");
558 default : stat_out("UNKNOWN\n");
564 fileFormat = new_value;
569 /***************************************************************************
571 * Routine: Icon_Coords *
573 * Purpose: Convert a set of [x,y] values (acquired from the tablet) *
574 * into the equivalent [x,y] values they represent on the *
575 * actual icon being created/modified. *
577 ***************************************************************************/
586 *fat_x = normal_x / MagFactor;
587 *fat_y = normal_y / MagFactor;
591 /***************************************************************************
593 * Routine: Tablet_Coords *
595 * Purpose: Convert a set of fat [x,y] values back into raw [x,y] values *
596 * which map to the top-left corner of the fat pixel value. *
598 ***************************************************************************/
607 *raw_x = fat_x * MagFactor;
608 *raw_y = fat_y * MagFactor;
612 /***************************************************************************
614 * Routine: Quantize *
616 * Purpose: Adjust a set of [x,] values so that they mark the top-left *
617 * corner (or the middle, depending on the 'center' flag) of *
618 * whatever 'fat' pixel they map onto. This will insure that *
619 * any operation involving rubberband lines leaps from fat *
620 * pixel center to fat pixel center, providing a clear visual *
621 * indicator of which pixel currently contains the line/point. *
623 ***************************************************************************/
636 if ((lx%MagFactor) != 0)
637 lx = (lx / MagFactor) * MagFactor;
638 if ((ly%MagFactor) != 0)
639 ly = (ly / MagFactor) * MagFactor;
649 /***************************************************************************
651 * Routine: Repaint_Exposed_Tablet *
653 * Purpose: Repaint the rectangular section of the tablet currently *
654 * visible in the clipping area widget of the scrolled window *
655 * widget. To do this, we get the current width and height *
656 * of the clipping area widget, the current width and height *
657 * of the drawing area manager widget (the clipping area *
658 * widget's immediate child), and the x and y position of the *
659 * drawing area manager widget. This will allow us to cal- *
660 * culate what portion of the tablet (drawn button widget) is *
661 * currently visible in the clipping area widget. We then *
662 * request th Repaint_Tablet() routine to repaint that portion *
663 * of the drawn button. *
665 ***************************************************************************/
668 Repaint_Exposed_Tablet( void )
673 Dimension c_width, c_height, t_width, t_height;
676 XtSetArg(args[i], XmNwidth, &c_width); i++;
677 XtSetArg(args[i], XmNheight, &c_height); i++;
678 XtGetValues(clip_wid, args, i);
680 XtSetArg(args[i], XmNx, &t_x); i++;
681 XtSetArg(args[i], XmNy, &t_y); i++;
682 XtSetArg(args[i], XmNwidth, &t_width); i++;
683 XtSetArg(args[i], XmNheight, &t_height); i++;
684 XtGetValues(tabletBorder, args, i);
690 if (t_x < 0) t_x = 0;
691 if (t_y < 0) t_y = 0;
693 Repaint_Tablet(tablet_win, t_x, t_y, c_width, c_height);
697 /***************************************************************************
699 * Routine: Repaint_Tablet *
701 * Purpose: Repaint the rectangular section of the tablet described by *
702 * the [x,y,width,height] values in the XRectangle. *
704 ***************************************************************************/
717 scratch_img = XGetImage(dpy, color_icon, 0, 0, icon_width, icon_height,
721 stat_out("****** Repaint_Tablet: x,y=%d,%d w,h=%d,%d\n", x,y,width,height);
724 for (i=x; i<x+width+MagFactor; i+=MagFactor)
725 for (j=y; j<y+height+MagFactor; j+=MagFactor) {
726 Icon_Coords(i, j, &lx, &ly);
727 if ((lx >= 0) && (lx < icon_width) &&
728 (ly >= 0) && (ly < icon_height)) {
729 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, lx, ly));
730 XFillRectangle(dpy, tablet_win, scratch_gc,
731 lx*MagFactor, ly*MagFactor, MagFactor, MagFactor);
733 if ((lx == X_Hot) && (ly == Y_Hot)) {
734 XDrawLine(dpy, tablet_win, Grid_gc,
735 lx*MagFactor, ly*MagFactor+MagFactor, lx*MagFactor+MagFactor, ly*MagFactor);
736 XDrawLine(dpy, tablet_win, Grid_gc,
737 lx*MagFactor, ly*MagFactor, lx*MagFactor+MagFactor, ly*MagFactor+MagFactor);
742 Quantize(&x, &y, False);
743 width += (MagFactor*2);
744 height += (MagFactor*2);
747 Draw the grid if Enabled....
750 for (i=x; i<=x+width+MagFactor; i+=MagFactor)
751 XDrawLine(dpy, win, Grid_gc, i, y, i, (y+height));
752 for (i=y; i<=y+height+MagFactor; i+=MagFactor)
753 XDrawLine(dpy, win, Grid_gc, x, i, (x+width), i);
757 XDestroyImage(scratch_img);
761 /***************************************************************************
763 * Routine: Paint_Tile *
765 * Purpose: Paint a single rectangular tile of size MagFactor x *
766 * MagFactor with the color supplied in the passed GC. *
767 * The X and Y parameters are coordinates for the 1:1 *
768 * sized icon, and not direct coordinates for the tablet. *
770 ***************************************************************************/
778 XFillRectangle(dpy, tablet_win, gc,
779 x*MagFactor, y*MagFactor, MagFactor, MagFactor);
782 XDrawRectangle(dpy, tablet_win, Grid_gc,
783 x*MagFactor, y*MagFactor, MagFactor, MagFactor);
786 if ((x == X_Hot) && (y == Y_Hot)) {
787 XDrawLine(dpy, tablet_win, Grid_gc,
788 x*MagFactor, y*MagFactor+MagFactor, x*MagFactor+MagFactor, y*MagFactor);
789 XDrawLine(dpy, tablet_win, Grid_gc,
790 x*MagFactor, y*MagFactor, x*MagFactor+MagFactor, y*MagFactor+MagFactor);
795 /***************************************************************************
797 * Routine: Transfer_Back_Image *
799 * Purpose: Paint a single rectangular tile of size MagFactor x *
800 * MagFactor with the color supplied in the passed GC. *
801 * The [x,y] coordinate pairs are both icon coordinates, *
802 * not tablet coordinates. *
804 ***************************************************************************/
814 int min_x, min_y, max_x, max_y, i, j;
819 stat_out("Entering Transfer_Back_Image\n");
820 stat_out("Values are x1:%d, y1:%d, x2:%d, y2:%d, flag = ",
822 stat_out(" icon size is width:%d, height:%d\n", icon_width, icon_height);
824 case HOLLOW : stat_out("HOLLOW\n");
826 case FILL : stat_out("FILL\n");
828 default : stat_out("UNKNOWN\n");
834 min_x = ((x1 < x2) ? x1 : x2);
835 min_y = ((y1 < y2) ? y1 : y2);
836 max_x = ((x1 > x2) ? x1 : x2);
837 max_y = ((y1 > y2) ? y1 : y2);
839 /*** make sure max_x and max_y are within icon ***/
840 if (max_x >= icon_width)
841 max_x = icon_width-1;
842 if (max_y >= icon_height)
843 max_y = icon_height-1;
845 scratch_img = XGetImage(dpy, color_icon, 0, 0, icon_width, icon_height,
847 /*** do the entire rectangular area... ***/
849 for (i = min_x; i <= max_x; i++)
850 for (j = min_y; j <= max_y; j++) {
851 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, i, j));
852 Paint_Tile(i, j, scratch_gc);
855 /*** ...or just do the border of rectangle ***/
857 for (i = min_x; i <= max_x; i++) {
858 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, i, min_y));
859 Paint_Tile(i, min_y, scratch_gc);
861 for (i = min_x; i <= max_x; i++) {
862 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, i, max_y));
863 Paint_Tile(i, max_y, scratch_gc);
865 for (i = min_y; i <= max_y; i++) {
866 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, min_x, i));
867 Paint_Tile(min_x, i, scratch_gc);
869 for (i = min_y; i <= max_y; i++) {
870 XSetForeground(dpy, scratch_gc, XGetPixel(scratch_img, max_x, i));
871 Paint_Tile(max_x, i, scratch_gc);
874 XDestroyImage(scratch_img);
878 stat_out("Leaving Transfer_Back_Image\n");
884 /***************************************************************************
886 * Routine: Init_Widget_list *
888 * Purpose: Initialize all the pen color widgets into 2 widget ID *
889 * arrays, to simplify referencing them later. *
891 ***************************************************************************/
894 Init_Widget_List( void )
898 GraphicOpsWid[POINT] = pointButton;
899 GraphicOpsWid[FLOOD] = floodButton;
900 GraphicOpsWid[LINE] = lineButton;
901 GraphicOpsWid[POLYLINE] = polylineButton;
902 GraphicOpsWid[RECTANGLE] = rectangleButton;
903 GraphicOpsWid[POLYGON] = polygonButton;
904 GraphicOpsWid[CIRCLE] = circleButton;
905 GraphicOpsWid[ELLIPSE] = ellipseButton;
906 GraphicOpsWid[ERASER] = eraseButton;
907 GraphicOpsWid[SELECT] = selectButton;
909 DynamicWid[BG_COLOR-BG_COLOR] = bgColorToggle;
910 DynamicWid[FG_COLOR-BG_COLOR] = fgColorToggle;
911 DynamicWid[TS_COLOR-BG_COLOR] = tsColorToggle;
912 DynamicWid[BS_COLOR-BG_COLOR] = bsColorToggle;
913 DynamicWid[SELECT_COLOR-BG_COLOR] = selectColorToggle;
914 DynamicWid[TRANS_COLOR-BG_COLOR] = transparentColorToggle;
916 StaticWid[COLOR1] = color_pb1;
917 StaticWid[COLOR2] = color_pb2;
918 StaticWid[COLOR3] = color_pb3;
919 StaticWid[COLOR4] = color_pb4;
920 StaticWid[COLOR5] = color_pb5;
921 StaticWid[COLOR6] = color_pb6;
922 StaticWid[COLOR7] = color_pb7;
923 StaticWid[COLOR8] = color_pb8;
924 StaticWid[GREY1] = grey_pb1;
925 StaticWid[GREY2] = grey_pb2;
926 StaticWid[GREY3] = grey_pb3;
927 StaticWid[GREY4] = grey_pb4;
928 StaticWid[GREY5] = grey_pb5;
929 StaticWid[GREY6] = grey_pb6;
930 StaticWid[GREY7] = grey_pb7;
931 StaticWid[GREY8] = grey_pb8;
937 /***************************************************************************
939 * Routine: Init_Pen_Colors *
941 * Purpose: Initialize all the pen colors (both Static and Dynamic) and *
942 * set the appropriate fg/bg colors for each pen button widget *
945 ***************************************************************************/
955 int i, j, pixelTableIndex;
958 XtSetArg(arg[i], XmNbackground, &Background); i++;
959 XtGetValues(wid, arg, i);
960 XmGetColors(screen_ptr, Cmap, Background, &Foreground, &TopShadow,
961 &BottomShadow, &Select);
965 stat_out("Return from XmGetColors()\n");
968 /*** Set FOREGROUND Button fg/bg colors ***/
970 XtSetArg(arg[i], XmNbackground, Foreground); i++;
971 pixelTableIndex = PixelTableLookup (Foreground, False);
972 if (PIXEL_TABLE_MONO(pixelTableIndex) == white_pixel) {
973 XtSetArg(arg[i], XmNforeground, black_pixel); i++;
976 XtSetArg(arg[i], XmNforeground, white_pixel); i++;
978 XtSetValues(fgColorToggle, arg, i);
980 /*** Set BACKGROUND Button fg/bg colors ***/
982 XtSetArg(arg[i], XmNbackground, Background); i++;
983 XtSetArg(arg[i], XmNforeground, Foreground); i++;
984 XtSetValues(bgColorToggle, arg, i);
986 /*** Set TOP_SHADOW Button fg/bg colors ***/
988 XtSetArg(arg[i], XmNbackground, TopShadow); i++;
989 if (TopShadow == Foreground) /* B & W */
990 { XtSetArg(arg[i], XmNforeground, Background); i++; }
992 { XtSetArg(arg[i], XmNforeground, Foreground); i++; }
993 XtSetValues(tsColorToggle, arg, i);
995 /*** Set BOTTOM_SHADOW Button fg/bg colors ***/
997 XtSetArg(arg[i], XmNbackground, BottomShadow); i++;
998 if (BottomShadow == Foreground) /* B & W */
999 { XtSetArg(arg[i], XmNforeground, Background); i++; }
1001 { XtSetArg(arg[i], XmNforeground, Foreground); i++; }
1002 XtSetValues(bsColorToggle, arg, i);
1004 /*** Set SELECT Button fg/bg colors ***/
1006 XtSetArg(arg[i], XmNbackground, Select); i++;
1007 XtSetArg(arg[i], XmNforeground, Foreground); i++;
1008 XtSetValues(selectColorToggle, arg, i);
1010 /*** Set TRANSPARENT Button fg/bg colors ***/
1012 XtSetArg(arg[i], XmNbackground, &Transparent); i++;
1013 XtSetArg(arg[i], XmNforeground, &transFg); i++;
1014 XtGetValues(menu1, arg, i);
1016 XtSetArg(arg[i], XmNbackground, Transparent); i++;
1017 XtSetArg(arg[i], XmNforeground, transFg); i++;
1018 XtSetValues(transparentColorToggle, arg, i);
1020 /*** Store the colors in the dynamic array ***/
1022 DynamicPen[BG_COLOR-BG_COLOR] = Background;
1023 DynamicPen[FG_COLOR-BG_COLOR] = Foreground;
1024 DynamicPen[TS_COLOR-BG_COLOR] = TopShadow;
1025 DynamicPen[BS_COLOR-BG_COLOR] = BottomShadow;
1026 DynamicPen[SELECT_COLOR-BG_COLOR] = Select;
1027 DynamicPen[TRANS_COLOR-BG_COLOR] = Transparent;
1031 stat_out("Backgrounds set for all 6 dynamic colors\n");
1034 /*** STUB *********************************************************/
1035 DynamicMono[BG_COLOR-BG_COLOR] = black_pixel;
1036 DynamicMono[FG_COLOR-BG_COLOR] = white_pixel;
1037 DynamicMono[TS_COLOR-BG_COLOR] = white_pixel;
1038 DynamicMono[BS_COLOR-BG_COLOR] = black_pixel;
1039 DynamicMono[SELECT_COLOR-BG_COLOR] = white_pixel;
1040 DynamicMono[TRANS_COLOR-BG_COLOR] = Transparent;
1042 for (i=0; i<NUM_STATICS; i++) {
1043 /*** Init the 16 color values ***/
1044 status = XParseColor(dpy, Cmap, color_table[i][5], &exact_def);
1046 sprintf(err_str, "%s %d",
1047 GETSTR(10,30, "Unable to parse static color no."), i+1);
1050 status = XAllocColor(dpy, Cmap, &exact_def);
1052 sprintf(err_str, "%s %d",
1053 GETSTR(10,32, "Unable to allocate static color no."), i+1);
1056 StaticPen[i] = exact_def.pixel;
1058 XtSetArg(arg[j], XmNbackground, StaticPen[i]); j++;
1059 XtSetValues(StaticWid[i], arg, j);
1060 /*** Init the 16 monochrome values ***/
1061 status = XParseColor(dpy, Cmap, color_table[i][2], &exact_def);
1063 sprintf(err_str, "%s %d",
1064 GETSTR(10,30, "Unable to parse static color no."), i+1);
1067 status = XAllocColor(dpy, Cmap, &exact_def);
1069 sprintf(err_str, "%s %d",
1070 GETSTR(10,32, "Unable to allocate static color no."), i+1);
1073 StaticMono[i] = exact_def.pixel;
1075 /******************************************************************/
1079 /***************************************************************************
1081 * Routine: Init_Color_Table *
1083 * Purpose: Complete initialization of the color_table used to specify *
1084 * color naming conventions when writing out XPM files. Then *
1085 * initialize the name and pixel fields for all the elements *
1086 * of the global array colorSymbols. *
1088 ***************************************************************************/
1091 Init_Color_Table( void )
1097 cmap_size = XDisplayCells(dpy, screen);
1100 for (i=NUM_STATICS; i<NUM_STATICS+5; i++) {
1101 if (DynamicMono[i-NUM_STATICS] == black_pixel)
1102 color_table[i][2] = black_string;
1104 color_table[i][2] = white_string;
1105 cval.pixel = DynamicPen[i-NUM_STATICS];
1106 XQueryColor(dpy, Cmap, &cval);
1107 sprintf(dynamic_c_str[i-NUM_STATICS], "#%04X%04X%04X",
1108 cval.red, cval.green, cval.blue);
1109 color_table[i][5] = dynamic_c_str[i-NUM_STATICS];
1111 color_table[NUM_PENS-1][2] = none_string;
1113 cval.pixel = DynamicPen[TRANS_COLOR-BG_COLOR];
1114 XQueryColor(dpy, Cmap, &cval);
1115 sprintf(dynamic_c_str[NUM_DYNAMICS-1], "#%04X%04X%04X",
1116 cval.red, cval.green, cval.blue);
1117 color_table[NUM_PENS-1][5] = dynamic_c_str[NUM_DYNAMICS-1];
1122 stat_out("XPM Color Table initialized:\n");
1123 for (i=0; i<(NUM_PENS); i++)
1124 stat_out(" %s %18s %18s\n", color_table[i][0], color_table[i][1],
1129 colorSymbols = (XpmColorSymbol *) XtMalloc(NUM_PENS * sizeof(XpmColorSymbol));
1131 Abort(GETSTR(10,38, "No memory(0)"));
1132 for (i=0; i<NUM_STATICS; i++) {
1133 colorSymbols[i].name = (char *) XtMalloc(strlen(color_table[i][1]) +1);
1134 if (!colorSymbols[i].name)
1135 Abort(GETSTR(10,40, "No memory(1)"));
1136 strcpy(colorSymbols[i].name, color_table[i][1]);
1137 colorSymbols[i].value = "";
1138 colorSymbols[i].pixel = StaticPen[i];
1140 for (i=NUM_STATICS; i<NUM_STATICS+NUM_DYNAMICS; i++) {
1141 colorSymbols[i].name = (char *) XtMalloc(strlen(color_table[i][1]) +1);
1142 if (!colorSymbols[i].name)
1143 Abort(GETSTR(10,42, "No memory(2)"));
1144 strcpy(colorSymbols[i].name, color_table[i][1]);
1145 colorSymbols[i].value = "";
1146 colorSymbols[i].pixel = DynamicPen[i-NUM_STATICS];
1151 stat_out("%d Color Symbols installed:\n", NUM_PENS);
1152 for (i=0; i<NUM_PENS; i++) {
1153 stat_out(" %d - %s | %s | %d\n", (i+1), colorSymbols[i].name,
1154 colorSymbols[i].value, colorSymbols[i].pixel);
1159 /*** now comes the ugly part, initialize the .colorTable field ***/
1160 /*** in xpm_WriteAttribs. This should remain constant for the ***/
1161 /*** life of the executable, and so only needs to be initialized ***/
1164 colorTable = (char ***) calloc(NUM_PENS, sizeof(char **));
1165 xpm_WriteAttribs.colorTable = (XpmColor*)colorTable;
1166 xpm_WriteAttribs.pixels = (Pixel *) calloc(NUM_PENS, sizeof(Pixel));
1167 if (!xpm_WriteAttribs.colorTable)
1168 Abort(GETSTR(10,44, "No memory(3)"));
1169 for (i=0; i<NUM_PENS; i++) {
1170 colorTable[i] = (char **) calloc(6, sizeof(char *));
1172 Abort(GETSTR(10,46, "No memory(4)"));
1174 for (i=0; i<NUM_PENS; i++) {
1175 xpm_WriteAttribs.pixels[i] = colorSymbols[i].pixel;
1176 for (j=0; j<6; j++) {
1177 if (color_table[i][j] && strlen(color_table[i][j]) > 0) {
1178 colorTable[i][j] = (char *) XtMalloc(strlen(color_table[i][j])+1);
1179 if (!colorTable[i][j])
1180 Abort(GETSTR(10,48, "No memory(5)"));
1181 strcpy(colorTable[i][j], color_table[i][j]);
1185 xpm_WriteAttribs.ncolors = NUM_PENS;
1186 xpm_WriteAttribs.hints_cmt = hints_cmt;
1187 xpm_WriteAttribs.colors_cmt = colors_cmt;
1188 xpm_WriteAttribs.pixels_cmt = pixels_cmt;
1189 xpm_WriteAttribs.mask_pixel = 0x80000000;
1193 Dump_AttribStruct(&xpm_WriteAttribs);
1198 /***************************************************************************
1200 * Routine: Size_IconForm *
1202 * Purpose: Given new dimensions for the Color and Mono icon widgets, *
1203 * calculate and set the new overall dimensions for the icon *
1204 * form widget (iconForm) which holds both of them and their *
1207 ***************************************************************************/
1216 Dimension label1_w, label1_h, label2_w, label2_h;
1217 Dimension form_width, form_height, junk;
1218 XmString label1_str, label2_str;
1219 XmFontList label_fontlist;
1224 stat_out("Entering Size_IconForm\n");
1227 /*********************************************************************
1228 * Before re-sizing the 2 icons (up or down), make sure their parent *
1229 * form's width is at least wide enough to fully show the two label *
1230 * gadgets (iconSize and monoLabel). If the icon widths are smaller *
1231 * than this, set offsets to center them on the space provided. *
1232 *********************************************************************/
1234 /*********************************************************************
1235 * First, get the minimum usable widths for the two label gadgets, *
1236 * and their current heights. *
1237 *********************************************************************/
1239 XtSetArg(args[i], XmNfontList, &label_fontlist); i++;
1240 XtSetArg(args[i], XmNlabelString, &label1_str); i++;
1241 XtGetValues(iconSize, args, i);
1243 XtSetArg(args[i], XmNlabelString, &label2_str); i++;
1244 XtGetValues(monoLabel, args, i);
1246 XmStringExtent(label_fontlist, label1_str, &label1_w, &junk);
1247 XmStringExtent(label_fontlist, label2_str, &label2_w, &junk);
1249 XtSetArg(args[i], XmNheight, &label1_h); i++;
1250 XtGetValues(iconSize, args, i);
1252 XtSetArg(args[i], XmNheight, &label2_h); i++;
1253 XtGetValues(monoLabel, args, i);
1255 /*********************************************************************
1256 * If the min. width for either label gadget is greater than the *
1257 * current icon widths, use half the difference between the two *
1258 * widths as a left and right offset for the two icon (drawn button) *
1260 *********************************************************************/
1261 if ((label1_w > width) || (label2_w > width))
1262 diff = (Position) (((label1_w > label2_w) ? label1_w : label2_w)
1268 XtSetArg(args[i], XmNleftOffset, diff); i++;
1269 XtSetValues(iconImage, args, i);
1270 XtSetValues(monoImage, args, i);
1272 /*********************************************************************
1273 * The overall form dimensions should be as follows: the form width *
1274 * will be the greater of the icon widths, or the widths of the two *
1275 * label gadgets. The form height will be the sum of the two icon *
1276 * heights, plus the sum of heights of the two label gadgets, plus *
1277 * the vertical offset between the bottom of the first label and the *
1278 * top of the second icon. *
1279 *********************************************************************/
1281 XtSetArg(args[i], XmNtopOffset, &top_offset); i++;
1282 XtGetValues(monoImage, args, i);
1283 form_width = max(width, (Dimension)max(label1_w, label2_w));
1284 form_height = (height*2) + label1_h + label2_h + top_offset;
1287 stat_out(" form_width = %d (of %d,%d,%d)\n", form_width, width, label1_w,
1289 stat_out(" form_height = %d\n", form_height);
1293 XtSetArg(args[i], XmNwidth, form_width); i++;
1294 XtSetArg(args[i], XmNheight, form_height); i++;
1295 XtSetValues(iconForm, args, i);
1299 stat_out("Leaving Size_IconForm\n");
1304 /***************************************************************************
1306 * Routine: Init_Icons *
1308 * Purpose: Initialize new color and mono icons at program start-up *
1309 * and at the following times: *
1310 * o When 'New' is selected from the 'File' pull-down menu. *
1311 * o When 'Resize Icon' is selected from the 'Edit' pull-down *
1313 * o When 'Load' is selected from the 'File' pull-down menu, *
1314 * and a new file is read in. *
1315 * o When 'Grab Screen Image' is selected from the 'Edit' *
1316 * pull-down menu, and the image is loaded into the editor. *
1318 * This routine sizes the iconImage, monoImage, and tablet *
1319 * widgets to the new dimensions (*MagFactor, and +1 in the *
1320 * case of the tablet widget). It also creates the application-*
1321 * internal Pixmaps associated with the iconImage and monoImage.*
1322 * If the 'saveFlag' flag is 'True', it is assumed that the *
1323 * current icons are being resized and that there are existing *
1324 * images that need to be retained. In this case, the new *
1325 * Pixmaps are created and the old Pixmaps are copied onto the *
1326 * new ones, before the old Pixmaps are freed. *
1328 ***************************************************************************/
1337 Pixmap tmp_color, tmp_mono;
1340 int i, x_offset, y_offset;
1345 stat_out("Entering Init_Icons: flag=%d\n", saveFlag);
1346 stat_out(" Init_Icons: color=%x mono=%x\n", color_icon, mono_icon);
1352 /*** App. init or 'New Icon' ***/
1355 XFreePixmap(dpy, color_icon);
1357 XFreePixmap(dpy, mono_icon);
1359 /*** Resizing the existing icon ***/
1362 tmp_color = color_icon;
1364 tmp_mono = mono_icon;
1369 color_icon = XCreatePixmap(dpy, root, width, height,
1370 DefaultDepth(dpy, screen));
1371 mono_icon = XCreatePixmap(dpy, root, width, height,
1372 DefaultDepth(dpy, screen));
1374 if ((color_icon == 0) || (mono_icon == 0))
1375 Abort(GETSTR(10,50, "Cannot initialize application icon storage"));
1377 XSetForeground(dpy, scratch_gc, Transparent);
1378 XFillRectangle(dpy, color_icon, scratch_gc, 0, 0, width, height);
1379 XFillRectangle(dpy, mono_icon, scratch_gc, 0, 0, width, height);
1381 sprintf(text, "%d x %d", width, height);
1383 local_str = XmStringCreateLocalized(text);
1384 XtSetArg(args[i], XmNlabelString, local_str); i++;
1385 XtSetValues(iconSize, args, i);
1386 XmStringFree(local_str);
1389 XtSetArg(args[i], XmNwidth, width); i++;
1390 XtSetArg(args[i], XmNheight, height); i++;
1391 XtSetValues(iconImage, args, i);
1392 XtSetValues(monoImage, args, i);
1394 /*********************************************************************
1395 * Call Size_IconForm() to re-do the layout of the iconForm widget, *
1396 * which contains the iconImage, iconSize, monoImage, and monoLabel *
1398 *********************************************************************/
1400 Size_IconForm(width, height);
1403 XCopyArea(dpy, tmp_color, color_icon, Color_gc, 0, 0,
1404 icon_width, icon_height, x_offset, y_offset);
1405 XCopyArea(dpy, tmp_mono, mono_icon, Mono_gc, 0, 0,
1406 icon_width, icon_height, x_offset, y_offset);
1408 XFreePixmap(dpy, tmp_color);
1410 XFreePixmap(dpy, tmp_mono);
1413 if (XtWindow(iconImage))
1414 XCopyArea(dpy, color_icon, XtWindow(iconImage), Color_gc,
1415 0, 0, width, height, 0, 0);
1416 if (XtWindow(monoImage))
1417 XCopyArea(dpy, mono_icon, XtWindow(monoImage), Mono_gc,
1418 0, 0, width, height, 0, 0);
1420 XtSetArg(args[i], XmNwidth, ((width*MagFactor)+1)); i++;
1421 XtSetArg(args[i], XmNheight, ((height*MagFactor)+1)); i++;
1422 XtSetValues(tablet_wid, args, i);
1425 icon_height = height;
1427 /* This code does not seem to be needed and since it slows down
1428 the grid drawing I'll take it out for now*/
1431 Repaint_Exposed_Tablet();
1436 stat_out("Leaving Init_Icons\n");
1443 XtPointer client_data,
1444 XtPointer call_data)
1446 DtDndTransferCallback transferInfo = (DtDndTransferCallback) call_data;
1448 if (transferInfo->reason == DtCR_DND_TRANSFER &&
1449 transferInfo->operation == XmDROP_COPY) {
1451 Process_DropCheckOp(w, client_data, call_data);
1453 transferInfo->status = DtDND_FAILURE;
1460 XtPointer client_data,
1461 XtPointer call_data)
1463 DtDndDropAnimateCallbackStruct *animateInfo =
1464 (DtDndDropAnimateCallbackStruct *) call_data;
1466 if (animateInfo->reason == DtCR_DND_DROP_ANIMATE) {
1468 Process_DropOp(w, client_data, call_data);
1472 /***************************************************************************
1474 * Routine: RegisterDropSites *
1476 * Purpose: Register the tablet as a valid drop zone. *
1478 ***************************************************************************/
1481 RegisterDropSites( void )
1483 static XtCallbackRec transferCB[] = { {TransferCallback, NULL},
1485 static XtCallbackRec animateCB[] = { {AnimateCallback, NULL},
1491 XtSetArg(args[0], XmNclipWindow, &clipWin);
1492 XtGetValues(viewport, args, 1);
1495 * This code makes assumptions about the order of the arguments.
1496 * XmNanimationStyle is assumed to be first and
1497 * DtNregisterChildren is assumed to be last
1500 XtSetArg(args[n], XmNanimationStyle, XmDRAG_UNDER_NONE); n++; /* first */
1501 XtSetArg(args[n], DtNdropAnimateCallback, animateCB); n++;
1502 XtSetArg(args[n], DtNregisterChildren, True); n++; /* last */
1504 DtDndDropRegister(clipWin, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1505 (XtCallbackList) transferCB, args, n);
1507 DtDndDropRegister(tabletBorder, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1508 (XtCallbackList) transferCB, args, n);
1510 DtDndDropRegister(tabletFrame, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1511 (XtCallbackList) transferCB, args, n);
1513 DtDndDropRegister(tablet, DtDND_FILENAME_TRANSFER, XmDROP_COPY,
1514 (XtCallbackList) transferCB, args, n - 1);
1517 * Once the drag and drop library is fixed, the following calls
1518 * will not be necessary. Currently the dnd library does not pass on
1519 * Motif resource values, in this case XmNanimationStyle.
1522 XmDropSiteUpdate(clipWin, args, 1);
1523 XmDropSiteUpdate(tabletBorder, args, 1);
1524 XmDropSiteUpdate(tabletFrame, args, 1);
1525 XmDropSiteUpdate(tablet, args, 1);
1528 /***************************************************************************
1532 * Purpose: Print a fatal error message and then exit. *
1534 ***************************************************************************/
1541 _DtSimpleError (progName, DtError, NULL, str, NULL);
1546 /***************************************************************************
1548 * Routine: stat_out *
1550 * Purpose: Generate a debug message to stderr. Flush stdout, and then *
1551 * print the message(s) to stderr and flush stderr. By doing *
1552 * an fflush after each fprintf, we can always determin where *
1553 * in the code the process is running. The stat_out() routine *
1554 * is invoked like printf() with up to 7 arguments. It is *
1555 * source-code identical to the outl() routine used in the xwd *
1556 * and xwud utilities which are part of standard X11. *
1558 *X11***********************************************************************/
1571 /* static char str[1024]; */
1574 fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
1577 /* sprintf(str, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
1578 _DtSimpleError ("dticon-stat_out", DtError, NULL, str, NULL);*/
1581 /***************************************************************************
1583 * Routine: PixelTableClear *
1585 * Purpose: Reset the pixel table to force subsequent lookups to get *
1586 * new pixel information. Do not free up space for table. *
1588 *X11***********************************************************************/
1592 pixelTable.numItems = 0;
1593 pixelTable.lastFound = 0;
1596 /***************************************************************************
1598 * Routine: PixelTableLookup *
1600 * Purpose: Return index into the Pixel Table for the pixel passed in. *
1601 * If the pixel passed in isn't already in the table, it will *
1602 * be added. This may require allocating a larger pixel table. *
1603 * In order to clear the Pixel Table (which should be done each *
1604 * time a new image is being processed in order to get current *
1605 * pixel data) call PixelTableClear(). *
1607 * For performance, save the last lookup result, and check it *
1608 * first. This should improve performance unless image is very *
1609 * "dithered". The allocNew parameter will be set if the image *
1610 * was grabbed from screen. In this case, each "screen" pixel *
1611 * will need a new pixel allocated for it. *
1613 *X11***********************************************************************/
1622 /** first, check to see if the last lookup was for the same pixel **/
1623 if (pixelTable.lastFound < pixelTable.numItems)
1624 if (pixelTable.item[pixelTable.lastFound].xcolor.pixel == pixelIn)
1625 return pixelTable.lastFound;
1627 /** look through table to see if there is an entry for this pixel **/
1628 for (i=0; i<pixelTable.numItems; i++)
1630 if (pixelTable.item[i].xcolor.pixel == pixelIn)
1632 pixelTable.lastFound = i;
1638 /** No entry for this pixel, create one **/
1641 /** Allocate larger table if needed **/
1642 if (pixelTable.numItems == pixelTable.pixelTableSize)
1644 pixelTable.pixelTableSize += PIXEL_TABLE_INC;
1645 pixelTable.item = (PixelTableItem *)XtRealloc((char *)pixelTable.item,
1646 sizeof(PixelTableItem)*pixelTable.pixelTableSize);
1649 /** Get color information for pixelIn **/
1650 i = pixelTable.numItems;
1651 pixelTable.numItems++;
1653 pixelTable.item[i].xcolor.pixel = pixelIn;
1654 XQueryColor(dpy, Cmap, &(pixelTable.item[i].xcolor));
1656 /*--- < ESTABLISH THE GREYSCALE IMAGE > ---*/
1657 /*--- The NTSC formula for converting an RGB value into the ---*/
1658 /*--- corresponding grayscale value is: ---*/
1659 /*--- luminosity = .299 red + .587 green + .114 blue ---*/
1661 grayValue = ( (int)((pixelTable.item[i].xcolor.red*299) +
1662 (pixelTable.item[i].xcolor.green*587) +
1663 (pixelTable.item[i].xcolor.blue*114)) / 1000) >> 8;
1665 if (grayValue < GAMMA_CUTOFF)
1666 pixelTable.item[i].mono = black_pixel;
1668 pixelTable.item[i].mono = white_pixel;
1670 /** Allocate new color cell if needed (use old for mono conversion) **/
1673 tmpXColor.red = pixelTable.item[i].xcolor.red;
1674 tmpXColor.green = pixelTable.item[i].xcolor.green;
1675 tmpXColor.blue = pixelTable.item[i].xcolor.blue;
1677 if (!XAllocColor(dpy, Cmap, &tmpXColor))
1679 /* for lack of something better, use the old color cell */
1680 pixelTable.item[i].newCell = pixelTable.item[i].xcolor.pixel;
1681 DoErrorDialog(GETSTR(10,62,"Operation failed.\nColormap is full"));
1684 pixelTable.item[i].newCell = tmpXColor.pixel;
1687 pixelTable.lastFound = i;
1692 /***************************************************************************
1694 * Routine: Switch_FillSolids *
1696 * Purpose: Toggles the state of the global FillSolids flag, based on *
1697 * the XmNset resource for the fillToggle widget. *
1699 *X11***********************************************************************/
1702 Switch_FillSolids( void )
1708 XtSetArg(args[i], XmNset, &FillSolids); i++;
1709 XtGetValues(fillToggle, args, i);
1711 Set_Gfx_Labels(FILL);
1713 Set_Gfx_Labels(HOLLOW);
1716 stat_out("Fill_Solids toggle = %s\n", (FillSolids? "True" : "False"));
1721 /***************************************************************************
1723 * Routine: Select_New_Pen *
1725 * Purpose: Changes the fg color of the pen GC, based on the parameter *
1728 *X11***********************************************************************/
1734 int new_block, new_pen;
1737 new_block = STATIC_COLOR;
1741 new_block = DYNAMIC_COLOR;
1742 new_pen = n - BG_COLOR;
1746 stat_out("**** n = %d, new_block = %d, new_pen = %d\n", n,
1747 new_block, new_pen);
1751 /*** if the new choice is the current pen, re-set it and return ***/
1752 if ((new_block == ColorBlock) && (new_pen == CurrentColor)) {
1753 if (new_block == STATIC_COLOR)
1754 XmToggleButtonSetState(StaticWid[new_pen], True, False);
1756 XmToggleButtonSetState(DynamicWid[new_pen], True, False);
1760 /*** un-set the previous choice ***/
1761 if (ColorBlock == STATIC_COLOR)
1762 XmToggleButtonSetState(StaticWid[CurrentColor], False, False);
1764 XmToggleButtonSetState(DynamicWid[CurrentColor], False, False);
1768 stat_out(" New pen color = %d\n", n);
1771 ColorBlock = new_block; /*** STATIC or DYNAMIC? ***/
1772 CurrentColor = new_pen; /*** index w/i the appropriate block ***/
1774 XSetForeground(dpy, Color_gc,
1775 (ColorBlock ? DynamicPen[CurrentColor] : StaticPen[CurrentColor]));
1776 XSetForeground(dpy, Mono_gc,
1777 (ColorBlock ? DynamicMono[CurrentColor] : StaticMono[CurrentColor]));
1781 /***************************************************************************
1783 * Routine: Backup_Icons *
1785 * Purpose: Copy the current contents of the color and mono icons to *
1786 * their undo storage areas, just prior to modifying them with *
1787 * the current graphics operation. *
1789 *X11***********************************************************************/
1792 Backup_Icons( void )
1794 /*** If we're backing up the tablet contents, it's dirty ***/
1795 /*** and may need to be saved to file at some point. ***/
1799 /*** if the icon sizes don't match the backup sizes, or ***/
1800 /*** either of the backup icons don't exist, create them ***/
1802 if ((icon_width != backup_width) ||
1803 (icon_height != backup_height) ||
1804 (!prev_color_icon) ||
1805 (!prev_mono_icon)) {
1806 if (prev_color_icon)
1807 XFreePixmap(dpy, prev_color_icon);
1809 XFreePixmap(dpy, prev_mono_icon);
1810 prev_color_icon = XCreatePixmap(dpy, root, icon_width, icon_height,
1811 DefaultDepth(dpy, screen));
1812 prev_mono_icon = XCreatePixmap(dpy, root, icon_width, icon_height,
1813 DefaultDepth(dpy, screen));
1814 backup_width = icon_width;
1815 backup_height = icon_height;
1818 /*** now, copy the color and mono pixmap to the backup pixmaps ***/
1820 XCopyArea(dpy, color_icon, prev_color_icon,
1821 Color_gc, 0, 0, icon_width, icon_height, 0, 0);
1822 XCopyArea(dpy, mono_icon, prev_mono_icon,
1823 Mono_gc, 0, 0, icon_width, icon_height, 0, 0);
1825 XtSetSensitive( editMenu_undo_pb, True);
1829 /***************************************************************************
1831 * Routine: DoErrorDialog *
1833 * Purpose: Some error has just occurred in the application. Pop up *
1834 * the error dialog and display the message passed in. *
1836 *X11***********************************************************************/
1847 local_str = XmStringCreateLocalized(str);
1848 XtSetArg(arg[i], XmNmessageString, local_str);
1850 XtSetValues(stdErrDialog, arg, i);
1851 XmStringFree(local_str);
1852 XtManageChild(stdErrDialog);
1856 /***************************************************************************
1858 * Routine: DoQueryDialog *
1860 * Purpose: The user should be prompted on an action they're attempting. *
1861 * Pop up the query dialog and display the message passed in. *
1863 *X11***********************************************************************/
1872 static Widget w=NULL;
1874 XtPopup(dtIconShell, XtGrabNone);
1875 XMapRaised(XtDisplay(dtIconShell), XtWindow(dtIconShell));
1878 w = XmMessageBoxGetChild(queryDialog, XmDIALOG_CANCEL_BUTTON);
1881 local_str = XmStringCreateLocalized(str);
1882 XtSetArg(arg[i], XmNmessageString, local_str); i++;
1883 XtSetValues(queryDialog, arg, i);
1884 XmStringFree(local_str);
1885 XtManageChild(queryDialog);
1887 XmProcessTraversal(w, XmTRAVERSE_CURRENT);
1891 /***************************************************************************
1893 * Routine: Do_GrabOp *
1895 * Purpose: Switch to GRAB mode. Grab the server and the pointer until *
1896 * the user has made a selection from the screen. The server *
1897 * and pointer are ungrabbed in Do_ButtonOp(). *
1899 * Note: Moved the server grab until the mouse button is pressed *
1900 * (beginning the screen grab) in order to give the windows *
1901 * time to repaint. This was needed specifically for the *
1902 * queryDialog used when the icon image is "Dirty". *
1904 *X11***********************************************************************/
1909 Backup_G_Op = GraphicsOp;
1910 GraphicsOp = S_GRAB;
1911 cursor = XCreateFontCursor(dpy, XC_crosshair);
1912 XGrabPointer(dpy, root, False,
1913 ButtonPressMask|PointerMotionMask|ButtonReleaseMask,
1914 GrabModeAsync, GrabModeAsync, None, cursor, CurrentTime);
1918 /***************************************************************************
1920 * Routine: LoadGrabbedImage *
1922 * Purpose: Given an [x,y] coordinate, plus width and height, grab an *
1923 * XImage from the Root window and load it into the icon *
1926 *X11***********************************************************************/
1934 XImage *img, *mono_img;
1936 int pixelTableIndex;
1940 stat_out("LoadGrabbedImage: [%d,%d] - width: %d, height: %d\n",
1941 x, y, width, height);
1946 if (width > 0 && height > 0)
1947 img = XGetImage(dpy, root, x, y, width, height, AllPlanes, format);
1949 XUngrabPointer (dpy, CurrentTime);
1950 XUngrabServer (dpy);
1954 DoErrorDialog( GETSTR(10,60, "Screen image capture failed") );
1958 /*********************************************************************
1959 * OK, now that we've got the image, we need to convert the entire *
1960 * thing to pixels that the icon editor won't lose control over. *
1961 * To do this, we find all the pixel values in the image and request *
1962 * equivalent read-only colors in the colormap (we won't be drawing *
1963 * with any pen colors we don't already have). Once the requests to *
1964 * the Cmap have been honored, we go thru the image one more time *
1965 * and replace each old pixel with the correct new value. *
1966 * NOTE: Old code assumed 256 max colors... NOT OKAY. Added dynamic *
1967 * pixel table for color lookup, which also handles allocating *
1968 * the new read-only color. - julie *
1969 *********************************************************************/
1971 /*********************************************************************
1972 * Dup the XImage so there'll be two identical copies: one to *
1973 * update with the new color values, and one with which to create *
1974 * a monochrome equivalent. *
1975 *********************************************************************/
1976 mono_img = XSubImage(img, 0, 0, img->width, img->height);
1978 DoErrorDialog( GETSTR(10,60, "Screen image capture failed") );
1982 /* force new pixel lookup, in case pixel data has changed */
1984 for (i=0; i<img->width; i++)
1986 for (j=0; j<img->height; j++)
1988 pixelTableIndex = PixelTableLookup(XGetPixel(img, i, j), True);
1989 XPutPixel(img, i, j, PIXEL_TABLE_NEW_CELL(pixelTableIndex));
1990 XPutPixel(mono_img, i, j, PIXEL_TABLE_MONO(pixelTableIndex));
1995 Init_Icons(img->width, img->height, DO_NOT_SAVE);
1996 XPutImage(dpy, color_icon, Color_gc, img, 0, 0, 0, 0,
1997 img->width, img->height);
1998 XPutImage(dpy, mono_icon, Mono_gc, mono_img, 0, 0, 0, 0,
1999 img->width, img->height);
2002 XDestroyImage(mono_img);
2008 /***************************************************************************
2010 * Routine: ParseAppArgs *
2012 * Purpose: Parse the invocation arguments, looking for '-f' and '-x'. *
2013 * This routine is invoked once by dticon. *
2015 * Each of the args should be accompanied by a parameter. If *
2016 * one does not exist, abort dticon with the appropriate *
2017 * error message. Otherwise, store the parameter in a global *
2018 * variable for processing by ProcessAppArgs() (called once *
2021 *X11***********************************************************************/
2033 stat_out("Entering ParseAppArgs\n");
2036 for (i=0; i<NUM_PARAMS; i++)
2037 param_flag[i] = False;
2038 argsNeedProcessed = False;
2040 /*** First, figure out which arguments get used ***/
2042 /* don't process command line args if restoring from a session file */
2043 if (xrdb.session != NULL)
2044 argsNeedProcessed = True;
2047 for (i=1; i<num; i++)
2051 if (cmd_arg[0] == '-') /* process command line switches */
2057 if (strncpy(start_file, cmd[i], 255)) {
2058 param_flag[AUTO_FILE] = True;
2059 argsNeedProcessed = True;
2062 Abort(GETSTR(10,52, "Invalid use of the '-f' parameter"));
2065 Abort(GETSTR(10,52, "Invalid use of the '-f' parameter"));
2067 case 'x': if (++i < num)
2069 if (strcpy(start_size, cmd[i])) {
2070 param_flag[AUTO_SIZE] = True;
2071 argsNeedProcessed = True;
2074 Abort(GETSTR(10,54, "Invalid use of the '-x' parameter"));
2077 Abort(GETSTR(10,54, "Invalid use of the '-x' parameter"));
2087 for (i=0; i<NUM_PARAMS; i++)
2088 stat_out(" param_flag = %s\n", (param_flag[i] ? "True" : "False"));
2089 stat_out("Leaving ParseAppArgs\n");
2096 /***************************************************************************
2098 * Routine: ProcessAppArgs *
2100 * Purpose: Process the invocation arguments, '-f'and '-x' *
2102 * If '-f' exists, the following parameter should be the name *
2103 * of a file to load at application start-up. Invoke the *
2104 * Read_File() routine with that parameter. *
2106 * If '-x' exists, the following parameter should be the *
2107 * initial geometry for the icon tablet (work area). Parse *
2108 * the string with XParseGeometry and pass the results (if *
2109 * valid) to Eval_NewSize(). *
2111 *X11***********************************************************************/
2113 #define MASK (WidthValue & HeightValue)
2116 ProcessAppArgs( void )
2123 stat_out("Entering ProcessAppArgs\n");
2126 argsNeedProcessed = False;
2128 /*** Attempt to honor the arguments, in order of priority ***/
2129 /*** ('-session', '-f', '-x', in that order). ***/
2131 /*** GetSessionInfo() will already set start_file if needed **/
2133 if ( param_flag[AUTO_FILE] || (session.useSession && start_file[0] != '\0') )
2135 fileIOMode = FILE_READ;
2136 if (!Read_File(start_file))
2137 DoErrorDialog( GETSTR(16,2,
2138 "The file cannot be accessed\nor contains invalid data") );
2140 if (successFormat == FORMAT_XPM) {
2141 X_Hot = xpm_ReadAttribs.x_hotspot;
2142 Y_Hot = xpm_ReadAttribs.y_hotspot;
2143 Display_XPMFile(xpm_ReadAttribs.width, xpm_ReadAttribs.height);
2145 else if (successFormat == FORMAT_XBM) {
2148 Display_XBMFile(width_ret, height_ret);
2152 else if(param_flag[AUTO_SIZE]) {
2153 result = XParseGeometry(start_size, &x_ret, &y_ret,
2154 &width_ret, &height_ret);
2155 if ((!MASK) & result)
2156 Abort(GETSTR(10,64, "Invalid dimension parameter"));
2158 Eval_NewSize(width_ret, height_ret);
2163 stat_out("Leaving ProcessAppArgs\n");
2169 /***************************************************************************
2171 * Routine: Set_Gfx_Labels *
2173 * Purpose: Set the label pixmaps of the 'Rectangle', 'Polygon', *
2174 * 'Circle', and 'Ellipse' graphics tool toggle to either *
2175 * Solid or Hollow, depending on the flag passed in. *
2177 *X11***********************************************************************/
2186 if (flag == HOLLOW) {
2188 XtSetArg(args[i], XmNlabelPixmap, rectPix); i++;
2189 XtSetValues(rectangleButton, args, i);
2191 XtSetArg(args[i], XmNlabelPixmap, circlePix); i++;
2192 XtSetValues(circleButton, args, i);
2194 XtSetArg(args[i], XmNlabelPixmap, polygonPix); i++;
2195 XtSetValues(polygonButton, args, i);
2197 XtSetArg(args[i], XmNlabelPixmap, ellipsePix); i++;
2198 XtSetValues(ellipseButton, args, i);
2202 XtSetArg(args[i], XmNlabelPixmap, rectSolidPix); i++;
2203 XtSetValues(rectangleButton, args, i);
2205 XtSetArg(args[i], XmNlabelPixmap, circleSolidPix); i++;
2206 XtSetValues(circleButton, args, i);
2208 XtSetArg(args[i], XmNlabelPixmap, polygonSolidPix); i++;
2209 XtSetValues(polygonButton, args, i);
2211 XtSetArg(args[i], XmNlabelPixmap, ellipseSolidPix); i++;
2212 XtSetValues(ellipseButton, args, i);
2217 /***************************************************************************
2219 * Routine: jskXerrorDebug *
2221 * Purpose: This routine takes the place of the default non-fatal error *
2222 * handler normally used by the X server. If an error occurs, *
2223 * this routine simply stores the error_code in the global *
2224 * variable XErrorFlag (making it available to other sections *
2225 * of the application). Then it returns. *
2227 ***************************************************************************/
2228 #define MAX_MSG_STR 1024
2230 static int jskXerrorDebug(disp, error_event)
2232 XErrorEvent *error_event;
2234 char error_msg[MAX_MSG_STR];
2238 stat_out("\n\nX Protocol Error:\n");
2240 _DtPrintDefaultErrorSafe(disp, error_event, error_msg, MAX_MSG_STR);
2241 _DtSimpleError (progName, DtWarning, NULL, error_msg, NULL);
2248 /***************************************************************************
2250 * Routine: jskXerrorIODebug *
2252 * Purpose: This routine is needed in order to get good bfa (bba) stats *
2253 **************************************************************************/
2254 static int jskXerrorIODebug(disp)
2262 /***************************************************************************
2264 * Routine: SaveSession *
2266 * Purpose: save state information for session management *
2267 **************************************************************************/
2273 char *xa_CommandStr[3];
2274 char *tmpStr, *tmpStr2;
2276 Dimension width, height;
2277 char bufr[1024]; /* make bigger if needed */
2278 XmVendorShellExtObject vendorExt;
2279 XmWidgetExtData extData;
2281 Atom wmStateAtom, actualType;
2283 unsigned long nitems, leftover;
2288 stat_out("SaveSession\n");
2291 DtSessionSavePath(dtIconShell, &path, &name);
2293 /* Create the session file */
2294 if ((fd = creat(path, S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP)) == -1)
2296 tmpStr = GETSTR(16,24, "Couldn't save session to file");
2297 tmpStr2 = (char *)XtMalloc(strlen(tmpStr) + strlen(path)+ 3);
2298 sprintf(tmpStr2, "%s: %s\n", tmpStr, path);
2299 _DtSimpleErrnoError(progName, DtError, NULL, tmpStr2, NULL);
2301 XtFree ((char *)path);
2302 XtFree ((char *)name);
2307 /* Getting the WM_STATE property to see if iconified or not */
2309 wmStateAtom = XInternAtom(dpy, "WM_STATE", False);
2311 XGetWindowProperty (dpy, XtWindow(dtIconShell), wmStateAtom, 0L,
2312 (long)BUFSIZ, False, wmStateAtom, &actualType,
2313 &actualFormat, &nitems, &leftover,
2314 (unsigned char **) &wmState);
2316 if (wmState->state == IconicState)
2317 sprintf(bufr, "*iconic: True\n");
2319 sprintf(bufr, "*iconic: False\n");
2321 /*** Get and write out the geometry info for our Window ***/
2323 x = XtX(dtIconShell);
2324 y = XtY(dtIconShell);
2325 width = XtWidth(dtIconShell);
2326 height = XtHeight(dtIconShell);
2328 /* Modify x & y to take into account window mgr frames
2329 * This is pretty bogus, but I don't know a better way to do it.
2331 extData = _XmGetWidgetExtData(dtIconShell, XmSHELL_EXTENSION);
2332 vendorExt = (XmVendorShellExtObject)extData->widget;
2333 x -= vendorExt->vendor.xOffset;
2334 y -= vendorExt->vendor.yOffset;
2336 sprintf(bufr, "%s*x: %d\n", bufr, x);
2337 sprintf(bufr, "%s*y: %d\n", bufr, y);
2338 sprintf(bufr, "%s*width: %d\n", bufr, width);
2339 sprintf(bufr, "%s*height: %d\n", bufr, height);
2340 if (last_fname[0] != '\0')
2341 sprintf(bufr, "%s*file: %s\n", bufr, last_fname);
2343 write (fd, bufr, strlen(bufr));
2347 xa_CommandStr[n] = execName; n++;
2348 xa_CommandStr[n] = "-session"; n++;
2349 xa_CommandStr[n] = name; n++;
2351 XSetCommand(dpy, XtWindow(dtIconShell), xa_CommandStr, n);
2352 XtFree ((char *)path);
2353 XtFree ((char *)name);
2355 /* Don't exit yet, SM needs time to get the new commandStr.*/
2359 /***************************************************************************
2361 * Routine: GetSessionInfo *
2363 * Purpose: get dticon session information *
2364 **************************************************************************/
2365 #define DEFAULT_WIDTH 536
2366 #define DEFAULT_HEIGHT 477
2369 GetSessionInfo( void )
2372 char *tmpStr, *tmpStr2;
2374 XrmName xrm_name[5];
2375 XrmRepresentation rep_type;
2380 stat_out("GetSessionInfo\n");
2383 if (xrdb.session == NULL)
2385 session.useSession = False;
2389 session.useSession = True;
2391 /*** Open the resource database file ***/
2393 /* TopLevel is used because dtIconShell isn't created yet... */
2394 /* okay because it only uses it to get a display, not a window */
2395 if (DtSessionRestorePath(TopLevel, &path, xrdb.session) == False)
2396 path = xrdb.session;
2398 if ((db = XrmGetFileDatabase (path)) == NULL)
2400 tmpStr = GETSTR(16,22, "Couldn't restore session from file");
2401 tmpStr2 = (char *)XtMalloc(strlen(tmpStr) + strlen(path)+ 3);
2402 sprintf(tmpStr2, "%s: %s\n", tmpStr, path);
2403 _DtSimpleErrnoError(progName, DtError, NULL, tmpStr2, NULL);
2405 if (path != xrdb.session)
2407 session.useSession = False;
2410 if (path != xrdb.session)
2414 /*** now get the information we want from the database ***/
2415 /*** make sure values are at least somewhat reasonable ***/
2419 /* get x position */
2420 xrm_name[0] = XrmStringToQuark ("x");
2421 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2422 session.x = (Position)atoi((char *)value.addr);
2425 if (session.x < 0) session.x = 0;
2427 /* get y position */
2428 xrm_name[0] = XrmStringToQuark ("y");
2429 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2430 session.y = (Position)atoi((char *)value.addr);
2433 if (session.y < 0) session.y = 0;
2436 xrm_name[0] = XrmStringToQuark ("width");
2437 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2438 session.width = (Dimension)atoi((char *)value.addr);
2440 session.width = DEFAULT_WIDTH;
2441 if (session.width < DEFAULT_WIDTH) session.width = DEFAULT_WIDTH;
2444 xrm_name[0] = XrmStringToQuark ("height");
2445 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2446 session.height = (Dimension)atoi((char *)value.addr);
2448 session.height = DEFAULT_HEIGHT;
2449 if (session.height < DEFAULT_HEIGHT) session.height = DEFAULT_HEIGHT;
2451 /* get iconic state */
2452 xrm_name[0] = XrmStringToQuark ("iconic");
2453 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2455 if ( value.addr!=NULL && strcmp((char *)value.addr, "True")==0 )
2456 session.iconicState = IconicState;
2458 session.iconicState = NormalState;
2462 xrm_name[0] = XrmStringToQuark ("file");
2463 if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value))
2465 strncpy(start_file, value.addr, 255);
2468 start_file[0] = '\0';
2472 /***************************************************************************
2474 * Routine: ChangeTitle *
2476 * Purpose: Put the file name in the window title... *
2477 ***************************************************************************/
2482 static char *dialogTitle = NULL;
2492 name = GETSTR(12, 1, "Icon Editor");
2493 dialogTitle = XtMalloc (strlen(name) + 4);
2494 sprintf(dialogTitle, "%s - ", name);
2497 if (last_fname && *last_fname)
2499 if (name = strrchr(last_fname, '/'))
2507 tmpStr = GETSTR(10, 66, "(UNTITLED)");
2508 name = XtNewString(tmpStr);
2512 title = XtMalloc (strlen(dialogTitle) + strlen(name) + 1);
2513 sprintf(title, "%s%s", dialogTitle, name);
2516 XtSetArg(al[ac], XmNtitle, title); ac++;
2517 XtSetArg(al[ac], XmNiconName, name); ac++;
2518 XtSetValues(dtIconShell, al, ac);
2519 if(freeName == True)