123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: graphics.c /main/4 1995/11/02 14:05:07 rswiston $ */
- /*********************************************************************
- * (c) Copyright 1993, 1994 Hewlett-Packard Company
- * (c) Copyright 1993, 1994 International Business Machines Corp.
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
- * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of
- * Novell, Inc.
- **********************************************************************/
- /******************************************************************************
- ** Program: dticon
- **
- ** Description: X11-based multi-color icon editor
- **
- ** File: graphics.c, which contains the following subroutines or
- ** functions:
- ** Flicker_Arc()
- ** Circle_Box()
- ** Set_HotBox_Coords()
- ** Start_HotBox()
- ** Do_HotBox()
- ** Stop_HotBox()
- **
- ******************************************************************************
- **
- ** Copyright Hewlett-Packard Company, 1990, 1991, 1992.
- ** All rights are reserved. Copying or reproduction of this program,
- ** except for archival purposes, is prohibited without prior written
- ** consent of Hewlett-Packard Company.
- **
- ** Hewlett-Packard makes no representations about the suitibility of this
- ** software for any purpose. It is provided "as is" without express or
- ** implied warranty.
- **
- ******************************************************************************/
- #include <stdlib.h>
- #include <math.h>
- #include <Xm/Xm.h>
- #include "externals.h"
- #include "utils.h"
- #include "process.h"
- extern GC scratch_gc;
- extern Widget editMenu_cut_pb;
- extern Widget editMenu_copy_pb;
- extern Widget editMenu_rotate_pb;
- extern Widget editMenu_flip_pb;
- extern Widget editMenu_scale_pb;
- extern void Stop_HotBox(void);
- /***************************************************************************
- * *
- * Routine: Flicker_Arc *
- * *
- * Purpose: Given 2 points (top-left and bottom-right), draw an *
- * invertable ellipse around the box they form. *
- * *
- *X11***********************************************************************/
- void
- Flicker_Arc(
- Window win,
- int x1,
- int y1,
- int x2,
- int y2 )
- {
- int x, y, width, height;
- x = min(x1, x2);
- y = min(y1, y2);
- width = abs(x1 - x2);
- height = abs(y1 - y2);
- #ifdef DEBUG
- if (debug)
- stat_out("Doing Flicker_Arc: x=%d, y=%d, width=%d, height=%d\n",
- x, y, width, height);
- #endif
- if ((width > 0) && (height > 0))
- XDrawArc(dpy, win, Flicker_gc, x, y, width, height, 0, 360*64);
- }
- /***************************************************************************
- * *
- * Routine: Circle_Box *
- * *
- * Purpose: Given 2 points (the center and radius of a circle) *
- * generate a box which would exactly enclose this circle, *
- * and then draw a flickering circle that matches the box. *
- * WARNING: [x1,y1] are always assumed to be the centerpoint *
- * and this routine will generate bogus results if this is *
- * not TRUE. *
- * *
- *X11***********************************************************************/
- void
- Circle_Box(
- Window win,
- int x1,
- int y1,
- int x2,
- int y2,
- XRectangle *box )
- {
- int radius, top_x, top_y, bottom_x, bottom_y, width, height;
- double size;
- #ifdef DEBUG
- if (debug)
- stat_out("Entering Circle_Box\n");
- #endif
- width = mag(x1, x2);
- height = mag(y1, y2);
- size = (double) ((width * width) + (height * height));
- radius = (int) sqrt(size);
- top_x = x1 - radius;
- top_y = y1 - radius;
- bottom_x = x1 + radius;
- bottom_y = y1 + radius;
- #ifdef DEBUG
- if (debug)
- stat_out(" Circle_Box values: tx=%d, ty=%d, bx=%d, by=%d\n",
- top_x, top_y, bottom_x, bottom_x);
- #endif
- Flicker_Arc(win, top_x, top_y, bottom_x, bottom_y);
- box->x = top_x;
- box->y = top_y;
- box->width = bottom_x - top_x + 1;
- box->height = bottom_y - top_y + 1;
- #ifdef DEBUG
- if (debug)
- stat_out("Leaving Circle_Box\n");
- #endif
- }
- /***************************************************************************
- * *
- * Routine: Set_HotBox_Coords *
- * *
- * Purpose: A SELECT operation has just occurred. Initiate a timer *
- * calculate the area to enclose. *
- * not TRUE. *
- * *
- *X11***********************************************************************/
- #define FLASH_INTERVAL 300
- static Boolean FlashState=False;
- static int flash_x, flash_y, flash_width, flash_height;
- static int box_x1, box_y1, box_x2, box_y2;
- static XtIntervalId selectTimerID;
- static void Do_HotBox();
- void
- Set_HotBox_Coords( void )
- {
- int min_x, min_y, max_x, max_y, tmp_x, tmp_y;
- min_x = min(ix, last_ix);
- min_y = min(iy, last_iy);
- max_x = max(ix, last_ix);
- max_y = max(iy, last_iy);
- /*** make sure all four points are on the tablet ***/
- if (min_x < 0)
- min_x = 0;
- if (min_y < 0)
- min_y = 0;
- if ((max_x) >= icon_width)
- max_x = icon_width-1;
- if ((max_y) >= icon_height)
- max_y = icon_height-1;
- select_box.x = min_x;
- select_box.y = min_y;
- select_box.width = max_x - min_x + 1;
- select_box.height = max_y - min_y + 1;
- box_x1 = min_x;
- box_y1 = min_y;
- box_x2 = max_x+1;
- box_y2 = max_y+1;
- Tablet_Coords(min_x, min_y, &flash_x, &flash_y);
- Tablet_Coords(max_x+1, max_y+1, &tmp_x, &tmp_y);
- flash_width = tmp_x - flash_x;
- flash_height = tmp_y - flash_y;
- #ifdef DEBUG
- if (debug) {
- stat_out(" select_box: x=%d, y=%d, width=%d, height=%d\n",
- select_box.x, select_box.y,
- select_box.width, select_box.height);
- stat_out(" flash box: x=%d, y=%d, width=%d, height=%d\n",
- flash_x, flash_y, flash_width, flash_height);
- }
- #endif
- }
- /***************************************************************************
- * *
- * Routine: Start_HotBox *
- * *
- * Purpose: A SELECT operation has just occurred. Initiate a timer *
- * which flashes a 1-pixel wide box around the perimeter of *
- * the selected rectangle every FLASH_INTERVAL milliseconds. *
- * Use the global variables ix, iy, last_ix, last_iy to *
- * calculate the area to enclose. *
- * *
- *X11***********************************************************************/
- void
- Start_HotBox(
- int flag )
- {
- #ifdef DEBUG
- if (debug)
- stat_out("Entering Start_HotBox\n");
- #endif
- Selected = True;
- /* turn on stuff that uses the selected area */
- XtSetSensitive( editMenu_cut_pb, True);
- XtSetSensitive( editMenu_copy_pb, True);
- XtSetSensitive(editMenu_rotate_pb, True);
- XtSetSensitive(editMenu_flip_pb, True);
- XtSetSensitive(editMenu_scale_pb, True);
- XSync(dpy, 0);
- if (flag == INITIAL)
- Set_HotBox_Coords();
- selectTimerID = XtAppAddTimeOut(AppContext,
- FLASH_INTERVAL,
- (XtTimerCallbackProc) Do_HotBox,
- NULL);
- #ifdef DEBUG
- if (debug)
- stat_out("Leaving Start_HotBox - TimerID=%d\n", selectTimerID);
- #endif
- }
- /***************************************************************************
- * *
- * Routine: Do_HotBox *
- * *
- * Purpose: Flash one alternating pulse around the selected area, and *
- * then re-set itself to activate again in FLASH_INTERVAL *
- * milliseconds. *
- * *
- * note: Check selectTimerID so that timeouts added for previous selects *
- * are ignored. ex: if new select is started before previous select *
- * timeout is serviced, "Selected" will already be set to true again *
- * (for new select) when timeout from old selection is called... so *
- * now Stop_HotBox is called immediately (before HotBox Coords are *
- * set for new select), and last timeout is ignored. *
- * *
- *X11***********************************************************************/
- static void
- Do_HotBox(
- XtPointer *client_data,
- XtIntervalId *local_id )
- {
- #ifdef DEBUG
- if (debug)
- stat_out(". ");
- #endif
- if (GraphicsOp != SELECT)
- Selected = False;
- if (*local_id == selectTimerID)
- {
- if (Selected)
- {
- if (FlashState) {
- FlashState = False;
- XSetForeground(dpy, scratch_gc, black_pixel);
- }
- else
- {
- FlashState = True;
- XSetForeground(dpy, scratch_gc, white_pixel);
- }
- XSetLineAttributes(dpy, scratch_gc, 1, LineSolid, CapButt, JoinMiter);
- XDrawRectangle(dpy, tablet_win, scratch_gc,
- flash_x, flash_y, flash_width, flash_height);
- selectTimerID=XtAppAddTimeOut(AppContext,
- FLASH_INTERVAL,
- (XtTimerCallbackProc) Do_HotBox,
- NULL);
- }
- else
- Stop_HotBox();
- }
- }
- /***************************************************************************
- * *
- * Routine: Stop_HotBox *
- * *
- * Purpose: Undo the last Selected border operation. *
- * *
- *X11***********************************************************************/
- void
- Stop_HotBox( void )
- {
- int min_x, min_y, max_x, max_y, tmp_x, tmp_y;
- static int tmp_ix, tmp_iy;
- static Boolean Rotate_Move=False;
- #ifdef DEBUG
- if (debug)
- stat_out("Entering Stop_HotBox\n");
- #endif
- if (GridEnabled) {
- XDrawLine(dpy, tablet_win, Grid_gc,
- flash_x, flash_y, (flash_x+flash_width), flash_y);
- XDrawLine(dpy, tablet_win, Grid_gc,
- flash_x, (flash_y+flash_height), (flash_x+flash_width),
- (flash_y+flash_height));
- XDrawLine(dpy, tablet_win, Grid_gc,
- flash_x, flash_y, flash_x, (flash_y+flash_height));
- XDrawLine(dpy, tablet_win, Grid_gc,
- (flash_x+flash_width), flash_y, (flash_x+flash_width),
- (flash_y+flash_height));
- }
- else {
- /* since Rotate left and right moves ix and iy revert to tmp_ix, tmp_iy */
- if (Rotate_Move) { Rotate_Move = False;
- ix = tmp_ix;
- iy = tmp_iy; }
- min_x = min(ix, last_ix);
- min_y = min(iy, last_iy);
- max_x = max(ix, last_ix);
- max_y = max(iy, last_iy);
- if (++max_x >= icon_width) max_x--;
- if (++max_y >= icon_height) max_y--;
- Transfer_Back_Image(min_x, min_y, max_x, max_y, HOLLOW);
- /* if it is a Rotate Op. then keep ix, iy */
- if(GraphicsOp == S_ROTATE) { Rotate_Move = True;
- tmp_ix = ix;
- tmp_iy = iy; }
- }
- #ifdef DEBUG
- if (debug)
- stat_out("Leaving Stop_HotBox\n");
- #endif
- }
|