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 libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: graphics.c /main/4 1995/11/02 14:05:07 rswiston $ */
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: graphics.c, which contains the following subroutines or
40 ** Set_HotBox_Coords()
45 ******************************************************************************
47 ** Copyright Hewlett-Packard Company, 1990, 1991, 1992.
48 ** All rights are reserved. Copying or reproduction of this program,
49 ** except for archival purposes, is prohibited without prior written
50 ** consent of Hewlett-Packard Company.
52 ** Hewlett-Packard makes no representations about the suitibility of this
53 ** software for any purpose. It is provided "as is" without express or
56 ******************************************************************************/
59 #include "externals.h"
63 Widget editMenu_cut_pb;
64 Widget editMenu_copy_pb;
65 Widget editMenu_rotate_pb;
66 Widget editMenu_flip_pb;
67 Widget editMenu_scale_pb;
69 extern void Stop_HotBox(void);
71 /***************************************************************************
73 * Routine: Flicker_Arc *
75 * Purpose: Given 2 points (top-left and bottom-right), draw an *
76 * invertable ellipse around the box they form. *
78 *X11***********************************************************************/
88 int x, y, width, height;
93 height = abs(y1 - y2);
97 stat_out("Doing Flicker_Arc: x=%d, y=%d, width=%d, height=%d\n",
101 if ((width > 0) && (height > 0))
102 XDrawArc(dpy, win, Flicker_gc, x, y, width, height, 0, 360*64);
106 /***************************************************************************
108 * Routine: Circle_Box *
110 * Purpose: Given 2 points (the center and radius of a circle) *
111 * generate a box which would exactly enclose this circle, *
112 * and then draw a flickering circle that matches the box. *
113 * WARNING: [x1,y1] are always assumed to be the centerpoint *
114 * and this routine will generate bogus results if this is *
117 *X11***********************************************************************/
128 int radius, top_x, top_y, bottom_x, bottom_y, width, height;
133 stat_out("Entering Circle_Box\n");
137 height = mag(y1, y2);
138 size = (double) ((width * width) + (height * height));
139 radius = (int) sqrt(size);
143 bottom_x = x1 + radius;
144 bottom_y = y1 + radius;
148 stat_out(" Circle_Box values: tx=%d, ty=%d, bx=%d, by=%d\n",
149 top_x, top_y, bottom_x, bottom_x);
152 Flicker_Arc(win, top_x, top_y, bottom_x, bottom_y);
156 box->width = bottom_x - top_x + 1;
157 box->height = bottom_y - top_y + 1;
160 stat_out("Leaving Circle_Box\n");
165 /***************************************************************************
167 * Routine: Set_HotBox_Coords *
169 * Purpose: A SELECT operation has just occurred. Initiate a timer *
170 * calculate the area to enclose. *
173 *X11***********************************************************************/
175 #define FLASH_INTERVAL 300
176 static Boolean FlashState=False;
177 static int flash_x, flash_y, flash_width, flash_height;
178 static int box_x1, box_y1, box_x2, box_y2;
179 static XtIntervalId selectTimerID;
180 static void Do_HotBox();
183 Set_HotBox_Coords( void )
185 int min_x, min_y, max_x, max_y, tmp_x, tmp_y;
187 min_x = min(ix, last_ix);
188 min_y = min(iy, last_iy);
189 max_x = max(ix, last_ix);
190 max_y = max(iy, last_iy);
192 /*** make sure all four points are on the tablet ***/
198 if ((max_x) >= icon_width)
199 max_x = icon_width-1;
200 if ((max_y) >= icon_height)
201 max_y = icon_height-1;
203 select_box.x = min_x;
204 select_box.y = min_y;
205 select_box.width = max_x - min_x + 1;
206 select_box.height = max_y - min_y + 1;
213 Tablet_Coords(min_x, min_y, &flash_x, &flash_y);
214 Tablet_Coords(max_x+1, max_y+1, &tmp_x, &tmp_y);
215 flash_width = tmp_x - flash_x;
216 flash_height = tmp_y - flash_y;
220 stat_out(" select_box: x=%d, y=%d, width=%d, height=%d\n",
221 select_box.x, select_box.y,
222 select_box.width, select_box.height);
223 stat_out(" flash box: x=%d, y=%d, width=%d, height=%d\n",
224 flash_x, flash_y, flash_width, flash_height);
230 /***************************************************************************
232 * Routine: Start_HotBox *
234 * Purpose: A SELECT operation has just occurred. Initiate a timer *
235 * which flashes a 1-pixel wide box around the perimeter of *
236 * the selected rectangle every FLASH_INTERVAL milliseconds. *
237 * Use the global variables ix, iy, last_ix, last_iy to *
238 * calculate the area to enclose. *
240 *X11***********************************************************************/
249 stat_out("Entering Start_HotBox\n");
253 /* turn on stuff that uses the selected area */
254 XtSetSensitive( editMenu_cut_pb, True);
255 XtSetSensitive( editMenu_copy_pb, True);
256 XtSetSensitive(editMenu_rotate_pb, True);
257 XtSetSensitive(editMenu_flip_pb, True);
258 XtSetSensitive(editMenu_scale_pb, True);
263 selectTimerID = XtAppAddTimeOut(AppContext,
265 (XtTimerCallbackProc) Do_HotBox,
270 stat_out("Leaving Start_HotBox - TimerID=%d\n", selectTimerID);
276 /***************************************************************************
278 * Routine: Do_HotBox *
280 * Purpose: Flash one alternating pulse around the selected area, and *
281 * then re-set itself to activate again in FLASH_INTERVAL *
284 * note: Check selectTimerID so that timeouts added for previous selects *
285 * are ignored. ex: if new select is started before previous select *
286 * timeout is serviced, "Selected" will already be set to true again *
287 * (for new select) when timeout from old selection is called... so *
288 * now Stop_HotBox is called immediately (before HotBox Coords are *
289 * set for new select), and last timeout is ignored. *
291 *X11***********************************************************************/
295 XtPointer *client_data,
296 XtIntervalId *local_id )
304 if (GraphicsOp != SELECT)
306 if (*local_id == selectTimerID)
312 XSetForeground(dpy, scratch_gc, black_pixel);
317 XSetForeground(dpy, scratch_gc, white_pixel);
319 XSetLineAttributes(dpy, scratch_gc, 1, LineSolid, CapButt, JoinMiter);
320 XDrawRectangle(dpy, tablet_win, scratch_gc,
321 flash_x, flash_y, flash_width, flash_height);
322 selectTimerID=XtAppAddTimeOut(AppContext,
324 (XtTimerCallbackProc) Do_HotBox,
333 /***************************************************************************
335 * Routine: Stop_HotBox *
337 * Purpose: Undo the last Selected border operation. *
339 *X11***********************************************************************/
344 int min_x, min_y, max_x, max_y, tmp_x, tmp_y;
345 static int tmp_ix, tmp_iy;
346 static Boolean Rotate_Move=False;
350 stat_out("Entering Stop_HotBox\n");
354 XDrawLine(dpy, tablet_win, Grid_gc,
355 flash_x, flash_y, (flash_x+flash_width), flash_y);
356 XDrawLine(dpy, tablet_win, Grid_gc,
357 flash_x, (flash_y+flash_height), (flash_x+flash_width),
358 (flash_y+flash_height));
359 XDrawLine(dpy, tablet_win, Grid_gc,
360 flash_x, flash_y, flash_x, (flash_y+flash_height));
361 XDrawLine(dpy, tablet_win, Grid_gc,
362 (flash_x+flash_width), flash_y, (flash_x+flash_width),
363 (flash_y+flash_height));
366 /* since Rotate left and right moves ix and iy revert to tmp_ix, tmp_iy */
367 if (Rotate_Move) { Rotate_Move = False;
370 min_x = min(ix, last_ix);
371 min_y = min(iy, last_iy);
372 max_x = max(ix, last_ix);
373 max_y = max(iy, last_iy);
374 if (++max_x >= icon_width) max_x--;
375 if (++max_y >= icon_height) max_y--;
376 Transfer_Back_Image(min_x, min_y, max_x, max_y, HOLLOW);
377 /* if it is a Rotate Op. then keep ix, iy */
378 if(GraphicsOp == S_ROTATE) { Rotate_Move = True;
385 stat_out("Leaving Stop_HotBox\n");