ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/graphics.C
Revision: 1.5
Committed: Wed Jan 28 23:48:04 2004 UTC (20 years, 3 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +1 -1 lines
State: FILE REMOVED
Log Message:
*** empty log message ***

File Contents

# Content
1 /*--------------------------------*-C-*---------------------------------*
2 * File: graphics.c
3 *----------------------------------------------------------------------*
4 * $Id: graphics.C,v 1.4 2003/12/18 02:07:12 pcg 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->gr_root;
110 if (grwin->next)
111 grwin->next->prev = grwin;
112 R->gr_root = grwin;
113 grwin->graphics = NULL;
114 R->graphics_up++;
115
116 R->tt_printf("\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->gr_root = grwin->next;
227 free(grwin);
228
229 R->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->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->gr_last_id != None))
366 win_id = R->gr_last_id;
367
368 if (win_id == None)
369 return;
370
371 grwin = R->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->gr_prev_start == R->TermWin.view_start))
440 return;
441
442 R->gr_prev_start = R->TermWin.view_start;
443
444 for (grwin = R->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->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->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->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->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->gr_root; grwin != NULL; grwin = next) {
535 next = grwin->next;
536 rxvt_Gr_DestroyWindow(aR_ grwin);
537 }
538
539 R->graphics_up = 0;
540 }
541
542 /* EXTPROTO */
543 int
544 rxvt_Gr_Displayed(pR)
545 {
546 return R->graphics_up;
547 }
548 #endif
549 /*----------------------- end-of-file (C source) -----------------------*/