1 /* windClient.c -
2 *
3 * Send button pushes and commands to the window's command
4 * interpreters.
5 *
6 * *********************************************************************
7 * * Copyright (C) 1985, 1990 Regents of the University of California. *
8 * * Permission to use, copy, modify, and distribute this *
9 * * software and its documentation for any purpose and without *
10 * * fee is hereby granted, provided that the above copyright *
11 * * notice appear in all copies. The University of California *
12 * * makes no representations about the suitability of this *
13 * * software for any purpose. It is provided "as is" without *
14 * * express or implied warranty. Export of this software outside *
15 * * of the United States of America may require an export license. *
16 * *********************************************************************
17 */
18
19 #ifndef lint
20 static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/windows/windClient.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
21 #endif /* not lint */
22
23 #include <stdio.h>
24
25 #include "utils/magic.h"
26 #include "textio/textio.h"
27 #include "utils/geometry.h"
28 #include "windows/windows.h"
29 #include "graphics/glyphs.h"
30 #include "windows/windInt.h"
31 #include "tiles/tile.h"
32 #include "utils/hash.h"
33 #include "database/database.h"
34 #include "utils/main.h"
35 #include "utils/macros.h"
36 #include "utils/utils.h"
37 #include "utils/malloc.h"
38 #include "graphics/graphics.h"
39 #include "utils/styles.h"
40 #include "textio/txcommands.h"
41 #include "utils/undo.h"
42
43 /* The following defines are used to indicate corner positions
44 * of the box:
45 */
46
47 #define WIND_BL 0
48 #define WIND_BR 1
49 #define WIND_TR 2
50 #define WIND_TL 3
51 #define WIND_ILG -1
52
53 /* our window client ID */
54 global WindClient windClientID = (WindClient) NULL;
55
56 extern int windBorderCmd();
57 extern int windCaptionCmd(), windCrashCmd(), windCursorCmd();
58 extern int windFilesCmd(), windCloseCmd(), windOpenCmd();
59 extern int windQuitCmd(), windRedrawCmd();
60 extern int windResetCmd(), windSpecialOpenCmd();
61 extern int windOverCmd(), windUnderCmd(), windDebugCmd();
62 extern int windDumpCmd(), windHelpCmd();
63 extern int windMacroCmd(), windIntMacroCmd();
64 extern int windLogCommandsCmd(), windUpdateCmd(), windSleepCmd();
65 extern int windSetpointCmd();
66 extern int windPushbuttonCmd();
67 extern int windPauseCmd(), windGrstatsCmd();
68 extern int windGrowCmd();
69 extern int windUndoCmd(), windRedoCmd();
70 extern int windCenterCmd(), windScrollCmd();
71 extern int windVersionCmd(), windViewCmd(), windXviewCmd(), windZoomCmd();
72 extern int windScrollBarsCmd(), windPositionsCmd();
73 extern int windNamesCmd();
74
75
76 #ifdef MAGIC_WRAPPER
77 extern int windBypassCmd();
78 #else
79 extern int windEchoCmd(), windSourceCmd(), windSendCmd();
80 #endif
81
82 static Rect windFrameRect;
83 static MagWindow *windFrameWindow;
84 static int windButton = TX_LEFT_BUTTON;
85 static int windCorner = WIND_ILG; /* Nearest corner when button went
86 * down.
87 */
88
89
90 /*
91 * ----------------------------------------------------------------------------
92 * windButtonSetCursor --
93 *
94 * Used to set the programmable cursor for a particular
95 * button state.
96 *
97 * Results:
98 * None.
99 *
100 * Side effects:
101 * Selects and sets a programmable cursor based on the given
102 * button (for sizing or moving) and corner.
103 * ----------------------------------------------------------------------------
104 */
105
106 void
windButtonSetCursor(button,corner)107 windButtonSetCursor(button, corner)
108 int button; /* Button that is down. */
109 int corner; /* Corner to be displayed in cursor. */
110 {
111 switch (corner)
112 {
113 case WIND_BL:
114 if (button == TX_LEFT_BUTTON)
115 GrSetCursor(STYLE_CURS_LLWIND);
116 else
117 GrSetCursor(STYLE_CURS_LLWINDCORN);
118 break;
119 case WIND_BR:
120 if (button == TX_LEFT_BUTTON)
121 GrSetCursor(STYLE_CURS_LRWIND);
122 else
123 GrSetCursor(STYLE_CURS_LRWINDCORN);
124 break;
125 case WIND_TL:
126 if (button == TX_LEFT_BUTTON)
127 GrSetCursor(STYLE_CURS_ULWIND);
128 else
129 GrSetCursor(STYLE_CURS_ULWINDCORN);
130 break;
131 case WIND_TR:
132 if (button == TX_LEFT_BUTTON)
133 GrSetCursor(STYLE_CURS_URWIND);
134 else
135 GrSetCursor(STYLE_CURS_URWINDCORN);
136 break;
137 }
138 }
139
140
141 /*
142 * ----------------------------------------------------------------------------
143 * windGetCorner --
144 *
145 * Returns the corner of the window closest to a given screen location.
146 *
147 * Results:
148 * An integer value is returned, indicating the corner closest to
149 * the given screen location.
150 *
151 * Side effects:
152 * None.
153 * ----------------------------------------------------------------------------
154 */
155
156 int
windGetCorner(screenPoint,screenRect)157 windGetCorner(screenPoint, screenRect)
158 Point *screenPoint;
159 Rect *screenRect;
160
161 {
162 Rect r;
163
164 /* Find out which corner is closest. Consider only the
165 * intersection of the box with the window (otherwise it
166 * may not be possible to select off-screen corners.
167 */
168
169 r = *screenRect;
170 GeoClip(&r, &GrScreenRect);
171 if (screenPoint->p_x < ((r.r_xbot + r.r_xtop)/2))
172 {
173 if (screenPoint->p_y < ((r.r_ybot + r.r_ytop)/2))
174 return WIND_BL;
175 else
176 return WIND_TL;
177 }
178 else
179 {
180 if (screenPoint->p_y < ((r.r_ybot + r.r_ytop)/2))
181 return WIND_BR;
182 else
183 return WIND_TR;
184 }
185 }
186
187 /*
188 * ----------------------------------------------------------------------------
189 * windMoveRect --
190 *
191 * Repositions a rectangle by one of its corners.
192 *
193 * Results:
194 * None.
195 *
196 * Side effects:
197 * The rectangle is changed so that the given corner is at the
198 * given position.
199 * ----------------------------------------------------------------------------
200 */
201
202 void
windMoveRect(wholeRect,corner,p,rect)203 windMoveRect(wholeRect, corner, p, rect)
204 bool wholeRect; /* move the whole thing? or just a corner? */
205 int corner; /* Specifies a corner in the format
206 * returned by ToolGetCorner.
207 */
208 Point *p; /* New position of corner, in screen
209 * coordinates.
210 */
211 Rect *rect;
212 {
213 int x, y, tmp;
214
215 /* Move the rect. If an illegal corner is specified, then
216 * move by the bottom-left corner.
217 */
218
219 if (wholeRect)
220 {
221 switch (corner)
222 {
223 case WIND_BL:
224 x = p->p_x - rect->r_xbot;
225 y = p->p_y - rect->r_ybot;
226 break;
227 case WIND_BR:
228 x = p->p_x - rect->r_xtop;
229 y = p->p_y - rect->r_ybot;
230 break;
231 case WIND_TR:
232 x = p->p_x - rect->r_xtop;
233 y = p->p_y - rect->r_ytop;
234 break;
235 case WIND_TL:
236 x = p->p_x - rect->r_xbot;
237 y = p->p_y - rect->r_ytop;
238 break;
239 default:
240 x = p->p_x - rect->r_xbot;
241 y = p->p_y - rect->r_ybot;
242 break;
243 }
244 rect->r_xbot += x;
245 rect->r_ybot += y;
246 rect->r_xtop += x;
247 rect->r_ytop += y;
248 }
249 else
250 {
251 switch (corner)
252 {
253 case WIND_BL:
254 rect->r_xbot = p->p_x;
255 rect->r_ybot = p->p_y;
256 break;
257 case WIND_BR:
258 rect->r_xtop = p->p_x;
259 rect->r_ybot = p->p_y;
260 break;
261 case WIND_TR:
262 rect->r_xtop = p->p_x;
263 rect->r_ytop = p->p_y;
264 break;
265 case WIND_TL:
266 rect->r_xbot = p->p_x;
267 rect->r_ytop = p->p_y;
268 break;
269 }
270
271 /* If the movement turned the box inside out, turn it right
272 * side out again.
273 */
274
275 if (rect->r_xbot > rect->r_xtop)
276 {
277 tmp = rect->r_xtop;
278 rect->r_xtop = rect->r_xbot;
279 rect->r_xbot = tmp;
280 }
281 if (rect->r_ybot > rect->r_ytop)
282 {
283 tmp = rect->r_ytop;
284 rect->r_ytop = rect->r_ybot;
285 rect->r_ybot = tmp;
286 }
287
288 }
289 }
290
291
292 /*
293 * ----------------------------------------------------------------------------
294 * Button Routines --
295 *
296 * This page contains a set of routines to handle the puck
297 * buttons within the window border.
298 *
299 * Results:
300 * None.
301 *
302 * Side effects:
303 * Left button: used to move the whole window by the lower-left corner.
304 * Right button: used to re-size the window by its upper-right corner.
305 * If one of the left or right buttons is pushed, then the
306 * other is pushed, the corner is switched to the nearest
307 * one to the cursor. This corner is remembered for use
308 * in box positioning/sizing when both buttons have gone up.
309 * Bottom button: Center the view on the point where the crosshair is
310 * at when the button is released.
311 * ----------------------------------------------------------------------------
312 */
313
314 void
windFrameDown(w,cmd)315 windFrameDown(w, cmd)
316 MagWindow *w;
317 TxCommand *cmd;
318 {
319 if (WindOldButtons == 0)
320 {
321 windFrameRect = w->w_frameArea;
322 windFrameWindow = w;
323 windButton = cmd->tx_button;
324 }
325 #define BOTHBUTTONS (TX_LEFT_BUTTON | TX_RIGHT_BUTTON)
326 if ((WindNewButtons & BOTHBUTTONS) == BOTHBUTTONS)
327 {
328 windCorner = windGetCorner(&(cmd->tx_p), &(windFrameWindow->w_frameArea));
329 }
330 else if (cmd->tx_button == TX_LEFT_BUTTON)
331 {
332 windCorner = WIND_BL;
333 windButtonSetCursor(windButton, windCorner);
334 }
335 else if (cmd->tx_button == TX_RIGHT_BUTTON)
336 {
337 windCorner = WIND_TR;
338 windButtonSetCursor(windButton, windCorner);
339 }
340 }
341
342 /*ARGSUSED*/
343 void
windFrameUp(w,cmd)344 windFrameUp(w, cmd)
345 MagWindow *w;
346 TxCommand *cmd;
347 {
348 if (WindNewButtons == 0)
349 {
350 GrSetCursor(STYLE_CURS_NORMAL);
351 switch (cmd->tx_button)
352 {
353 case TX_LEFT_BUTTON:
354 case TX_RIGHT_BUTTON:
355 windMoveRect( (windButton == TX_LEFT_BUTTON),
356 windCorner, &(cmd->tx_p), &windFrameRect);
357 WindReframe(windFrameWindow, &windFrameRect, FALSE,
358 (windButton == TX_LEFT_BUTTON) );
359 break;
360 }
361 }
362 else
363 {
364 /* If both buttons are down and one is released, we just change
365 * the cursor to reflect the current corner and the remaining
366 * button (i.e. move or size window).
367 */
368
369 windCorner = windGetCorner(&(cmd->tx_p), &(windFrameWindow->w_frameArea));
370 windButtonSetCursor(windButton, windCorner);
371 }
372 }
373
374 /*
375 * ----------------------------------------------------------------------------
376 * windFrameButtons --
377 *
378 * Handle button pushes to the window frame area (zoom and scroll)
379 * Always handle scroll bars ourselves, even if there is an external
380 * window package. BUT---in the Tcl/Tk version of Magic, the
381 * window does not set WIND_SCROLLBARS, causing this routine to be
382 * bypassed.
383 *
384 * Results:
385 * TRUE if the button was pushed in the frame and handled by one
386 * of the button handler routines, FALSE if not.
387 *
388 * Side effects:
389 * Depends upon where the button was pushed.
390 * ----------------------------------------------------------------------------
391 */
392
393 bool
windFrameButtons(w,cmd)394 windFrameButtons(w, cmd)
395 MagWindow *w;
396 TxCommand *cmd;
397 {
398 extern void windBarLocations();
399
400 Rect leftBar, botBar, up, down, right, left, zoom;
401 Point p;
402
403 if (w == NULL) return FALSE;
404 p.p_x = w->w_screenArea.r_xtop - w->w_screenArea.r_xbot;
405 p.p_y = w->w_screenArea.r_ytop - w->w_screenArea.r_ybot;
406
407 if ((w->w_flags & WIND_SCROLLBARS) != 0)
408 {
409 windBarLocations(w, &leftBar, &botBar, &up, &down, &right, &left, &zoom);
410 if (cmd->tx_button == TX_MIDDLE_BUTTON) {
411 if (GEO_ENCLOSE(&cmd->tx_p, &leftBar))
412 {
413 /* move elevator */
414 p.p_x = 0;
415 p.p_y = w->w_bbox->r_ybot +
416 ((w->w_bbox->r_ytop - w->w_bbox->r_ybot) *
417 (cmd->tx_p.p_y - leftBar.r_ybot))
418 / (leftBar.r_ytop - leftBar.r_ybot) -
419 (w->w_surfaceArea.r_ytop + w->w_surfaceArea.r_ybot)/2;
420 WindScroll(w, &p, (Point *) NULL);
421 return TRUE;
422 }
423 else if (GEO_ENCLOSE(&cmd->tx_p, &botBar))
424 {
425 /* move elevator */
426 p.p_y = 0;
427 p.p_x = w->w_bbox->r_xbot +
428 ((w->w_bbox->r_xtop - w->w_bbox->r_xbot) *
429 (cmd->tx_p.p_x - botBar.r_xbot))
430 / (botBar.r_xtop - botBar.r_xbot) -
431 (w->w_surfaceArea.r_xtop + w->w_surfaceArea.r_xbot)/2;
432 WindScroll(w, &p, (Point *) NULL);
433 return TRUE;
434 }
435 else if (GEO_ENCLOSE(&cmd->tx_p, &up))
436 {
437 /* scroll up */
438 p.p_y = -p.p_y;
439 p.p_x = 0;
440 WindScroll(w, (Point *) NULL, &p);
441 return TRUE;
442 }
443 else if (GEO_ENCLOSE(&cmd->tx_p, &down))
444 {
445 /* scroll down */
446 p.p_x = 0;
447 WindScroll(w, (Point *) NULL, &p);
448 return TRUE;
449 }
450 else if (GEO_ENCLOSE(&cmd->tx_p, &right))
451 {
452 /* scroll right */
453 p.p_x = -p.p_x;
454 p.p_y = 0;
455 WindScroll(w, (Point *) NULL, &p);
456 return TRUE;
457 }
458 else if (GEO_ENCLOSE(&cmd->tx_p, &left))
459 {
460 /* scroll left */
461 p.p_y = 0;
462 WindScroll(w, (Point *) NULL, &p);
463 return TRUE;
464 }
465 }
466 if (GEO_ENCLOSE(&cmd->tx_p, &zoom)) {
467 /* zoom in, out, or view */
468 switch (cmd->tx_button)
469 {
470 case TX_LEFT_BUTTON:
471 WindZoom(w, 2.0);
472 break;
473 case TX_MIDDLE_BUTTON:
474 WindView(w);
475 break;
476 case TX_RIGHT_BUTTON:
477 WindZoom(w, 0.5);
478 break;
479 }
480 return TRUE;
481 }
482 }
483 return FALSE;
484 }
485
486 /*
487 * ----------------------------------------------------------------------------
488 * windClientButtons --
489 *
490 * Handle button pushes to the window border.
491 *
492 * Results:
493 * None.
494 *
495 * Side effects:
496 * depends upon where the button was pushed.
497 * ----------------------------------------------------------------------------
498 */
499
500 void
windClientButtons(w,cmd)501 windClientButtons(w, cmd)
502 MagWindow *w;
503 TxCommand *cmd;
504 {
505 /*
506 * Is this an initial 'down push' in a non-iconic window? If so, we
507 * will initiate some user-interaction sequence, such as moving the corner
508 * of the window or growing it to full-screen size.
509 *
510 * (An 'iconic' window is one that is closed down to an icon -- this
511 * currently only happens when we are using the Sun window package, but
512 * in the future it might happen in other cases too.)
513 *
514 */
515
516 if ((WindOldButtons == 0) && ((w->w_flags & WIND_ISICONIC) == 0))
517 {
518 /* single button down */
519 Point p;
520 Rect caption;
521
522 windFrameWindow = NULL;
523 if (w == NULL) return;
524 p.p_x = w->w_screenArea.r_xtop - w->w_screenArea.r_xbot;
525 p.p_y = w->w_screenArea.r_ytop - w->w_screenArea.r_ybot;
526 caption = w->w_allArea;
527 if ((w->w_flags & WIND_CAPTION) != 0)
528 caption.r_ybot = caption.r_ytop - TOP_BORDER(w) + 1;
529 else
530 caption.r_ybot = caption.r_ytop;
531
532 /* Handle 'grow' for our window package. */
533 if (WindPackageType == WIND_MAGIC_WINDOWS)
534 {
535 if ((cmd->tx_button == TX_MIDDLE_BUTTON) &&
536 GEO_ENCLOSE(&cmd->tx_p, &caption))
537 {
538 WindFullScreen(w);
539 return;
540 }
541 }
542 if (windFrameButtons(w, cmd)) return;
543
544 /* Otherwise, continue onward */
545 }
546
547 /*
548 * At this point, we have decided that the button was not an initial
549 * button push for Magic's window package. Maybe an external window
550 * package wants it, or maybe it is a continuation of a previous Magic
551 * sequence (such as moving a corner of a window).
552 */
553 switch ( WindPackageType )
554 {
555 case WIND_X_WINDOWS:
556 break;
557
558 default:
559 /* Magic Windows */
560 if (cmd->tx_button == TX_MIDDLE_BUTTON)
561 return;
562 if ((cmd->tx_buttonAction == TX_BUTTON_UP) &&
563 (windFrameWindow == NULL))
564 return;
565
566 /* no special area or else an up push -- reframe window */
567 switch (cmd->tx_buttonAction)
568 {
569 case TX_BUTTON_DOWN:
570 windFrameDown(w, cmd);
571 break;
572 case TX_BUTTON_UP:
573 windFrameUp(w, cmd);
574 break;
575 default:
576 TxError("windClientButtons() failed!\n");
577 break;
578 }
579 }
580 }
581
582 /*
583 * ----------------------------------------------------------------------------
584 * WindButtonInFrame --
585 *
586 * To be called from the graphics packages. Handle button pushes to
587 * the window frame area (zoom and scroll) by calling windFrameButtons()
588 * if it appears to be appropriate for this MagWindow structure.
589 * This bypasses the key macro handler, thus hard-coding the button
590 * actions for the frame.
591 *
592 * Results:
593 * TRUE if the button was pushed in the frame and handled by one
594 * of the button handler routines, FALSE if not.
595 *
596 * Side effects:
597 * Depends upon where the button was pushed.
598 * ----------------------------------------------------------------------------
599 */
600
601 bool
WindButtonInFrame(w,x,y,b)602 WindButtonInFrame(w, x, y, b)
603 MagWindow *w;
604 int x;
605 int y;
606 int b;
607 {
608 TxCommand cmd;
609 cmd.tx_p.p_x = x;
610 cmd.tx_p.p_y = y;
611 cmd.tx_button = b;
612 if (windFrameButtons(w, &cmd))
613 {
614 WindUpdate();
615 return TRUE;
616 }
617 return FALSE;
618 }
619
620
621 /*
622 * ----------------------------------------------------------------------------
623 *
624 * windClientInterp
625 *
626 * Window's command interpreter.
627 * Dispatches to long commands, providing them with the window and command
628 * we are passed.
629 *
630 * Results:
631 * none.
632 *
633 * Side effects:
634 * Whatever occur as a result of executing the long
635 * command supplied.
636 *
637 * ----------------------------------------------------------------------------
638 */
639
640 void
windCmdInterp(w,cmd)641 windCmdInterp(w, cmd)
642 MagWindow *w;
643 TxCommand *cmd;
644 {
645 int cmdNum;
646
647 switch (cmd->tx_button)
648 {
649 case TX_LEFT_BUTTON:
650 case TX_RIGHT_BUTTON:
651 case TX_MIDDLE_BUTTON:
652 windClientButtons(w, cmd);
653 break;
654 case TX_NO_BUTTON:
655 if (WindExecute(w, windClientID, cmd) >= 0)
656 UndoNext();
657 break;
658 default:
659 ASSERT(FALSE, "windCmdInterp");
660 break;
661 }
662 }
663
664
665 /*
666 * ----------------------------------------------------------------------------
667 * windCmdInit --
668 *
669 * Initialize the window client.
670 *
671 * Results:
672 * None.
673 *
674 * Side effects:
675 * None.
676 * ----------------------------------------------------------------------------
677 */
678
679 void
windClientInit()680 windClientInit()
681 {
682 windClientID = WindAddClient(WINDOW_CLIENT, ( bool (*)() ) NULL,
683 ( bool (*)() ) NULL, ( void (*)() ) NULL, windCmdInterp,
684 ( void (*)() ) NULL, ( bool (*)() ) NULL, ( void (*)() ) NULL,
685 (GrGlyph *) NULL);
686
687 /* Set up all of the window commands */
688
689 #ifdef MAGIC_WRAPPER
690 WindAddCommand(windClientID,
691 "*bypass command run command independently of the command line",
692 windBypassCmd, FALSE);
693 #endif
694 WindAddCommand(windClientID,
695 "*crash cause a core dump",
696 windCrashCmd, FALSE);
697 WindAddCommand(windClientID,
698 "*files print out currently open files",
699 windFilesCmd, FALSE);
700 WindAddCommand(windClientID,
701 "*grstats print out stats on graphics",
702 windGrstatsCmd, FALSE);
703 WindAddCommand(windClientID,
704 "*pause [args] print args and wait for <cr>",
705 windPauseCmd, FALSE);
706 WindAddCommand(windClientID,
707 "*winddebug set debugging mode",
708 windDebugCmd, FALSE);
709 WindAddCommand(windClientID,
710 "*winddump print out debugging info",
711 windDumpCmd, FALSE);
712
713 WindAddCommand(windClientID,
714 "center [x y] center window on the cursor or indicated coordinate",
715 windCenterCmd, FALSE);
716 WindAddCommand(windClientID,
717 "closewindow [name] close a window",
718 windCloseCmd, FALSE);
719 WindAddCommand(windClientID,
720 "cursor return magic coordinates of the cursor",
721 windCursorCmd, FALSE);
722 WindAddCommand(windClientID,
723 "grow blow a window up to full-screen size or back again",
724 windGrowCmd, FALSE);
725 WindAddCommand(windClientID,
726 "help [pattern] print out synopses for all commands valid\n\
727 in the current window (or just those\n\
728 containing pattern)",
729 windHelpCmd, FALSE);
730 WindAddCommand(windClientID,
731 "imacro [char [string]] define or print an interactive macro called char",
732 windIntMacroCmd, FALSE);
733 WindAddCommand(windClientID,
734 "logcommands [file [update]]\n\
735 log all commands into a file",
736 windLogCommandsCmd, FALSE);
737 WindAddCommand(windClientID,
738 "macro [char [string]] define or print a macro called char",
739 windMacroCmd, FALSE);
740 WindAddCommand(windClientID,
741 "openwindow [cell][name]\n\
742 open a new window with indicated name, bound to indicated cell",
743 windOpenCmd, FALSE);
744 WindAddCommand(windClientID,
745 "over move a window over (on top of) the rest",
746 windOverCmd, FALSE);
747 WindAddCommand(windClientID,
748 "pushbutton button act push a mouse button",
749 windPushbuttonCmd, FALSE);
750 WindAddCommand(windClientID,
751 "redo [count] redo commands",
752 windRedoCmd, FALSE);
753 WindAddCommand(windClientID,
754 "redraw redraw the display",
755 windRedrawCmd, FALSE);
756 WindAddCommand(windClientID,
757 "reset reset the display",
758 windResetCmd, FALSE);
759 WindAddCommand(windClientID,
760 "scroll dir [amount] scroll the window",
761 windScrollCmd, FALSE);
762 WindAddCommand(windClientID,
763 "setpoint [x y [WID]] force to cursor (point) to x,y in window WID",
764 windSetpointCmd, FALSE);
765 WindAddCommand(windClientID,
766 "sleep seconds sleep for a number of seconds",
767 windSleepCmd, FALSE);
768 WindAddCommand(windClientID,
769 "specialopen [coords] type [args]\n\
770 open a special window",
771 windSpecialOpenCmd, FALSE);
772 WindAddCommand(windClientID,
773 "quit exit magic",
774 windQuitCmd, FALSE);
775 WindAddCommand(windClientID,
776 "underneath move a window underneath the rest",
777 windUnderCmd, FALSE);
778 WindAddCommand(windClientID,
779 "undo [count] undo commands",
780 windUndoCmd, FALSE);
781 WindAddCommand(windClientID,
782 #ifdef MAGIC_WRAPPER
783 "updatedisplay [suspend|resume]\n\
784 force display update, or suspend/resume updates",
785 #else
786 "updatedisplay force the display to be updated",
787 #endif
788 windUpdateCmd, FALSE);
789 WindAddCommand(windClientID,
790 "version print out version info",
791 windVersionCmd, FALSE);
792 WindAddCommand(windClientID,
793 "view [get] zoom window out so everything is visible",
794 windViewCmd, FALSE);
795 WindAddCommand(windClientID,
796 "windowborder [on|off] toggle border drawing for new windows",
797 windBorderCmd, FALSE);
798 WindAddCommand(windClientID,
799 "windowcaption [on|off] toggle title caption for new windows",
800 windCaptionCmd, FALSE);
801 WindAddCommand(windClientID,
802 "windowscrollbars [on|off]\n\
803 toggle scroll bars for new windows",
804 windScrollBarsCmd, FALSE);
805 WindAddCommand(windClientID,
806 "windowpositions [file] print out window positions",
807 windPositionsCmd, FALSE);
808 WindAddCommand(windClientID,
809 "xview zoom window out so everything is unexpanded",
810 windXviewCmd, FALSE);
811 WindAddCommand(windClientID,
812 "zoom amount zoom window by amount",
813 windZoomCmd, FALSE);
814 WindAddCommand(windClientID,
815 "windownames [all|type] get name of current or all windows",
816 windNamesCmd, FALSE);
817 #ifndef MAGIC_WRAPPER
818 WindAddCommand(windClientID,
819 "echo [-n] [strings] print text on the terminal",
820 windEchoCmd, FALSE);
821 WindAddCommand(windClientID,
822 "send type command send a command to a certain window type",
823 windSendCmd, FALSE);
824 WindAddCommand(windClientID,
825 "source filename read in commands from file",
826 windSourceCmd, FALSE);
827 #endif
828 }
829