ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/graphics.C
Revision: 1.1
Committed: Mon Nov 24 17:28:08 2003 UTC (20 years, 6 months ago) by pcg
Content type: text/plain
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*--------------------------------*-C-*---------------------------------*
2     * File: graphics.c
3     *----------------------------------------------------------------------*
4     * $Id: graphics.C,v 1.2 2003/11/23 19:32:49 root Exp $
5     *
6     * All portions of code are copyright by their respective author/s.
7     * Copyright (c) 1994 Rob Nation <nation@rocket.sanders.lockheed.com>
8     * - original version
9     * Copyright (c) 1997 Raul Garcia Garcia <rgg@tid.es>
10     * Copyright (c) 1997,1998 mj olesen <olesen@me.queensu.ca>
11     *
12     * This program is free software; you can redistribute it and/or modify
13     * it under the terms of the GNU General Public License as published by
14     * the Free Software Foundation; either version 2 of the License, or
15     * (at your option) any later version.
16     *
17     * This program is distributed in the hope that it will be useful,
18     * but WITHOUT ANY WARRANTY; without even the implied warranty of
19     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20     * GNU General Public License for more details.
21     *
22     * You should have received a copy of the GNU General Public License
23     * along with this program; if not, write to the Free Software
24     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25     *----------------------------------------------------------------------*/
26    
27     #include "../config.h" /* NECESSARY */
28     #ifdef RXVT_GRAPHICS
29     #include "rxvt.h" /* NECESSARY */
30     #include "rxvtgrx.h"
31    
32     typedef struct grcmd_t {
33     char cmd;
34     short color;
35     short ncoords;
36     int *coords;
37     unsigned char *text;
38     struct grcmd_t *next;
39     } grcmd_t;
40    
41     typedef struct grwin_t {
42     Window win;
43     int x, y;
44     unsigned int w, h;
45     short screen;
46     grcmd_t *graphics;
47     struct grwin_t *prev, *next;
48     } grwin_t;
49    
50     #include "graphics.intpro" /* PROTOS for internal routines */
51     #include <X11/cursorfont.h>
52    
53     /* commands:
54     * 'C' = Clear
55     * 'F' = Fill
56     * 'G' = Geometry
57     * 'L' = Line
58     * 'P' = Points
59     * 'T' = Text
60     * 'W' = Window
61     */
62    
63     #ifndef GRX_SCALE
64     # define GRX_SCALE 10000
65     #endif
66    
67     /*----------------------------------------------------------------------*
68     * local functions
69     */
70     /* ARGSUSED */
71     /* INTPROTO */
72     void
73     rxvt_Gr_NewWindow(pR_ int nargs, int args[])
74     {
75     int x, y;
76     unsigned int w, h;
77     Window win;
78     grwin_t *grwin;
79     Cursor cursor;
80    
81     if (nargs != 4) {
82     rxvt_print_error("NewWindow: 4 args needed, got %d\n", nargs);
83     return;
84     }
85     x = args[0] * TermWin_TotalWidth() / GRX_SCALE;
86     y = args[1] * TermWin_TotalHeight() / GRX_SCALE;
87     w = args[2] * TermWin_TotalWidth() / GRX_SCALE;
88     h = args[3] * TermWin_TotalHeight() / GRX_SCALE;
89    
90     win = XCreateSimpleWindow(R->Xdisplay, R->TermWin.vt,
91     x, y, w, h,
92     0,
93     R->PixColors[Color_fg],
94     R->PixColors[Color_bg]);
95    
96     cursor = XCreateFontCursor(R->Xdisplay, XC_crosshair);
97     XDefineCursor(R->Xdisplay, win, cursor);
98     XMapWindow(R->Xdisplay, win);
99     XSelectInput(R->Xdisplay, win, ExposureMask);
100    
101     grwin = (grwin_t *) rxvt_malloc(sizeof(grwin_t));
102     grwin->win = win;
103     grwin->x = x;
104     grwin->y = y;
105     grwin->w = w;
106     grwin->h = h;
107     grwin->screen = 0;
108     grwin->prev = NULL;
109     grwin->next = R->h->gr_root;
110     if (grwin->next)
111     grwin->next->prev = grwin;
112     R->h->gr_root = grwin;
113     grwin->graphics = NULL;
114     R->h->graphics_up++;
115    
116     rxvt_tt_printf(aR_ "\033W%ld\n", (long)grwin->win);
117     }
118    
119     /* ARGSUSED */
120     /* INTPROTO */
121     void
122     rxvt_Gr_ClearWindow(pR_ grwin_t *grwin)
123     {
124     grcmd_t *cmd, *next;
125    
126     for (cmd = grwin->graphics; cmd != NULL; cmd = next) {
127     next = cmd->next;
128     free(cmd->coords);
129     if (cmd->text != NULL)
130     free(cmd->text);
131     free(cmd);
132     }
133     grwin->graphics = NULL;
134     XClearWindow(R->Xdisplay, grwin->win);
135     }
136    
137     /*
138     * arg [0] = x
139     * arg [1] = y
140     * arg [2] = alignment
141     * arg [3] = strlen (text)
142     */
143     /* ARGSUSED */
144     /* INTPROTO */
145     void
146     rxvt_Gr_Text(pR_ grwin_t *grwin, grcmd_t *data)
147     {
148     int x, y, align;
149    
150     if (data->ncoords < 4 || data->text == NULL || *(data->text) == '\0')
151     return;
152    
153     x = data->coords[0] * grwin->w / GRX_SCALE;
154     y = data->coords[1] * grwin->h / GRX_SCALE;
155     align = data->coords[2];
156    
157     if ((align & HORIZONTAL_ALIGNMENT) == RIGHT_TEXT)
158     x -= XTextWidth(R->TermWin.font, data->text, data->coords[3]);
159     else if ((align & HORIZONTAL_ALIGNMENT) == HCENTER_TEXT)
160     x -= (XTextWidth(R->TermWin.font, data->text, data->coords[3]) >> 1);
161    
162     if ((align & VERTICAL_ALIGNMENT) == TOP_TEXT)
163     y += R->TermWin.font->ascent;
164     else if ((align & VERTICAL_ALIGNMENT) == BOTTOM_TEXT)
165     y -= R->TermWin.font->descent;
166    
167     if ((align & VERTICAL_ALIGNMENT) == VCENTER_TEXT)
168     y -= R->TermWin.font->descent
169     + ((R->TermWin.font->ascent + R->TermWin.font->descent) >> 1);
170     if ((align & VERTICAL_ALIGNMENT) == VCAPS_CENTER_TEXT)
171     y += (R->TermWin.font->ascent >> 1);
172    
173     XPMClearArea(R->Xdisplay, grwin->win, x, y - R->TermWin.font->ascent,
174     Width2Pixel(data->coords[3]), Height2Pixel(1), 0);
175     XDrawString(R->Xdisplay, grwin->win, R->TermWin.gc, x, y,
176     data->text, data->coords[3]);
177     }
178    
179     /* ARGSUSED */
180     /* INTPROTO */
181     void
182     rxvt_Gr_Geometry(pR_ grwin_t *grwin, grcmd_t *data __attribute__((unused)))
183     {
184     if (grwin)
185     rxvt_tt_printf(aR_ "\033G%ld %d %d %u %u %d %d %ld %ld %d\n",
186     (long)grwin->win,
187     grwin->x, grwin->y, grwin->w, grwin->h,
188     R->TermWin.fwidth,
189     R->TermWin.fheight,
190     (long)GRX_SCALE * R->TermWin.fwidth / grwin->w,
191     (long)GRX_SCALE * R->TermWin.fheight / grwin->h,
192     XDEPTH);
193     else /* rxvt terminal window size */
194     rxvt_tt_printf(aR_ "\033G0 0 0 %d %d %d %d %ld %ld %d\n",
195     TermWin_TotalWidth(), TermWin_TotalHeight(),
196     R->TermWin.fwidth, R->TermWin.fheight,
197     (long)GRX_SCALE * R->TermWin.fwidth / R->TermWin.width,
198     (long)GRX_SCALE * R->TermWin.fheight / R->TermWin.height,
199     XDEPTH);
200     }
201    
202     /* ARGSUSED */
203     /* INTPROTO */
204     void
205     rxvt_Gr_DestroyWindow(pR_ grwin_t *grwin)
206     {
207     grcmd_t *cmd, *next;
208    
209     if (grwin == NULL)
210     return;
211    
212     for (cmd = grwin->graphics; cmd; cmd = next) {
213     next = cmd->next;
214     free(cmd->coords);
215     if (cmd->text != NULL)
216     free(cmd->text);
217     free(cmd);
218     }
219    
220     XDestroyWindow(R->Xdisplay, grwin->win);
221     if (grwin->next != NULL)
222     grwin->next->prev = grwin->prev;
223     if (grwin->prev != NULL)
224     grwin->prev->next = grwin->next;
225     else
226     R->h->gr_root = grwin->next;
227     free(grwin);
228    
229     R->h->graphics_up--;
230     }
231    
232     /* ARGSUSED */
233     /* INTPROTO */
234     void
235     rxvt_Gr_Dispatch(pR_ grwin_t *grwin, grcmd_t *data)
236     {
237     int i, n;
238     union {
239     XPoint pt[NGRX_PTS / 2];
240     XRectangle rect[NGRX_PTS / 4];
241     } xdata;
242    
243     if (data->color != Color_fg) {
244     XGCValues gcv;
245    
246     gcv.foreground = R->PixColors[data->color];
247     XChangeGC(R->Xdisplay, R->TermWin.gc, GCForeground, &gcv);
248     }
249     if (grwin)
250     switch (data->cmd) {
251     case 'L':
252     if (data->ncoords > 3) {
253     for (n = i = 0; i < data->ncoords; i += 2, n++) {
254     xdata.pt[n].x = data->coords[i] * grwin->w / GRX_SCALE;
255     xdata.pt[n].y = data->coords[i + 1] * grwin->h / GRX_SCALE;
256     }
257     XDrawLines(R->Xdisplay,
258     grwin->win, R->TermWin.gc, xdata.pt, n, CoordModeOrigin);
259     }
260     break;
261    
262     case 'P':
263     if (data->ncoords > 3) {
264     for (n = i = 0; i < data->ncoords; i += 2, n++) {
265     xdata.pt[n].x = data->coords[i] * grwin->w / GRX_SCALE;
266     xdata.pt[n].y = data->coords[i + 1] * grwin->h / GRX_SCALE;
267     }
268     XDrawPoints(R->Xdisplay,
269     grwin->win, R->TermWin.gc, xdata.pt, n, CoordModeOrigin);
270     }
271     break;
272    
273     case 'F':
274     if (data->ncoords > 0) {
275     for (n = i = 0; i < data->ncoords; i += 4, n++) {
276     xdata.rect[n].x = data->coords[i] * grwin->w / GRX_SCALE;
277     xdata.rect[n].y = data->coords[i + 1] * grwin->h
278     / GRX_SCALE;
279     xdata.rect[n].width = ((data->coords[i + 2]
280     - data->coords[i] + 1) *
281     grwin->w / GRX_SCALE);
282     xdata.rect[n].height = ((data->coords[i + 3]
283     - data->coords[i + 1] + 1) *
284     grwin->h / GRX_SCALE);
285     XPMClearArea(R->Xdisplay, grwin->win,
286     xdata.rect[n].x, xdata.rect[n].y,
287     xdata.rect[n].width, xdata.rect[n].height,
288     0);
289     }
290     XFillRectangles(R->Xdisplay, grwin->win, R->TermWin.gc, xdata.rect,
291     n);
292     }
293     break;
294     case 'T':
295     rxvt_Gr_Text(aR_ grwin, data);
296     break;
297     case 'C':
298     rxvt_Gr_ClearWindow(aR_ grwin);
299     break;
300     }
301     if (data->color != Color_fg) {
302     XGCValues gcv;
303    
304     gcv.foreground = R->PixColors[Color_fg];
305     XChangeGC(R->Xdisplay, R->TermWin.gc, GCForeground, &gcv);
306     }
307     }
308    
309     /* ARGSUSED */
310     /* INTPROTO */
311     void
312     rxvt_Gr_Redraw(pR_ grwin_t *grwin)
313     {
314     grcmd_t *cmd;
315    
316     for (cmd = grwin->graphics; cmd != NULL; cmd = cmd->next)
317     rxvt_Gr_Dispatch(aR_ grwin, cmd);
318     }
319    
320     /*----------------------------------------------------------------------*
321     * end of static functions
322     */
323     /* ARGSUSED */
324     /* EXTPROTO */
325     void
326     rxvt_Gr_ButtonReport(pR_ int but, int x, int y)
327     {
328     grwin_t *grwin;
329    
330     for (grwin = R->h->gr_root; grwin != NULL; grwin = grwin->next)
331     if ((x > grwin->x)
332     && (y > grwin->y)
333     && ((unsigned int)x < grwin->x + grwin->w)
334     && ((unsigned int)y < grwin->y + grwin->h))
335     break;
336    
337     if (grwin == NULL)
338     return;
339    
340     x = GRX_SCALE * (x - grwin->x) / grwin->w;
341     y = GRX_SCALE * (y - grwin->y) / grwin->h;
342     rxvt_tt_printf(aR_ "\033%c%ld;%d;%d;\n", but, (long)grwin->win, x, y);
343     }
344    
345     /* ARGSUSED */
346     /* EXTPROTO */
347     void
348     rxvt_Gr_do_graphics(pR_ int cmd, unsigned int nargs, int args[], unsigned char *text)
349     {
350     int i;
351     Window win_id;
352     grwin_t *grwin;
353     grcmd_t *newcmd, *oldcmd;
354    
355     if (cmd == 'W') {
356     rxvt_Gr_NewWindow(aR_ nargs, args);
357     return;
358     }
359     win_id = (nargs > 0) ? (Window) args[0] : None;
360    
361     if ((cmd == 'G') && (win_id == None)) {
362     rxvt_Gr_Geometry(aR_ NULL, NULL);
363     return;
364     }
365     if ((win_id == None) && (R->h->gr_last_id != None))
366     win_id = R->h->gr_last_id;
367    
368     if (win_id == None)
369     return;
370    
371     grwin = R->h->gr_root;
372     while ((grwin != NULL) && (grwin->win != win_id))
373     grwin = grwin->next;
374    
375     if (grwin == NULL)
376     return;
377    
378     if (cmd == 'G') {
379     rxvt_Gr_Geometry(aR_ grwin, NULL);
380     return;
381     }
382     nargs--;
383     args++; /* skip over window id */
384    
385     /* record this new command */
386     newcmd = (grcmd_t *) rxvt_malloc(sizeof(grcmd_t));
387     newcmd->ncoords = nargs;
388     newcmd->coords = (int *)rxvt_malloc((newcmd->ncoords * sizeof(int)));
389    
390     newcmd->next = NULL;
391     newcmd->cmd = cmd;
392     newcmd->color = rxvt_scr_get_fgcolor(aR);
393     newcmd->text = text;
394    
395     for (i = 0; i < newcmd->ncoords; i++)
396     newcmd->coords[i] = args[i];
397    
398     /*
399     * If newcmd == fill, and rectangle is full window, drop all prior
400     * commands.
401     */
402     if ((newcmd->cmd == 'F') && (grwin) && (grwin->graphics)) {
403     for (i = 0; i < newcmd->ncoords; i += 4) {
404     if ((newcmd->coords[i] == 0)
405     && (newcmd->coords[i + 1] == 0)
406     && (newcmd->coords[i + 2] == GRX_SCALE)
407     && (newcmd->coords[i + 3] == GRX_SCALE)) {
408     /* drop previous commands */
409     oldcmd = grwin->graphics;
410     while (oldcmd->next != NULL) {
411     grcmd_t *tmp = oldcmd;
412    
413     oldcmd = oldcmd->next;
414     free(tmp);
415     }
416     grwin->graphics = NULL;
417     }
418     }
419     }
420     /* insert new command into command list */
421     oldcmd = grwin->graphics;
422     if (oldcmd == NULL)
423     grwin->graphics = newcmd;
424     else {
425     while (oldcmd->next != NULL)
426     oldcmd = oldcmd->next;
427     oldcmd->next = newcmd;
428     }
429     rxvt_Gr_Dispatch(aR_ grwin, newcmd);
430     }
431    
432     /* ARGSUSED */
433     /* EXTPROTO */
434     void
435     rxvt_Gr_scroll(pR_ int count)
436     {
437     grwin_t *grwin, *next;
438    
439     if ((count == 0) && (R->h->gr_prev_start == R->TermWin.view_start))
440     return;
441    
442     R->h->gr_prev_start = R->TermWin.view_start;
443    
444     for (grwin = R->h->gr_root; grwin != NULL; grwin = next) {
445     next = grwin->next;
446     grwin->y -= (count * R->TermWin.fheight);
447     if ((long)(grwin->y + grwin->h)
448     < -(long)(R->TermWin.saveLines * R->TermWin.fheight))
449     rxvt_Gr_DestroyWindow(aR_ grwin);
450     else
451     XMoveWindow(R->Xdisplay, grwin->win,
452     grwin->x,
453     grwin->y + (R->TermWin.view_start * R->TermWin.fheight));
454     }
455     }
456    
457     /* EXTPROTO */
458     void
459     rxvt_Gr_ClearScreen(pR)
460     {
461     grwin_t *grwin, *next;
462    
463     for (grwin = R->h->gr_root; grwin != NULL; grwin = next) {
464     next = grwin->next;
465     if ((grwin->screen == 0) && (grwin->y + grwin->h > 0)) {
466     if (grwin->y >= 0)
467     rxvt_Gr_DestroyWindow(aR_ grwin);
468     else
469     XResizeWindow(R->Xdisplay, grwin->win,
470     grwin->w, -grwin->y);
471     }
472     }
473     }
474    
475     /* EXTPROTO */
476     void
477     rxvt_Gr_ChangeScreen(pR)
478     {
479     grwin_t *grwin, *next;
480    
481     for (grwin = R->h->gr_root; grwin != NULL; grwin = next) {
482     next = grwin->next;
483     if (grwin->y + grwin->h > 0) {
484     if (grwin->screen == 1) {
485     XMapWindow(R->Xdisplay, grwin->win);
486     grwin->screen = 0;
487     } else {
488     XUnmapWindow(R->Xdisplay, grwin->win);
489     grwin->screen = 1;
490     }
491     }
492     }
493     }
494    
495     /* ARGSUSED */
496     /* EXTPROTO */
497     void
498     rxvt_Gr_expose(pR_ Window win)
499     {
500     grwin_t *grwin;
501    
502     for (grwin = R->h->gr_root; grwin != NULL; grwin = grwin->next) {
503     if (grwin->win == win) {
504     rxvt_Gr_Redraw(aR_ grwin);
505     break;
506     }
507     }
508     }
509    
510     /* ARGSUSED */
511     /* EXTPROTO */
512     void
513     rxvt_Gr_Resize(pR_ int w __attribute__((unused)), int h)
514     {
515     grwin_t *grwin;
516    
517     for (grwin = R->h->gr_root; grwin != NULL; grwin = grwin->next) {
518     if (R->TermWin.height != h) {
519     grwin->y += (R->TermWin.height - h);
520     XMoveWindow(R->Xdisplay, grwin->win,
521     grwin->x,
522     grwin->y + (R->TermWin.view_start * R->TermWin.fheight));
523     }
524     rxvt_Gr_Redraw(aR_ grwin);
525     }
526     }
527    
528     /* EXTPROTO */
529     void
530     rxvt_Gr_reset(pR)
531     {
532     grwin_t *grwin, *next;
533    
534     for (grwin = R->h->gr_root; grwin != NULL; grwin = next) {
535     next = grwin->next;
536     rxvt_Gr_DestroyWindow(aR_ grwin);
537     }
538    
539     R->h->graphics_up = 0;
540     }
541    
542     /* EXTPROTO */
543     int
544     rxvt_Gr_Displayed(pR)
545     {
546     return R->h->graphics_up;
547     }
548     #endif
549     /*----------------------- end-of-file (C source) -----------------------*/