1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/drawing.c,v 1.69 2011/06/09 16:11:41 cvsps Exp $
19 */
20
21 #define _INCLUDE_FROM_DRAWING_C_
22
23 #include "tgifdefs.h"
24 #include "cmdids.h"
25
26 #include "align.e"
27 #include "animate.e"
28 #include "arc.e"
29 #include "attr.e"
30 #include "auxtext.e"
31 #include "box.e"
32 #include "choice.e"
33 #include "cmd.e"
34 #include "color.e"
35 #include "cutpaste.e"
36 #include "cursor.e"
37 #include "dialog.e"
38 #include "drawing.e"
39 #include "dup.e"
40 #include "edit.e"
41 #include "eps.e"
42 #include "exec.e"
43 #include "file.e"
44 #include "font.e"
45 #include "grid.e"
46 #include "group.e"
47 #include "help.e"
48 #include "imgproc.e"
49 #include "import.e"
50 #include "inmethod.e"
51 #include "mark.e"
52 #include "mainloop.e"
53 #include "mainmenu.e"
54 #include "menu.e"
55 #include "menuinfo.e"
56 #include "miniline.e"
57 #include "msg.e"
58 #include "navigate.e"
59 #include "names.e"
60 #include "obj.e"
61 #include "oval.e"
62 #include "page.e"
63 #include "pattern.e"
64 #include "pin.e"
65 #include "poly.e"
66 #include "polygon.e"
67 #include "raster.e"
68 #include "rcbox.e"
69 #include "rect.e"
70 #include "remote.e"
71 #include "ruler.e"
72 #include "scroll.e"
73 #include "select.e"
74 #include "setup.e"
75 #include "shape.e"
76 #include "shortcut.e"
77 #include "special.e"
78 #include "stk.e"
79 #include "stream.e"
80 #include "stretch.e"
81 #include "strtbl.e"
82 #include "tangram2.e"
83 #include "tcp.e"
84 #include "text.e"
85 #include "tidget.e"
86 #include "util.e"
87 #include "wb.e"
88 #include "xbitmap.e"
89 #include "xpixmap.e"
90
91 #define O_VIS 4
92 #define O_INVIS 4
93 #define O_GRID (O_VIS+O_INVIS)
94
95 #define DEF_CHECK_INTERVAL 1
96
97 int disableRedraw=FALSE;
98 int intrCheckInterval=DEF_CHECK_INTERVAL;
99 int pasteInDrawTextMode=FALSE;
100 int pasteFromFileInDrawTextMode=FALSE;
101 int pasteCompoundTextInDrawTextMode=FALSE;
102 char pasteFromFileName[MAXPATHLENGTH+1];
103 int copyInDrawTextMode=FALSE;
104 int copyDoubleByteStringInDrawTextMode=FALSE;
105 int numRedrawBBox=INVALID;
106 int numClipRecs=0;
107 int clipOrdering=Unsorted;
108 XRectangle clipRecs[4];
109 int checkBBox=TRUE;
110
111 int btn1Warp=FALSE;
112
113 int userDisableRedraw=FALSE;
114 int executingCommands=FALSE;
115 int escPressedWhileExecutingCommands=FALSE;
116 int gnDisableShortcuts=FALSE;
117 int enableMouseWheel=TRUE;
118 int btn2PopupMainMenu=FALSE;
119
120 static Pixmap execAnimatePixmap=None;
121 static int execAnimatePixmapW=0, execAnimatePixmapH=0;
122 static int execAnimatePixmapDataW=0, execAnimatePixmapDataH=0;
123
124 static Pixmap execAnimateRulerPixmap=None;
125 static int execAnimateRulerPixmapW=0, execAnimateRulerPixmapH=0;
126
127 static struct BBRec smallArea[2];
128
129 static int skipCrossHair=FALSE;
130
SetXorDrawGC(xor_pixel)131 void SetXorDrawGC(xor_pixel)
132 int xor_pixel;
133 {
134 XGCValues values;
135
136 values.foreground = xor_pixel;
137 values.function = GXxor;
138 values.fill_style = FillSolid;
139 #ifdef NO_THIN_LINE
140 values.line_width = 1;
141 #else
142 values.line_width = 0;
143 #endif
144 values.line_style = LineSolid;
145
146 XChangeGC(mainDisplay, drawGC,
147 GCForeground | GCFunction | GCFillStyle | GCLineWidth | GCLineStyle,
148 &values);
149 }
150
SetDefaultDrawWinClipRecs()151 void SetDefaultDrawWinClipRecs()
152 {
153 SetRecVals(clipRecs[0], 0, 0, ZOOMED_SIZE(drawWinW), ZOOMED_SIZE(drawWinH));
154 numClipRecs = 1;
155 clipOrdering = YXBanded;
156 XSetClipRectangles(mainDisplay, drawGC, 0, 0, clipRecs, numClipRecs,
157 clipOrdering);
158 }
159
SetDefaultIconWinClipRecs()160 void SetDefaultIconWinClipRecs()
161 {
162 SetRecVals(clipRecs[0], 0, 0, iconWindowW, iconWindowH);
163 numClipRecs = 1;
164 clipOrdering = YXBanded;
165 XSetClipRectangles(mainDisplay, drawGC, 0, 0, clipRecs, numClipRecs,
166 clipOrdering);
167 }
168
169 static
DrawHorizOutline(Win,Y,X1,X2,XStart,XEnd)170 void DrawHorizOutline(Win, Y, X1, X2, XStart, XEnd)
171 Window Win;
172 int Y, X1, X2, XStart, XEnd;
173 /* XStart and XEnd are the real place, X1 and X2 are on outline grid */
174 {
175 register int i;
176
177 if (XStart-X1 < O_VIS) {
178 XDrawLine(mainDisplay, Win, defaultGC, XStart, Y, X1+O_VIS-1, Y);
179 }
180 for (i=X1+O_GRID; i < X2-O_GRID; i+= O_GRID) {
181 XDrawLine(mainDisplay, Win, defaultGC, i, Y, i+O_VIS-1, Y);
182 }
183 if (X2-XEnd < O_VIS) {
184 XDrawLine(mainDisplay, Win, defaultGC, X2-O_GRID, Y, XEnd, Y);
185 } else {
186 XDrawLine(mainDisplay, Win, defaultGC, X2-O_GRID, Y, X2-O_INVIS-1, Y);
187 }
188 }
189
190 static
DrawVertOutline(Win,X,Y1,Y2,YStart,YEnd)191 void DrawVertOutline(Win, X, Y1, Y2, YStart, YEnd)
192 Window Win;
193 int X, Y1, Y2, YStart, YEnd;
194 /* YStart and YEnd are the real place, Y1 and Y2 are on outline grid */
195 {
196 register int i;
197
198 if (YStart-Y1 < O_VIS) {
199 XDrawLine(mainDisplay, Win, defaultGC, X, YStart, X, Y1+O_VIS-1);
200 }
201 for (i=Y1+O_GRID; i < Y2-O_GRID; i+= O_GRID) {
202 XDrawLine(mainDisplay, Win, defaultGC, X, i, X, i+O_VIS-1);
203 }
204 if (Y2-YEnd < O_VIS) {
205 XDrawLine(mainDisplay, Win, defaultGC, X, Y2-O_GRID, X, YEnd);
206 } else {
207 XDrawLine(mainDisplay, Win, defaultGC, X, Y2-O_GRID, X, Y2-O_INVIS-1);
208 }
209 }
210
211 static
DrawSymOutline(Win,XOff,YOff,ObjPtr)212 void DrawSymOutline(Win, XOff, YOff, ObjPtr)
213 Window Win;
214 int XOff, YOff;
215 struct ObjRec *ObjPtr;
216 {
217 int ltx, lty, rbx, rby, x_start, x_end, y_start, y_end;
218
219 ltx = ZOOMED_SIZE(ObjPtr->obbox.ltx - XOff - QUARTER_INCH) + 1;
220 lty = ZOOMED_SIZE(ObjPtr->obbox.lty - YOff - QUARTER_INCH) + 1;
221 rbx = ZOOMED_SIZE(ObjPtr->obbox.rbx - XOff + QUARTER_INCH) - 1;
222 rby = ZOOMED_SIZE(ObjPtr->obbox.rby - YOff + QUARTER_INCH) - 1;
223
224 x_start = (ltx % O_GRID == 0) ? ltx : (int)(ltx / O_GRID) * O_GRID;
225 x_end = (rbx % O_GRID == 0) ? rbx : ((int)(rbx / O_GRID) + 1) * O_GRID;
226 DrawHorizOutline(Win, lty, x_start, x_end, ltx, rbx);
227 DrawHorizOutline(Win, rby, x_start, x_end, ltx, rbx);
228 y_start = (lty % O_GRID == 0) ? lty : (int)(lty / O_GRID) * O_GRID;
229 y_end = (rby % O_GRID == 0) ? rby : ((int)(rby / O_GRID) + 1) * O_GRID;
230 DrawVertOutline(Win, ltx, y_start, y_end, lty, rby);
231 DrawVertOutline(Win, rbx, y_start, y_end, lty, rby);
232 }
233
234 static
NeedToDraw(ObjBBox)235 int NeedToDraw(ObjBBox)
236 struct BBRec ObjBBox;
237 {
238 switch (numRedrawBBox) {
239 case 0: return (BBoxIntersect(ObjBBox, drawWinBBox));
240 case 1: return (BBoxIntersect(ObjBBox, drawWinBBox) &&
241 BBoxIntersect(ObjBBox, smallArea[0]));
242 case 2: return (BBoxIntersect(ObjBBox, drawWinBBox) &&
243 (BBoxIntersect(ObjBBox, smallArea[0]) ||
244 BBoxIntersect(ObjBBox, smallArea[1])));
245 default:
246 fprintf(stderr, "%s\n", TgLoadString(STID_WARN_INVALID_NUMREDRAWBBOX));
247 break;
248 }
249 return TRUE;
250 }
251
252 #include "xbm/intr.xbm"
253 #include "xbm/trek.xbm"
254
255 static int intrShown=FALSE;
256 static int checkCount=0;
257 static int savedCheckInterval=(-1);
258 static int intrIndex=(-1);
259
260 static long intrTick=0L;
261
262 static
RedrawInterrupt()263 void RedrawInterrupt()
264 {
265 GC gc;
266 XGCValues values;
267 int x=0, y=0, bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel);
268 #ifdef _NO_GETTIMEOFDAY
269 struct timeb now;
270 #else /* ~_NO_GETTIMEOFDAY */
271 struct timeval now;
272 struct timezone zone;
273 #endif /* _NO_GETTIMEOFDAY */
274 long cur_tick;
275
276 if (!intrShown) return;
277
278 #ifdef _NO_GETTIMEOFDAY
279 ftime(&now);
280 cur_tick = ((long)(((long)now.millitm) / 200)) +
281 ((long)(((long)now.time) * 5));
282 #else /* ~_NO_GETTIMEOFDAY */
283 gettimeofday(&now, &zone);
284 cur_tick = ((long)(now.tv_usec / 200000)) + ((long)(now.tv_sec * 5));
285 #endif /* _NO_GETTIMEOFDAY */
286 if (intrIndex != (-1) && intrTick == cur_tick) return;
287
288 intrTick = cur_tick;
289 if (++intrIndex == MAXINTRS) intrIndex = 0;
290
291 x = ((rulerW-intr_width)>>1);
292 y = ((rulerW-intr_height)>>1);
293 values.foreground = myFgPixel;
294 values.background = bg_pixel;
295 values.function = GXcopy;
296 values.fill_style = FillSolid;
297 gc = XCreateGC(mainDisplay, dummyWindow1,
298 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
299 if (gc != NULL) {
300 if (threeDLook) {
301 XSetForeground(mainDisplay, gc, bg_pixel);
302 XFillRectangle(mainDisplay, dummyWindow1, gc, 0, 0, rulerW, rulerW);
303 }
304 values.foreground = myFgPixel;
305 values.fill_style = FillOpaqueStippled;
306 values.stipple = intrPixmap[intrIndex];
307 values.ts_x_origin = x;
308 values.ts_y_origin = y;
309 XChangeGC(mainDisplay, gc, GCForeground | GCFillStyle | GCStipple |
310 GCTileStipXOrigin | GCTileStipYOrigin, &values);
311 XFillRectangle(mainDisplay, dummyWindow1, gc, x, y, intr_width,
312 intr_height);
313 XFreeGC(mainDisplay, gc);
314 }
315 XSync(mainDisplay, False);
316 }
317
318 static
ShowHyperSpace()319 void ShowHyperSpace()
320 {
321 GC gc;
322 XGCValues values;
323 int x=0, y=0, bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel);
324
325 x = ((rulerW-1-trek_width)>>1);
326 y = ((rulerW-1-trek_height)>>1);
327 values.foreground = myFgPixel;
328 values.background = bg_pixel;
329 values.function = GXcopy;
330 values.fill_style = FillSolid;
331 gc = XCreateGC(mainDisplay, dummyWindow1,
332 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
333 if (gc != NULL) {
334 if (threeDLook) {
335 XSetForeground(mainDisplay, gc, bg_pixel);
336 XFillRectangle(mainDisplay, dummyWindow1, gc, 0, 0, rulerW, rulerW);
337 }
338 values.foreground = myFgPixel;
339 values.fill_style = FillOpaqueStippled;
340 values.stipple = trekPixmap;
341 values.ts_x_origin = x;
342 values.ts_y_origin = y;
343 XChangeGC(mainDisplay, gc, GCForeground | GCFillStyle | GCStipple |
344 GCTileStipXOrigin | GCTileStipYOrigin, &values);
345 XFillRectangle(mainDisplay, dummyWindow1, gc, x, y, trek_width,
346 trek_height);
347 XFreeGC(mainDisplay, gc);
348 }
349 }
350
351 static int interruptLevel=0;
352
ShowInterrupt(CheckInterval)353 void ShowInterrupt(CheckInterval)
354 int CheckInterval;
355 {
356 if (PRTGIF || interruptLevel++ > 0) return;
357
358 if (CheckInterval > 0) {
359 savedCheckInterval = intrCheckInterval;
360 intrCheckInterval = CheckInterval;
361 }
362 if (intrCheckInterval <= 0) return;
363
364 intrShown = TRUE;
365 intrIndex = (-1);
366 RedrawInterrupt();
367 }
368
HideInterrupt()369 int HideInterrupt()
370 {
371 if (PRTGIF || --interruptLevel > 0) return interruptLevel;
372 interruptLevel = 0;
373 if (execAnimatePixmap == None) {
374 XEvent ev;
375
376 while (XCheckWindowEvent(mainDisplay,dummyWindow1,ButtonPressMask,&ev)) ;
377 }
378 XClearWindow(mainDisplay, dummyWindow1);
379 intrShown = FALSE;
380 checkCount = 0;
381 if (savedCheckInterval > 0) {
382 intrCheckInterval = savedCheckInterval;
383 savedCheckInterval = (-1);
384 }
385 if (inHyperSpace) ShowHyperSpace();
386 XSync(mainDisplay, False);
387 return 0;
388 }
389
390 static
HighLightDummyWindow1(highlight)391 void HighLightDummyWindow1(highlight)
392 int highlight;
393 {
394 if (threeDLook) {
395 struct BBRec bbox;
396
397 SetBBRec(&bbox, 0, 0, rulerW-1, rulerW-1);
398 if (highlight) {
399 TgDrawThreeDButton(mainDisplay, dummyWindow1, textMenuGC, &bbox,
400 TGBS_RAISED, 1, FALSE);
401 } else {
402 TgClearThreeDButton(mainDisplay, dummyWindow1, textMenuGC, &bbox, 1);
403 }
404 }
405 }
406
RedrawDummyWindow1()407 void RedrawDummyWindow1()
408 {
409 XEvent ev;
410
411 if (mainDisplay == NULL) return;
412
413 while (XCheckWindowEvent(mainDisplay, dummyWindow1, ExposureMask, &ev)) ;
414 while (XCheckWindowEvent(mainDisplay, dummyWindow1, ButtonPressMask, &ev)) ;
415 if (intrShown) {
416 RedrawInterrupt();
417 } else if (inHyperSpace) {
418 ShowHyperSpace();
419 } else {
420 HideInterrupt();
421 }
422 if (intr_bits != NULL && trek_bits != NULL) { } /* do nothing but reference the variable */
423 }
424
425 #include "xbm/run.xbm"
426
427 static
ShowRunning(dpy,win,win_w,win_h)428 void ShowRunning(dpy, win, win_w, win_h)
429 Display *dpy;
430 Window win;
431 int win_w, win_h;
432 {
433 GC gc;
434 XGCValues values;
435 int x=0, y=0, bg_pixel=(threeDLook ? myLtGryPixel : myBgPixel);
436
437 x = ((rulerW-run_width)>>1);
438 y = ((rulerW-run_height)>>1);
439 values.foreground = myFgPixel;
440 values.background = bg_pixel;
441 values.function = GXcopy;
442 values.fill_style = FillSolid;
443 gc = XCreateGC(dpy, win,
444 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
445 if (gc != NULL) {
446 if (threeDLook) {
447 XSetForeground(dpy, gc, bg_pixel);
448 XFillRectangle(dpy, win, gc, 0, 0, win_w, win_h);
449 }
450 values.foreground = myFgPixel;
451 values.fill_style = FillOpaqueStippled;
452 values.stipple = runBitmap;
453 values.ts_x_origin = x;
454 values.ts_y_origin = y;
455 XChangeGC(dpy, gc, GCForeground | GCFillStyle | GCStipple |
456 GCTileStipXOrigin | GCTileStipYOrigin, &values);
457 XFillRectangle(dpy, win, gc, 0, 0, run_width, run_height);
458 XFreeGC(dpy, gc);
459 }
460 if (run_bits != NULL) { } /* do nothing but reference the variable */
461 }
462
RedrawDummyWindow2()463 void RedrawDummyWindow2()
464 {
465 XEvent ev;
466
467 if (mainDisplay == NULL) return;
468
469 XClearWindow(mainDisplay, dummyWindow2);
470 while (XCheckWindowEvent(mainDisplay, dummyWindow2, ExposureMask, &ev)) ;
471 if (gnDisableShortcuts) {
472 ShowRunning(mainDisplay, dummyWindow2, scrollBarW, scrollBarW);
473 }
474 if (threeDLook) {
475 struct BBRec bbox;
476
477 SetBBRec(&bbox, 0, 0, scrollBarW, scrollBarW);
478 TgDrawThreeDButton(mainDisplay, dummyWindow2, textMenuGC, &bbox,
479 gnDisableShortcuts ? TGBS_RAISED : TGBS_LOWRED, 2, TRUE);
480 }
481 }
482
DummiesEventHandler(input)483 void DummiesEventHandler(input)
484 XEvent *input;
485 {
486 if (input->xany.window == dummyWindow1) {
487 if (input->type == Expose) {
488 RedrawDummyWindow1();
489 } else if (input->type == EnterNotify) {
490 if (intrShown) {
491 SetMouseStatus(TgLoadCachedString(CSTID_INTERRUPT),
492 TgLoadCachedString(CSTID_INTERRUPT),
493 TgLoadCachedString(CSTID_INTERRUPT));
494 } else if (inHyperSpace) {
495 SetMouseStatus(TgLoadCachedString(CSTID_LEAVE_HYPERSPACE),
496 TgLoadCachedString(CSTID_PARANED_NONE),
497 TgLoadCachedString(CSTID_PARANED_NONE));
498 } else {
499 SetMouseStatus(TgLoadCachedString(CSTID_ENTER_HYPERSPACE),
500 TgLoadCachedString(CSTID_PARANED_NONE),
501 TgLoadCachedString(CSTID_PARANED_NONE));
502 }
503 if (inHyperSpace) {
504 HighLightDummyWindow1(TRUE);
505 }
506 } else if (input->type == LeaveNotify) {
507 SetMouseStatus("", "", "");
508 if (inHyperSpace) {
509 HighLightDummyWindow1(FALSE);
510 }
511 } else if (input->type == ButtonPress) {
512 if (!intrShown && execAnimatePixmap == None) {
513 ToggleHyperSpace(FALSE);
514 if (inHyperSpace) {
515 HighLightDummyWindow1(TRUE);
516 }
517 } else if (intrShown) {
518 HideInterrupt();
519 }
520 }
521 } else if (input->xany.window == dummyWindow2) {
522 if (input->type == Expose) {
523 RedrawDummyWindow2();
524 } else if (input->type == EnterNotify) {
525 SetMouseStatusToAllNone();
526 }
527 }
528 }
529
530 static XComposeStatus c_stat;
531
KeyPressEventIsEscape(key_ev)532 int KeyPressEventIsEscape(key_ev)
533 XKeyEvent *key_ev;
534 {
535 KeySym key_sym=(KeySym)0;
536 char buf[80];
537 int has_ch=XLookupString(key_ev, buf, sizeof(buf), &key_sym, &c_stat);
538
539 TranslateKeys(buf, &key_sym);
540 if (CharIsESC(key_ev, buf, key_sym, &has_ch)) {
541 return TRUE;
542 }
543 return FALSE;
544 }
545
546 static
CheckESC(p_display,p_ev,psz_arg)547 Bool CheckESC(p_display, p_ev, psz_arg)
548 Display *p_display;
549 XEvent *p_ev;
550 char *psz_arg;
551 {
552 if (p_ev->type == KeyPress) {
553 if (KeyPressEventIsEscape(&p_ev->xkey)) {
554 return True;
555 }
556 }
557 return False;
558 }
559
ESCPressed()560 int ESCPressed()
561 {
562 XEvent ev;
563
564 if (PRTGIF) return FALSE;
565 if (XCheckIfEvent(mainDisplay, &ev, CheckESC, NULL)) {
566 if (executingCommands) {
567 escPressedWhileExecutingCommands = TRUE;
568 }
569 return TRUE;
570 }
571 if (executingCommands) {
572 return escPressedWhileExecutingCommands;
573 }
574 return FALSE;
575 }
576
CheckInterrupt(check_esc)577 int CheckInterrupt(check_esc)
578 int check_esc;
579 {
580 if (PRTGIF) return FALSE;
581 if (execAnimatePixmap == None && intrCheckInterval <= 0) return FALSE;
582 if (check_esc && ESCPressed()) return TRUE;
583 if (++checkCount >= intrCheckInterval) {
584 XEvent ev;
585
586 RedrawInterrupt();
587 checkCount = 0;
588 if (check_esc && XCheckWindowEvent(mainDisplay, dummyWindow1,
589 ButtonPressMask, &ev)) {
590 while (XCheckWindowEvent(mainDisplay, dummyWindow1, ButtonPressMask,
591 &ev)) ;
592 return TRUE;
593 }
594 }
595 return FALSE;
596 }
597
DrawClippedPixmap(pixmap,win,gc,pixmap_w,pixmap_h,ltx,lty)598 void DrawClippedPixmap(pixmap, win, gc, pixmap_w, pixmap_h, ltx, lty)
599 Pixmap pixmap;
600 Window win;
601 GC gc;
602 int pixmap_w, pixmap_h, ltx, lty;
603 {
604 if (numClipRecs <= 0) {
605 XCopyArea(mainDisplay, pixmap, win, gc, 0, 0, pixmap_w, pixmap_h,
606 ltx, lty);
607 } else {
608 int i;
609 struct BBRec pixmap_bbox;
610
611 pixmap_bbox.ltx = ltx;
612 pixmap_bbox.lty = lty;
613 pixmap_bbox.rbx = ltx+pixmap_w;
614 pixmap_bbox.rby = lty+pixmap_h;
615 for (i=0; i < numClipRecs; i++) {
616 struct BBRec bbox;
617
618 bbox.ltx = (int)clipRecs[i].x;
619 bbox.lty = (int)clipRecs[i].y;
620 bbox.rbx = bbox.ltx + ((int)clipRecs[i].width);
621 bbox.rby = bbox.lty + ((int)clipRecs[i].height);
622 if (BBoxIntersect(pixmap_bbox, bbox)) {
623 int x, y, w, h;
624
625 bbox.ltx = max(bbox.ltx, pixmap_bbox.ltx);
626 bbox.lty = max(bbox.lty, pixmap_bbox.lty);
627 bbox.rbx = min(bbox.rbx, pixmap_bbox.rbx);
628 bbox.rby = min(bbox.rby, pixmap_bbox.rby);
629 x = bbox.ltx - pixmap_bbox.ltx;
630 y = bbox.lty - pixmap_bbox.lty;
631 w = bbox.rbx - bbox.ltx;
632 h = bbox.rby - bbox.lty;
633 XCopyArea(mainDisplay, pixmap, win, gc, x, y, w, h,
634 ltx+x, lty+y);
635 }
636 }
637 }
638 }
639
FillClippedRectangle(win,gc,ltx,lty,orig_w,orig_h)640 void FillClippedRectangle(win, gc, ltx, lty, orig_w, orig_h)
641 Window win;
642 GC gc;
643 int ltx, lty, orig_w, orig_h;
644 {
645 if (numClipRecs <= 0) {
646 XFillRectangle(mainDisplay, win, gc, ltx, lty, orig_w, orig_h);
647 } else {
648 int i;
649 struct BBRec obj_bbox;
650
651 obj_bbox.ltx = ltx;
652 obj_bbox.lty = lty;
653 obj_bbox.rbx = ltx+orig_w;
654 obj_bbox.rby = lty+orig_h;
655 for (i=0; i < numClipRecs; i++) {
656 struct BBRec bbox;
657
658 bbox.ltx = (int)clipRecs[i].x;
659 bbox.lty = (int)clipRecs[i].y;
660 bbox.rbx = bbox.ltx + ((int)clipRecs[i].width);
661 bbox.rby = bbox.lty + ((int)clipRecs[i].height);
662 if (BBoxIntersect(obj_bbox, bbox)) {
663 int x, y, w, h;
664
665 bbox.ltx = max(bbox.ltx, obj_bbox.ltx);
666 bbox.lty = max(bbox.lty, obj_bbox.lty);
667 bbox.rbx = min(bbox.rbx, obj_bbox.rbx);
668 bbox.rby = min(bbox.rby, obj_bbox.rby);
669 x = bbox.ltx - obj_bbox.ltx;
670 y = bbox.lty - obj_bbox.lty;
671 w = bbox.rbx - bbox.ltx;
672 h = bbox.rby - bbox.lty;
673 XFillRectangle(mainDisplay, win, gc, ltx+x, lty+y, w, h);
674 }
675 }
676 }
677 }
678
ObjInVisibleLayer(ObjPtr)679 int ObjInVisibleLayer(ObjPtr)
680 struct ObjRec *ObjPtr;
681 {
682 struct ObjRec *obj_ptr;
683 struct AttrRec *attr_ptr;
684
685 if (!colorLayers) return TRUE;
686
687 switch (ObjPtr->type) {
688 case OBJ_POLY:
689 case OBJ_BOX:
690 case OBJ_OVAL:
691 case OBJ_POLYGON:
692 case OBJ_ARC:
693 case OBJ_RCBOX:
694 case OBJ_XBM:
695 if (colorLayerOn[ObjPtr->color]) {
696 return TRUE;
697 }
698 break;
699
700 case OBJ_TEXT:
701 if (ObjPtr->detail.t->fill != NONEPAT && colorLayerOn[ObjPtr->color]) {
702 return TRUE;
703 } else {
704 return MiniLinesInVisibleLayer(&ObjPtr->detail.t->minilines);
705 }
706 break;
707
708 case OBJ_XPM: return TRUE;
709
710 case OBJ_GROUP:
711 case OBJ_ICON:
712 case OBJ_SYM:
713 for (obj_ptr=ObjPtr->detail.r->last; obj_ptr != NULL;
714 obj_ptr=obj_ptr->prev) {
715 obj_ptr->tmp_parent = ObjPtr;
716 if (ObjInVisibleLayer(obj_ptr)) {
717 return TRUE;
718 }
719 }
720 break;
721
722 case OBJ_PIN:
723 obj_ptr = GetPinObj(ObjPtr);
724 obj_ptr->tmp_parent = ObjPtr;
725 if (ObjInVisibleLayer(obj_ptr)) {
726 return TRUE;
727 }
728 break;
729 }
730 for (attr_ptr=ObjPtr->fattr; attr_ptr != NULL; attr_ptr = attr_ptr->next) {
731 if (attr_ptr->shown && ObjInVisibleLayer(attr_ptr->obj)) {
732 return TRUE;
733 }
734 }
735 return FALSE;
736 }
737
DrawObj(Win,ObjPtr)738 int DrawObj(Win, ObjPtr)
739 Window Win;
740 register struct ObjRec *ObjPtr;
741 /* returns TRUE if all objects are drawn */
742 /* returns FALSE if interrupted by the user */
743 {
744 if (disableRedraw || (placingTopObj && ObjPtr==topObj)) {
745 return TRUE;
746 }
747 switch (ObjPtr->type) {
748 case OBJ_POLY:
749 if (!colorLayers ||
750 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
751 DrawPolyObj(Win, drawOrigX, drawOrigY, ObjPtr);
752 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
753 }
754 break;
755 case OBJ_BOX:
756 if (!colorLayers ||
757 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
758 DrawBoxObj(Win, drawOrigX, drawOrigY, ObjPtr);
759 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
760 }
761 break;
762 case OBJ_OVAL:
763 if (!colorLayers ||
764 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
765 DrawOvalObj(Win, drawOrigX, drawOrigY, ObjPtr);
766 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
767 }
768 break;
769 case OBJ_TEXT:
770 if (!colorLayers ||
771 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
772 DrawTextObj(Win, drawOrigX, drawOrigY, ObjPtr);
773 }
774 break;
775 case OBJ_POLYGON:
776 if (!colorLayers ||
777 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
778 DrawPolygonObj(Win, drawOrigX, drawOrigY, ObjPtr);
779 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
780 }
781 break;
782 case OBJ_ARC:
783 if (!colorLayers ||
784 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
785 DrawArcObj(Win, drawOrigX, drawOrigY, ObjPtr);
786 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
787 }
788 break;
789 case OBJ_RCBOX:
790 if (!colorLayers ||
791 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
792 DrawRCBoxObj(Win, drawOrigX, drawOrigY, ObjPtr);
793 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
794 }
795 break;
796 case OBJ_XBM:
797 if (!colorLayers ||
798 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
799 DrawXBmObj(Win, drawOrigX, drawOrigY, ObjPtr);
800 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
801 }
802 break;
803 case OBJ_XPM:
804 if (!colorLayers ||
805 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
806 DrawXPmObj(Win, drawOrigX, drawOrigY, ObjPtr);
807 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
808 }
809 break;
810
811 case OBJ_SYM:
812 case OBJ_ICON:
813 case OBJ_GROUP:
814 if (!colorLayers ||
815 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
816 struct ObjRec *obj_ptr=ObjPtr->detail.r->last;
817
818 for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev) {
819 if (!checkBBox || NeedToDraw(obj_ptr->bbox)) {
820 obj_ptr->tmp_parent = ObjPtr;
821 if (!DrawObj(Win, obj_ptr)) return FALSE;
822 if (execAnimatePixmap == None && CheckInterrupt(TRUE)) {
823 SetStringStatus(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
824 Msg(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
825 return FALSE;
826 }
827 }
828 }
829 if (ObjPtr->type == OBJ_ICON && ObjPtr->dirty) {
830 struct AttrRec *attr_ptr=ObjPtr->fattr;
831
832 for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next) {
833 UpdTextBBox(attr_ptr->obj);
834 }
835 AdjObjBBox(ObjPtr);
836 UpdSelBBox();
837 ObjPtr->dirty = FALSE;
838 }
839 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
840 if (ObjPtr->type == OBJ_SYM) {
841 DrawSymOutline(Win, drawOrigX, drawOrigY, ObjPtr);
842 }
843 }
844 break;
845
846 case OBJ_PIN:
847 if (!colorLayers ||
848 ObjPtr->tmp_parent!=NULL || ObjInVisibleLayer(ObjPtr)) {
849 struct ObjRec *obj_ptr=GetPinObj(ObjPtr);
850
851 if (!checkBBox || NeedToDraw(obj_ptr->bbox)) {
852 obj_ptr->tmp_parent = ObjPtr;
853 if (!DrawObj(Win, obj_ptr)) return FALSE;
854 if (execAnimatePixmap == None && CheckInterrupt(TRUE)) {
855 SetStringStatus(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
856 Msg(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
857 return FALSE;
858 }
859 }
860 DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
861 }
862 break;
863 }
864 return TRUE;
865 }
866
DrawPaperBoundary(Win)867 void DrawPaperBoundary(Win)
868 Window Win;
869 {
870 register int x_end, y_end;
871
872 if (mainDisplay == NULL || inSlideShow) return;
873
874 if (drawOrigX+drawWinW > paperWidth) {
875 x_end = OFFSET_X(paperWidth);
876 if (drawOrigY+drawWinH > paperHeight) {
877 y_end = OFFSET_Y(paperHeight);
878 XDrawLine(mainDisplay, Win, defaultGC, x_end, 0, x_end, y_end);
879 XDrawLine(mainDisplay, Win, defaultGC, 0, y_end, x_end, y_end);
880 } else {
881 XDrawLine(mainDisplay, Win, defaultGC, x_end, 0, x_end,
882 ZOOMED_SIZE(drawWinH));
883 }
884 } else if (drawOrigY+drawWinH > paperHeight) {
885 y_end = OFFSET_Y(paperHeight);
886 XDrawLine(mainDisplay, Win, defaultGC, 0, y_end,
887 ZOOMED_SIZE(drawWinW), y_end);
888 }
889 }
890
RedrawAnArea(BotObj,LtX,LtY,RbX,RbY)891 void RedrawAnArea(BotObj, LtX, LtY, RbX, RbY)
892 struct ObjRec *BotObj;
893 int LtX, LtY, RbX, RbY;
894 /* LtX, LtY, RbX, RbY are absolute coordinates */
895 {
896 register struct ObjRec *obj_ptr;
897 int x=OFFSET_X(LtX), y=OFFSET_Y(LtY), redraw_cross_hair=FALSE;
898 int w=ZOOMED_SIZE(RbX-LtX)+1, h=ZOOMED_SIZE(RbY-LtY)+1;
899
900 if (mainDisplay == NULL || disableRedraw) return;
901
902 if (!userDisableRedraw) {
903 smallArea[0].ltx = LtX; smallArea[0].lty = LtY;
904 smallArea[0].rbx = RbX; smallArea[0].rby = RbY;
905 if (!BBoxIntersect(smallArea[0], drawWinBBox)) {
906 return;
907 }
908 SetRecVals(clipRecs[0], OFFSET_X(LtX), OFFSET_Y(LtY),
909 ZOOMED_SIZE(RbX-LtX)+1, ZOOMED_SIZE(RbY-LtY)+1);
910 numClipRecs = 1;
911 clipOrdering = YXBanded;
912 XSetClipRectangles(mainDisplay, drawGC, 0, 0, clipRecs, numClipRecs,
913 clipOrdering);
914
915 if (execAnimatePixmap != None) {
916 XGCValues values;
917 int real_w=(x+w >= execAnimatePixmapW ? execAnimatePixmapW-x : w);
918 int real_h=(y+h >= execAnimatePixmapH ? execAnimatePixmapH-y : h);
919
920 if (!skipCrossHair && showCrossHair) {
921 int cx, cy;
922
923 GetCrossHairPosition(&cx, &cy, NULL);
924 if (cx >= x && cx < x+real_w && cy >= y && cy < y+real_h) {
925 RedrawCrossHair();
926 redraw_cross_hair = TRUE;
927 }
928 }
929 values.foreground = GetDrawingBgPixel(INVALID, INVALID);
930 values.function = GXcopy;
931 values.fill_style = FillSolid;
932 XChangeGC(mainDisplay, drawGC,
933 GCForeground | GCFunction | GCFillStyle, &values);
934 XFillRectangle(mainDisplay, execAnimatePixmap, drawGC,
935 x, y, real_w, real_h);
936 } else {
937 if (!skipCrossHair && showCrossHair) {
938 int cx, cy;
939
940 GetCrossHairPosition(&cx, &cy, NULL);
941 if (cx >= x && cx < x+w && cy >= y && cy < y+h) {
942 RedrawCrossHair();
943 redraw_cross_hair = TRUE;
944 }
945 }
946 XClearArea(mainDisplay, drawWindow, x, y, w, h, FALSE);
947 }
948
949 if ((paperWidth >= LtX && paperWidth <= RbX) ||
950 (paperHeight >= LtY && paperHeight <= RbY)) {
951 DrawPaperBoundary(execAnimatePixmap==None ? drawWindow :
952 execAnimatePixmap);
953 }
954 if (execAnimatePixmap != None) {
955 DrawGridLines(execAnimatePixmap, x, y, w, h);
956 DrawPageLines(execAnimatePixmap, x, y, w, h);
957 } else {
958 DrawGridLines(drawWindow, x, y, w, h);
959 DrawPageLines(drawWindow, x, y, w, h);
960 }
961 ShowInterrupt(DEF_CHECK_INTERVAL);
962 }
963 numRedrawBBox = 1;
964 smallArea[0].ltx = LtX; smallArea[0].lty = LtY;
965 smallArea[0].rbx = RbX; smallArea[0].rby = RbY;
966 for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) {
967 obj_ptr->tmp_parent = NULL;
968 if (BBoxIntersect(obj_ptr->bbox, drawWinBBox) &&
969 BBoxIntersect(obj_ptr->bbox, smallArea[0])) {
970 if (!DrawObj(execAnimatePixmap==None ? drawWindow : execAnimatePixmap,
971 obj_ptr)) {
972 break;
973 }
974 if (execAnimatePixmap == None && CheckInterrupt(TRUE)) {
975 SetStringStatus(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
976 Msg(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
977 break;
978 }
979 }
980 }
981 if (!userDisableRedraw) {
982 HideInterrupt();
983 SetDefaultDrawWinClipRecs();
984 if (execAnimatePixmap != None && execAnimateRedraw &&
985 x < execAnimatePixmapW && y < execAnimatePixmapH) {
986 int real_w=(x+w >= execAnimatePixmapW ? execAnimatePixmapW-x : w);
987 int real_h=(y+h >= execAnimatePixmapH ? execAnimatePixmapH-y : h);
988
989 XSetFunction(mainDisplay, drawGC, GXcopy);
990 XCopyArea(mainDisplay, execAnimatePixmap, drawWindow, drawGC,
991 x, y, real_w, real_h, x, y);
992 }
993 if (redraw_cross_hair) RedrawCrossHair();
994 }
995 }
996
RedrawAreas(BotObj,LtX1,LtY1,RbX1,RbY1,LtX2,LtY2,RbX2,RbY2)997 void RedrawAreas(BotObj, LtX1, LtY1, RbX1, RbY1, LtX2, LtY2, RbX2, RbY2)
998 struct ObjRec *BotObj;
999 int LtX1, LtY1, RbX1, RbY1, LtX2, LtY2, RbX2, RbY2;
1000 /* note: these coordinates are absolute */
1001 {
1002 register struct ObjRec *obj_ptr;
1003 struct BBRec bbox1, bbox2;
1004 int rec1_slot, redraw_cross_hair=FALSE;
1005 int x1=OFFSET_X(LtX1), y1=OFFSET_Y(LtY1);
1006 int w1=ZOOMED_SIZE(RbX1-LtX1)+1, h1=ZOOMED_SIZE(RbY1-LtY1)+1;
1007 int x2=OFFSET_X(LtX2), y2=OFFSET_Y(LtY2);
1008 int w2=ZOOMED_SIZE(RbX2-LtX2)+1, h2=ZOOMED_SIZE(RbY2-LtY2)+1;
1009
1010 if (mainDisplay == NULL || disableRedraw) return;
1011
1012 bbox1.ltx = LtX1; bbox1.lty = LtY1;
1013 bbox1.rbx = RbX1; bbox1.rby = RbY1;
1014 bbox2.ltx = LtX2; bbox2.lty = LtY2;
1015 bbox2.rbx = RbX2; bbox2.rby = RbY2;
1016
1017 if (Inside(bbox1, bbox2)) {
1018 RedrawAnArea(BotObj, LtX2, LtY2, RbX2, RbY2);
1019 return;
1020 } else if (Inside(bbox2, bbox1)) {
1021 RedrawAnArea(BotObj, LtX1, LtY1, RbX1, RbY1);
1022 return;
1023 }
1024 if (!BBoxIntersect(bbox1, drawWinBBox) &&
1025 !BBoxIntersect(bbox2, drawWinBBox)) {
1026 return;
1027 }
1028
1029 if (!userDisableRedraw) {
1030 if (execAnimatePixmap != None) {
1031 XGCValues values;
1032 int real_w=(x1+w1 >= execAnimatePixmapW ? execAnimatePixmapW-x1 : w1);
1033 int real_h=(y1+h1 >= execAnimatePixmapH ? execAnimatePixmapH-y1 : h1);
1034
1035 if (!skipCrossHair && showCrossHair) {
1036 int cx, cy;
1037
1038 GetCrossHairPosition(&cx, &cy, NULL);
1039 if (cx >= x1 && cx < x1+real_w && cy >= y1 && cy < y1+real_h) {
1040 RedrawCrossHair();
1041 redraw_cross_hair = TRUE;
1042 }
1043 }
1044 values.foreground = GetDrawingBgPixel(INVALID, INVALID);
1045 values.function = GXcopy;
1046 values.fill_style = FillSolid;
1047 XChangeGC(mainDisplay, drawGC,
1048 GCForeground | GCFunction | GCFillStyle, &values);
1049 XFillRectangle(mainDisplay, execAnimatePixmap, drawGC,
1050 x1, y1, real_w, real_h);
1051 } else {
1052 if (!skipCrossHair && showCrossHair) {
1053 int cx, cy;
1054
1055 GetCrossHairPosition(&cx, &cy, NULL);
1056 if (cx >= x1 && cx < x1+w1 && cy >= y1 && cy < y1+h1) {
1057 RedrawCrossHair();
1058 redraw_cross_hair = TRUE;
1059 }
1060 }
1061 XClearArea(mainDisplay, drawWindow, x1, y1, w1, h1, FALSE);
1062 }
1063
1064 if (BBoxIntersect(bbox1, bbox2)) {
1065 int union_ltx, union_lty, union_rbx, union_rby;
1066
1067 union_ltx = min(LtX1,LtX2); union_lty = min(LtY1,LtY2);
1068 union_rbx = max(RbX1,RbX2); union_rby = max(RbY1,RbY2);
1069 skipCrossHair = TRUE;
1070 RedrawAnArea(BotObj, union_ltx, union_lty, union_rbx, union_rby);
1071 skipCrossHair = FALSE;
1072 if (redraw_cross_hair) RedrawCrossHair();
1073 return;
1074 }
1075 if (LtY1 == LtY2) {
1076 rec1_slot = (LtX1 <= LtX2) ? 0 : 1;
1077 SetRecVals(clipRecs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1078 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-LtY1)+1);
1079 SetRecVals(clipRecs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1080 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-LtY2)+1);
1081 numClipRecs = 2;
1082 } else {
1083 if (LtY1 < LtY2) {
1084 if (RbY1 <= LtY2) { /* y-extents do not intersect */
1085 SetRecVals(clipRecs[0], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1086 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-LtY1)+1);
1087 SetRecVals(clipRecs[1], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1088 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-LtY2)+1);
1089 numClipRecs = 2;
1090 } else if (RbY1 >= RbY2) {
1091 /* box 2's y-extents is inside box 1's y-extents */
1092 /*
1093 * Updated on 6/7/2009. The old code below using rec1_slot
1094 * did not make sense.
1095 *
1096 * rec1_slot = (LtX1 < LtX2) ? 0 : 1;
1097 */
1098 SetRecVals(clipRecs[0], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1099 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-LtY1)+1);
1100 SetRecVals(clipRecs[1], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1101 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-LtY2)+1);
1102 numClipRecs = 2;
1103 } else {
1104 SetRecVals(clipRecs[0], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1105 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(LtY2-LtY1)+1);
1106 if (LtX1 < LtX2) {
1107 SetRecVals(clipRecs[1], OFFSET_X(LtX1), OFFSET_Y(LtY2),
1108 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-LtY2)+1);
1109 SetRecVals(clipRecs[2], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1110 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY1-LtY2)+1);
1111 } else {
1112 SetRecVals(clipRecs[1], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1113 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY1-LtY2)+1);
1114 SetRecVals(clipRecs[2], OFFSET_X(LtX1), OFFSET_Y(LtY2),
1115 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-LtY2)+1);
1116 }
1117 SetRecVals(clipRecs[3], OFFSET_X(LtX2), OFFSET_Y(RbY1),
1118 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-RbY1)+1);
1119 numClipRecs = 4;
1120 }
1121 } else {
1122 if (RbY2 <= LtY1) { /* y-extents do not intersect */
1123 SetRecVals(clipRecs[0], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1124 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-LtY2)+1);
1125 SetRecVals(clipRecs[1], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1126 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-LtY1)+1);
1127 numClipRecs = 2;
1128 } else if (RbY2 >= RbY1) {
1129 /* box 1's y-extents is inside box 2's y-extents */
1130 rec1_slot = (LtX1 < LtX2) ? 0 : 1;
1131 SetRecVals(clipRecs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1132 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-LtY1)+1);
1133 SetRecVals(clipRecs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1134 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-LtY2)+1);
1135 numClipRecs = 2;
1136 } else {
1137 SetRecVals(clipRecs[0], OFFSET_X(LtX2), OFFSET_Y(LtY2),
1138 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(LtY1-LtY2)+1);
1139 if (LtX1 < LtX2) {
1140 SetRecVals(clipRecs[1], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1141 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY2-LtY1)+1);
1142 SetRecVals(clipRecs[2], OFFSET_X(LtX2), OFFSET_Y(LtY1),
1143 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-LtY1)+1);
1144 } else {
1145 SetRecVals(clipRecs[1], OFFSET_X(LtX2), OFFSET_Y(LtY1),
1146 ZOOMED_SIZE(RbX2-LtX2)+1, ZOOMED_SIZE(RbY2-LtY1)+1);
1147 SetRecVals(clipRecs[2], OFFSET_X(LtX1), OFFSET_Y(LtY1),
1148 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY2-LtY1)+1);
1149 }
1150 SetRecVals(clipRecs[3], OFFSET_X(LtX1), OFFSET_Y(RbY2),
1151 ZOOMED_SIZE(RbX1-LtX1)+1, ZOOMED_SIZE(RbY1-RbY2)+1);
1152 numClipRecs = 4;
1153 }
1154 }
1155 }
1156 clipOrdering = YXSorted;
1157 XSetClipRectangles(mainDisplay, drawGC, 0, 0, clipRecs, numClipRecs,
1158 clipOrdering);
1159
1160 if ((paperWidth >= LtX1 && paperWidth <= RbX1) ||
1161 (paperHeight >= LtY1 && paperHeight <= RbY1) ||
1162 (paperWidth >= LtX2 && paperWidth <= RbX2) ||
1163 (paperHeight >= LtY2 && paperHeight <= RbY2)) {
1164 DrawPaperBoundary(execAnimatePixmap==None ? drawWindow :
1165 execAnimatePixmap);
1166 }
1167 if (execAnimatePixmap != None) {
1168 DrawGridLines(execAnimatePixmap, x1, y1, w1, h1);
1169 DrawPageLines(execAnimatePixmap, x1, y1, w1, h1);
1170 } else {
1171 DrawGridLines(drawWindow, x1, y1, w1, h1);
1172 DrawPageLines(drawWindow, x1, y1, w1, h1);
1173 }
1174 ShowInterrupt(DEF_CHECK_INTERVAL);
1175 }
1176 numRedrawBBox = 2;
1177 smallArea[0].ltx = LtX1; smallArea[0].lty = LtY1;
1178 smallArea[0].rbx = RbX1; smallArea[0].rby = RbY1;
1179 smallArea[1].ltx = LtX2; smallArea[1].lty = LtY2;
1180 smallArea[1].rbx = RbX2; smallArea[1].rby = RbY2;
1181 for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) {
1182 obj_ptr->tmp_parent = NULL;
1183 if (BBoxIntersect(obj_ptr->bbox, drawWinBBox) &&
1184 (BBoxIntersect(obj_ptr->bbox, bbox1) ||
1185 BBoxIntersect(obj_ptr->bbox, bbox2))) {
1186 if (!DrawObj(execAnimatePixmap==None ? drawWindow : execAnimatePixmap,
1187 obj_ptr)) {
1188 break;
1189 }
1190 if (execAnimatePixmap == None && CheckInterrupt(TRUE)) {
1191 SetStringStatus(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
1192 Msg(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
1193 break;
1194 }
1195 }
1196 }
1197 if (!userDisableRedraw) {
1198 HideInterrupt();
1199 SetDefaultDrawWinClipRecs();
1200 if (execAnimatePixmap != None && execAnimateRedraw) {
1201 XSetFunction(mainDisplay, drawGC, GXcopy);
1202 if (x1 < execAnimatePixmapW && y1 < execAnimatePixmapH) {
1203 int real_w=(x1+w1>=execAnimatePixmapW ? execAnimatePixmapW-x1 : w1);
1204 int real_h=(y1+h1>=execAnimatePixmapH ? execAnimatePixmapH-y1 : h1);
1205
1206 XCopyArea(mainDisplay, execAnimatePixmap, drawWindow, drawGC,
1207 x1, y1, real_w, real_h, x1, y1);
1208 }
1209 if (x2 < execAnimatePixmapW && y2 < execAnimatePixmapH) {
1210 int real_w=(x2+w2>=execAnimatePixmapW ? execAnimatePixmapW-x2 : w2);
1211 int real_h=(y2+h2>=execAnimatePixmapH ? execAnimatePixmapH-y2 : h2);
1212
1213 XCopyArea(mainDisplay, execAnimatePixmap, drawWindow, drawGC,
1214 x2, y2, real_w, real_h, x2, y2);
1215 }
1216 }
1217 if (redraw_cross_hair) RedrawCrossHair();
1218 }
1219 }
1220
1221 static
GetBetterBBox(ObjPtr,LtX,LtY,RbX,RbY,AlreadyFound)1222 void GetBetterBBox(ObjPtr, LtX, LtY, RbX, RbY, AlreadyFound)
1223 struct ObjRec *ObjPtr;
1224 int *LtX, *LtY, *RbX, *RbY, *AlreadyFound;
1225 {
1226 int found, style=INVALID, w=0, ltx, lty, rbx, rby;
1227 struct ObjRec *obj_ptr;
1228 struct AttrRec *attr_ptr;
1229
1230 if (colorLayers &&
1231 ObjPtr->tmp_parent==NULL && !ObjInVisibleLayer(ObjPtr)) {
1232 return;
1233 }
1234 if (*AlreadyFound && ObjPtr->bbox.ltx >= *LtX && ObjPtr->bbox.lty >= *LtY &&
1235 ObjPtr->bbox.rbx <= *RbX && ObjPtr->bbox.rby <= *RbY) {
1236 return;
1237 }
1238 switch (ObjPtr->type) {
1239 case OBJ_POLY:
1240 case OBJ_ARC:
1241 switch (ObjPtr->type) {
1242 case OBJ_POLY:
1243 w = ObjPtr->detail.p->width;
1244 style = ObjPtr->detail.p->style;
1245 break;
1246 case OBJ_ARC:
1247 w = ObjPtr->detail.a->width;
1248 style = ObjPtr->detail.a->style;
1249 break;
1250 }
1251 if (style==LS_PLAIN && (w & 0x1)) {
1252 w = (w-1)>>1;
1253 ltx = ObjPtr->obbox.ltx-w; lty = ObjPtr->obbox.lty-w;
1254 rbx = ObjPtr->obbox.rbx+w; rby = ObjPtr->obbox.rby+w;
1255 } else {
1256 ltx = ObjPtr->bbox.ltx; lty = ObjPtr->bbox.lty;
1257 rbx = ObjPtr->bbox.rbx; rby = ObjPtr->bbox.rby;
1258 }
1259 break;
1260 case OBJ_BOX:
1261 case OBJ_OVAL:
1262 case OBJ_POLYGON:
1263 case OBJ_RCBOX:
1264 switch (ObjPtr->type) {
1265 case OBJ_BOX: w = ObjPtr->detail.b->width; break;
1266 case OBJ_OVAL: w = ObjPtr->detail.o->width; break;
1267 case OBJ_POLYGON: w = ObjPtr->detail.g->width; break;
1268 case OBJ_RCBOX: w = ObjPtr->detail.rcb->width; break;
1269 }
1270 if (w & 0x1) {
1271 w = (w-1)>>1;
1272 ltx = ObjPtr->obbox.ltx-w; lty = ObjPtr->obbox.lty-w;
1273 rbx = ObjPtr->obbox.rbx+w; rby = ObjPtr->obbox.rby+w;
1274 } else {
1275 ltx = ObjPtr->bbox.ltx; lty = ObjPtr->bbox.lty;
1276 rbx = ObjPtr->bbox.rbx; rby = ObjPtr->bbox.rby;
1277 }
1278 break;
1279
1280 case OBJ_TEXT:
1281 ltx = ObjPtr->bbox.ltx; lty = ObjPtr->bbox.lty;
1282 rbx = ObjPtr->bbox.rbx; rby = ObjPtr->bbox.rby;
1283 break;
1284
1285 case OBJ_XBM:
1286 case OBJ_XPM:
1287 ltx = ObjPtr->bbox.ltx; lty = ObjPtr->bbox.lty;
1288 rbx = ObjPtr->bbox.rbx-1; rby = ObjPtr->bbox.rby-1;
1289 break;
1290
1291 case OBJ_GROUP:
1292 case OBJ_ICON:
1293 case OBJ_SYM:
1294 found = FALSE;
1295 obj_ptr = ObjPtr->detail.r->last;
1296 for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev) {
1297 obj_ptr->tmp_parent = ObjPtr;
1298 GetBetterBBox(obj_ptr, <x, <y, &rbx, &rby, &found);
1299 }
1300 if (!found) {
1301 return;
1302 }
1303 break;
1304
1305 case OBJ_PIN:
1306 found = FALSE;
1307 obj_ptr = GetPinObj(ObjPtr);
1308 obj_ptr->tmp_parent = ObjPtr;
1309 GetBetterBBox(obj_ptr, <x, <y, &rbx, &rby, &found);
1310 if (!found) {
1311 return;
1312 }
1313 break;
1314 }
1315 for (attr_ptr=ObjPtr->lattr; attr_ptr!=NULL; attr_ptr=attr_ptr->prev) {
1316 if (attr_ptr->shown) {
1317 if (attr_ptr->obj->bbox.ltx < ltx) ltx = attr_ptr->obj->bbox.ltx;
1318 if (attr_ptr->obj->bbox.lty < lty) lty = attr_ptr->obj->bbox.lty;
1319 if (attr_ptr->obj->bbox.rbx > rbx) rbx = attr_ptr->obj->bbox.rbx;
1320 if (attr_ptr->obj->bbox.rby > rby) rby = attr_ptr->obj->bbox.rby;
1321 }
1322 }
1323 if (ObjPtr->type == OBJ_SYM) {
1324 if (ObjPtr->obbox.ltx-QUARTER_INCH < ltx) {
1325 ltx = ObjPtr->obbox.ltx - QUARTER_INCH;
1326 }
1327 if (ObjPtr->obbox.lty-QUARTER_INCH < lty) {
1328 lty = ObjPtr->obbox.lty - QUARTER_INCH;
1329 }
1330 if (ObjPtr->obbox.rbx+QUARTER_INCH > rbx) {
1331 rbx = ObjPtr->obbox.rbx + QUARTER_INCH;
1332 }
1333 if (ObjPtr->obbox.rby+QUARTER_INCH > rby) {
1334 rby = ObjPtr->obbox.rby + QUARTER_INCH;
1335 }
1336 }
1337 if (*AlreadyFound) {
1338 if (ltx < *LtX) *LtX = ltx; if (lty < *LtY) *LtY = lty;
1339 if (rbx > *RbX) *RbX = rbx; if (rby > *RbY) *RbY = rby;
1340 } else {
1341 *LtX = ltx; *LtY = lty; *RbX = rbx; *RbY = rby;
1342 }
1343 *AlreadyFound = TRUE;
1344 }
1345
RedrawDuringScrolling()1346 int RedrawDuringScrolling()
1347 {
1348 return (scrollingCanvas != INVALID && (execAnimatePixmap != None ||
1349 smoothScrollingCanvas == JUMP_SCROLLING));
1350 }
1351
1352 static
RedrawVertSliceFromCache(start_frac,scroll_all_the_way)1353 void RedrawVertSliceFromCache(start_frac, scroll_all_the_way)
1354 double start_frac;
1355 int scroll_all_the_way;
1356 {
1357 int y=0;
1358
1359 if (start_frac < 0.0) start_frac = 0.0;
1360 if (start_frac > 1.0) start_frac = 1.0;
1361 if (scroll_all_the_way) {
1362 GetMaxScrollOrigin(NULL, &y);
1363 } else {
1364 double dv=(double)0;
1365
1366 switch (gridSystem) {
1367 case ENGLISH_GRID:
1368 dv = ((double)paperHeight) * start_frac;
1369 break;
1370 case METRIC_GRID:
1371 if (zoomedIn && zoomScale > 1) {
1372 dv = ((double)paperHeight) * start_frac;
1373 } else {
1374 dv = ((double)paperHeight) * start_frac;
1375 }
1376 break;
1377 }
1378 y = round(dv);
1379 }
1380 XCopyArea(mainDisplay, execAnimatePixmap, drawWindow, drawGC,
1381 0, ZOOMED_SIZE(y), initDrawWinW, initDrawWinH, 0, 0);
1382 XCopyArea(mainDisplay, execAnimateRulerPixmap, vRuleWindow, defaultGC,
1383 0, ZOOMED_SIZE(y), rulerW-windowPadding, initDrawWinH, 0, 0);
1384 }
1385
1386 static
RedrawHoriSliceFromCache(start_frac,scroll_all_the_way)1387 void RedrawHoriSliceFromCache(start_frac, scroll_all_the_way)
1388 double start_frac;
1389 int scroll_all_the_way;
1390 {
1391 int x=0;
1392
1393 if (start_frac < 0.0) start_frac = 0.0;
1394 if (start_frac > 1.0) start_frac = 1.0;
1395 if (scroll_all_the_way) {
1396 GetMaxScrollOrigin(&x, NULL);
1397 } else {
1398 double dv=(double)0;
1399
1400 switch (gridSystem) {
1401 case ENGLISH_GRID:
1402 dv = ((double)paperWidth) * start_frac;
1403 break;
1404 case METRIC_GRID:
1405 if (zoomedIn && zoomScale > 1) {
1406 dv = ((double)paperWidth) * start_frac;
1407 } else {
1408 dv = ((double)paperWidth) * start_frac;
1409 }
1410 break;
1411 }
1412 x = round(dv);
1413 }
1414 XCopyArea(mainDisplay, execAnimatePixmap, drawWindow, drawGC,
1415 ZOOMED_SIZE(x), 0, initDrawWinW, initDrawWinH, 0, 0);
1416 XCopyArea(mainDisplay, execAnimateRulerPixmap, hRuleWindow, defaultGC,
1417 ZOOMED_SIZE(x), 0, initDrawWinW, rulerW-windowPadding, 0, 0);
1418 }
1419
RedrawAreaFromCache(start_frac,scroll_all_the_way)1420 void RedrawAreaFromCache(start_frac, scroll_all_the_way)
1421 double start_frac;
1422 int scroll_all_the_way;
1423 {
1424 if (mainDisplay == NULL || disableRedraw) return;
1425
1426 if (RedrawDuringScrolling()) {
1427 switch (scrollingCanvas) {
1428 case SCRL_UP:
1429 case SCRL_DN:
1430 RedrawVertSliceFromCache(start_frac, scroll_all_the_way);
1431 break;
1432 case SCRL_LF:
1433 case SCRL_RT:
1434 RedrawHoriSliceFromCache(start_frac, scroll_all_the_way);
1435 break;
1436 }
1437 }
1438 }
1439
RedrawDrawWindow(BotObj)1440 void RedrawDrawWindow(BotObj)
1441 struct ObjRec *BotObj;
1442 {
1443 register struct ObjRec *obj_ptr;
1444
1445 if (mainDisplay == NULL || disableRedraw) return;
1446
1447 if (!skipCrossHair) {
1448 RedrawCrossHair();
1449 }
1450 if (execAnimating) {
1451 int already_animating=(execAnimatePixmap!=None), x=0, y=0, w=0, h=0;
1452
1453 if (execAnimatePixmap != None) {
1454 XFreePixmap(mainDisplay, execAnimatePixmap);
1455 }
1456 if (execAnimateRulerPixmap != None) {
1457 XFreePixmap(mainDisplay, execAnimateRulerPixmap);
1458 }
1459 execAnimatePixmap = execAnimateRulerPixmap = None;
1460 switch (scrollingCanvas) {
1461 case SCRL_UP:
1462 case SCRL_DN:
1463 execAnimatePixmapW = ZOOMED_SIZE(drawWinW);
1464 GetMaxScrollOrigin(NULL, &y);
1465 execAnimatePixmapDataH = ZOOMED_SIZE(y+drawWinH);
1466 h = ZOOMED_SIZE(paperHeight);
1467 if ((h % initDrawWinH) == 0) {
1468 execAnimatePixmapH = (((int)(h / initDrawWinH))+1)*initDrawWinH;
1469 } else {
1470 execAnimatePixmapH = (((int)(h / initDrawWinH))+2)*initDrawWinH;
1471 }
1472 execAnimateRulerPixmapW = rulerW-windowPadding;
1473 execAnimateRulerPixmapH = execAnimatePixmapH;
1474 break;
1475 case SCRL_LF:
1476 case SCRL_RT:
1477 w = ZOOMED_SIZE(paperWidth);
1478 if ((w % initDrawWinW) == 0) {
1479 execAnimatePixmapW = (((int)(w / initDrawWinW))+1)*initDrawWinW;
1480 } else {
1481 execAnimatePixmapW = (((int)(w / initDrawWinW))+2)*initDrawWinW;
1482 }
1483 GetMaxScrollOrigin(&x, NULL);
1484 execAnimatePixmapDataW = ZOOMED_SIZE(x+drawWinW);
1485 execAnimatePixmapH = ZOOMED_SIZE(drawWinH);
1486
1487 execAnimateRulerPixmapW = execAnimatePixmapW;
1488 execAnimateRulerPixmapH = rulerW-windowPadding;
1489 break;
1490 default:
1491 execAnimatePixmapW = ZOOMED_SIZE(drawWinW);
1492 execAnimatePixmapH = ZOOMED_SIZE(drawWinH);
1493 break;
1494 }
1495 execAnimatePixmap = XCreatePixmap(mainDisplay, mainWindow,
1496 execAnimatePixmapW, execAnimatePixmapH, mainDepth);
1497 if (execAnimatePixmap == None) {
1498 if (already_animating) {
1499 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_ALLOC_XPM_NO_ANIM),
1500 execAnimatePixmapW, execAnimatePixmapH);
1501 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1502 }
1503 } else {
1504 XGCValues values;
1505
1506 values.foreground = GetDrawingBgPixel(INVALID, INVALID);
1507 values.function = GXcopy;
1508 values.fill_style = FillSolid;
1509 XChangeGC(mainDisplay, drawGC,
1510 GCForeground | GCFunction | GCFillStyle, &values);
1511 if (scrollingCanvas != INVALID) {
1512 int saved_win_w=drawWinW, saved_win_h=drawWinH, abort=FALSE;
1513
1514 execAnimateRulerPixmap = XCreatePixmap(mainDisplay, mainWindow,
1515 execAnimateRulerPixmapW, execAnimateRulerPixmapH, mainDepth);
1516 if (execAnimateRulerPixmap == None) {
1517 abort = TRUE;
1518 }
1519 drawWinW = ABS_SIZE(execAnimatePixmapW);
1520 drawWinH = ABS_SIZE(execAnimatePixmapH);
1521
1522 SetDefaultDrawWinClipRecs();
1523
1524 XFillRectangle(mainDisplay, execAnimatePixmap, drawGC,
1525 0, 0, execAnimatePixmapW, execAnimatePixmapH);
1526 if (execAnimateRulerPixmap != None) {
1527 XFillRectangle(mainDisplay, execAnimateRulerPixmap, drawGC,
1528 0, 0, execAnimateRulerPixmapW, execAnimateRulerPixmapH);
1529 }
1530 drawWinW = saved_win_w;
1531 drawWinH = saved_win_h;
1532 SetDefaultDrawWinClipRecs();
1533
1534 if (abort) {
1535 XFreePixmap(mainDisplay, execAnimatePixmap);
1536 execAnimatePixmap = None;
1537 }
1538 } else {
1539 XFillRectangle(mainDisplay, execAnimatePixmap, drawGC,
1540 0, 0, execAnimatePixmapW, execAnimatePixmapH);
1541 }
1542 }
1543 }
1544 if (execAnimatePixmap != None && scrollingCanvas != INVALID) {
1545 int saved_orig_x=drawOrigX, saved_orig_y=drawOrigY, x=0, y=0;
1546 int saved_win_w=drawWinW, saved_win_h=drawWinH, scroll_vertical=FALSE;
1547 int watch_cursor=watchCursorOnMainWindow;
1548
1549 SaveStatusStrings();
1550 SetStringStatus(TgLoadCachedString(CSTID_CACHING_IMAGE));
1551 if (!watch_cursor) {
1552 SetWatchCursor(drawWindow);
1553 SetWatchCursor(mainWindow);
1554 }
1555 switch (scrollingCanvas) {
1556 case SCRL_UP:
1557 case SCRL_DN:
1558 x = 0;
1559 y = ZOOMED_SIZE(drawOrigY);
1560 drawOrigY = 0;
1561 drawWinH = ABS_SIZE(execAnimatePixmapH);
1562 scroll_vertical = TRUE;
1563 break;
1564 case SCRL_LF:
1565 case SCRL_RT:
1566 x = ZOOMED_SIZE(drawOrigX);
1567 y = 0;
1568 drawOrigX = 0;
1569 drawWinW = ABS_SIZE(execAnimatePixmapW);
1570 scroll_vertical = FALSE;
1571 break;
1572 }
1573 UpdDrawWinBBox();
1574 SetDefaultDrawWinClipRecs();
1575
1576 DrawPaperBoundary(execAnimatePixmap);
1577 RedrawGridLines(execAnimatePixmap);
1578 RedrawPageLines(execAnimatePixmap);
1579
1580 if (scroll_vertical) {
1581 RedrawVRuler(mainDisplay, execAnimateRulerPixmap);
1582 } else {
1583 RedrawHRuler(mainDisplay, execAnimateRulerPixmap);
1584 }
1585 AdjSplineVs();
1586
1587 numRedrawBBox = 0;
1588 ShowInterrupt(DEF_CHECK_INTERVAL);
1589 for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) {
1590 obj_ptr->tmp_parent = NULL;
1591 if (BBoxIntersect(obj_ptr->bbox, drawWinBBox)) {
1592 if (!TgAnyButtonDown(mainDisplay, drawWindow)) {
1593 /* canceled */
1594 Msg(TgLoadString(STID_SCROLLING_CANCELED));
1595 break;
1596 }
1597 if (!DrawObj(execAnimatePixmap, obj_ptr) && CheckInterrupt(TRUE)) {
1598 break;
1599 }
1600 }
1601 }
1602 HideInterrupt();
1603
1604 XSetFunction(mainDisplay, drawGC, GXcopy);
1605 XCopyArea(mainDisplay, execAnimatePixmap, drawWindow, drawGC,
1606 x, y, initDrawWinW, initDrawWinH, 0, 0);
1607
1608 drawOrigX = saved_orig_x;
1609 drawOrigY = saved_orig_y;
1610 drawWinW = saved_win_w;
1611 drawWinH = saved_win_h;
1612 UpdDrawWinBBox();
1613 SetDefaultDrawWinClipRecs();
1614
1615 if (!watch_cursor) {
1616 SetDefaultCursor(mainWindow);
1617 ShowCursor();
1618 }
1619 RestoreStatusStrings();
1620 } else {
1621 DrawPaperBoundary(execAnimatePixmap==None ? drawWindow :
1622 execAnimatePixmap);
1623 RedrawGridLines(execAnimatePixmap==None ? drawWindow : execAnimatePixmap);
1624 RedrawPageLines(execAnimatePixmap==None ? drawWindow : execAnimatePixmap);
1625
1626 numRedrawBBox = 0;
1627 ShowInterrupt(DEF_CHECK_INTERVAL);
1628 for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) {
1629 obj_ptr->tmp_parent = NULL;
1630 if (BBoxIntersect(obj_ptr->bbox, drawWinBBox)) {
1631 if (!DrawObj(execAnimatePixmap==None ? drawWindow :
1632 execAnimatePixmap, obj_ptr)) {
1633 break;
1634 }
1635 if (execAnimatePixmap == None && CheckInterrupt(TRUE)) {
1636 SetStringStatus(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
1637 Msg(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
1638 break;
1639 }
1640 }
1641 }
1642 HideInterrupt();
1643 if (execAnimatePixmap != None) {
1644 XSetFunction(mainDisplay, drawGC, GXcopy);
1645 XCopyArea(mainDisplay, execAnimatePixmap, drawWindow, drawGC,
1646 0, 0, execAnimatePixmapW, execAnimatePixmapH, 0, 0);
1647 }
1648 if (!skipCrossHair) {
1649 RedrawCrossHair();
1650 }
1651 }
1652 }
1653
DrawAllOnPixmap(LtX,LtY,W,H,nRedraw)1654 Pixmap DrawAllOnPixmap(LtX, LtY, W, H, nRedraw)
1655 int *LtX, *LtY, *W, *H, nRedraw;
1656 {
1657 register struct ObjRec *obj_ptr;
1658 int ltx, lty, rbx, rby, w, h, saved_zoom_scale, saved_zoomed_in, found=FALSE;
1659 int saved_draw_orig_x, saved_draw_orig_y, saved_draw_win_w, saved_draw_win_h;
1660 Pixmap pixmap;
1661 XGCValues values;
1662
1663 ltx = lty = rbx = rby = 0;
1664 for (obj_ptr = botObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) {
1665 obj_ptr->tmp_parent = NULL;
1666 GetBetterBBox(obj_ptr, <x, <y, &rbx, &rby, &found);
1667 }
1668 if (!found) {
1669 *LtX = *LtY = *W = *H = 0;
1670 sprintf(gszMsgBox, "No objects to print!");
1671 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1672 return None;
1673 }
1674 *W = w = rbx - ltx + 1;
1675 *H = h = rby - lty + 1;
1676 *LtX = ltx;
1677 *LtY = lty;
1678
1679 saved_draw_orig_x = drawOrigX; saved_draw_orig_y = drawOrigY;
1680 saved_draw_win_w = drawWinW; saved_draw_win_h = drawWinH;
1681 saved_zoom_scale = zoomScale;
1682 saved_zoomed_in = zoomedIn;
1683
1684 drawOrigX = ltx; drawOrigY = lty;
1685 drawWinW = w; drawWinH = h;
1686 zoomScale = 0;
1687 zoomedIn = FALSE;
1688
1689 SetDefaultDrawWinClipRecs();
1690
1691 pixmap = XCreatePixmap(mainDisplay, mainWindow, w, h, mainDepth);
1692
1693 if (pixmap == None) {
1694 FailAllocPixmapMessage(w, h);
1695 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE), w, h);
1696 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1697 return None;
1698 }
1699
1700 values.foreground = GetDrawingBgPixel(INVALID, INVALID);
1701 values.function = GXcopy;
1702 values.fill_style = FillSolid;
1703 XChangeGC(mainDisplay, drawGC,
1704 GCForeground | GCFunction | GCFillStyle, &values);
1705 XFillRectangle(mainDisplay, pixmap, drawGC, 0, 0, w, h);
1706
1707 AdjCaches();
1708 AdjSplineVs();
1709
1710 checkBBox = FALSE;
1711 ShowInterrupt(DEF_CHECK_INTERVAL);
1712 for (obj_ptr=botObj; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
1713 obj_ptr->tmp_parent = NULL;
1714 if (!DrawObj(pixmap, obj_ptr)) {
1715 XFreePixmap(mainDisplay, pixmap);
1716 pixmap = None;
1717 break;
1718 }
1719 if (execAnimatePixmap == None && CheckInterrupt(TRUE)) {
1720 SetStringStatus(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
1721 Msg(TgLoadString(STID_USER_INTR_ABORT_REPAINT));
1722 XFreePixmap(mainDisplay, pixmap);
1723 pixmap = None;
1724 break;
1725 }
1726 }
1727 HideInterrupt();
1728 checkBBox = TRUE;
1729
1730 drawOrigX = saved_draw_orig_x; drawOrigY = saved_draw_orig_y;
1731 drawWinW = saved_draw_win_w; drawWinH = saved_draw_win_h;
1732 zoomedIn = saved_zoomed_in;
1733 zoomScale = saved_zoom_scale;
1734
1735 AdjSplineVs();
1736 AdjCaches();
1737 SetDefaultDrawWinClipRecs();
1738
1739 skipCrossHair = TRUE;
1740 if (nRedraw) RedrawDrawWindow(botObj);
1741 skipCrossHair = FALSE;
1742
1743 if (gpExportClipBBox != NULL) {
1744 int y, intersect_w=0, intersect_h=0;
1745 int src_offset_x=0, src_offset_y=0, dest_offset_x=0, dest_offset_y=0;
1746 int dest_w=gpExportClipBBox->rbx-gpExportClipBBox->ltx;
1747 int dest_h=gpExportClipBBox->rby-gpExportClipBBox->lty;
1748 Pixmap dest_pixmap=XCreatePixmap(mainDisplay, mainWindow, dest_w,
1749 dest_h, mainDepth);
1750 XImage *src_image=NULL, *dest_image=NULL;
1751 struct BBRec src_bbox, intersect_bbox;
1752
1753 if (dest_pixmap == None) FailAllocBitmapMessage(dest_w, dest_h);
1754 XSetForeground(mainDisplay, drawGC, GetDrawingBgPixel(INVALID, INVALID));
1755 XFillRectangle(mainDisplay, dest_pixmap, drawGC, 0, 0, dest_w, dest_h);
1756
1757 SetBBRec(&src_bbox, (*LtX), (*LtY), (*LtX)+(*W), (*LtY)+(*H));
1758 if (!IntersectRect(src_bbox, *gpExportClipBBox, &intersect_bbox)) {
1759 XFreePixmap(mainDisplay, pixmap);
1760 return dest_pixmap;
1761 }
1762 dest_image = XGetImage(mainDisplay, dest_pixmap, 0, 0, dest_w, dest_h,
1763 AllPlanes, ZPixmap);
1764 if (dest_image == NULL) FailAllocMessage();
1765
1766 src_image = XGetImage(mainDisplay, pixmap, 0, 0, (*W), (*H), AllPlanes,
1767 ZPixmap);
1768 if (src_image == NULL) FailAllocMessage();
1769
1770 intersect_w = intersect_bbox.rbx-intersect_bbox.ltx;
1771 intersect_h = intersect_bbox.rby-intersect_bbox.lty;
1772 src_offset_x = intersect_bbox.ltx-src_bbox.ltx;
1773 src_offset_y = intersect_bbox.lty-src_bbox.lty;
1774 dest_offset_x = intersect_bbox.ltx-gpExportClipBBox->ltx;
1775 dest_offset_y = intersect_bbox.lty-gpExportClipBBox->lty;
1776
1777 for (y=0; y < intersect_h; y++) {
1778 int x;
1779
1780 for (x=0; x < intersect_w; x++) {
1781 XPutPixel(dest_image, x+dest_offset_x, y+dest_offset_y,
1782 XGetPixel(src_image, x+src_offset_x, y+src_offset_y));
1783 }
1784 }
1785 XPutImage(mainDisplay, dest_pixmap, xpmGC, dest_image, 0, 0, 0, 0,
1786 dest_w, dest_h);
1787 XDestroyImage(dest_image);
1788 XDestroyImage(src_image);
1789 XFreePixmap(mainDisplay, pixmap);
1790 *LtX = gpExportClipBBox->ltx;
1791 *LtY = gpExportClipBBox->lty;
1792 *W = gpExportClipBBox->rbx-(*LtX);
1793 *H = gpExportClipBBox->rby-(*LtY);
1794 return dest_pixmap;
1795 }
1796 return pixmap;
1797 }
1798
ClearAndRedrawDrawWindow()1799 void ClearAndRedrawDrawWindow()
1800 {
1801 if (mainDisplay == NULL || disableRedraw) return;
1802
1803 XClearWindow(mainDisplay, drawWindow);
1804 if (execAnimatePixmap != None) {
1805 XGCValues values;
1806
1807 values.foreground = GetDrawingBgPixel(INVALID, INVALID);
1808 values.function = GXcopy;
1809 values.fill_style = FillSolid;
1810 XChangeGC(mainDisplay, drawGC,
1811 GCForeground | GCFunction | GCFillStyle, &values);
1812 XFillRectangle(mainDisplay, execAnimatePixmap, drawGC,
1813 0, 0, execAnimatePixmapW, execAnimatePixmapH);
1814 }
1815 somethingHighLighted = FALSE;
1816 skipCrossHair = TRUE;
1817 RedrawDrawWindow(botObj);
1818 skipCrossHair = FALSE;
1819 ResetDirtyBBoxInfo();
1820 RedrawCurText();
1821 if (!execAnimating) HighLightForward();
1822 RedrawCrossHair();
1823 }
1824
ClearAndRedrawDrawWindowNoCurT()1825 void ClearAndRedrawDrawWindowNoCurT()
1826 /* use to be ClearAndRedrawDrawWindowDontDrawCurText() */
1827 {
1828 if (mainDisplay == NULL || disableRedraw) return;
1829
1830 XClearWindow(mainDisplay, drawWindow);
1831 if (execAnimatePixmap != None) {
1832 XGCValues values;
1833
1834 values.foreground = GetDrawingBgPixel(INVALID, INVALID);
1835 values.function = GXcopy;
1836 values.fill_style = FillSolid;
1837 XChangeGC(mainDisplay, drawGC,
1838 GCForeground | GCFunction | GCFillStyle, &values);
1839 XFillRectangle(mainDisplay, execAnimatePixmap, drawGC,
1840 0, 0, execAnimatePixmapW, execAnimatePixmapH);
1841 }
1842 somethingHighLighted = FALSE;
1843 skipCrossHair = TRUE;
1844 RedrawDrawWindow(botObj);
1845 skipCrossHair = FALSE;
1846 HighLightForward();
1847 RedrawCrossHair();
1848 }
1849
BeginExecAnimate()1850 int BeginExecAnimate()
1851 {
1852 execAnimating = TRUE;
1853 execAnimateRedraw = TRUE;
1854 RedrawDrawWindow(botObj);
1855
1856 if (execAnimatePixmap == None) {
1857 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_ALLOC_PIXMAP_OF_SIZE),
1858 execAnimatePixmapW, execAnimatePixmapH);
1859 if (scrollingCanvas == INVALID) {
1860 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1861 } else {
1862 SetStringStatus(gszMsgBox);
1863 }
1864 execAnimatePixmapW = execAnimatePixmapH = 0;
1865 execAnimating = execAnimateRedraw = FALSE;
1866 return FALSE;
1867 }
1868 return TRUE;
1869 }
1870
EndExecAnimate()1871 void EndExecAnimate()
1872 {
1873 if (execAnimatePixmap != None) {
1874 XFreePixmap(mainDisplay, execAnimatePixmap);
1875 }
1876 if (execAnimateRulerPixmap != None) {
1877 XFreePixmap(mainDisplay, execAnimateRulerPixmap);
1878 }
1879 execAnimatePixmap = execAnimateRulerPixmap = None;
1880 execAnimatePixmapW = execAnimatePixmapH = 0;
1881 execAnimatePixmapDataW = execAnimatePixmapDataH = 0;
1882 execAnimating = execAnimateRedraw = FALSE;
1883 }
1884
CleanUpDrawingWindow()1885 void CleanUpDrawingWindow()
1886 {
1887 FreeEditAttrInfo(gpEditAttrInEditorAttrInfo);
1888 gpEditAttrInEditorAttrInfo = NULL;
1889
1890 if (execAnimatePixmap != None) {
1891 Msg(TgLoadString(STID_FORCING_END_ANIMATE));
1892 EndExecAnimate();
1893 }
1894 SetCurChoice(NOTHING);
1895 if (topSel != NULL) {
1896 if (!deserializingFile) HighLightReverse();
1897 RemoveAllSel();
1898 }
1899 if (tgifObj != NULL && tgifObj->fattr != NULL) {
1900 DelAllAttrs(tgifObj->fattr);
1901 tgifObj->fattr = tgifObj->lattr = NULL;
1902 }
1903 DelAllPages();
1904 ResetRotatePivotValidInfo();
1905 }
1906
1907 static
GetElapseTime(long start_sec,long start_msec,long end_sec,long end_msec)1908 long GetElapseTime(long start_sec, long start_msec, long end_sec, long end_msec)
1909 {
1910 long diff_sec=end_sec-start_sec;
1911 long diff_msec=end_msec-start_msec;
1912
1913 if (diff_msec < 0) {
1914 diff_sec--;
1915 diff_msec += 1000;
1916 }
1917 return ((diff_sec*1000)+diff_msec);
1918 }
1919
1920 static
BenchMark()1921 void BenchMark()
1922 {
1923 static int count=0;
1924 int need_to_check_auto_exec=FALSE, i=0;
1925
1926 while (XPending(mainDisplay)) {
1927 i++;
1928 TryProcessAnXEvent(&need_to_check_auto_exec);
1929 }
1930 /* debug, do not translate */
1931 fprintf(stderr, "%1d BenchMark Ready (%1d events processed)!\n", count, i);
1932 if (count++ < 3) {
1933 SendCommandToSelf(CMDID_BENCHMARK, INVALID);
1934 } else {
1935 long start_sec=0L, start_msec=0L, end_sec=0L, end_msec=0L;
1936 long elapsed_msec=0L;
1937 int x=0, y=0, z=0, w=64, x_end=(min(drawWinW,drawWinH)-64), total=1000000;
1938 XRectangle rectangles[1000];
1939
1940 XSetForeground(mainDisplay, defaultGC, colorPixels[y%maxColors]);
1941 UtilGetMilliSecTime(&start_sec, &start_msec);
1942 for (i=0; i < total; i++) {
1943 XDrawRectangle(mainDisplay, drawWindow, defaultGC, x+y, x, w, w);
1944 if (x++ >= x_end) {
1945 x=0;
1946 if (y++ >= x_end) {
1947 y=0;
1948 XSetForeground(mainDisplay, defaultGC,
1949 colorPixels[(++z)%maxColors]);
1950 }
1951 }
1952 }
1953 XSetForeground(mainDisplay, defaultGC, myFgPixel);
1954 UtilGetMilliSecTime(&end_sec, &end_msec);
1955 elapsed_msec = GetElapseTime(start_sec, start_msec, end_sec, end_msec);
1956 if (elapsed_msec > 0) {
1957 double avg=((double)total)*((double)1000)/((double)elapsed_msec);
1958
1959 /* debug, do not translate */
1960 fprintf(stderr, "Took %ld ms to draw %1d rectangles (%.2f %s).\n",
1961 elapsed_msec, total, avg, "rectangles per second");
1962 }
1963 x = y = z = 0;
1964 XSetForeground(mainDisplay, defaultGC, colorPixels[y%maxColors]);
1965 UtilGetMilliSecTime(&start_sec, &start_msec);
1966 for (i=0; i < 1000; i++) {
1967 rectangles[i].width = rectangles[i].height = w;
1968 }
1969 w = 0;
1970 for (i=0; i < total; i++) {
1971 if (w < 1000) {
1972 rectangles[w].x = x+y;
1973 rectangles[w].y = x;
1974 w++;
1975 } else {
1976 XDrawRectangles(mainDisplay, drawWindow, defaultGC, rectangles,
1977 1000);
1978 w = 0;
1979 }
1980 if (x++ >= x_end) {
1981 x=0;
1982 if (y++ >= x_end) {
1983 y=0;
1984 XSetForeground(mainDisplay, defaultGC,
1985 colorPixels[(++z)%maxColors]);
1986 }
1987 }
1988 }
1989 XSetForeground(mainDisplay, defaultGC, myFgPixel);
1990 UtilGetMilliSecTime(&end_sec, &end_msec);
1991 elapsed_msec = GetElapseTime(start_sec, start_msec, end_sec, end_msec);
1992 if (elapsed_msec > 0) {
1993 double avg=((double)total)*((double)1000)/((double)elapsed_msec);
1994
1995 /* debug, do not translate */
1996 fprintf(stderr, "Took %ld ms to draw %1d rectangles (%.2f %s).\n",
1997 elapsed_msec, total, avg, "rectangles per second");
1998 }
1999 }
2000 }
2001
2002 static
ToggleShowChat()2003 void ToggleShowChat()
2004 {
2005 noChatWindow = !noChatWindow;
2006 if (noChatWindow) {
2007 XUnmapWindow(mainDisplay, chatWindow);
2008 } else {
2009 XMapWindow(mainDisplay, chatWindow);
2010 }
2011 Reconfigure(TRUE);
2012 }
2013
2014 static
DoShortCut(key_ev,name,key_sym,state,args)2015 int DoShortCut(key_ev, name, key_sym, state, args)
2016 XKeyEvent *key_ev;
2017 char *name, *args;
2018 KeySym key_sym;
2019 unsigned int state;
2020 /* returns INVALID if the key event can be caught by other windows */
2021 {
2022 if (gnDisableShortcuts) {
2023 sprintf(gszMsgBox, TgLoadString(STID_TOOL_NOT_FINISH_WITH_EXEC),
2024 TOOL_NAME);
2025 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2026 return BAD;
2027 }
2028 if ((state & ControlMask) && (!(state & METAMASK))) {
2029 int rc=BAD;
2030
2031 switch (key_sym&0xff) {
2032 case 'a': /*^a*/ SelAllObj(TRUE, FALSE); break;
2033 case 'b': /*^b*/ BackProc(); break;
2034 case 'c': /*^c*/ CopyToCutBuffer(); break;
2035 case 'd': /*^d*/ DupSelObj(); break;
2036 case 'e': /*^e*/ PushCurChoice(); break;
2037 case 'f': /*^f*/ FrontProc(); break;
2038 case 'g': /*^g*/ GroupSelObj(TRUE, TRUE, TRUE); break;
2039 case 'h': /*^h*/ return(INVALID);
2040 case 'i': /*^i*/ Instantiate(); break;
2041 case 'j': /*^j*/ return(INVALID);
2042 case 'k': /*^k*/ PopIcon(); break;
2043 case 'l': /*^l*/ AlignSelObjs(); break;
2044 case 'm': /*^m*/ return(INVALID);
2045 case 'n': /*^n*/ NewProc(); break;
2046 case 'o': /*^o*/
2047 OpenProc((args==NULL || *args=='\0') ? NULL : args);
2048 break;
2049 case 'p': /*^p*/ Dump(""); break;
2050 case 'q': /*^q*/ if ((rc=QuitProc())==INVALID) return BAD; return rc;
2051 case 'r': /*^r*/ ClearAndRedrawDrawWindow(); break;
2052 case 's': /*^s*/ SaveFile(); break;
2053 case 't': /*^t*/ AlignSelToGrid(); break;
2054 case 'u': /*^u*/ UngroupSelObj(TRUE, TRUE); break;
2055 case 'v': /*^v*/ PasteFromCutBuffer(); break;
2056 case 'w': /*^w*/ SetCurChoice(DRAWTEXT); break;
2057 case 'x': /*^x*/ CutToCutBuffer(); break;
2058 case 'y': /*^y*/ RedoCmd(); break;
2059 case 'z': /*^z*/ UndoCmd(); break;
2060 case ',': /*^,*/ ScrollLeft(NULL); break;
2061 case '.': /*^.*/ ScrollRight(NULL); break;
2062 case '-': /*^-*/ PrintWithCommand(""); break;
2063 case '1': /*^1*/ ScreenCapture(); break;
2064 case '2': /*^2*/ FullScreenCapture(); break;
2065
2066 case ' ':
2067 case '\\':
2068 if (curChoice == DRAWTEXT && textCursorShown &&
2069 (canvasFontDoubleByte || gstCopyUTF8Info.double_byte_valid)) {
2070 if (textHighlight) {
2071 curTextModified = TRUE;
2072 DelSelText();
2073 }
2074 if (!canvasFontDoubleByte && gstCopyUTF8Info.double_byte_valid) {
2075 SwitchToDoubleByteFont(&gstCopyUTF8Info.double_byte_seg);
2076 }
2077 if (tgIMActiveOnCntrlSpace(mainDisplay, drawWindow)) {
2078 if (tgIMHandleCntrlSpace(mainDisplay, drawWindow)) {
2079 if (gnInputMethod != TGIM_NONE && gnOverTheSpot) {
2080 if (!tgIMTellCursorPosition(mainDisplay, drawWindow,
2081 textCurX, textCurBaselineY+curStrBlock->seg->des)) {
2082 }
2083 }
2084 }
2085 } else {
2086 return INVALID;
2087 }
2088 }
2089 break;
2090 default: return INVALID;
2091 }
2092 } else if ((state & METAMASK) && (!(state & ControlMask))) {
2093 switch (key_sym&0xff) {
2094 case 'a': /*#a*/ AddAttrs(); break;
2095 case 'b': /*#b*/ return ProbeProc();
2096 case 'c': /*#c*/ RotateCounter(); break;
2097 case 'd': /*#d*/ DecGrid(); break;
2098 case 'e': /*#e*/ AnimateSel(); break;
2099 case 'f': /*#f*/ FlashSelColor(); break;
2100 case 'g': /*#f*/ ToggleGridShown(); break;
2101 case 'h': /*#h*/ FlipHorizontal(); break;
2102 case 'i': /*#i*/ IncGrid(); break;
2103 case 'j': /*#j*/ HideAllAttrNames(); break;
2104 case 'k': /*#k*/ SetCurChoice(NOTHING); break;
2105 case 'l': /*#l*/ DistrSelObjs(); break;
2106 case 'm': /*#m*/ MoveAttr(); break;
2107 case 'n': /*#n*/ ShowAllAttrNames(); break;
2108 case 'o': /*#o*/ ZoomOut(); break;
2109 case 'p': /*#p*/ ImportFile(); break;
2110 case 'q': /*#q*/ SetCurChoice(DRAWPOLY); break;
2111 case 'r': /*#r*/ SetCurChoice(DRAWBOX); break;
2112 case 's': /*#s*/ return SolveProc();
2113 case 't': /*#t*/ DetachAttrs(); break;
2114 case 'u': /*#u*/ return AnimateProc(); break;
2115 case 'v': /*#v*/ FlipVertical(); break;
2116 case 'w': /*#w*/ RotateClockWise(); break;
2117 case 'x': /*#x*/ return EscapeProc();
2118 case 'y': /*#y*/ return SimulateProc();
2119 case 'z': /*#z*/ ZoomIn(); break;
2120 case '9': /*#9*/ MakePreciseArc(); break;
2121 case '0': /*#0*/ UpdateSelObjs(); break;
2122 case ',': /*#,*/ ScrollUp(NULL); break;
2123 case '.': /*#.*/ ScrollDown(NULL); break;
2124 case '-': /*#-*/ ShowAllAttrs(); break;
2125 case '{': /*#{*/ AlignObjsTop(); break;
2126 case '+': /*#+*/ AlignObjsMiddle(); break;
2127 case '}': /*#}*/ AlignObjsBottom(); break;
2128 case '[': /*#[*/ AlignObjsLeft(); break;
2129 case '=': /*#=*/ AlignObjsCenter(); break;
2130 case ']': /*#]*/ AlignObjsRight(); break;
2131 case '"': /*#"*/ MakeRegularPolygon(); break;
2132 case '%': /*#%*/ SetPrintReduction(); break;
2133 case ':': /*#:*/ DefaultZoom(); break;
2134 case '`': /*#`*/ ZoomWayOut(); break;
2135 case '~': /*#~*/ SaveNewFile(TRUE, NULL); break;
2136 case ';': /*#;*/ CutMaps(); break;
2137 case '_': /*#_*/ AbutHorizontal(); break;
2138 case '|': /*#|*/ AbutVertical(); break;
2139 case '#': /*##*/
2140 BreakUpText((args==NULL || *args=='\0') ? NULL : args);
2141 break;
2142 case '^': /*#^*/ ScrollToOrigin(); break;
2143 case '@': /*#@*/ ToggleMoveMode(); break;
2144 case '$': /*#$*/ SetCurChoice(VERTEXMODE); break;
2145 case '&': /*#&*/ AlignSelToPage(); break;
2146 case '*': /*#**/ ChangeDomain(); break;
2147 case '(': /*#(*/
2148 ImportEPSFile(FALSE, (args==NULL || *args=='\0') ? NULL : args);
2149 break;
2150 case ')': /*#)*/ ScaleAllSelObj(); break;
2151 case '<': /*#<*/ LockSelObj(); break;
2152 case '>': /*#>*/ UnlockSelObj(); break;
2153 default: return INVALID;
2154 }
2155 } else if ((state & METAMASK) && (state & ControlMask)) {
2156 switch (key_sym&0xff) {
2157 case 'a': /*^#a*/ AddPoint(); break;
2158 case 'b': /*^#b*/ ChangeFontStyle(STYLE_BR); break;
2159 case 'c': /*^#c*/ ChangeFontJust(JUST_C); break;
2160 case 'd': /*^#d*/ DeletePoint(); break;
2161 case 'e': /*^#e*/ SetCurChoice(DRAWRCBOX); break;
2162 case 'f': /*^#f*/ InvertXBitmaps(); break;
2163 case 'g': /*^#g*/ ToggleSnapOn(); break;
2164 case 'h': /*^#h*/ HideAllAttrs(); break;
2165 case 'i': /*^#i*/ MakeIconic(NULL, TRUE); break;
2166 case 'j': /*^#j*/ UnMakeIconic(); break;
2167 case 'k': /*^#k*/ ToggleColorPostScript(); break;
2168 case 'l': /*^#l*/ ChangeFontJust(JUST_L); break;
2169 case 'm': /*^#m*/ MakeSymbolic(); break;
2170 case 'n': /*^#n*/ UnMakeSymbolic(); break;
2171 case 'o': /*^#o*/ ChangeFontStyle(STYLE_NR); break;
2172 case 'p': /*^#p*/ ChangeFontStyle(STYLE_BI); break;
2173 case 'q': /*^#q*/ SetCurChoice(DRAWPOLYGON); break;
2174 case 'r': /*^#r*/ ChangeFontJust(JUST_R); break;
2175 case 's': /*^#s*/
2176 SaveNewFile(FALSE, (args==NULL || *args=='\0') ? NULL : args);
2177 break;
2178 case 't': /*^#t*/ ChangeFontStyle(STYLE_NI); break;
2179 case 'u': /*^#u*/ UpdateSymbols(); break;
2180 case 'v': /*^#v*/ SetCurChoice(DRAWCORNEROVAL); break;
2181 case 'w': /*^#w*/ ToggleAllSelLineType(); break;
2182 case 'x': /*^#x*/ ToggleWhereToPrint(); break;
2183 case 'y': /*^#y*/ PushIcon(); break;
2184 case 'Y': /*^#Y*/ PasteCompoundText(); break;
2185 case 'z': /*^#z*/ SetCurChoice(DRAWARC); break;
2186 case '.': /*^#.*/ ImportXBitmapFile(); break;
2187 case ',': /*^#,*/ ImportXPixmapFile(); break;
2188 case '-': /*^#-*/ ToggleGridSystem(); break;
2189 case '=': /*^#=*/ FindAgain(); break;
2190 case '5': /*^#5*/ InsertRightSubscript(); break;
2191 case '6': /*^#6*/ InsertRightSuperscript(); break;
2192 case '7': /*^#7*/ ToggleEqAttrShown(); break;
2193 case '8': /*^#8*/
2194 if (inSlideShow) {
2195 LeaveSlideShow();
2196 } else {
2197 EnterSlideShow();
2198 }
2199 break;
2200 case '9': /*^#9*/ FindNoCase(); break;
2201 case '0': /*^#0*/ FindCaseSensitive(); break;
2202 default: return INVALID;
2203 }
2204 } else if (name != NULL && key_sym == '\0' && state == 0) {
2205 XButtonEvent button_ev;
2206
2207 button_ev.state = ShiftMask;
2208
2209 /* do not translate -- program constants */
2210 if (strcmp(name, "Delete()") == 0) {
2211 if (curChoice == DRAWTEXT && textCursorShown) {
2212 DelSelText();
2213 } else {
2214 DelAllSelObj();
2215 }
2216 } else if (strcmp(name, "DrawCornerOval()") == 0) {
2217 SetCurChoice(DRAWCORNEROVAL);
2218 } else if (strcmp(name, "DrawCenterOval()") == 0) {
2219 SetCurChoice(DRAWCENTEROVAL);
2220 } else if (strcmp(name, "DrawEdgeOval()") == 0) {
2221 SetCurChoice(DRAWEDGECIRCLE);
2222 } else if (strcmp(name, "DrawEdgeArc()") == 0) {
2223 SetCurChoice(DRAWEDGEARC);
2224 } else if (strcmp(name, "ScrollPageUp()") == 0) {
2225 ScrollUp(&button_ev);
2226 } else if (strcmp(name, "ScrollPageDown()") == 0) {
2227 ScrollDown(&button_ev);
2228 } else if (strcmp(name, "ScrollPageRight()") == 0) {
2229 ScrollRight(&button_ev);
2230 } else if (strcmp(name, "ScrollPageLeft()") == 0) {
2231 ScrollLeft(&button_ev);
2232 } else if (strcmp(name, "FlushUndoBuffer()") == 0) {
2233 FlushUndoBuffer();
2234 } else if (strcmp(name, "PrintMsgBuffer()") == 0) {
2235 PrintMsgBuffer();
2236 } else if (strcmp(name, "SaveOrigin()") == 0) {
2237 SaveOrigin();
2238 } else if (strcmp(name, "RestoreImageWH()") == 0) {
2239 RestoreImageWH();
2240 } else if (strcmp(name, "UpdateEPS()") == 0) {
2241 UpdateEPS();
2242 } else if (strcmp(name, "ToggleMapShown()") == 0) {
2243 ToggleMapShown();
2244 } else if (strcmp(name, "ToggleUseGrayScale()") == 0) {
2245 ToggleUseGray();
2246 } else if (strcmp(name, "FreeHandMode()") == 0) {
2247 SetCurChoice(FREEHAND);
2248 } else if (strcmp(name, "SaveSymInLibrary()") == 0) {
2249 SaveSymInLibrary();
2250 } else if (strcmp(name, "CenterAnEndPoint()") == 0 ||
2251 strcmp(name, "CenterAVertex()") == 0) {
2252 CenterAnEndPoint();
2253 } else if (strcmp(name, "NextPage()") == 0) {
2254 NextPage();
2255 } else if (strcmp(name, "PrevPage()") == 0) {
2256 PrevPage();
2257 } else if (strcmp(name, "NamePages()") == 0) {
2258 NamePages();
2259 } else if (strcmp(name, "GotoPage()") == 0) {
2260 GotoPage((args==NULL || *args=='\0') ? NULL : args);
2261 } else if (strcmp(name, "AddPageBefore()") == 0) {
2262 AddPageBefore();
2263 } else if (strcmp(name, "AddPageAfter()") == 0) {
2264 AddPageAfter();
2265 } else if (strcmp(name, "DeleteCurPage()") == 0) {
2266 DeleteCurPage();
2267 } else if (strcmp(name, "TogglePageLineShown()") == 0) {
2268 TogglePageLineShown();
2269 } else if (strcmp(name, "SpecifyDrawingSize()") == 0) {
2270 SpecifyDrawingSize();
2271 } else if (strcmp(name, "PrintOnePage()") == 0) {
2272 PrintOnePage();
2273 } else if (strcmp(name, "ToggleNamedAttrShown()") == 0) {
2274 if (args != NULL) {
2275 ToggleNamedAttrShown(args);
2276 }
2277 } else if (strcmp(name, "AttachFileAttrs()") == 0) {
2278 AddFileAttrs();
2279 } else if (strcmp(name, "DetachFileAttrs()") == 0) {
2280 DetachFileAttrs();
2281 } else if (strcmp(name, "EditFileAttrs()") == 0) {
2282 EditFileAttrs();
2283 } else if (strcmp(name, "PrintSelectedObjs()") == 0) {
2284 PrintSelectedObjs();
2285 } else if (strcmp(name, "InputPolyPts()") == 0) {
2286 InputPolyPts();
2287 } else if (strcmp(name, "InputPolygonPts()") == 0) {
2288 InputPolygonPts();
2289 } else if (strcmp(name, "EditAttrs()") == 0) {
2290 EditAttrs();
2291 } else if (strcmp(name, "ConvertIntSpline()") == 0) {
2292 ConvertIntSpline();
2293 } else if (strcmp(name, "PasteFromFile()") == 0) {
2294 PasteFromFile();
2295 } else if (strcmp(name, "ToggleShowMeasurement()") == 0) {
2296 ToggleShowMeasurement();
2297 } else if (strcmp(name, "SetMeasureUnit()") == 0) {
2298 SetMeasureUnit();
2299 } else if (strcmp(name, "Cut()") == 0) {
2300 CutToCutBuffer();
2301 } else if (strcmp(name, "ToggleSmoothHinge()") == 0) {
2302 ToggleSmoothHinge();
2303 } else if (strcmp(name, "ToggleShowMenubar()") == 0) {
2304 ToggleShowMenubar();
2305 } else if (strcmp(name, "ToggleShowStatus()") == 0) {
2306 ToggleShowStatus();
2307 } else if (strcmp(name, "BrowseXBitmap()") == 0) {
2308 BrowseXBitmap();
2309 } else if (strcmp(name, "BrowseXPixmap()") == 0) {
2310 BrowseXPixmap();
2311 } else if (strcmp(name, "SpecifyPaperSize()") == 0) {
2312 SpecifyPaperSize();
2313 } else if (strcmp(name, "ToggleOneMotionSelMove()") == 0) {
2314 ToggleOneMotionSelectMove();
2315 } else if (strcmp(name, "GoBack()") == 0) {
2316 NavigateBack();
2317 } else if (strcmp(name, "GoForward()") == 0) {
2318 NavigateForward();
2319 } else if (strcmp(name, "RefreshCurrent()") == 0) {
2320 NavigateRefresh();
2321 } else if (strcmp(name, "HotList()") == 0) {
2322 NavigateHotList();
2323 } else if (strcmp(name, "AddCurrentToHotList()") == 0) {
2324 NavigateAddToHotList();
2325 } else if (strcmp(name, "SessionHistory()") == 0) {
2326 NavigateSessionHistory();
2327 } else if (strcmp(name, "ToggleHyperSpace()") == 0) {
2328 ToggleHyperSpace (FALSE);
2329 } else if (strcmp(name, "EmbedEPSFile()") == 0) {
2330 ImportEPSFile(TRUE, NULL);
2331 } else if (strcmp(name, "SetSelLineWidth()") == 0) {
2332 SetSelLineWidth(NULL);
2333 } else if (strcmp(name, "AddColor()") == 0) {
2334 AddColor();
2335 } else if (strcmp(name, "ImportAttrs()") == 0) {
2336 ImportAttrs();
2337 } else if (strcmp(name, "ExportAttrs()") == 0) {
2338 ExportAttrs();
2339 } else if (strcmp(name, "MergeWithTable()") == 0) {
2340 MergeWithTable();
2341 } else if (strcmp(name, "ExportToTable()") == 0) {
2342 ExportToTable();
2343 } else if (strcmp(name, "DeletePages()") == 0) {
2344 DeletePages();
2345 } else if (strcmp(name, "PrintOneFilePerPage()") == 0) {
2346 PrintOneFilePerPage();
2347 } else if (strcmp(name, "ImportGIFFile()") == 0) {
2348 ImportGIFFile();
2349 } else if (strcmp(name, "ImportPNGFile()") == 0) {
2350 ImportPNGFile();
2351 } else if (strcmp(name, "ImportJPEGFile()") == 0) {
2352 ImportJPEGFile(TRUE, NULL);
2353 } else if (strcmp(name, "ImportPBMFile()") == 0) {
2354 ImportPBMFile();
2355 } else if (strcmp(name, "ImportPGMFile()") == 0) {
2356 ImportPGMFile();
2357 } else if (strcmp(name, "ImportPPMFile()") == 0) {
2358 ImportPPMFile();
2359 } else if (strcmp(name, "SetExportPixelTrim()") == 0) {
2360 SetExportPixelTrim(FALSE);
2361 } else if (strcmp(name, "ToggleColorLayers()") == 0) {
2362 ToggleColorLayers();
2363 } else if (strcmp(name, "ToggleStretchableText()") == 0) {
2364 ToggleStretchableText();
2365 } else if (strcmp(name, "BreakUpBit/Pixmap()") == 0) {
2366 BreakUpMaps();
2367 } else if (strcmp(name, "LayoutOnArc()") == 0) {
2368 LayoutOnArc();
2369 } else if (strcmp(name, "PreciseRotate()") == 0) {
2370 PreciseRotate();
2371 } else if (strcmp(name, "JoinPoly()") == 0) {
2372 JoinPoly();
2373 } else if (strcmp(name, "CutPoly()") == 0) {
2374 CutPoly();
2375 } else if (strcmp(name, "GetBoundingBox()") == 0) {
2376 GetBoundingBox();
2377 } else if (strcmp(name, "SetTemplate()") == 0) {
2378 SetTemplate();
2379 } else if (strcmp(name, "MakeGray()") == 0) {
2380 MakeGray();
2381 } else if (strcmp(name, "InvertColor()") == 0) {
2382 InvertColor();
2383 } else if (strcmp(name, "InterpolateColor()") == 0) {
2384 InterpolateColor();
2385 } else if (strcmp(name, "BrightenDarken()") == 0) {
2386 BrightenDarken();
2387 } else if (strcmp(name, "ChangeSaturation()") == 0) {
2388 ChangeSaturation();
2389 } else if (strcmp(name, "ChangeHue()") == 0) {
2390 ChangeHue();
2391 } else if (strcmp(name, "ContrastEnhance()") == 0) {
2392 ContrastEnhance();
2393 } else if (strcmp(name, "ColorBalance()") == 0) {
2394 ColorBalance();
2395 } else if (strcmp(name, "Gamma()") == 0) {
2396 Gamma(NULL);
2397 } else if (strcmp(name, "EdgeDetect()") == 0) {
2398 EdgeDetect();
2399 } else if (strcmp(name, "Emboss()") == 0) {
2400 Emboss();
2401 } else if (strcmp(name, "ReduceColors()") == 0) {
2402 ReduceColors();
2403 } else if (strcmp(name, "ReduceToPixmapColors()") == 0) {
2404 ReduceToPixmapColors();
2405 } else if (strcmp(name, "SetDefaultColorLevels()") == 0) {
2406 SetDefaultColorLevels();
2407 } else if (strcmp(name, "ReduceToDefaultColors()") == 0) {
2408 ReduceToDefaultColors();
2409 } else if (strcmp(name, "DefaultErrorDiffuse()") == 0) {
2410 DefaultErrorDiffuse();
2411 } else if (strcmp(name, "Spread()") == 0) {
2412 Spread();
2413 } else if (strcmp(name, "Sharpen()") == 0) {
2414 Sharpen();
2415 } else if (strcmp(name, "Blur3()") == 0) {
2416 Blur3();
2417 } else if (strcmp(name, "Blur5()") == 0) {
2418 Blur5();
2419 } else if (strcmp(name, "Blur7()") == 0) {
2420 Blur7();
2421 } else if (strcmp(name, "RunBggen()") == 0) {
2422 RunBggen();
2423 } else if (strcmp(name, "CircularBggen()") == 0) {
2424 CircularBggen();
2425 } else if (strcmp(name, "SimpleRectBggen()") == 0) {
2426 SimpleRectBggen();
2427 } else if (strcmp(name, "RegenerateImage()") == 0) {
2428 RegenerateImage();
2429 } else if (strcmp(name, "CropImage()") == 0) {
2430 CropImage();
2431 } else if (strcmp(name, "GetColor()") == 0) {
2432 GetColor();
2433 } else if (strcmp(name, "ReplaceColor()") == 0) {
2434 ReplaceColor();
2435 } else if (strcmp(name, "FloodFill()") == 0) {
2436 FloodFill();
2437 } else if (strcmp(name, "CreateContour()") == 0) {
2438 CreateContour();
2439 } else if (strcmp(name, "Subtract()") == 0) {
2440 Subtract();
2441 } else if (strcmp(name, "AlphaCombine()") == 0) {
2442 AlphaCombine();
2443 } else if (strcmp(name, "XorColors()") == 0) {
2444 XorColors();
2445 } else if (strcmp(name, "ImportOtherFile()") == 0) {
2446 ImportOtherFile();
2447 } else if (strcmp(name, "ImportOtherFileType()") == 0) {
2448 if (args != NULL) {
2449 ImportOtherFileType(args);
2450 }
2451 } else if (strcmp(name, "BrowseOther()") == 0) {
2452 BrowseOther();
2453 } else if (strcmp(name, "BrowseOtherType()") == 0) {
2454 if (args != NULL) {
2455 BrowseOtherType(args);
2456 }
2457 } else if (strcmp(name, "ToggleShowCrossHair()") == 0) {
2458 ToggleShowCrossHair();
2459 } else if (strcmp(name, "SetShapeShadow()") == 0) {
2460 SetShapeShadow();
2461 } else if (strcmp(name, "NoTransform()") == 0) {
2462 NoTransform();
2463 } else if (strcmp(name, "About()") == 0) {
2464 About();
2465 } else if (strcmp(name, "Copyright()") == 0) {
2466 Copyright();
2467 } else if (strcmp(name, "SetSelFontSize()") == 0) {
2468 SetSelFontSize(NULL);
2469 } else if (strcmp(name, "ZoomInAtCursor()") == 0) {
2470 if (key_ev != NULL) {
2471 int abs_x=ABS_X(key_ev->x);
2472 int abs_y=ABS_Y(key_ev->y);
2473
2474 ZoomInAtCursor(abs_x, abs_y);
2475 }
2476 } else if (strcmp(name, "CenterAtCursor()") == 0) {
2477 if (key_ev != NULL) {
2478 int abs_x=ABS_X(key_ev->x);
2479 int abs_y=ABS_Y(key_ev->y);
2480
2481 CenterAtCursor(abs_x, abs_y);
2482 }
2483 } else if (strcmp(name, "SetEditTextSize()") == 0) {
2484 SetEditTextSize();
2485 } else if (strcmp(name, "SetTextRotation()") == 0) {
2486 SetTextRotation(NULL);
2487 } else if (strcmp(name, "SetRotationIncrement()") == 0) {
2488 SetRotationIncrement(NULL);
2489 } else if (strcmp(name, "CurrentVersionInfo()") == 0 ||
2490 strcmp(name, "LatestReleaseInfo()") == 0) {
2491 LatestReleaseInfo();
2492 } else if (strcmp(name, "VectorWarp()") == 0) {
2493 VectorWarp();
2494 } else if (strcmp(name, "ConnectPins()") == 0) {
2495 ConnectPins();
2496 } else if (strcmp(name, "PasteCompoundText()") == 0) {
2497 PasteCompoundText();
2498 } else if (strcmp(name, "CopyProperties()") == 0) {
2499 CopyProperties(TRUE);
2500 } else if (strcmp(name, "SaveProperties()") == 0) {
2501 SaveProperties();
2502 } else if (strcmp(name, "PasteProperties()") == 0) {
2503 PasteProperties(TRUE);
2504 } else if (strcmp(name, "RestoreProperties()") == 0) {
2505 RestoreProperties();
2506 } else if (strcmp(name, "RotateShearMode()") == 0) {
2507 SetCurChoice(ROTATEMODE);
2508 } else if (strcmp(name, "ChangeAllSelFill()") == 0) {
2509 if (args != NULL) {
2510 ChangeAllSelFill(atoi(args), TRUE);
2511 }
2512 } else if (strcmp(name, "ChangeAllSelPen()") == 0) {
2513 if (args != NULL) {
2514 ChangeAllSelPen(atoi(args), TRUE);
2515 }
2516 } else if (strcmp(name, "ChangeAllSelLineWidth()") == 0) {
2517 if (args != NULL) {
2518 ChangeAllSelLineWidth(atoi(args), TRUE);
2519 }
2520 } else if (strcmp(name, "ChangeAllSelLineStyle()") == 0) {
2521 if (args != NULL) {
2522 ChangeAllSelLineStyle(atoi(args), TRUE);
2523 }
2524 } else if (strcmp(name, "ChangeAllSelLineType()") == 0) {
2525 if (args != NULL) {
2526 ChangeAllSelLineType(atoi(args), TRUE);
2527 }
2528 } else if (strcmp(name, "ChangeAllSelLineDash()") == 0) {
2529 if (args != NULL) {
2530 ChangeAllSelLineDash(atoi(args), TRUE);
2531 }
2532 } else if (strcmp(name, "ChangeAllSelFont()") == 0) {
2533 if (args != NULL) {
2534 ChangeFont(atoi(args), FALSE);
2535 }
2536 } else if (strcmp(name, "ChangeAllSelFontSize()") == 0) {
2537 if (args != NULL) {
2538 ChangeFontSize(atoi(args));
2539 }
2540 } else if (strcmp(name, "ChangeAllSelFontStyle()") == 0) {
2541 if (args != NULL) {
2542 ChangeFontStyle(atoi(args));
2543 }
2544 } else if (strcmp(name, "ChangeAllSelFontJust()") == 0) {
2545 if (args != NULL) {
2546 ChangeFontJust(atoi(args)-MAXFONTSTYLES-1);
2547 }
2548 } else if (strcmp(name, "ChangeAllSelColor()") == 0) {
2549 if (args != NULL) {
2550 ChangeAllSelColor(atoi(args), TRUE);
2551 }
2552 } else if (strcmp(name, "LanscapeMode()") == 0) {
2553 ChangePageStyle(LANDSCAPE);
2554 } else if (strcmp(name, "PortraitMode()") == 0) {
2555 ChangePageStyle(PORTRAIT);
2556 } else if (strcmp(name, "SetWhereToPrint()") == 0) {
2557 if (args != NULL) {
2558 SetWhereToPrint(atoi(args));
2559 }
2560 } else if (strcmp(name, "SetHoriAlign()") == 0) {
2561 if (args != NULL) {
2562 HoriAlignSubMenu(atoi(args));
2563 }
2564 } else if (strcmp(name, "SetVertAlign()") == 0) {
2565 if (args != NULL) {
2566 VertAlignSubMenu(atoi(args));
2567 }
2568 } else if (strcmp(name, "SetMoveMode()") == 0) {
2569 if (args != NULL) {
2570 MoveModeSubMenu(atoi(args));
2571 }
2572 } else if (strcmp(name, "SetStretchTextMode()") == 0) {
2573 if (args != NULL) {
2574 StretchableTextModeSubMenu(atoi(args));
2575 }
2576 } else if (strcmp(name, "CreateShape()") == 0) {
2577 if (args != NULL) {
2578 ShapeSubMenu(atoi(args));
2579 }
2580 } else if (strcmp(name, "SetPageLayoutMode()") == 0) {
2581 if (args != NULL) {
2582 PageLayoutSubMenu(atoi(args));
2583 }
2584 } else if (strcmp(name, "SetTransPatMode()") == 0) {
2585 if (args != NULL) {
2586 ChangeAllSelTransPat(atoi(args), TRUE);
2587 }
2588 } else if (strcmp(name, "ToggleShowMode()") == 0) {
2589 ToggleShowMode();
2590 } else if (strcmp(name, "SetSlideShowBorderColor()") == 0) {
2591 SetSlideShowBorderColor();
2592 } else if (strcmp(name, "SetSlideShowWindowOffsets()") == 0) {
2593 SetSlideShowWindowOffsets();
2594 } else if (strcmp(name, "ExportXPixmapDeckToGIF()") == 0) {
2595 ExportXPixmapDeckToGIF();
2596 } else if (strcmp(name, "ImportGIFToXPixmapDeck()") == 0) {
2597 ImportGIFToXPixmapDeck();
2598 } else if (strcmp(name, "InsertThinSpace()") == 0) {
2599 InsertThinSpace();
2600 } else if (strcmp(name, "InsertVerticalOffset()") == 0) {
2601 InsertVerticalOffset();
2602 } else if (strcmp(name, "RemoveVerticalOffset()") == 0) {
2603 RemoveVerticalOffset();
2604 } else if (strcmp(name, "InsertLeftSuperscript()") == 0) {
2605 InsertLeftSuperscript();
2606 } else if (strcmp(name, "InsertLeftSubscript()") == 0) {
2607 InsertLeftSubscript();
2608 } else if (strcmp(name, "InsertCenterSuperscript()") == 0) {
2609 InsertCenterSuperscript();
2610 } else if (strcmp(name, "InsertCenterSubscript()") == 0) {
2611 InsertCenterSubscript();
2612 } else if (strcmp(name, "SetScriptFraction()") == 0) {
2613 SetScriptFraction();
2614 } else if (strcmp(name, "FakeUserAgent()") == 0) {
2615 if (args != NULL) {
2616 FakeUserAgent(args);
2617 }
2618 } else if (strcmp(name, "FakeReferer()") == 0) {
2619 if (args != NULL) {
2620 FakeReferer(args);
2621 }
2622 } else if (strcmp(name, "ToggleKeepAlive()") == 0) {
2623 ToggleKeepAlive();
2624 } else if (strcmp(name, "SizeToWidest()") == 0) {
2625 SizeToWidest();
2626 } else if (strcmp(name, "SizeToNarrowest()") == 0) {
2627 SizeToNarrowest();
2628 } else if (strcmp(name, "SizeToTallest()") == 0) {
2629 SizeToTallest();
2630 } else if (strcmp(name, "SizeToShortest()") == 0) {
2631 SizeToShortest();
2632 } else if (strcmp(name, "SizeToGivenWidthHeight()") == 0) {
2633 SizeToGivenWidthHeight();
2634 } else if (strcmp(name, "SizeToGivenWidth()") == 0) {
2635 SizeToGivenWidth();
2636 } else if (strcmp(name, "SizeToGivenHeight()") == 0) {
2637 SizeToGivenHeight();
2638 } else if (strcmp(name, "ExecCmdsFromFile()") == 0) {
2639 if (args != NULL) {
2640 ExecCmdsFromFile(args);
2641 }
2642 } else if (strcmp(name, "StartExecCmdsFromFile()") == 0) {
2643 StartExecCmdsFromFile();
2644 } else if (strcmp(name, "CopyPlainTextAsObject()") == 0) {
2645 CopyPlainTextAsObject();
2646 } else if (strcmp(name, "SetTextFillPatternColor()") == 0) {
2647 SetTextFillPatternColor();
2648 } else if (strcmp(name, "AlignDirect()") == 0) {
2649 if (args != NULL) {
2650 AlignDirect(atoi(args));
2651 }
2652 } else if (strcmp(name, "DistributeDirect()") == 0) {
2653 if (args != NULL) {
2654 DistributeDirect(atoi(args));
2655 }
2656 } else if (strcmp(name, "ToggleVisibleGridInSlideShow()") == 0) {
2657 ToggleVisibleGridInSlideShow();
2658 } else if (strcmp(name, "ChangeScrollMode()") == 0) {
2659 if (args != NULL) {
2660 ChangeScrollMode(atoi(args));
2661 }
2662 } else if (strcmp(name, "SetAltEditTextBgColor()") == 0) {
2663 SetAltEditTextBgColor();
2664 } else if (strcmp(name, "SetAltEditTextHighlightColor()") == 0) {
2665 SetAltEditTextHighlightColor();
2666 } else if (strcmp(name, "ToggleAltEditTextBgColor()") == 0) {
2667 ToggleAltEditTextBgColor();
2668 } else if (strcmp(name, "ChangeAllSelFontUnderline()") == 0) {
2669 if (args != NULL) {
2670 ChangeFontUnderline(atoi(args)-MAXFONTSTYLES-MAXJUSTS-2);
2671 }
2672 } else if (strcmp(name, "ChangeAllSelFontOverline()") == 0) {
2673 if (args != NULL) {
2674 ChangeFontOverline(atoi(args)-MAXFONTSTYLES-MAXJUSTS-5);
2675 }
2676 } else if (strcmp(name, "EditPageFileNames()") == 0) {
2677 EditPageFileNames();
2678 } else if (strcmp(name, "ExportHalfToneBitmap()") == 0) {
2679 ExportHalfToneBitmap();
2680 } else if (strcmp(name, "ExportThresholdBitmap()") == 0) {
2681 ExportThresholdBitmap();
2682 } else if (strcmp(name, "SetExportBitmapThreshold()") == 0) {
2683 if (args != NULL) {
2684 SetExportBitmapThreshold(NULL);
2685 }
2686 } else if (strcmp(name, "PreciseScaleEverything()") == 0) {
2687 PreciseScaleEverything();
2688 } else if (strcmp(name, "SetPaperColor()") == 0) {
2689 SetPaperColor();
2690 } else if (strcmp(name, "DelayedFullScreenCapture()") == 0) {
2691 DelayedFullScreenCapture();
2692 } else if (strcmp(name, "ToggleHideDuringCapture()") == 0) {
2693 ToggleHideDuringCapture();
2694 } else if (strcmp(name, "EditDomainPaths()") == 0) {
2695 EditDomainPaths();
2696 } else if (strcmp(name, "SelectDefaultDomain()") == 0) {
2697 SelectDefaultDomain();
2698 } else if (strcmp(name, "AddADomain()") == 0) {
2699 AddADomain();
2700 } else if (strcmp(name, "DeleteADomain()") == 0) {
2701 DeleteADomain();
2702 } else if (strcmp(name, "ReloadDomainInfoFromX()") == 0) {
2703 ReloadDomainInfoFromX();
2704 } else if (strcmp(name, "EditIndexedAttrInEditor()") == 0) {
2705 if (args != NULL) {
2706 EditIndexedAttrInEditor(atoi(args));
2707 }
2708 } else if (strcmp(name, "EditIndexedAttrGroupInEditor()") == 0) {
2709 if (args != NULL) {
2710 EditIndexedAttrGroupInEditor(atoi(args));
2711 }
2712 } else if (strcmp(name, "GetProperty()") == 0) {
2713 if (args != NULL) {
2714 GetProperty(atoi(args));
2715 }
2716 } else if (strcmp(name, "PeekDimension()") == 0) {
2717 if (args != NULL) {
2718 PeekDimension(atoi(args));
2719 }
2720 } else if (strcmp(name, "SetHtmlExportTemplate()") == 0) {
2721 SetHtmlExportTemplate();
2722 } else if (strcmp(name, "PrintPages()") == 0) {
2723 PrintPages();
2724 } else if (strcmp(name, "GoHyperSpaceInSlideShow()") == 0) {
2725 GoHyperSpaceInSlideShow();
2726 } else if (strcmp(name, "FreehandModeInSlideShow()") == 0) {
2727 FreehandModeInSlideShow();
2728 } else if (strcmp(name, "OpenARecentlyUsedFile()") == 0) {
2729 if (args != NULL) {
2730 OpenARecentlyUsedFile(atoi(args));
2731 }
2732 } else if (strcmp(name, "MoveEditTextBox()") == 0) {
2733 MoveEditTextBox();
2734 } else if (strcmp(name, "ReplaceGraphic()") == 0) {
2735 ReplaceGraphic();
2736 } else if (strcmp(name, "ToggleShowMeasurementInTooltip()") == 0) {
2737 ToggleShowMeasurementInTooltip();
2738 } else if (strcmp(name, "ToggleAutoEPSPreviewBitmap()") == 0) {
2739 ToggleAutoEPSPreviewBitmap();
2740 } else if (strcmp(name, "CreateThumbnails()") == 0) {
2741 CreateThumbnails();
2742 } else if (strcmp(name, "ConnectTwoPortsByAWire()") == 0) {
2743 ConnectTwoPortsByAWire();
2744 } else if (strcmp(name, "RenameSignalNameForAPort()") == 0) {
2745 RenameSignalNameForAPort();
2746 } else if (strcmp(name, "ClearSignalNameForAPort()") == 0) {
2747 ClearSignalNameForAPort();
2748 } else if (strcmp(name, "ToggleShowWireSignalName()") == 0) {
2749 ToggleShowWireSignalName();
2750 } else if (strcmp(name, "ToggleShowChoicebar()") == 0) {
2751 ToggleShowChoicebar();
2752 } else if (strcmp(name, "MergePortsWithAnObject()") == 0) {
2753 MergePortsWithAnObject();
2754 } else if (strcmp(name, "RenumberObjectIds()") == 0) {
2755 RenumberObjectIds();
2756 } else if (strcmp(name, "RepeatConnectTwoPortsByAWire()") == 0) {
2757 RepeatConnectTwoPortsByAWire();
2758 } else if (strcmp(name, "ConnectPortsToBroadcastWire()") == 0) {
2759 ConnectPortsToBroadcastWire();
2760 } else if (strcmp(name, "ImportMultipageTextFile()") == 0) {
2761 ImportMultipageTextFile();
2762 } else if (strcmp(name, "SetMarginsForImportMultipageTextFile()") == 0) {
2763 SetMarginsForImportMultipageTextFile();
2764 } else if (strcmp(name,
2765 "ToggleWordWrapDuringImportMultipageTextFile()") == 0) {
2766 ToggleWordWrapDuringImportMultipageTextFile();
2767 } else if (strcmp(name, "HandleDataInMBuff()") == 0) {
2768 HandleDataInMBuff();
2769 } else if (strcmp(name, "BenchMark()") == 0) {
2770 BenchMark();
2771 } else if (strcmp(name, "ConvertToBezier()") == 0) {
2772 ConvertToBezier();
2773 } else if (strcmp(name, "SetBezierConvertNumSegs()") == 0) {
2774 SetBezierConvertNumSegs((args==NULL || *args=='\0') ? NULL : args);
2775 } else if (strcmp(name, "AddSquareTickMarks()") == 0) {
2776 AddTickMarks(CMDID_ADDSQUARETICKMARKS);
2777 } else if (strcmp(name, "AddTriangleTickMarks()") == 0) {
2778 AddTickMarks(CMDID_ADDTRIANGLETICKMARKS);
2779 } else if (strcmp(name, "AddCircleTickMarks()") == 0) {
2780 AddTickMarks(CMDID_ADDCIRCLETICKMARKS);
2781 } else if (strcmp(name, "AddXTickMarks()") == 0) {
2782 AddTickMarks(CMDID_ADDXTICKMARKS);
2783 } else if (strcmp(name, "AddDiamondTickMarks()") == 0) {
2784 AddTickMarks(CMDID_ADDDIAMONDTICKMARKS);
2785 } else if (strcmp(name, "AddBowtieTickMarks()") == 0) {
2786 AddTickMarks(CMDID_ADDBOWTIETICKMARKS);
2787 } else if (strcmp(name, "AddInvTriangleTickMarks()") == 0) {
2788 AddTickMarks(CMDID_ADDINVTRIANGLETICKMARKS);
2789 } else if (strcmp(name, "AddPlusTickMarks()") == 0) {
2790 AddTickMarks(CMDID_ADDPLUSTICKMARKS);
2791 } else if (strcmp(name, "AddHourGlassTickMarks()") == 0) {
2792 AddTickMarks(CMDID_ADDHOURGLASSTICKMARKS);
2793 } else if (strcmp(name, "SetTickMarkSize()") == 0) {
2794 SetTickMarkSize((args==NULL || *args=='\0') ? NULL : args);
2795 } else if (strcmp(name, "ToggleShowChat()") == 0) {
2796 ToggleShowChat();
2797 } else if (strcmp(name, "SavePagesAs()") == 0) {
2798 SavePagesAs();
2799 } else if (strcmp(name, "AddPageBeforeCopyAll()") == 0) {
2800 AddPageBeforeCopyAll();
2801 } else if (strcmp(name, "AddPageAfterCopyAll()") == 0) {
2802 AddPageAfterCopyAll();
2803 } else if (strcmp(name, "InsertHexOctalChar()") == 0) {
2804 InsertHexOctalChar();
2805 } else if (strcmp(name, "ResetInputMethod()") == 0) {
2806 ResetInputMethod();
2807 } else if (strcmp(name, "LinkExtJPEGFile()") == 0) {
2808 ImportJPEGFile(FALSE, NULL);
2809 } else if (strcmp(name, "NextSlide()") == 0) {
2810 NextSlide();
2811 } else if (strcmp(name, "PrevSlide()") == 0) {
2812 PrevSlide();
2813 } else if (strcmp(name, "SetObjectShadowColor()") == 0) {
2814 SetObjectShadowColor();
2815 } else if (strcmp(name, "SetObjectShadowOffsets()") == 0) {
2816 SetObjectShadowOffsets();
2817 } else if (strcmp(name, "AddObjectShadow()") == 0) {
2818 AddObjectShadow();
2819 } else if (strcmp(name, "RemoveObjectShadow()") == 0) {
2820 RemoveObjectShadow();
2821 } else if (strcmp(name, "CopyDoubleByteString()") == 0) {
2822 CopyDoubleByteString();
2823 } else if (strcmp(name, "PasteDoubleByteString()") == 0) {
2824 PasteDoubleByteString();
2825 } else if (strcmp(name, "ReduceToMobileWebSafeColors()") == 0) {
2826 ReduceToMobileWebSafeColors();
2827 } else if (strcmp(name, "CreatePixmapFromSelected()") == 0) {
2828 CreatePixmapFromSelected();
2829 } else if (strcmp(name, "ToggleAutoRotatePivot()") == 0) {
2830 ToggleAutoRotatePivot();
2831 } else if (strcmp(name, "SpecifyRotatePivot()") == 0) {
2832 SpecifyRotatePivot();
2833 } else if (strcmp(name, "ResetRotatePivot()") == 0) {
2834 ResetRotatePivot();
2835 } else if (strcmp(name, "NextPolyRotationPivot()") == 0) {
2836 NextPolyRotationPivot();
2837 } else if (strcmp(name, "MoveRotationPivotToArcCenter()") == 0) {
2838 MoveRotationPivotToArcCenter();
2839 } else if (strcmp(name, "MoveRotatePivotCenter()") == 0) {
2840 MoveRotatePivot(CORNER_NONE);
2841 } else if (strcmp(name, "MoveRotatePivotLeftTop()") == 0) {
2842 MoveRotatePivot(CORNER_LT);
2843 } else if (strcmp(name, "MoveRotatePivotRightTop()") == 0) {
2844 MoveRotatePivot(CORNER_RT);
2845 } else if (strcmp(name, "MoveRotatePivotLeftBottom()") == 0) {
2846 MoveRotatePivot(CORNER_LB);
2847 } else if (strcmp(name, "MoveRotatePivotRightBottom()") == 0) {
2848 MoveRotatePivot(CORNER_RB);
2849 } else if (strcmp(name, "MoveRotatePivotLeft()") == 0) {
2850 MoveRotatePivot(CORNER_LEFT);
2851 } else if (strcmp(name, "MoveRotatePivotRight()") == 0) {
2852 MoveRotatePivot(CORNER_RIGHT);
2853 } else if (strcmp(name, "MoveRotatePivotTop()") == 0) {
2854 MoveRotatePivot(CORNER_TOP);
2855 } else if (strcmp(name, "MoveRotatePivotBottom()") == 0) {
2856 MoveRotatePivot(CORNER_BOTTOM);
2857 } else if (strcmp(name, "ChooseRotatePivot()") == 0) {
2858 if (args != NULL) {
2859 AutoRotatePivotSubMenu(atoi(args));
2860 }
2861 } else if (strcmp(name, "ChooseColor()") == 0) {
2862 ChooseColor();
2863 } else if (strcmp(name, "ExtendSegment()") == 0) {
2864 ExtendSegment();
2865 } else if (strcmp(name, "InsertSymbol()") == 0) {
2866 InsertSymbol();
2867 } else if (strcmp(name, "ToggleRightMargin()") == 0) {
2868 ToggleRightMargin();
2869 } else if (strcmp(name, "SpecifyRightMargin()") == 0) {
2870 SpecifyRightMargin();
2871 } else if (strcmp(name, "ToggleFloodReplaceColorThreshold()") == 0) {
2872 ToggleFloodReplaceColorThreshold();
2873 } else if (strcmp(name, "SetFloodReplaceColorThreshold()") == 0) {
2874 SetFloodReplaceColorThreshold();
2875 } else if (strcmp(name, "RemoveTransparentPixel()") == 0) {
2876 RemoveTransparentPixel();
2877 } else if (strcmp(name, "ReplaceColorWithTrans()") == 0) {
2878 ReplaceColorWithTrans();
2879 #ifdef NOT_DEFINED
2880 } else if (strcmp(name, "ToggleTighterStructuredSplines()") == 0) {
2881 ToggleTighterStructuredSplines();
2882 #endif /* NOT_DEFINED */
2883 } else if (strcmp(name, "MakeBoxObjFromBoundingBox()") == 0) {
2884 MakeBoxObjFromBoundingBox();
2885 } else if (strcmp(name, "MakeRCBoxObjFromBoundingBox()") == 0) {
2886 MakeRCBoxObjFromBoundingBox();
2887 } else if (strcmp(name, "MakeOvalObjFromBoundingBox()") == 0) {
2888 MakeOvalObjFromBoundingBox();
2889 }
2890 }
2891 return BAD;
2892 }
2893
ShortHand(input)2894 int ShortHand(input)
2895 XEvent *input;
2896 /*
2897 * returns BAD if the character is a <CONTROL> or a <META> character
2898 * this will cause the event to be swollowed
2899 * returns INVALID if the character is a normal character, this means
2900 * that the event it not processed and will be handled by a
2901 * routine later
2902 * otherwise, returns the value of sub-functions, such as QuitProc()
2903 */
2904 {
2905 register int i;
2906 char buf[80], *name=NULL, args[MAXSTRING+1];
2907 int valid_shortcut=FALSE, have_ch;
2908 KeySym key_sym=(KeySym)0;
2909 XKeyEvent *key_ev;
2910
2911 key_ev = (&(input->xkey));
2912 have_ch = XLookupString(key_ev, buf, sizeof(buf), &key_sym, &c_stat);
2913 TranslateKeys(buf, &key_sym);
2914
2915 *args = '\0';
2916
2917 if (key_ev->window == drawWindow && CharIsCntrlINS(key_ev, key_sym)) {
2918 CopyToCutBuffer();
2919 return BAD;
2920 } else if (key_ev->window == drawWindow && CharIsShiftINS(key_ev, key_sym)) {
2921 PasteFromCutBuffer();
2922 return BAD;
2923 } else if (key_sym >= '\040' && (key_ev->state & (ControlMask | METAMASK))) {
2924 valid_shortcut = TRUE;
2925 } else if (key_sym >= XK_F1 && key_sym <= XK_F12) {
2926 char code='\0';
2927 unsigned int state=0;
2928
2929 valid_shortcut = FetchFuncKeyShortCut((int)(key_sym), &code, &state,
2930 &name, args, sizeof(args));
2931 if (valid_shortcut) {
2932 key_sym = code;
2933 key_ev->state = state;
2934 }
2935 } else if (((key_sym>'\040' && key_sym<='\177') ||
2936 (key_sym>0xa0 && key_sym<=0xff)) &&
2937 !(key_ev->state & (ControlMask | METAMASK)) &&
2938 curChoice != DRAWTEXT && !TidgetHasFocus()) {
2939 char code='\0';
2940 unsigned int state=0;
2941
2942 for (i = 0; i < numExtraWins; i++) {
2943 if (key_ev->window == extraWinInfo[i].window &&
2944 extraWinInfo[i].window != None) {
2945 break;
2946 }
2947 }
2948 if (i == numExtraWins) {
2949 valid_shortcut = FetchShortCut((int)(key_sym&0xff),
2950 &code, &state, &name, args, sizeof(args));
2951 if (valid_shortcut) {
2952 key_sym = code;
2953 key_ev->state = state;
2954 }
2955 }
2956 }
2957 if (valid_shortcut) {
2958 int rc=0;
2959 int try_x_lookup_keysym=FALSE;
2960
2961 Msg("");
2962 #ifndef _NO_XLOOKUPKEYSYM
2963 try_x_lookup_keysym = TRUE;
2964 #endif /* ~_NO_XLOOKUPKEYSYM */
2965 rc = DoShortCut(key_ev, name, key_sym, key_ev->state, args);
2966 if (rc == INVALID && try_x_lookup_keysym) {
2967 key_sym = XLookupKeysym(key_ev, 0);
2968
2969 return DoShortCut(key_ev, name, key_sym, key_ev->state, args);
2970 }
2971 return rc;
2972 }
2973 return INVALID;
2974 }
2975
ExecuteCmdById(nCmdId,nIndex)2976 int ExecuteCmdById(nCmdId, nIndex)
2977 int nCmdId, nIndex;
2978 {
2979 char *name=NULL, args[MAXSTRING+1], code='\0';
2980 unsigned int state;
2981 KeySym key_sym=(KeySym)0;
2982 XKeyEvent key_ev;
2983
2984 *args = '\0';
2985 if (FetchCmdById(nCmdId, &code, &state, &name, args)) {
2986 if (*args == '\0') sprintf(args, "%d", nIndex);
2987 key_sym = code;
2988 key_ev.state = state;
2989 Msg("");
2990 return DoShortCut(&key_ev, name, key_sym, key_ev.state, args);
2991 } else if (cmdLineTgrm2 && ValidTangram2CmdId(nCmdId)) {
2992 return DoTangram2Cmd(nCmdId, NULL);
2993 }
2994 return INVALID;
2995 }
2996
CallShortCut(name,argc,argv,code,state)2997 int CallShortCut(name, argc, argv, code, state)
2998 char *name, *argv[], *code;
2999 int argc;
3000 unsigned int state;
3001 {
3002 /* do not translate -- program constants */
3003 if (UtilStrICmp(name, "ZoomInAtCursor") == 0 ||
3004 UtilStrICmp(name, "CenterAtCursor") == 0) {
3005 return FALSE;
3006 }
3007 DoShortCut(NULL, name, (KeySym)(*code), state, (argc<=1 ? NULL : argv[1]));
3008 return TRUE;
3009 }
3010
SomethingDirty()3011 int SomethingDirty()
3012 {
3013 register struct ObjRec *obj_ptr=topObj;
3014
3015 for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->next) {
3016 if (obj_ptr->dirty) {
3017 return TRUE;
3018 }
3019 }
3020 return FALSE;
3021 }
3022
3023 static char gszEditorCmd[MAXSTRING];
3024
3025 static char gszDefEditorCmd[]="xterm -title '%s' -e vi '%s'";
3026
3027 static
InitEditor()3028 void InitEditor()
3029 {
3030 static int stInitialized=FALSE;
3031
3032 if (!stInitialized) {
3033 int count=0;
3034 char *psz=NULL;
3035
3036 strcpy(gszEditorCmd, gszDefEditorCmd);
3037 if ((psz=XGetDefault(mainDisplay, TOOL_NAME, "Editor")) != NULL) {
3038 UtilStrCpyN(gszEditorCmd, sizeof(gszEditorCmd), psz);
3039 }
3040 UtilTrimBlanks(gszEditorCmd);
3041 for(psz=strstr(gszEditorCmd,"%s"); psz != NULL; psz=strstr(++psz,"%s")) {
3042 count++;
3043 }
3044 if (count != 2) {
3045 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
3046 TOOL_NAME, "Editor", gszEditorCmd, gszDefEditorCmd);
3047 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3048 strcpy(gszEditorCmd, gszDefEditorCmd);
3049 }
3050 stInitialized = TRUE;
3051 }
3052 }
3053
3054 typedef struct tagTmpFileRec {
3055 char tmp_fname[MAXPATHLENGTH];
3056 struct stat stat_buf;
3057 } TmpFileInfo;
3058
3059 static
WriteAttrToTmp(attr_ptr,ptfi)3060 int WriteAttrToTmp(attr_ptr, ptfi)
3061 struct AttrRec *attr_ptr;
3062 TmpFileInfo *ptfi;
3063 {
3064 FILE *fp=NULL;
3065
3066 if (MkTempFile(ptfi->tmp_fname, sizeof(ptfi->tmp_fname), tmpDir,
3067 TOOL_NAME) == NULL) {
3068 return FALSE;
3069 }
3070 if ((fp=fopen(ptfi->tmp_fname, "w")) == NULL) {
3071 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
3072 ptfi->tmp_fname);
3073 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3074 return FALSE;
3075 }
3076 writeFileFailed = FALSE;
3077 if (*attr_ptr->attr_name.s == '\0') {
3078 DumpMiniLinesInAscii(fp, &attr_ptr->obj->detail.t->minilines, NULL);
3079 } else {
3080 int need_to_free_tmp_buf=FALSE;
3081 MiniLineInfo *pMiniLine=attr_ptr->obj->detail.t->minilines.first;
3082 char *tmp_buf=NULL, *psz=NULL;
3083
3084 tmp_buf = ConvertAttrNameFirstMiniLineToString(attr_ptr,
3085 &need_to_free_tmp_buf);
3086 psz = strchr(tmp_buf, '=');
3087 fprintf(fp, "%s\n", &psz[1]);
3088
3089 for (pMiniLine=pMiniLine->next; pMiniLine != NULL;
3090 pMiniLine=pMiniLine->next) {
3091 DumpMiniLineInAscii(fp, pMiniLine, NULL);
3092 if (fprintf(fp, "\n") == EOF) writeFileFailed = TRUE;
3093 }
3094 if (need_to_free_tmp_buf) UtilFree(tmp_buf);
3095 }
3096 fclose(fp);
3097
3098 if (writeFileFailed) {
3099 FailToWriteFileMessage(ptfi->tmp_fname);
3100 unlink(ptfi->tmp_fname);
3101 return FALSE;
3102 }
3103 if (tmpFileMode != 0 && chmod(ptfi->tmp_fname, tmpFileMode)) {
3104 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_CHMOD), ptfi->tmp_fname);
3105 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3106 unlink(ptfi->tmp_fname);
3107 return FALSE;
3108 }
3109 if (stat(ptfi->tmp_fname, &ptfi->stat_buf) != 0) {
3110 sprintf(gszMsgBox, TgLoadString(STID_STAT_FAIL_EDIT_ATTR_VAL_SAME),
3111 ptfi->tmp_fname);
3112 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3113 unlink(ptfi->tmp_fname);
3114 return FALSE;
3115 }
3116 return TRUE;
3117 }
3118
3119 static
WriteNamedAttrsToTmp(obj_ptr,num_restricted,ppsz_restricted,ptfi,pn_num_exported)3120 int WriteNamedAttrsToTmp(obj_ptr, num_restricted, ppsz_restricted, ptfi,
3121 pn_num_exported)
3122 struct ObjRec *obj_ptr;
3123 int num_restricted, *pn_num_exported;
3124 char **ppsz_restricted;
3125 TmpFileInfo *ptfi;
3126 {
3127 int i=0, num_found=0;
3128 FILE *fp=NULL;
3129
3130 if (MkTempFile(ptfi->tmp_fname, sizeof(ptfi->tmp_fname), tmpDir,
3131 TOOL_NAME) == NULL) {
3132 return FALSE;
3133 }
3134 if ((fp=fopen(ptfi->tmp_fname, "w")) == NULL) {
3135 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
3136 ptfi->tmp_fname);
3137 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3138 return FALSE;
3139 }
3140 sprintf(gszMsgBox, TgLoadCachedString(CSTID_WRITING_ATTR_TO_NAMED_FILE),
3141 ptfi->tmp_fname);
3142 Msg(gszMsgBox);
3143 writeFileFailed = FALSE;
3144
3145 for (i=0; i < num_restricted; i++) {
3146 char *attr_name=ppsz_restricted[i];
3147 struct AttrRec *attr_ptr=FindObjAttrWithName(obj_ptr, attr_name);
3148
3149 if (attr_ptr == NULL) {
3150 sprintf(gszMsgBox, TgLoadCachedString(CSTID_CANT_FIND_NAMED_ATTR),
3151 attr_name);
3152 Msg(gszMsgBox);
3153 } else {
3154 if (*attr_ptr->attr_name.s == '\0') {
3155 DumpMiniLinesInAscii(fp, &attr_ptr->obj->detail.t->minilines, NULL);
3156 } else {
3157 int need_to_free_tmp_buf=FALSE;
3158 MiniLineInfo *pMiniLine=attr_ptr->obj->detail.t->minilines.first;
3159 char *tmp_buf=NULL;
3160
3161 num_found++;
3162 tmp_buf = ConvertAttrNameFirstMiniLineToString(attr_ptr,
3163 &need_to_free_tmp_buf);
3164 fprintf(fp, "%s\n", tmp_buf);
3165
3166 for (pMiniLine=pMiniLine->next; pMiniLine != NULL;
3167 pMiniLine=pMiniLine->next) {
3168 DumpMiniLineInAscii(fp, pMiniLine, NULL);
3169 if (fprintf(fp, "\n") == EOF) writeFileFailed = TRUE;
3170 }
3171 if (need_to_free_tmp_buf) UtilFree(tmp_buf);
3172
3173 if (fprintf(fp, "%s\n", gszAttrSeparator) == EOF) {
3174 writeFileFailed = TRUE;
3175 }
3176 }
3177 }
3178 }
3179 fclose(fp);
3180
3181 if (writeFileFailed) {
3182 FailToWriteFileMessage(ptfi->tmp_fname);
3183 unlink(ptfi->tmp_fname);
3184 return FALSE;
3185 }
3186 if (tmpFileMode != 0 && chmod(ptfi->tmp_fname, tmpFileMode)) {
3187 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_CHMOD), ptfi->tmp_fname);
3188 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3189 unlink(ptfi->tmp_fname);
3190 return FALSE;
3191 }
3192 if (stat(ptfi->tmp_fname, &ptfi->stat_buf) != 0) {
3193 sprintf(gszMsgBox, TgLoadString(STID_STAT_FAIL_EDIT_ATTR_VAL_SAME),
3194 ptfi->tmp_fname);
3195 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3196 unlink(ptfi->tmp_fname);
3197 return FALSE;
3198 }
3199 sprintf(gszMsgBox, TgLoadString(STID_ATTR_EXPORTED_TO_NAMED_FILE),
3200 ptfi->tmp_fname);
3201 Msg(gszMsgBox);
3202
3203 if (pn_num_exported != NULL) *pn_num_exported = num_found;
3204
3205 return TRUE;
3206 }
3207
3208 static
TmpFileChanged(ptfi)3209 int TmpFileChanged(ptfi)
3210 TmpFileInfo *ptfi;
3211 {
3212 struct stat stat_buf;
3213
3214 memset(&stat_buf, 0, sizeof(struct stat));
3215 if (stat(ptfi->tmp_fname, &stat_buf) != 0) {
3216 sprintf(gszMsgBox, TgLoadString(STID_STAT_FAIL_EDIT_ATTR_VAL_SAME),
3217 ptfi->tmp_fname);
3218 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3219 return FALSE;
3220 }
3221 if (stat_buf.st_mtime == ptfi->stat_buf.st_mtime &&
3222 stat_buf.st_size == ptfi->stat_buf.st_size) {
3223 return FALSE;
3224 }
3225 return TRUE;
3226 }
3227
3228 static
ReadAttrFromTmp(attr_ptr,ptfi)3229 int ReadAttrFromTmp(attr_ptr, ptfi)
3230 struct AttrRec *attr_ptr;
3231 TmpFileInfo *ptfi;
3232 {
3233 struct ObjRec *attr_owner_obj=attr_ptr->owner;
3234 FILE *fp=NULL;
3235
3236 if ((fp=fopen(ptfi->tmp_fname, "r")) == NULL) {
3237 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_READING),
3238 ptfi->tmp_fname);
3239 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3240 return FALSE;
3241 }
3242 PrepareToReplaceAnObj(attr_owner_obj);
3243
3244 JustReadFileIntoAttr(fp, attr_ptr, attr_owner_obj);
3245
3246 fclose(fp);
3247
3248 return TRUE;
3249 }
3250
3251 static
ReadNamedAttrsFromTmp(obj_ptr,num_restricted,ppsz_restricted,ptfi)3252 int ReadNamedAttrsFromTmp(obj_ptr, num_restricted, ppsz_restricted, ptfi)
3253 struct ObjRec *obj_ptr;
3254 int num_restricted;
3255 char **ppsz_restricted;
3256 TmpFileInfo *ptfi;
3257 {
3258 FILE *fp=NULL;
3259 int rc=0;
3260
3261 if ((fp=fopen(ptfi->tmp_fname, "r")) == NULL) {
3262 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_READING),
3263 ptfi->tmp_fname);
3264 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3265 return FALSE;
3266 }
3267 rc = ImportNamedAttrs(fp, obj_ptr, num_restricted, ppsz_restricted,
3268 ptfi->tmp_fname);
3269 fclose(fp);
3270
3271 return rc;
3272 }
3273
3274 static
AbortLaunch(pVoid)3275 int AbortLaunch(pVoid)
3276 void *pVoid;
3277 {
3278 if (MsgBox(TgLoadString(STID_CNTRL_C_ABORT_LAUNCH), TOOL_NAME, YNC_MB) ==
3279 MB_ID_YES) {
3280 return TRUE;
3281 }
3282 return FALSE;
3283 }
3284
EditIndexedAttrInEditor(index)3285 void EditIndexedAttrInEditor(index)
3286 int index;
3287 {
3288 int i=0, num_attrs=0, total_attrs=0;
3289 int restricted=FALSE, num_restricted=0, actual_index=0, found=FALSE;
3290 char **attr_strings=NULL, cmd[MAXSTRING<<1], title[MAXSTRING];
3291 char **ppsz_restricted=NULL;
3292 struct AttrRec *attr_ptr=NULL, *restricted_attr=NULL;
3293 FILE *pfp=NULL;
3294 TmpFileInfo tfi;
3295
3296 InitEditor();
3297
3298 if (gpEditAttrInEditorAttrInfo == NULL || topSel == NULL ||
3299 topSel != botSel) {
3300 return;
3301 }
3302 for (attr_ptr=topSel->obj->fattr; attr_ptr != NULL;
3303 attr_ptr=attr_ptr->next, total_attrs++) {
3304 }
3305 attr_ptr = topSel->obj->fattr;
3306
3307 num_attrs = gpEditAttrInEditorAttrInfo->num_attrs;
3308 attr_strings = gpEditAttrInEditorAttrInfo->attr_strings;
3309
3310 if (total_attrs <= 0 || num_attrs <= 0 || attr_strings == NULL) return;
3311
3312 restricted = HasEditAttrsInContextMenu(topSel->obj, &restricted_attr);
3313 if (restricted) {
3314 GetRestrictedAttrNames(restricted_attr->obj, &ppsz_restricted,
3315 &num_restricted);
3316 if (ppsz_restricted == NULL || num_restricted <= 0) {
3317 return;
3318 }
3319 }
3320 for (i=0; i < total_attrs; i++, attr_ptr=attr_ptr->next) {
3321 if (restricted) {
3322 if (!IsRestrictedAttr(attr_ptr->attr_name.s, ppsz_restricted,
3323 num_restricted)) {
3324 continue;
3325 }
3326 }
3327 if (actual_index == index) {
3328 found = TRUE;
3329 break;
3330 }
3331 actual_index++;
3332 }
3333 FreeRestrictedAttrNames(ppsz_restricted, num_restricted);
3334
3335 if (!found) return;
3336
3337 memset(&tfi, 0, sizeof(TmpFileInfo));
3338 if (!WriteAttrToTmp(attr_ptr, &tfi)) return;
3339
3340 SaveStatusStrings();
3341 if (*attr_ptr->attr_name.s == '\0') {
3342 sprintf(title, TgLoadString(STID_EDIT_UNNAME_ATTR_DOTS));
3343 sprintf(cmd, gszEditorCmd, title, tfi.tmp_fname);
3344 sprintf(gszMsgBox, TgLoadString(STID_EDIT_UNNAME_ATTR_WITH_CMD), cmd);
3345 } else {
3346 sprintf(title, TgLoadString(STID_EDIT_VAL_OF_ATTR_DOTS),
3347 attr_ptr->attr_name.s);
3348 sprintf(cmd, gszEditorCmd, title, tfi.tmp_fname);
3349 sprintf(gszMsgBox, TgLoadString(STID_EDIT_VAL_OF_ATTR_WITH_CMD),
3350 attr_ptr->attr_name.s, cmd);
3351 }
3352 if (!FindProgramInPath(cmd, NULL, FALSE)) {
3353 RestoreStatusStrings();
3354 unlink(tfi.tmp_fname);
3355 return;
3356 }
3357 ShowInterrupt(DEF_CHECK_INTERVAL);
3358 SetStringStatus(gszMsgBox);
3359
3360 EndMeasureTooltip(FALSE);
3361 if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
3362 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), cmd);
3363 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3364 } else {
3365 int quit=FALSE, got_eof=FALSE, fd=fileno(pfp);
3366
3367 Msg(TgLoadCachedString(CSTID_CNTRL_C_TO_INTR_AND_ABEND));
3368 SetSocketBlockingState(&fd, FALSE);
3369
3370 /*
3371 * Note: Calling WaitForEvent() with the second argument being
3372 * TRUE can lose data in the pipe. Can do this here
3373 * because the data in the pipe is ignored.
3374 */
3375 while (WaitForEvent(pfp, TRUE, FALSE, &quit, EXPOSE_AND_ESC_X_EV_ONLY,
3376 AbortLaunch, NULL)) {
3377 if (quit) {
3378 break;
3379 } else if (PipeReachedEOF(pfp)) {
3380 got_eof = TRUE;
3381 break;
3382 }
3383 }
3384 if (quit && !got_eof) {
3385 sprintf(gszMsgBox,
3386 TgLoadString(STID_CMD_ABORT_LAUNCH_CLOSE_TOOL), cmd, TOOL_NAME);
3387 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3388 } else {
3389 pclose(pfp);
3390 }
3391 }
3392 RestoreStatusStrings();
3393 HideInterrupt();
3394
3395 if (TmpFileChanged(&tfi)) {
3396 HighLightReverse();
3397 if (ReadAttrFromTmp(attr_ptr, &tfi)) {
3398 SetFileModified(TRUE);
3399 }
3400 HighLightForward();
3401 }
3402 unlink(tfi.tmp_fname);
3403 }
3404
EditIndexedAttrGroupInEditor(index)3405 void EditIndexedAttrGroupInEditor(index)
3406 int index;
3407 {
3408 int num_attrs_in_attr_group=0, total_attrs_in_obj=0;
3409 int num_restricted=0, num_exported=0, done=FALSE;
3410 char **attr_name_array=NULL, cmd[MAXSTRING<<1], title[MAXSTRING];
3411 char **ppsz_restricted=NULL;
3412 struct AttrRec *attr_ptr=NULL;
3413 FILE *pfp=NULL;
3414 TmpFileInfo tfi;
3415
3416 InitEditor();
3417
3418 if (gpEditAttrInEditorAttrInfo == NULL || topSel == NULL ||
3419 topSel != botSel || index >= maxAttrGroups) {
3420 return;
3421 }
3422 for (attr_ptr=topSel->obj->fattr; attr_ptr != NULL;
3423 attr_ptr=attr_ptr->next, total_attrs_in_obj++) {
3424 }
3425 attr_ptr = topSel->obj->fattr;
3426
3427 num_attrs_in_attr_group = gAttrGroupInfo[index]->num_attrs;
3428 attr_name_array = gAttrGroupInfo[index]->attr_name;
3429
3430 if (total_attrs_in_obj <= 0 || num_attrs_in_attr_group <= 0 ||
3431 attr_name_array == NULL) {
3432 return;
3433 }
3434 /*
3435 * For this function, we do not need to call HasEditAttrsInContextMenu()
3436 * because the "edit_attrs_in_context_menu=" attribute is only for the
3437 * "Edit Attribute In Editor" submenu and *not* for the
3438 * "Edit Attribute Group In Editor" submenu.
3439 * We just pretend that the "edit_attrs_in_context_menu=" attribute is
3440 * there so we can reuse the code.
3441 */
3442 GetAttrGroupAttrNames(topSel->obj, index, &ppsz_restricted, &num_restricted);
3443 if (ppsz_restricted == NULL || num_restricted <= 0) {
3444 return;
3445 }
3446 memset(&tfi, 0, sizeof(TmpFileInfo));
3447 if (!WriteNamedAttrsToTmp(topSel->obj, num_restricted, ppsz_restricted,
3448 &tfi, &num_exported)) {
3449 FreeRestrictedAttrNames(ppsz_restricted, num_restricted);
3450 return;
3451 }
3452 if (num_restricted != num_exported) {
3453 sprintf(gszMsgBox, TgLoadString(STID_WARN_CANNOT_FIND_SOME_ATTRS),
3454 gAttrGroupInfo[index]->displayed_names);
3455 if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) != MB_ID_YES) {
3456 FreeRestrictedAttrNames(ppsz_restricted, num_restricted);
3457 unlink(tfi.tmp_fname);
3458 return;
3459 }
3460 }
3461 SaveStatusStrings();
3462 if (*attr_ptr->attr_name.s == '\0') {
3463 sprintf(title, TgLoadString(STID_EDIT_UNNAME_ATTR_DOTS));
3464 sprintf(cmd, gszEditorCmd, title, tfi.tmp_fname);
3465 sprintf(gszMsgBox, TgLoadString(STID_EDIT_UNNAME_ATTR_WITH_CMD), cmd);
3466 } else {
3467 sprintf(title, TgLoadString(STID_EDIT_VAL_OF_ATTR_DOTS),
3468 attr_ptr->attr_name.s);
3469 sprintf(cmd, gszEditorCmd, title, tfi.tmp_fname);
3470 sprintf(gszMsgBox, TgLoadString(STID_EDIT_VAL_OF_ATTR_WITH_CMD),
3471 attr_ptr->attr_name.s, cmd);
3472 }
3473 if (!FindProgramInPath(cmd, NULL, FALSE)) {
3474 RestoreStatusStrings();
3475 unlink(tfi.tmp_fname);
3476 return;
3477 }
3478 while (!done) {
3479 ShowInterrupt(DEF_CHECK_INTERVAL);
3480 SetStringStatus(gszMsgBox);
3481
3482 EndMeasureTooltip(FALSE);
3483 if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
3484 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), cmd);
3485 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3486 } else {
3487 int quit=FALSE, got_eof=FALSE, fd=fileno(pfp);
3488
3489 Msg(TgLoadCachedString(CSTID_CNTRL_C_TO_INTR_AND_ABEND));
3490 SetSocketBlockingState(&fd, FALSE);
3491
3492 /*
3493 * Note: Calling WaitForEvent() with the second argument being
3494 * TRUE can lose data in the pipe. Can do this here
3495 * because the data in the pipe is ignored.
3496 */
3497 while (WaitForEvent(pfp, TRUE, FALSE, &quit, EXPOSE_AND_ESC_X_EV_ONLY,
3498 AbortLaunch, NULL)) {
3499 if (quit) {
3500 break;
3501 } else if (PipeReachedEOF(pfp)) {
3502 got_eof = TRUE;
3503 break;
3504 }
3505 }
3506 if (quit && !got_eof) {
3507 sprintf(gszMsgBox,
3508 TgLoadString(STID_CMD_ABORT_LAUNCH_CLOSE_TOOL), cmd,
3509 TOOL_NAME);
3510 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3511 } else {
3512 pclose(pfp);
3513 }
3514 }
3515 RestoreStatusStrings();
3516 HideInterrupt();
3517
3518 if (TmpFileChanged(&tfi)) {
3519 HighLightReverse();
3520 if (ReadNamedAttrsFromTmp(topSel->obj, num_restricted, ppsz_restricted,
3521 &tfi)) {
3522 done = TRUE;
3523 } else {
3524 /* get the file modified */
3525 if (stat(tfi.tmp_fname, &tfi.stat_buf) != 0) {
3526 sprintf(gszMsgBox,
3527 TgLoadString(STID_STAT_FAIL_EDIT_ATTR_VAL_SAME),
3528 tfi.tmp_fname);
3529 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3530 unlink(tfi.tmp_fname);
3531 done = TRUE;
3532 }
3533 }
3534 HighLightForward();
3535 } else {
3536 done = TRUE;
3537 }
3538 }
3539 unlink(tfi.tmp_fname);
3540 }
3541
CreateEditAttrInEditorMenu(parent_menu,X,Y,menu_info,status_str_xlated)3542 TgMenu *CreateEditAttrInEditorMenu(parent_menu, X, Y, menu_info,
3543 status_str_xlated)
3544 TgMenu *parent_menu;
3545 int X, Y;
3546 TgMenuInfo *menu_info;
3547 int status_str_xlated; /* ignored, always 0 */
3548 {
3549 TgMenu *menu=NULL;
3550
3551 if (topSel == NULL || topSel != botSel) return NULL;
3552
3553 FreeEditAttrInfo(gpEditAttrInEditorAttrInfo);
3554 gpEditAttrInEditorAttrInfo = NULL;
3555
3556 gpEditAttrInEditorAttrInfo = CreateEditAttrInfo(topSel->obj);
3557
3558 if (gpEditAttrInEditorAttrInfo == NULL) return NULL;
3559
3560 menu = CreateAttrMenu(parent_menu, X, Y,
3561 gpEditAttrInEditorAttrInfo->num_attrs,
3562 gpEditAttrInEditorAttrInfo->attr_strings,
3563 gpEditAttrInEditorAttrInfo->status_strings,
3564 gpEditAttrInEditorAttrInfo->fore_colors);
3565 if (menu != NULL) {
3566 int i=0, num_items=menu->num_items;
3567 TgMenuItem *menuitems=menu->menuitems;
3568
3569 for (i=0; i < num_items; i++) {
3570 menuitems[i].cmdid = CMDID_EDITATTRINEDITOR;
3571 }
3572 }
3573 return menu;
3574 }
3575
CreateEditAttrGroupInEditorMenu(parent_menu,X,Y,menu_info,status_str_xlated)3576 TgMenu *CreateEditAttrGroupInEditorMenu(parent_menu, X, Y, menu_info,
3577 status_str_xlated)
3578 TgMenu *parent_menu;
3579 int X, Y;
3580 TgMenuInfo *menu_info;
3581 int status_str_xlated; /* ignored, always 0 */
3582 {
3583 TgMenu *menu=NULL;
3584
3585 if (topSel == NULL || topSel != botSel) return NULL;
3586
3587 FreeEditAttrInfo(gpEditAttrInEditorAttrInfo);
3588 gpEditAttrInEditorAttrInfo = NULL;
3589
3590 gpEditAttrInEditorAttrInfo = CreateEditAttrGroupInfo(topSel->obj);
3591
3592 if (gpEditAttrInEditorAttrInfo == NULL) return NULL;
3593
3594 menu = CreateAttrMenu(parent_menu, X, Y,
3595 gpEditAttrInEditorAttrInfo->num_attrs,
3596 gpEditAttrInEditorAttrInfo->attr_strings,
3597 gpEditAttrInEditorAttrInfo->status_strings,
3598 gpEditAttrInEditorAttrInfo->fore_colors);
3599 if (menu != NULL) {
3600 int i=0, num_items=menu->num_items;
3601 TgMenuItem *menuitems=menu->menuitems;
3602
3603 for (i=0; i < num_items; i++) {
3604 menuitems[i].cmdid = CMDID_EDITATTRGROUPINEDITOR;
3605 }
3606 }
3607 return menu;
3608 }
3609
GetProperty(index)3610 void GetProperty(index)
3611 int index;
3612 {
3613 DoGetProperty(index);
3614 }
3615
CreateGetPropertyMenu(parent_menu,X,Y,menu_info,status_str_xlated)3616 TgMenu *CreateGetPropertyMenu(parent_menu, X, Y, menu_info,
3617 status_str_xlated)
3618 TgMenu *parent_menu;
3619 int X, Y;
3620 TgMenuInfo *menu_info;
3621 int status_str_xlated; /* ignored, always 0 */
3622 {
3623 TgMenu *menu=NULL;
3624
3625 if (topSel == NULL || topSel != botSel) return NULL;
3626
3627 FreeEditAttrInfo(gpEditAttrInEditorAttrInfo);
3628 gpEditAttrInEditorAttrInfo = NULL;
3629
3630 gpEditAttrInEditorAttrInfo = CreateGetPropertyInfo();
3631
3632 if (gpEditAttrInEditorAttrInfo == NULL) return NULL;
3633
3634 menu = CreateAttrMenu(parent_menu, X, Y,
3635 gpEditAttrInEditorAttrInfo->num_attrs,
3636 gpEditAttrInEditorAttrInfo->attr_strings,
3637 gpEditAttrInEditorAttrInfo->status_strings,
3638 gpEditAttrInEditorAttrInfo->fore_colors);
3639 if (menu != NULL) {
3640 int i=0, num_items=menu->num_items;
3641 TgMenuItem *menuitems=menu->menuitems;
3642
3643 for (i=0; i < num_items; i++) {
3644 menuitems[i].cmdid = CMDID_GETPROPERTY;
3645 }
3646 }
3647 return menu;
3648 }
3649
3650 /* --------------------- PeekDimension stuff --------------------- */
3651
3652 static
SetPeekStrings(attr_strings,status_strings,i,menu_text,status_text)3653 void SetPeekStrings(attr_strings, status_strings, i, menu_text, status_text)
3654 char **attr_strings, **status_strings;
3655 int i;
3656 char *menu_text, *status_text;
3657 {
3658 attr_strings[i] = UtilStrDup(menu_text);
3659 status_strings[i] = UtilStrDup(status_text);
3660 if (attr_strings[i] == NULL || status_strings[i] == NULL) FailAllocMessage();
3661 }
3662
3663 static
CanGetArea(obj_ptr)3664 int CanGetArea(obj_ptr)
3665 struct ObjRec *obj_ptr;
3666 {
3667 int type=obj_ptr->type;
3668
3669 if (type == OBJ_GROUP || type == OBJ_SYM || type == OBJ_ICON ||
3670 type == OBJ_PIN) {
3671 if (obj_ptr->detail.r->first == obj_ptr->detail.r->last) {
3672 return CanGetArea(obj_ptr->detail.r->first);
3673 }
3674 return FALSE;
3675 }
3676 return (type == OBJ_BOX || type == OBJ_POLYGON);
3677 }
3678
3679 static
GetPolygonArea(polygon_ptr)3680 double GetPolygonArea(polygon_ptr)
3681 struct PolygonRec *polygon_ptr;
3682 {
3683 int i=0, n=0, curved=polygon_ptr->curved;
3684 int num_smooth_points=0, num_hinge_points=0;
3685 double area=(double)0;
3686 IntPoint *vs=NULL;
3687 char *smooth=NULL;
3688
3689 if (curved == LT_STRUCT_SPLINE) {
3690 n = polygon_ptr->ssn;
3691 vs = polygon_ptr->ssvlist;
3692 smooth = polygon_ptr->ssmooth;
3693 } else {
3694 n = polygon_ptr->n;
3695 vs = polygon_ptr->vlist;
3696 smooth = polygon_ptr->smooth;
3697 }
3698 switch (curved) {
3699 case LT_STRAIGHT:
3700 case LT_SPLINE:
3701 case LT_STRUCT_SPLINE:
3702 for (i=1; i < n; i++) {
3703 if (smooth[i]) {
3704 num_smooth_points++;
3705 } else {
3706 num_hinge_points++;
3707 }
3708 }
3709 if (num_smooth_points == 0) {
3710 for (i=0; i < n-1; i++) {
3711 area += (double)(((double)vs[i].x) * ((double)vs[i+1].y) -
3712 ((double)vs[i+1].x) * ((double)vs[i].y));
3713 }
3714 area = area / ((double)2);
3715 } else {
3716 /* don't know how to calculate with smooth points */
3717 }
3718 break;
3719 case LT_INTSPLINE:
3720 /* don't know how to calculate with smooth points */
3721 break;
3722 }
3723 for (i=0; i < n-1; i++) {
3724 area += (double)(((double)vs[i].x) * ((double)vs[i+1].y) -
3725 ((double)vs[i+1].x) * ((double)vs[i].y));
3726 }
3727 area = area / ((double)2);
3728
3729 return area;
3730 }
3731
3732 static
GetArea(obj_ptr)3733 double GetArea(obj_ptr)
3734 struct ObjRec *obj_ptr;
3735 {
3736 int type=obj_ptr->type, w=0, h=0;
3737 double area=(double)0, scale_x=(double)0, scale_y=(double)0;
3738
3739 if (type == OBJ_GROUP || type == OBJ_SYM || type == OBJ_ICON ||
3740 type == OBJ_PIN) {
3741 if (obj_ptr->detail.r->first == obj_ptr->detail.r->last) {
3742 return GetArea(obj_ptr->detail.r->first);
3743 }
3744 }
3745 switch (type) {
3746 case OBJ_BOX:
3747 if (obj_ptr->ctm == NULL) {
3748 w = obj_ptr->obbox.rbx-obj_ptr->obbox.ltx;
3749 h = obj_ptr->obbox.rby-obj_ptr->obbox.lty;
3750 area = (double)(((double)w)*((double)h));
3751 } else {
3752 w = obj_ptr->orig_obbox.rbx-obj_ptr->orig_obbox.ltx;
3753 h = obj_ptr->orig_obbox.rby-obj_ptr->orig_obbox.lty;
3754 area = (double)(((double)w)*((double)h));
3755 scale_x = (double) (((double)fabs(obj_ptr->ctm->m[CTM_SX])) /
3756 ((double)1000));
3757 scale_y = (double) (((double)fabs(obj_ptr->ctm->m[CTM_SY])) /
3758 ((double)1000));
3759 area = area * scale_x * scale_y;
3760 }
3761 break;
3762 case OBJ_POLYGON:
3763 area = GetPolygonArea(obj_ptr->detail.g);
3764 if (obj_ptr->ctm != NULL) {
3765 scale_x = (double) (((double)fabs(obj_ptr->ctm->m[CTM_SX])) /
3766 ((double)1000));
3767 scale_y = (double) (((double)fabs(obj_ptr->ctm->m[CTM_SY])) /
3768 ((double)1000));
3769 area = area * scale_x * scale_y;
3770 }
3771 break;
3772 }
3773 return area;
3774 }
3775
3776
3777 static
CreatePeekDimensionInfo()3778 EditAttrInfo *CreatePeekDimensionInfo()
3779 {
3780 EditAttrInfo *pEditAttrInfo=NULL;
3781 char **attr_strings=NULL, **status_strings=NULL;
3782 char menu_text[MAXSTRING], status_text[MAXSTRING];
3783 char buf[MAXSTRING], buf1[MAXSTRING], *psz=NULL, *psz1=NULL;
3784 int num_attrs=10, can_get_area=FALSE;
3785 struct ObjRec *obj_ptr=NULL;
3786
3787 if (topSel == NULL) return NULL;
3788
3789 obj_ptr = topSel->obj;
3790
3791 can_get_area = CanGetArea(obj_ptr);
3792 if (can_get_area) {
3793 num_attrs += 2;
3794 }
3795 pEditAttrInfo = (EditAttrInfo*)malloc(sizeof(EditAttrInfo));
3796 if (pEditAttrInfo == NULL) FailAllocMessage();
3797 memset(pEditAttrInfo, 0, sizeof(EditAttrInfo));
3798
3799 attr_strings = (char**)malloc(num_attrs*sizeof(char*));
3800 status_strings = (char**)malloc(num_attrs*sizeof(char*));
3801 if (attr_strings == NULL || status_strings == NULL) FailAllocMessage();
3802 memset(attr_strings, 0, num_attrs*sizeof(char*));
3803 memset(status_strings, 0, num_attrs*sizeof(char*));
3804
3805 PixelToMeasurementUnit(buf, obj_ptr->obbox.rbx-obj_ptr->obbox.ltx);
3806 PixelToMeasurementUnit(buf1, obj_ptr->bbox.rbx-obj_ptr->bbox.ltx);
3807 psz = ((*buf) == '+' ? &buf[1] : buf);
3808 psz1 = ((*buf1) == '+' ? &buf1[1] : buf1);
3809 /* do not translate -- program constants */
3810 sprintf(menu_text, "width = %s (outer width = %s)", psz, psz1);
3811 strcpy(status_text, TgLoadString(STID_PEEK_DIM_WIDTH));
3812 SetPeekStrings(attr_strings, status_strings, 0, menu_text, status_text);
3813
3814 PixelToMeasurementUnit(buf, obj_ptr->obbox.rby-obj_ptr->obbox.lty);
3815 PixelToMeasurementUnit(buf1, obj_ptr->bbox.rby-obj_ptr->bbox.lty);
3816 psz = ((*buf) == '+' ? &buf[1] : buf);
3817 psz1 = ((*buf1) == '+' ? &buf1[1] : buf1);
3818 /* do not translate -- program constants */
3819 sprintf(menu_text, "height = %s (outer height = %s)", psz, psz1);
3820 strcpy(status_text, TgLoadString(STID_PEEK_DIM_HEIGHT));
3821 SetPeekStrings(attr_strings, status_strings, 1, menu_text, status_text);
3822
3823 attr_strings[2] = TGMUITEM_SEPARATOR;
3824
3825 PixelToMeasurementUnit(buf, obj_ptr->obbox.ltx);
3826 PixelToMeasurementUnit(buf1, obj_ptr->bbox.ltx);
3827 psz = ((*buf) == '+' ? &buf[1] : buf);
3828 psz1 = ((*buf1) == '+' ? &buf1[1] : buf1);
3829 /* do not translate -- program constants */
3830 sprintf(menu_text, "left = %s (outer left = %s)", psz, psz1);
3831 strcpy(status_text, TgLoadString(STID_PEEK_DIM_LEFT));
3832 SetPeekStrings(attr_strings, status_strings, 3, menu_text, status_text);
3833
3834 PixelToMeasurementUnit(buf, obj_ptr->obbox.lty);
3835 PixelToMeasurementUnit(buf1, obj_ptr->bbox.lty);
3836 psz = ((*buf) == '+' ? &buf[1] : buf);
3837 psz1 = ((*buf1) == '+' ? &buf1[1] : buf1);
3838 /* do not translate -- program constants */
3839 sprintf(menu_text, "top = %s (outer top = %s)", psz, psz1);
3840 strcpy(status_text, TgLoadString(STID_PEEK_DIM_TOP));
3841 SetPeekStrings(attr_strings, status_strings, 4, menu_text, status_text);
3842
3843 PixelToMeasurementUnit(buf, obj_ptr->obbox.rbx);
3844 PixelToMeasurementUnit(buf1, obj_ptr->bbox.rbx);
3845 psz = ((*buf) == '+' ? &buf[1] : buf);
3846 psz1 = ((*buf1) == '+' ? &buf1[1] : buf1);
3847 /* do not translate -- program constants */
3848 sprintf(menu_text, "right = %s (outer right = %s)", psz, psz1);
3849 strcpy(status_text, TgLoadString(STID_PEEK_DIM_RIGHT));
3850 SetPeekStrings(attr_strings, status_strings, 5, menu_text, status_text);
3851
3852 PixelToMeasurementUnit(buf, obj_ptr->obbox.rby);
3853 PixelToMeasurementUnit(buf1, obj_ptr->bbox.rby);
3854 psz = ((*buf) == '+' ? &buf[1] : buf);
3855 psz1 = ((*buf1) == '+' ? &buf1[1] : buf1);
3856 /* do not translate -- program constants */
3857 sprintf(menu_text, "bottom = %s (outer bottom = %s)", psz, psz1);
3858 strcpy(status_text, TgLoadString(STID_PEEK_DIM_BOTTOM));
3859 SetPeekStrings(attr_strings, status_strings, 6, menu_text, status_text);
3860
3861 attr_strings[7] = TGMUITEM_SEPARATOR;
3862
3863 PixelToMeasurementUnit(buf, ((obj_ptr->obbox.rbx+obj_ptr->obbox.ltx)>>1));
3864 psz = ((*buf) == '+' ? &buf[1] : buf);
3865 /* do not translate -- program constants */
3866 sprintf(menu_text, "cx = %s", psz);
3867 strcpy(status_text, TgLoadString(STID_PEEK_DIM_CX));
3868 SetPeekStrings(attr_strings, status_strings, 8, menu_text, status_text);
3869
3870 PixelToMeasurementUnit(buf, ((obj_ptr->obbox.rby+obj_ptr->obbox.lty)>>1));
3871 psz = ((*buf) == '+' ? &buf[1] : buf);
3872 /* do not translate -- program constants */
3873 sprintf(menu_text, "cy = %s", psz);
3874 strcpy(status_text, TgLoadString(STID_PEEK_DIM_CY));
3875 SetPeekStrings(attr_strings, status_strings, 9, menu_text, status_text);
3876
3877 if (can_get_area) {
3878 double area=GetArea(obj_ptr);
3879
3880 attr_strings[10] = TGMUITEM_SEPARATOR;
3881
3882 SquarePixelToMeasurementUnit(buf, round(area));
3883 psz = ((*buf) == '+' ? &buf[1] : buf);
3884 /* do not translate -- program constants */
3885 sprintf(menu_text, "area = %s", psz);
3886 strcpy(status_text, TgLoadString(STID_PEEK_AREA));
3887 SetPeekStrings(attr_strings, status_strings, 11, menu_text, status_text);
3888 }
3889 pEditAttrInfo->num_attrs = num_attrs;
3890 pEditAttrInfo->fore_colors = NULL;
3891 pEditAttrInfo->attr_indices = NULL;
3892 pEditAttrInfo->attr_names = NULL;
3893 pEditAttrInfo->attr_values = NULL;
3894 pEditAttrInfo->attr_strings = attr_strings;
3895 pEditAttrInfo->status_strings = status_strings;
3896
3897 return pEditAttrInfo;
3898 }
3899
PeekDimension(index)3900 void PeekDimension(index)
3901 int index;
3902 {
3903 /* There's really nothing to do! */
3904 }
3905
CreatePeekDimensionMenu(parent_menu,X,Y,menu_info,status_str_xlated)3906 TgMenu *CreatePeekDimensionMenu(parent_menu, X, Y, menu_info,
3907 status_str_xlated)
3908 TgMenu *parent_menu;
3909 int X, Y;
3910 TgMenuInfo *menu_info;
3911 int status_str_xlated; /* ignored, always 0 */
3912 {
3913 TgMenu *menu=NULL;
3914
3915 if (topSel == NULL || topSel != botSel) return NULL;
3916
3917 FreeEditAttrInfo(gpEditAttrInEditorAttrInfo);
3918 gpEditAttrInEditorAttrInfo = NULL;
3919
3920 gpEditAttrInEditorAttrInfo = CreatePeekDimensionInfo();
3921
3922 if (gpEditAttrInEditorAttrInfo == NULL) return NULL;
3923
3924 menu = CreateAttrMenu(parent_menu, X, Y,
3925 gpEditAttrInEditorAttrInfo->num_attrs,
3926 gpEditAttrInEditorAttrInfo->attr_strings,
3927 gpEditAttrInEditorAttrInfo->status_strings,
3928 gpEditAttrInEditorAttrInfo->fore_colors);
3929 if (menu != NULL) {
3930 int i=0, num_items=menu->num_items;
3931 TgMenuItem *menuitems=menu->menuitems;
3932
3933 for (i=0; i < num_items; i++) {
3934 menuitems[i].cmdid = CMDID_GETPROPERTY;
3935 }
3936 }
3937 return menu;
3938 }
3939
3940 /* --------------------- RefreshContextMenu() --------------------- */
3941
RefreshContextMenu(menu)3942 int RefreshContextMenu(menu)
3943 TgMenu *menu;
3944 {
3945 int ok=TRUE;
3946
3947 if (topSel == NULL || topSel != botSel) return FALSE;
3948
3949 /* ImageProc submenu */
3950 ok &= TgEnableMenuItemById(menu, MENU_IMAGEPROC, CanPerformImageProc());
3951
3952 /* Edit Attribute In Editor */
3953 ok &= TgEnableMenuItemBySubMenuInfoPtr(menu, &editAttrInEditorMenuInfo,
3954 topSel->obj->fattr != NULL);
3955
3956 /* Edit Attribute Group In Editor */
3957 ok &= TgEnableMenuItemBySubMenuInfoPtr(menu, &editAttrGroupInEditorMenuInfo,
3958 topSel->obj->fattr != NULL && maxAttrGroups > 0);
3959
3960 /* Get Property */
3961 ok &= TgEnableMenuItemBySubMenuInfoPtr(menu, &getPropertyMenuInfo,
3962 !(topSel->obj->type == OBJ_XPM || (topSel->obj->type == OBJ_XBM &&
3963 topSel->obj->detail.xbm->real_type==XBM_EPS)));
3964
3965 /* Get Dimension */
3966 ok &= TgEnableMenuItemBySubMenuInfoPtr(menu, &peekDimensionMenuInfo,
3967 topSel != NULL);
3968
3969 return ok;
3970 }
3971
CreateContextMenu(parent_menu,X,Y,menu_info,status_str_xlated)3972 TgMenu *CreateContextMenu(parent_menu, X, Y, menu_info, status_str_xlated)
3973 TgMenu *parent_menu;
3974 int X, Y;
3975 TgMenuInfo *menu_info;
3976 int status_str_xlated; /* ignored, always 0 */
3977 {
3978 TgMenu *menu=TgCreateMenuFromMenuInfo(parent_menu, X, Y, menu_info, FALSE);
3979
3980 if (menu != NULL) {
3981 if (!RefreshContextMenu(menu)) {
3982 return TgDestroyMenu(menu, TRUE);
3983 }
3984 menu->refresh_proc = ((RefreshMenuFunc*)RefreshContextMenu);
3985 }
3986 return menu;
3987 }
3988
RefreshEditTextContextMenu(menu)3989 int RefreshEditTextContextMenu(menu)
3990 TgMenu *menu;
3991 {
3992 int ok=TRUE;
3993
3994 /* Copy */
3995 ok &= TgEnableMenuItemById(menu, CMDID_COPY, textHighlight);
3996 /* CopyPlainTextAsObject */
3997 ok &= TgEnableMenuItemById(menu, CMDID_COPYPLAINTEXTASOBJECT,
3998 (curChoice == DRAWTEXT && textHighlight));
3999 /* Cut */
4000 ok &= TgEnableMenuItemById(menu, CMDID_CUT, textHighlight);
4001 /* Duplicate */
4002 ok &= TgEnableMenuItemById(menu, CMDID_DUPLICATE, textHighlight);
4003 /* Delete */
4004 ok &= TgEnableMenuItemById(menu, CMDID_DELETE, textHighlight);
4005
4006 return ok;
4007 }
4008
CreateEditTextContextMenu(parent_menu,X,Y,menu_info,status_str_xlated)4009 TgMenu *CreateEditTextContextMenu(parent_menu, X, Y, menu_info,
4010 status_str_xlated)
4011 TgMenu *parent_menu;
4012 int X, Y;
4013 TgMenuInfo *menu_info;
4014 int status_str_xlated; /* ignored, always 0 */
4015 {
4016 TgMenu *menu=TgCreateMenuFromMenuInfo(parent_menu, X, Y, menu_info, FALSE);
4017
4018 if (menu != NULL) {
4019 if (!RefreshEditTextContextMenu(menu)) {
4020 return TgDestroyMenu(menu, TRUE);
4021 }
4022 menu->refresh_proc = ((RefreshMenuFunc*)RefreshContextMenu);
4023 }
4024 return menu;
4025 }
4026
ContextMenu(X,Y,TrackMenubar)4027 int ContextMenu(X, Y, TrackMenubar)
4028 int X, Y, TrackMenubar;
4029 {
4030 int rc=INVALID;
4031 TgMenu *menu=NULL;
4032
4033 if (curChoice == DRAWTEXT && textCursorShown) {
4034 menu = (editTextContextMenuInfo.create_proc)(NULL, X, Y,
4035 &editTextContextMenuInfo, INVALID);
4036 } else {
4037 menu = (baseContextMenuInfo.create_proc)(NULL, X, Y, &baseContextMenuInfo,
4038 INVALID);
4039 }
4040 activeMenu = INVALID;
4041 if (menu != NULL) {
4042 menu->track_menubar = TrackMenubar;
4043
4044 rc = TgMenuLoop(menu);
4045 TgDestroyMenu(menu, TRUE);
4046 }
4047 return rc;
4048 }
4049
HandleMotionForPortInDrawWindow(mouse_x,mouse_y)4050 void HandleMotionForPortInDrawWindow(mouse_x, mouse_y)
4051 int mouse_x, mouse_y;
4052 {
4053 int need_to_highlight=FALSE, something_changed=FALSE;
4054 struct ObjRec *owner_obj=NULL, *obj_ptr, *obj_under_cursor=NULL;
4055 char port_name[MAXSTRING];
4056
4057 obj_ptr = FindAnObj(mouse_x, mouse_y, &owner_obj, &obj_under_cursor,
4058 port_name);
4059 if (drawPolyHighlightedNode != NULL) {
4060 if (obj_under_cursor != drawPolyHighlightedNode) {
4061 /* un-highlight */
4062 SelBox(drawWindow, revGrayGC,
4063 OFFSET_X(drawPolyHighlightedNode->bbox.ltx)-2,
4064 OFFSET_Y(drawPolyHighlightedNode->bbox.lty)-2,
4065 OFFSET_X(drawPolyHighlightedNode->bbox.rbx)+2,
4066 OFFSET_Y(drawPolyHighlightedNode->bbox.rby)+2);
4067 /* do not translate -- program constants */
4068 if (obj_under_cursor != NULL && ObjIsAPort(obj_under_cursor)) {
4069 drawPolyHighlightedNode = obj_under_cursor;
4070 SetWiringNodeInfo(obj_under_cursor, owner_obj, port_name, TRUE);
4071 } else {
4072 drawPolyHighlightedNode = NULL;
4073 SetWiringNodeInfo(NULL, NULL, NULL, TRUE);
4074 }
4075 if (drawPolyHighlightedNode != NULL) {
4076 need_to_highlight = TRUE;
4077 }
4078 something_changed = TRUE;
4079 }
4080 } else if (obj_under_cursor != NULL) {
4081 if (ObjIsAPort(obj_under_cursor)) {
4082 drawPolyHighlightedNode = obj_under_cursor;
4083 SetWiringNodeInfo(obj_under_cursor, owner_obj, port_name, TRUE);
4084 } else {
4085 drawPolyHighlightedNode = NULL;
4086 SetWiringNodeInfo(NULL, NULL, NULL, TRUE);
4087 }
4088 if (drawPolyHighlightedNode != NULL) {
4089 need_to_highlight = TRUE;
4090 something_changed = TRUE;
4091 }
4092 }
4093 if (need_to_highlight) {
4094 SelBox(drawWindow, revGrayGC,
4095 OFFSET_X(drawPolyHighlightedNode->bbox.ltx)-2,
4096 OFFSET_Y(drawPolyHighlightedNode->bbox.lty)-2,
4097 OFFSET_X(drawPolyHighlightedNode->bbox.rbx)+2,
4098 OFFSET_Y(drawPolyHighlightedNode->bbox.rby)+2);
4099 }
4100 if (something_changed) {
4101 if (*gstWiringInfo.first_port_name != '\0') {
4102 char signal_name[MAXSTRING];
4103 struct AttrRec *first_attr_ptr=FindAttrWithName(
4104 gstWiringInfo.first_port_obj, "signal_name=", NULL);
4105
4106 *signal_name = '\0';
4107 if (first_attr_ptr != NULL) {
4108 UtilStrCpyN(signal_name, sizeof(signal_name),
4109 first_attr_ptr->attr_value.s);
4110 }
4111 if (gstWiringInfo.num_ports_to_connect == 99) {
4112 /* rename signal_name */
4113 SetHyperSpaceCursor(drawWindow);
4114 sprintf(gszMsgBox,
4115 TgLoadCachedString(CSTID_SET_SIGNAME_FOR_NAMED_PORT),
4116 signal_name, gstWiringInfo.first_port_name);
4117 } else if (gstWiringInfo.num_ports_to_connect == 999) {
4118 /* clear signal_name */
4119 SetHyperSpaceCursor(drawWindow);
4120 sprintf(gszMsgBox,
4121 TgLoadCachedString(CSTID_CLEAR_SIGNAME_FOR_NAMED_PORT),
4122 signal_name, gstWiringInfo.first_port_name);
4123 } else {
4124 sprintf(gszMsgBox,
4125 TgLoadCachedString(CSTID_START_A_WIRE_FROM_NAMED_PORT),
4126 gstWiringInfo.first_port_name);
4127 }
4128 SetStringStatus(gszMsgBox);
4129 } else {
4130 if (gstWiringInfo.num_ports_to_connect == 99 ||
4131 gstWiringInfo.num_ports_to_connect == 999) {
4132 SetHandCursor(drawWindow);
4133 }
4134 ShowCurChoiceMouseStatus(DRAWPOLY, 0, FALSE);
4135 }
4136 }
4137 }
4138
4139 static int motionCursorIsMoveCursor=FALSE;
4140
4141 static
HandleMotionInDrawWindow(input)4142 void HandleMotionInDrawWindow(input)
4143 XEvent *input;
4144 {
4145 int mouse_x=0, mouse_y=0, grid_x=0, grid_y=0, cursor_is_move_cursor=FALSE;
4146 int saved_motion_cursor_is_move_cursor=motionCursorIsMoveCursor;
4147 unsigned int state=0;
4148 XEvent ev;
4149
4150 while (XCheckWindowEvent(mainDisplay,drawWindow,PointerMotionMask,&ev)) ;
4151
4152 state = (input->xmotion).state;
4153 mouse_x = (input->xmotion).x;
4154 mouse_y = (input->xmotion).y;
4155 GridXY(mouse_x, mouse_y, &grid_x, &grid_y);
4156 simpleMotionInDrawWin = TRUE;
4157 MarkRulers(grid_x, grid_y);
4158 simpleMotionInDrawWin = FALSE;
4159 if (curChoice == DRAWPOLY && gstWiringInfo.num_ports_to_connect > 0) {
4160 HandleMotionForPortInDrawWindow(mouse_x, mouse_y);
4161 #ifdef _NOT_DEFINED
4162 /*
4163 * drawPolyToConnectPins is only set to > 0 in "pin.c"
4164 * what's in "pin.c" is not used at this time
4165 */
4166 } else if (curChoice == DRAWPOLY && drawPolyToConnectPins > 0) {
4167 HandlePinHighlights(mouse_x, mouse_y);
4168 if (drawPolyHighlightedNode != NULL) {
4169 gpStartPin = drawPolyHighlightedNode;
4170 }
4171 #endif /* _NOT_DEFINED */
4172 } else if (!inHyperSpace && !btn1Warp &&
4173 !(inSlideShow && !goHyperSpaceInSlideShow)) {
4174 if (curChoice == DRAWTEXT && textCursorShown && MouseInCurText(input)) {
4175 if (MouseOnCurTextBoundary(input)) {
4176 SetCurChoiceMouseStatusStrings(curChoice, FALSE, NULL, TRUE, state);
4177 cursor_is_move_cursor = TRUE;
4178 } else {
4179 SetCurChoiceMouseStatusStrings(curChoice, FALSE, curTextObj, TRUE,
4180 state);
4181 }
4182 } else {
4183 struct ObjRec *obj_ptr=NULL, *owner_obj=NULL;
4184
4185 if ((obj_ptr=FindAnObj(mouse_x, mouse_y, &owner_obj, NULL, NULL)) !=
4186 NULL) {
4187 if (owner_obj != NULL) obj_ptr = owner_obj;
4188 }
4189 ShowCursor();
4190 SetCurChoiceMouseStatusStrings(curChoice, FALSE, obj_ptr, FALSE,
4191 state);
4192 }
4193 } else if (inHyperSpace || btn1Warp) {
4194 struct ObjRec *obj_ptr=NULL, *owner_obj=NULL;
4195 struct AttrRec *attr_ptr=NULL;
4196
4197 if ((obj_ptr=FindAnObj(mouse_x, mouse_y, &owner_obj, NULL, NULL)) !=
4198 NULL) {
4199 if (owner_obj != NULL) obj_ptr = owner_obj;
4200 /* do not translate -- program constants */
4201 if ((attr_ptr=FindAttrWithName(obj_ptr, TELEPORT_ATTR, NULL)) !=
4202 NULL || (((attr_ptr=FindAttrWithName(obj_ptr, "href=",
4203 NULL)) != NULL) && *attr_ptr->attr_value.s != '\0')) {
4204 char fname[MAXPATHLENGTH+1];
4205
4206 SetHyperSpaceCursor(drawWindow);
4207 if (FormNewFileName(curDir, attr_ptr->attr_value.s,
4208 (strcmp(attr_ptr->attr_name.s,TELEPORT_ATTR)==0 ?
4209 OBJ_FILE_EXT : NULL), fname, NULL)) {
4210 SetStringStatus(fname);
4211 }
4212 } else if ((allowLaunchInHyperSpace &&
4213 (attr_ptr=FindAttrWithName(obj_ptr, LAUNCH_ATTR, NULL)) !=
4214 NULL) || (attr_ptr=FindAttrWithName(obj_ptr, EXEC_ATTR,
4215 NULL)) != NULL) {
4216 SetHyperSpaceCursor(drawWindow);
4217 sprintf(gszMsgBox, "%s%s", attr_ptr->attr_name.s,
4218 (*attr_ptr->attr_value.s=='\0' ? "..." :
4219 attr_ptr->attr_value.s));
4220 SetStringStatus(gszMsgBox);
4221 } else {
4222 ShowCursor();
4223 ShowCurChoiceMouseStatus(INVALID, 0, FALSE);
4224 }
4225 } else {
4226 ShowCursor();
4227 ShowCurChoiceMouseStatus(INVALID, 0, FALSE);
4228 }
4229 }
4230 if (cursor_is_move_cursor != saved_motion_cursor_is_move_cursor) {
4231 if (cursor_is_move_cursor) {
4232 XDefineCursor(mainDisplay, drawWindow, moveCursor);
4233 } else {
4234 ShowCursor();
4235 }
4236 motionCursorIsMoveCursor = cursor_is_move_cursor;
4237 }
4238 }
4239
HandlePressForPortInDrawWindow(cancel)4240 int HandlePressForPortInDrawWindow(cancel)
4241 int cancel;
4242 {
4243 if (drawPolyHighlightedNode != NULL) {
4244 /* un-highlight */
4245 SelBox(drawWindow, revGrayGC,
4246 OFFSET_X(drawPolyHighlightedNode->bbox.ltx)-2,
4247 OFFSET_Y(drawPolyHighlightedNode->bbox.lty)-2,
4248 OFFSET_X(drawPolyHighlightedNode->bbox.rbx)+2,
4249 OFFSET_Y(drawPolyHighlightedNode->bbox.rby)+2);
4250 if (cancel) {
4251 drawPolyHighlightedNode = NULL;
4252 SetWiringNodeInfo(NULL, NULL, NULL, TRUE);
4253 }
4254 }
4255 if (cancel) {
4256 if (connectingPortsByWire) {
4257 MakeQuiescent();
4258 Msg(TgLoadString(STID_CONNECT_PORTS_CANCEL_BY_USER));
4259 }
4260 return FALSE;
4261 }
4262 return TRUE;
4263 }
4264
4265 static
HandlePressInDrawWindow(input,pn_status)4266 int HandlePressInDrawWindow(input, pn_status)
4267 XEvent *input;
4268 int *pn_status;
4269 {
4270 XButtonEvent *button_ev;
4271
4272 button_ev = &(input->xbutton);
4273 if (enableMouseWheel &&
4274 (button_ev->button == Button4 || button_ev->button == Button5)) {
4275 if ((button_ev->state & METAMASK) == METAMASK) {
4276 if (button_ev->button == Button4) {
4277 ScrollLeft(button_ev);
4278 } else if (button_ev->button == Button5) {
4279 ScrollRight(button_ev);
4280 }
4281 } else {
4282 if (button_ev->button == Button4) {
4283 ScrollUp(button_ev);
4284 } else if (button_ev->button == Button5) {
4285 ScrollDown(button_ev);
4286 }
4287 }
4288 *pn_status = INVALID;
4289 return TRUE;
4290 }
4291 if ((button_ev->state & ShiftMask) && (button_ev->state & ControlMask)) {
4292 int abs_x=ABS_X(button_ev->x);
4293 int abs_y=ABS_Y(button_ev->y);
4294
4295 if (button_ev->button == Button1) {
4296 ZoomInAtCursor(abs_x, abs_y);
4297 } else if (button_ev->button == Button2) {
4298 CenterAtCursor(abs_x, abs_y);
4299 } else if (button_ev->button == Button3) {
4300 ZoomOut();
4301 }
4302 *pn_status = INVALID;
4303 return TRUE;
4304 } else if (button_ev->button == Button3 &&
4305 (button_ev->state & ShiftMask)) {
4306 SetCurChoice(NOTHING);
4307 *pn_status = INVALID;
4308 return TRUE;
4309 } else if (button_ev->button == Button2 && curChoice == DRAWTEXT &&
4310 textCursorShown) {
4311 if (((button_ev->state & ControlMask) == ControlMask &&
4312 MouseInCurText(input)) || MouseOnCurTextBoundary(input)) {
4313 MoveEditText(input);
4314 *pn_status = INVALID;
4315 } else if (btn2PopupMainMenu) {
4316 *pn_status = MainMenu();
4317 } else {
4318 *pn_status = INVALID;
4319 }
4320 return TRUE;
4321 } else if ((button_ev->button == Button2 && curChoice == NOTHING &&
4322 (button_ev->state & ShiftMask)) ||
4323 (inHyperSpace && button_ev->button == Button1)) {
4324 Teleport(button_ev);
4325 *pn_status = INVALID;
4326 return TRUE;
4327 } else if (button_ev->button == Button1 && curChoice == NOTHING &&
4328 ((button_ev->state & (ShiftMask | ControlMask)) == 0) &&
4329 btn1Warp) {
4330 Teleport(button_ev);
4331 *pn_status = INVALID;
4332 return TRUE;
4333 } else if (button_ev->button == Button1 && !inHyperSpace && !btn1Warp &&
4334 !(inSlideShow && !goHyperSpaceInSlideShow) && curChoice == DRAWTEXT &&
4335 textCursorShown && MouseOnCurTextBoundary(input)) {
4336 MoveEditText(input);
4337 *pn_status = INVALID;
4338 return TRUE;
4339 } else if (button_ev->button == Button2) {
4340 if (curChoice == DRAWPOLY && gstWiringInfo.num_ports_to_connect > 0) {
4341 return HandlePressForPortInDrawWindow(TRUE);
4342 } else if (btn2PopupMainMenu) {
4343 *pn_status = MainMenu();
4344 } else {
4345 *pn_status = INVALID;
4346 }
4347 return TRUE;
4348 } else if (button_ev->button == Button3) {
4349 /* context-sensitive menu? */
4350 if (curChoice == DRAWPOLY && gstWiringInfo.num_ports_to_connect > 0) {
4351 return HandlePressForPortInDrawWindow(TRUE);
4352 }
4353 if (btn3PopupModeMenu) {
4354 ModeMenu(button_ev->x_root, button_ev->y_root, FALSE);
4355 } else if (!inHyperSpace &&
4356 !(inSlideShow && !goHyperSpaceInSlideShow)) {
4357 if (curChoice == DRAWTEXT && textCursorShown &&
4358 MouseInCurText(input)) {
4359 ContextMenu(button_ev->x_root, button_ev->y_root, FALSE);
4360 } else {
4361 struct ObjRec *obj_ptr=NULL, *owner_obj=NULL;
4362
4363 if ((obj_ptr=FindAnObj(button_ev->x, button_ev->y, &owner_obj,
4364 NULL, NULL)) != NULL) {
4365 if (owner_obj != NULL) obj_ptr = owner_obj;
4366 }
4367 if (obj_ptr == NULL) {
4368 ModeMenu(button_ev->x_root, button_ev->y_root, FALSE);
4369 } else {
4370 int obj_may_not_exist=FALSE;
4371
4372 if (curChoice == DRAWTEXT && textCursorShown &&
4373 obj_ptr == curTextObj) {
4374 obj_may_not_exist = TRUE;
4375 }
4376 if (!(topSel != NULL && topSel == botSel &&
4377 topSel->obj == obj_ptr)) {
4378 TieLooseEnds();
4379 if (obj_may_not_exist && textDrawn) {
4380 obj_may_not_exist = FALSE;
4381 }
4382 SetCurChoice(NOTHING);
4383 if (topSel != NULL) {
4384 HighLightReverse();
4385 RemoveAllSel();
4386 }
4387 if (obj_may_not_exist) {
4388 UpdSelBBox();
4389 } else {
4390 AddNewSelObj(obj_ptr);
4391 UpdSelBBox();
4392 justDupped = FALSE;
4393 HighLightForward();
4394 }
4395 }
4396 ContextMenu(button_ev->x_root, button_ev->y_root, FALSE);
4397 }
4398 }
4399 } else if (inSlideShow) {
4400 SlideShowModeMenu(button_ev->x_root, button_ev->y_root, FALSE);
4401 }
4402 *pn_status = INVALID;
4403 return TRUE;
4404 }
4405 return FALSE;
4406 }
4407
DrawingEventHandler(input)4408 int DrawingEventHandler(input)
4409 XEvent *input;
4410 {
4411 XEvent ev;
4412
4413 if (input->type == Expose) {
4414 XSync(mainDisplay, False);
4415 while (XCheckWindowEvent(mainDisplay, drawWindow, ExposureMask, &ev)) ;
4416
4417 if (topSel != NULL || curChoice == VERTEXMODE || SomethingDirty()) {
4418 ClearAndRedrawDrawWindow();
4419 } else {
4420 RedrawDrawWindow(botObj);
4421 ResetDirtyBBoxInfo();
4422 RedrawCurText();
4423 }
4424 return INVALID;
4425 } else if (input->type == ClientMessage) {
4426 if (curChoice == DRAWTEXT && canvasFontDoubleByte &&
4427 textCursorShown && tgIMExpectClientMessage(mainDisplay,
4428 drawWindow)) {
4429 if (tgIMHandleClientMessage(mainDisplay,
4430 drawWindow, (XClientMessageEvent*)input, NULL, NULL)) {
4431 }
4432 }
4433 return INVALID;
4434 } else if (input->type == EnterNotify) {
4435 if (input->xcrossing.mode == NotifyNormal) {
4436 RestoreDrawWinDrawTextInfo(FALSE);
4437 if (curChoice == DRAWTEXT && textCursorShown) {
4438 tgIMFocusIn(mainDisplay, drawWindow);
4439 }
4440 }
4441 ShowCurChoiceMouseStatus(curChoice, 0, FALSE);
4442 return INVALID;
4443 } else if (input->type == LeaveNotify) {
4444 EndMeasureTooltip(FALSE);
4445
4446 if (input->xcrossing.mode == NotifyNormal) {
4447 SaveDrawWinDrawTextInfo(FALSE);
4448 if (curChoice == DRAWTEXT && textCursorShown) {
4449 tgIMFocusOut(mainDisplay, drawWindow);
4450 }
4451 }
4452 return INVALID;
4453 } else if (input->type == MotionNotify) {
4454 HandleMotionInDrawWindow(input);
4455 return INVALID;
4456 }
4457
4458 if (input->type == ButtonPress) {
4459 int rc=INVALID;
4460
4461 EndMeasureTooltip(FALSE);
4462 if (HandlePressInDrawWindow(input, &rc)) {
4463 return rc;
4464 }
4465 Msg("");
4466 }
4467 if (input->type == KeyPress && inSlideShow && !goHyperSpaceInSlideShow) {
4468 XKeyEvent *key_ev=(&(input->xkey));
4469 KeySym key_sym=(KeySym)0;
4470 char buf[80];
4471 int has_ch=XLookupString(key_ev, buf, sizeof(buf), &key_sym, &c_stat);
4472
4473 TranslateKeys(buf, &key_sym);
4474 if (CharIsESC(key_ev, buf, key_sym, &has_ch)) {
4475 LeaveSlideShow();
4476 return INVALID;
4477 } else if (CharIsCRorLF(key_ev, buf, key_sym, &has_ch)) {
4478 /*
4479 * For now, this only goes to the next page. In the future,
4480 * this would single step.
4481 */
4482 NextSlide();
4483 return INVALID;
4484 } else if (key_sym == XK_Left || key_sym == XK_KP_Left ||
4485 key_sym == XK_Up || key_sym == XK_KP_Up ||
4486 key_sym == XK_Right || key_sym == XK_KP_Right ||
4487 key_sym == XK_Down || key_sym == XK_KP_Down) {
4488 switch (key_sym) {
4489 case XK_Left: PrevSlide(); break;
4490 case XK_KP_Left: PrevSlide(); break;
4491 case XK_Up: PrevSlide(); break;
4492 case XK_KP_Up: PrevSlide(); break;
4493 case XK_Right: NextSlide(); break;
4494 case XK_KP_Right: NextSlide(); break;
4495 case XK_Down: NextSlide(); break;
4496 case XK_KP_Down: NextSlide(); break;
4497 }
4498 return INVALID;
4499 } else if (key_sym == XK_Page_Up || key_sym == XK_KP_Page_Up ||
4500 key_sym == XK_Page_Down || key_sym == XK_KP_Page_Down) {
4501 switch (key_sym) {
4502 case XK_Page_Up: PrevSlide(); break;
4503 case XK_KP_Page_Up: PrevSlide(); break;
4504 case XK_Page_Down: NextSlide(); break;
4505 case XK_KP_Page_Down: NextSlide(); break;
4506 }
4507 return INVALID;
4508 }
4509 }
4510 switch(curChoice) {
4511 case NOTHING: Select(input); break;
4512 case DRAWTEXT: DrawText(input); break;
4513 case DRAWBOX: DrawBox(input); break;
4514 case DRAWCORNEROVAL: DrawOval(input); break;
4515 case DRAWCENTEROVAL: DrawOval(input); break;
4516 case DRAWEDGECIRCLE: DrawOval(input); break;
4517 case DRAWPOLY: DrawPoly(input); break;
4518 case DRAWPOLYGON: DrawPolygon(input); break;
4519 case DRAWARC: DrawArc(input); break;
4520 case DRAWEDGEARC: DrawArc(input); break;
4521 case DRAWRCBOX: DrawRCBox(input); break;
4522 case FREEHAND: DrawPoly(input); break;
4523 case VERTEXMODE: Select(input); break;
4524 case ROTATEMODE: Select(input); break;
4525 }
4526 return INVALID;
4527 }
4528
4529