2
* Grace - GRaphing, Advanced Computation and Exploration of data
4
* Home page: http://plasma-gate.weizmann.ac.il/Grace/
6
* Copyright (c) 1991-1995 Paul J Turner, Portland, OR
7
* Copyright (c) 1996-2001 Grace Development Team
9
* Maintained by Evgeny Stambulchik <fnevgeny@plasma-gate.weizmann.ac.il>
14
* This program is free software; you can redistribute it and/or modify
15
* it under the terms of the GNU General Public License as published by
16
* the Free Software Foundation; either version 2 of the License, or
17
* (at your option) any later version.
19
* This program is distributed in the hope that it will be useful,
20
* but WITHOUT ANY WARRANTY; without even the implied warranty of
21
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
* GNU General Public License for more details.
24
* You should have received a copy of the GNU General Public License
25
* along with this program; if not, write to the Free Software
26
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35
#include <X11/cursorfont.h>
43
#include "graphutils.h"
51
extern Window root, xwin;
53
extern Widget app_shell;
54
extern XtAppContext app_con;
58
static Pixmap bufpixmap = (Pixmap) NULL;
60
extern int win_h, win_w; /* declared in x11drv.c */
63
extern char batchfile[];
65
extern Input_buffer *ib_tbl;
66
extern int ib_tblsize;
72
static Cursor wait_cursor;
73
static Cursor line_cursor;
74
static Cursor find_cursor;
75
static Cursor move_cursor;
76
static Cursor text_cursor;
77
static Cursor kill_cursor;
78
static int cur_cursor = -1;
80
static void xmonitor_rti(XtPointer ib, int *ptrFd, XtInputId *ptrId);
82
void DefineDialogCursor(Cursor c);
83
void UndefineDialogCursor();
85
void set_wait_cursor()
91
DefineDialogCursor(wait_cursor);
94
void unset_wait_cursor()
100
UndefineDialogCursor();
101
if (cur_cursor >= 0) {
102
set_cursor(cur_cursor);
106
void set_cursor(int c)
112
XUndefineCursor(disp, xwin);
116
XDefineCursor(disp, xwin, line_cursor);
119
XDefineCursor(disp, xwin, find_cursor);
122
XDefineCursor(disp, xwin, text_cursor);
125
XDefineCursor(disp, xwin, kill_cursor);
128
XDefineCursor(disp, xwin, move_cursor);
137
void init_cursors(void)
139
wait_cursor = XCreateFontCursor(disp, XC_watch);
140
line_cursor = XCreateFontCursor(disp, XC_crosshair);
141
find_cursor = XCreateFontCursor(disp, XC_hand2);
142
text_cursor = XCreateFontCursor(disp, XC_xterm);
143
kill_cursor = XCreateFontCursor(disp, XC_pirate);
144
move_cursor = XCreateFontCursor(disp, XC_fleur);
150
* put a string in the title bar
152
void set_title(char *ts)
154
static char *ts_save = NULL;
155
static int dstate_save = 0;
156
int dstate = is_dirtystate();
158
if (!inwin || ts == NULL) {
161
if (ts_save == NULL || strcmp(ts_save, ts) != 0 || dstate != dstate_save) {
163
ts_save = copy_string(ts_save, ts);
164
dstate_save = dstate;
165
buf1 = copy_string(NULL, "Grace: ");
166
buf1 = concat_strings(buf1, ts);
167
buf2 = copy_string(NULL, ts);
169
buf2 = concat_strings(buf2, "*");
170
buf1 = concat_strings(buf1, " (modified)");
172
XtVaSetValues(app_shell, XtNtitle, buf1, XtNiconName, buf2, NULL);
179
* Auxiliary routines for simultaneous drawing on display and pixmap
181
static void aux_XDrawLine(int x1, int y1, int x2, int y2)
183
XDrawLine(disp, xwin, gcxor, x1, y1, x2, y2);
184
if (bufpixmap != (Pixmap) NULL) {
185
XDrawLine(disp, bufpixmap, gcxor, x1, y1, x2, y2);
189
static void aux_XDrawRectangle(int x1, int y1, int x2, int y2)
191
XDrawRectangle(disp, xwin, gcxor, x1, y1, x2, y2);
192
if (bufpixmap != (Pixmap) NULL) {
193
XDrawRectangle(disp, bufpixmap, gcxor, x1, y1, x2, y2);
197
static void aux_XFillRectangle(int x, int y, unsigned int width, unsigned int height)
199
XFillRectangle(disp, xwin, gcxor, x, y, width, height);
200
if (bufpixmap != (Pixmap) NULL) {
201
XFillRectangle(disp, bufpixmap, gcxor, x, y, width, height);
207
* draw the graph focus indicators
209
void draw_focus(int gno)
211
int ix1, iy1, ix2, iy2;
215
if (draw_focus_flag == TRUE) {
216
get_graph_viewport(gno, &v);
219
xlibVPoint2dev(vp, &ix1, &iy1);
222
xlibVPoint2dev(vp, &ix2, &iy2);
223
aux_XFillRectangle(ix1 - 5, iy1 - 5, 10, 10);
224
aux_XFillRectangle(ix1 - 5, iy2 - 5, 10, 10);
225
aux_XFillRectangle(ix2 - 5, iy2 - 5, 10, 10);
226
aux_XFillRectangle(ix2 - 5, iy1 - 5, 10, 10);
231
* rubber band line (optionally erasing previous one)
233
void select_line(int x1, int y1, int x2, int y2, int erase)
235
static int x1_old, y1_old, x2_old, y2_old;
238
aux_XDrawLine(x1_old, y1_old, x2_old, y2_old);
244
aux_XDrawLine(x1, y1, x2, y2);
249
* draw an xor'ed box (optionally erasing previous one)
251
void select_region(int x1, int y1, int x2, int y2, int erase)
253
static int x1_old, y1_old, dx_old, dy_old;
266
aux_XDrawRectangle(x1_old, y1_old, dx_old, dy_old);
272
aux_XDrawRectangle(x1, y1, dx, dy);
276
* slide an xor'ed bbox shifted by shift_*, (optionally erasing previous one)
278
void slide_region(view bb, int shift_x, int shift_y, int erase)
286
xlibVPoint2dev(vp, &x1, &y1);
292
xlibVPoint2dev(vp, &x2, &y2);
296
select_region(x1, y1, x2, y2, erase);
299
static int crosshair_erase = FALSE;
301
void reset_crosshair(void)
303
crosshair_erase = FALSE;
307
* draw a crosshair cursor
309
void crosshair_motion(int x, int y)
311
static int cursor_oldx, cursor_oldy;
313
/* Erase the previous crosshair */
314
if (crosshair_erase == TRUE) {
315
aux_XDrawLine(0, cursor_oldy, win_w, cursor_oldy);
316
aux_XDrawLine(cursor_oldx, 0, cursor_oldx, win_h);
319
/* Draw the new crosshair */
320
aux_XDrawLine(0, y, win_w, y);
321
aux_XDrawLine(x, 0, x, win_h);
322
crosshair_erase = TRUE;
331
void expose_resize(Widget w, XtPointer client_data,
332
XmDrawingAreaCallbackStruct *cbs)
337
if (get_debuglevel() == 7) {
338
printf("Call to expose_resize(); reason == %d\n", cbs->reason);
355
if (inpipe == TRUE) {
356
getdata(get_cg(), "stdin", SOURCE_DISK, LOAD_SINGLE);
366
if (cbs->reason == XmCR_EXPOSE) {
367
xlibredraw(cbs->window, cbs->event->xexpose.x,
368
cbs->event->xexpose.y,
369
cbs->event->xexpose.width,
370
cbs->event->xexpose.height);
374
if (get_pagelayout() == PAGE_FREE) {
376
sync_canvas_size(&w, &h, TRUE);
384
void xdrawgraph(void)
386
if (inwin && (auto_redraw)) {
394
void xlibredraw(Window window, int x, int y, int width, int height)
396
if (inwin == TRUE && bufpixmap != (Pixmap) NULL) {
397
XCopyArea(disp, bufpixmap, window, gc, x, y, width, height, x, y);
401
Pixmap resize_bufpixmap(unsigned int w, unsigned int h)
403
static unsigned int pixmap_w = 0, pixmap_h = 0;
405
if (w == 0 || h == 0) {
409
if (bufpixmap == (Pixmap) NULL) {
410
bufpixmap = XCreatePixmap(disp, root, w, h, depth);
411
} else if (pixmap_w != w || pixmap_h != h) {
412
XFreePixmap(disp, bufpixmap);
413
bufpixmap = XCreatePixmap(disp, root, w, h, depth);
416
if (bufpixmap == (Pixmap) NULL) {
417
errmsg("Can't allocate buffer pixmap");
428
static void xmonitor_rti(XtPointer ib, int *ptrFd, XtInputId *ptrId)
432
monitor_input((Input_buffer *) ib, 1, 1);
437
void xunregister_rti(XtInputId id)
439
if (disp != (Display *) NULL) {
440
/* the screen has been initialized : we can remove the buffer */
445
void xregister_rti(Input_buffer *ib)
447
if (disp != (Display *) NULL) {
448
/* the screen has been initialized : we can register the buffer */
449
ib->id = (unsigned long) XtAppAddInput(app_con,
451
(XtPointer) XtInputReadMask,
458
* for the goto point feature
460
void setpointer(VPoint vp)
464
xlibVPoint2dev(vp, &x, &y);
466
/* Make sure we remain inside the DA widget dimensions */
472
XWarpPointer(disp, None, xwin, 0, 0, 0, 0, x, y);
475
char *display_name(void)
477
return DisplayString(disp);