~ubuntu-branches/ubuntu/jaunty/grace/jaunty

« back to all changes in this revision

Viewing changes to src/xutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2002-03-19 14:19:58 UTC
  • Revision ID: james.westby@ubuntu.com-20020319141958-5gxna6vo1ek3zjml
Tags: upstream-5.1.7
ImportĀ upstreamĀ versionĀ 5.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Grace - GRaphing, Advanced Computation and Exploration of data
 
3
 * 
 
4
 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
 
5
 * 
 
6
 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
 
7
 * Copyright (c) 1996-2001 Grace Development Team
 
8
 * 
 
9
 * Maintained by Evgeny Stambulchik <fnevgeny@plasma-gate.weizmann.ac.il>
 
10
 * 
 
11
 * 
 
12
 *                           All Rights Reserved
 
13
 * 
 
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.
 
18
 * 
 
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.
 
23
 * 
 
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.
 
27
 */
 
28
 
 
29
#include <config.h>
 
30
 
 
31
#include <stdlib.h>
 
32
#include <unistd.h>
 
33
 
 
34
#include <X11/Xlib.h>
 
35
#include <X11/cursorfont.h>
 
36
 
 
37
#include "defines.h"
 
38
#include "globals.h"
 
39
 
 
40
#include "utils.h"
 
41
#include "files.h"
 
42
#include "graphs.h"
 
43
#include "graphutils.h"
 
44
#include "plotone.h"
 
45
#include "device.h"
 
46
 
 
47
#include "x11drv.h"
 
48
 
 
49
#include "protos.h"
 
50
 
 
51
extern Window root, xwin;
 
52
extern Display *disp;
 
53
extern Widget app_shell;
 
54
extern XtAppContext app_con;
 
55
extern GC gc, gcxor;
 
56
extern int depth;
 
57
 
 
58
static Pixmap bufpixmap = (Pixmap) NULL;
 
59
 
 
60
extern int win_h, win_w;        /* declared in x11drv.c */
 
61
 
 
62
extern int inpipe;
 
63
extern char batchfile[];
 
64
 
 
65
extern Input_buffer *ib_tbl;
 
66
extern int ib_tblsize;
 
67
 
 
68
/*
 
69
 * cursors
 
70
 */
 
71
 
 
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;
 
79
 
 
80
static void xmonitor_rti(XtPointer ib, int *ptrFd, XtInputId *ptrId);
 
81
 
 
82
void DefineDialogCursor(Cursor c);
 
83
void UndefineDialogCursor();
 
84
 
 
85
void set_wait_cursor()
 
86
{
 
87
    if (disp == NULL) {
 
88
        return;
 
89
    }
 
90
    
 
91
    DefineDialogCursor(wait_cursor);
 
92
}
 
93
 
 
94
void unset_wait_cursor()
 
95
{
 
96
    if (disp == NULL) {
 
97
        return;
 
98
    }
 
99
    
 
100
    UndefineDialogCursor();
 
101
    if (cur_cursor >= 0) {
 
102
        set_cursor(cur_cursor);
 
103
    }
 
104
}
 
105
 
 
106
void set_cursor(int c)
 
107
{
 
108
    if (disp == NULL) {
 
109
        return;
 
110
    }
 
111
 
 
112
    XUndefineCursor(disp, xwin);
 
113
    cur_cursor = c;
 
114
    switch (c) {
 
115
    case 0:
 
116
        XDefineCursor(disp, xwin, line_cursor);
 
117
        break;
 
118
    case 1:
 
119
        XDefineCursor(disp, xwin, find_cursor);
 
120
        break;
 
121
    case 2:
 
122
        XDefineCursor(disp, xwin, text_cursor);
 
123
        break;
 
124
    case 3:
 
125
        XDefineCursor(disp, xwin, kill_cursor);
 
126
        break;
 
127
    case 4:
 
128
        XDefineCursor(disp, xwin, move_cursor);
 
129
        break;
 
130
    default:
 
131
        cur_cursor = -1;
 
132
        break;
 
133
    }
 
134
    XFlush(disp);
 
135
}
 
136
 
 
137
void init_cursors(void)
 
138
{
 
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);
 
145
    cur_cursor = -1;
 
146
}
 
147
 
 
148
 
 
149
/*
 
150
 * put a string in the title bar
 
151
 */
 
152
void set_title(char *ts)
 
153
{
 
154
    static char *ts_save = NULL;
 
155
    static int dstate_save = 0;
 
156
    int dstate = is_dirtystate();
 
157
    
 
158
    if (!inwin || ts == NULL) {
 
159
        return;
 
160
    } else
 
161
    if (ts_save == NULL || strcmp(ts_save, ts) != 0 || dstate != dstate_save) {
 
162
        char *buf1, *buf2;
 
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);
 
168
        if (dstate) {
 
169
            buf2 = concat_strings(buf2, "*");
 
170
            buf1 = concat_strings(buf1, " (modified)");
 
171
        }
 
172
        XtVaSetValues(app_shell, XtNtitle, buf1, XtNiconName, buf2, NULL);
 
173
        xfree(buf1);
 
174
        xfree(buf2);
 
175
    }
 
176
}
 
177
 
 
178
/*
 
179
 *  Auxiliary routines for simultaneous drawing on display and pixmap
 
180
 */
 
181
static void aux_XDrawLine(int x1, int y1, int x2, int y2)
 
182
{
 
183
    XDrawLine(disp, xwin, gcxor, x1, y1, x2, y2);
 
184
    if (bufpixmap != (Pixmap) NULL) {
 
185
        XDrawLine(disp, bufpixmap, gcxor, x1, y1, x2, y2);
 
186
    }
 
187
}
 
188
 
 
189
static void aux_XDrawRectangle(int x1, int y1, int x2, int y2)
 
190
{
 
191
    XDrawRectangle(disp, xwin, gcxor, x1, y1, x2, y2);
 
192
    if (bufpixmap != (Pixmap) NULL) {
 
193
        XDrawRectangle(disp, bufpixmap, gcxor, x1, y1, x2, y2);
 
194
    }
 
195
}
 
196
 
 
197
static void aux_XFillRectangle(int x, int y, unsigned int width, unsigned int height)
 
198
{
 
199
    XFillRectangle(disp, xwin, gcxor, x, y, width, height);
 
200
    if (bufpixmap != (Pixmap) NULL) {
 
201
        XFillRectangle(disp, bufpixmap, gcxor, x, y, width, height);
 
202
    }
 
203
}
 
204
 
 
205
 
 
206
/*
 
207
 * draw the graph focus indicators
 
208
 */
 
209
void draw_focus(int gno)
 
210
{
 
211
    int ix1, iy1, ix2, iy2;
 
212
    view v;
 
213
    VPoint vp;
 
214
    
 
215
    if (draw_focus_flag == TRUE) {
 
216
        get_graph_viewport(gno, &v);
 
217
        vp.x = v.xv1;
 
218
        vp.y = v.yv1;
 
219
        xlibVPoint2dev(vp, &ix1, &iy1);
 
220
        vp.x = v.xv2;
 
221
        vp.y = v.yv2;
 
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);
 
227
    }
 
228
}
 
229
 
 
230
/*
 
231
 * rubber band line (optionally erasing previous one)
 
232
 */
 
233
void select_line(int x1, int y1, int x2, int y2, int erase)
 
234
{
 
235
    static int x1_old, y1_old, x2_old, y2_old;
 
236
 
 
237
    if (erase) {
 
238
        aux_XDrawLine(x1_old, y1_old, x2_old, y2_old);
 
239
    }
 
240
    x1_old = x1;
 
241
    y1_old = y1;
 
242
    x2_old = x2;
 
243
    y2_old = y2;
 
244
    aux_XDrawLine(x1, y1, x2, y2);
 
245
}
 
246
 
 
247
 
 
248
/*
 
249
 * draw an xor'ed box (optionally erasing previous one)
 
250
 */
 
251
void select_region(int x1, int y1, int x2, int y2, int erase)
 
252
{
 
253
    static int x1_old, y1_old, dx_old, dy_old;
 
254
    int dx = x2 - x1;
 
255
    int dy = y2 - y1;
 
256
 
 
257
    if (dx < 0) {
 
258
        iswap(&x1, &x2);
 
259
        dx = -dx;
 
260
    }
 
261
    if (dy < 0) {
 
262
        iswap(&y1, &y2);
 
263
        dy = -dy;
 
264
    }
 
265
    if (erase) {
 
266
        aux_XDrawRectangle(x1_old, y1_old, dx_old, dy_old);
 
267
    }
 
268
    x1_old = x1;
 
269
    y1_old = y1;
 
270
    dx_old = dx;
 
271
    dy_old = dy;
 
272
    aux_XDrawRectangle(x1, y1, dx, dy);
 
273
}
 
274
 
 
275
/*
 
276
 * slide an xor'ed bbox shifted by shift_*, (optionally erasing previous one)
 
277
 */
 
278
void slide_region(view bb, int shift_x, int shift_y, int erase)
 
279
{
 
280
    int x1, x2;
 
281
    int y1, y2;
 
282
    VPoint vp;
 
283
 
 
284
    vp.x = bb.xv1;
 
285
    vp.y = bb.yv1;
 
286
    xlibVPoint2dev(vp, &x1, &y1);
 
287
    x1 += shift_x;
 
288
    y1 += shift_y;
 
289
    
 
290
    vp.x = bb.xv2;
 
291
    vp.y = bb.yv2;
 
292
    xlibVPoint2dev(vp, &x2, &y2);
 
293
    x2 += shift_x;
 
294
    y2 += shift_y;
 
295
    
 
296
    select_region(x1, y1, x2, y2, erase);
 
297
}
 
298
 
 
299
static int crosshair_erase = FALSE;
 
300
 
 
301
void reset_crosshair(void)
 
302
{
 
303
    crosshair_erase = FALSE;
 
304
}
 
305
 
 
306
/*
 
307
 * draw a crosshair cursor
 
308
 */
 
309
void crosshair_motion(int x, int y)
 
310
{
 
311
    static int cursor_oldx, cursor_oldy;
 
312
    
 
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);
 
317
    }
 
318
 
 
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;
 
323
    cursor_oldx = x;
 
324
    cursor_oldy = y;
 
325
}
 
326
 
 
327
 
 
328
/*
 
329
 * expose/resize proc
 
330
 */
 
331
void expose_resize(Widget w, XtPointer client_data,
 
332
                        XmDrawingAreaCallbackStruct *cbs)
 
333
{
 
334
    static int inc = 0;
 
335
 
 
336
#if defined(DEBUG)
 
337
    if (get_debuglevel() == 7) {
 
338
        printf("Call to expose_resize(); reason == %d\n", cbs->reason);
 
339
    }
 
340
#endif
 
341
    
 
342
    /* HACK */
 
343
    if (xwin == 0) {
 
344
        return;
 
345
    }
 
346
    
 
347
    if (!inc) {
 
348
        inwin = TRUE;
 
349
        inc++;
 
350
        
 
351
        if (batchfile[0]) {
 
352
            getparms(batchfile);
 
353
        }
 
354
        
 
355
        if (inpipe == TRUE) {
 
356
            getdata(get_cg(), "stdin", SOURCE_DISK, LOAD_SINGLE);
 
357
            inpipe = FALSE;
 
358
        }
 
359
 
 
360
        update_all();
 
361
        drawgraph();
 
362
 
 
363
        return;
 
364
    }
 
365
    
 
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);
 
371
        return;
 
372
    }
 
373
    
 
374
    if (get_pagelayout() == PAGE_FREE) {
 
375
        unsigned int w, h;
 
376
        sync_canvas_size(&w, &h, TRUE);
 
377
        drawgraph();
 
378
    }
 
379
}
 
380
 
 
381
/* 
 
382
 * redraw all
 
383
 */
 
384
void xdrawgraph(void)
 
385
{
 
386
    if (inwin && (auto_redraw)) {
 
387
        set_wait_cursor();
 
388
        drawgraph();
 
389
        unset_wait_cursor();
 
390
    }
 
391
}
 
392
 
 
393
 
 
394
void xlibredraw(Window window, int x, int y, int width, int height)
 
395
{
 
396
    if (inwin == TRUE && bufpixmap != (Pixmap) NULL) {
 
397
        XCopyArea(disp, bufpixmap, window, gc, x, y, width, height, x, y);
 
398
    }
 
399
}
 
400
 
 
401
Pixmap resize_bufpixmap(unsigned int w, unsigned int h)
 
402
{
 
403
    static unsigned int pixmap_w = 0, pixmap_h = 0;
 
404
    
 
405
    if (w == 0 || h == 0) {
 
406
        return (bufpixmap);
 
407
    }
 
408
    
 
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);
 
414
    }
 
415
    
 
416
    if (bufpixmap == (Pixmap) NULL) {
 
417
        errmsg("Can't allocate buffer pixmap");
 
418
        pixmap_w = 0;
 
419
        pixmap_h = 0;
 
420
        return (xwin);
 
421
    } else {
 
422
        pixmap_w = w;
 
423
        pixmap_h = h;
 
424
        return (bufpixmap);
 
425
    }
 
426
}
 
427
 
 
428
static void xmonitor_rti(XtPointer ib, int *ptrFd, XtInputId *ptrId)
 
429
{
 
430
    set_wait_cursor();
 
431
    
 
432
    monitor_input((Input_buffer *) ib, 1, 1);
 
433
    
 
434
    unset_wait_cursor();
 
435
}
 
436
 
 
437
void xunregister_rti(XtInputId id)
 
438
{
 
439
    if (disp != (Display *) NULL) {
 
440
        /* the screen has been initialized : we can remove the buffer */
 
441
        XtRemoveInput(id);
 
442
    }
 
443
}
 
444
 
 
445
void xregister_rti(Input_buffer *ib)
 
446
{
 
447
    if (disp != (Display *) NULL) {
 
448
        /* the screen has been initialized : we can register the buffer */
 
449
        ib->id = (unsigned long) XtAppAddInput(app_con,
 
450
                                               ib->fd,
 
451
                                               (XtPointer) XtInputReadMask,
 
452
                                               xmonitor_rti,
 
453
                                               (XtPointer) ib);
 
454
    }
 
455
}
 
456
 
 
457
/*
 
458
 * for the goto point feature
 
459
 */
 
460
void setpointer(VPoint vp)
 
461
{
 
462
    int x, y;
 
463
    
 
464
    xlibVPoint2dev(vp, &x, &y);
 
465
    
 
466
    /* Make sure we remain inside the DA widget dimensions */
 
467
    x = MAX2(x, 0);
 
468
    x = MIN2(x, win_w);
 
469
    y = MAX2(y, 0);
 
470
    y = MIN2(y, win_h);
 
471
    
 
472
    XWarpPointer(disp, None, xwin, 0, 0, 0, 0, x, y);
 
473
}
 
474
 
 
475
char *display_name(void)
 
476
{
 
477
    return DisplayString(disp);
 
478
}