tomm@voodoo.voodoo.uucp (Tom Mackey) (10/25/90)
I am doing some research right now on building multiple-window applications. I am playing with the multiwin program taken from the 4sight Programmer's guide, section 4.2. Note that in the function dodrawing, the reshapeviewport() and ortho() calls need to be moved above the color() and clear() calls. Also, the '0' near the end of each printf format string should be replaced with '\n"'. Must be some kind of typesetting screw-up ;^) Anyways, the program with added comments and de-linted appears at the end of my question, in case you are inclined to mess with it, but don't want to type it in. I've taken the liberty of imposing my own programming style; I hope it doesn't hurt anyone's feelings over in SGI-land. Here's the problem and question: If you run it so as to get several windows, and then "iconify" some of them, either by selecting the 'Stow' menu entry or by clicking on the stow window border button, and then try to tidy them either by selecting the 'Tidy' icon menu entry or the 'Tidy Icons' menu entry from the Windows toolchest, the iconified window is put in a strange state. It no longer opens with a LeftMouseButton hit, but instead changes color as if it were open, and cannot be picked and moved with a MiddleMouseButton hit, and does not respond with a popup menu given a RightMouseButton hit. It does close when the multiwin program is exited by selecting the 'Quit Multiwin' menu selection. There are no events entered on the queue when the icon is told to 'tidy'; I attempted to verify this by queueing all devices between 523 and 546 and then watching for them at the default case in the doqueue() switch statement... maybe there is some undocumented device??? The question boils down to: what do I have to do to make multiple windows behave under the window system, including having icons respond to a tidy request? And another thing: If I close multiwin window by window, all but the last get a WINSHUT as expected, but the last close generates a WINQUIT instead! Pretty neat, but how do it know??? Any and all replies or ideas appreciated! -------------------------------- cut here ----------------------------------- /*************************************************************************** * * Program: multiwin * * Description: sample program of multiple windows in a single process. * * Compile: cc -o multiwin multiwin.c -lgl_s * * To run: multiwin X * * The argument X determins how many windows to open (try 3, 5 max) * * The lwft mouse button cycles the color used to redraw the * background of each window. * ***************************************************************************/ #include <stdio.h> #include <gl.h> #include <device.h> /* ** declarations of functions from outside this module */ extern void exit(int); /* ** declarations of functions defined in this module */ void do_queue(short, short); void do_drawing(char *, short); int which_window(int); /* ** Other Defines */ #define MAXWINS 5 #define MINWINS 1 typedef struct { int gid; /* window identifier */ int color; /* what color is this window */ int iconic; /* is this window iconic or not */ int dblbuffered; /* is this window double-buffered or not */ } wrecord; /* ** static global variables used in this module */ static wrecord wins[MAXWINS+1]; /* mapping between windows and gid's etc. */ /* zero'th slot left empty */ static int current_win = 0; /* which window has input focus */ static int nwins = 0; /* how many windows to start with */ /*ARGSUSED*/ /* who uses the environment pointer? */ main(int argc, char *argv[], char **envp) { short dev, val; /* shouldn't that be long dev; short val; ? */ char buf[100]; int i; /* handy index variable */ if (argc < 2) { (void) fprintf(stderr,"usage: %s window_count\n", argv[0]); exit(1); } nwins = atoi(argv[1]); if (nwins > MAXWINS) { (void) fprintf(stderr,"%s: too many windows (%d)\n", argv[0], nwins); (void) fprintf(stderr,"maximum of %d\n", MAXWINS); exit(1); } if (nwins < MINWINS) { (void) fprintf(stderr,"%s: too few windows (%d)\n", argv[0], nwins); (void) fprintf(stderr,"minimum of %d\n", MINWINS); exit(1); } for (i=1; i<=nwins; i++) { iconsize(85, 66); /* needed to get control for drawing icon */ wins[i].gid = winopen("MultiWin"); wins[i].color = 1; wins[i].dblbuffered = FALSE; (void) sprintf(buf, "win %d of %d", i, nwins); wintitle(buf); ortho2(0.0, 10.0, 0.0, 10.0); if (i==1) { doublebuffer(); /* one window double-buffered */ gconfig(); wins[i].dblbuffered = TRUE; /* ** Device queued/unqueued is not a per window attribute ** so only needs to be done once. ** ** Both REDRAW and INPUTCHANGE are implicitly queued ** by winopen(): ** ** qdevice(REDRAW); ** tell us to redraw normal image ** qdevice(INPUTCHANGE); ** tell us when input changes */ qdevice(REDRAWICONIC); /* tell us to redraw iconic image */ qdevice(WINFREEZE); /* tell us of stow */ qdevice(WINTHAW); /* tell us of open (unstow) */ qdevice(WINQUIT); /* tell us of quit */ qdevice(WINSHUT); /* tell us of close */ qdevice(LEFTMOUSE); /* tell us of left mouse toggles */ } qenter(REDRAW, wins[i].gid); /* so they draw first time around */ } while (dev = (short)qread(&val)) { do_queue(dev, val); } exit(0); return 0; } void do_queue(short dev, short val) { switch (dev) { case LEFTMOUSE: if (val) /* activate on downstroke */ { (void) printf("got LEFTMOUSE, %d off graphics queue\n", val); wins[current_win].color++; if (wins[current_win].color > 7) { wins[current_win].color = 1; } if (wins[current_win].iconic) { qenter(REDRAWICONIC, wins[current_win].gid); } else { qenter(REDRAW, wins[current_win].gid); } } break; case REDRAW: (void) printf("got REDRAW, %d off graphics queue\n", val); /* ** for window with gid == val, redraw the contents */ do_drawing("Redraw", val); break; case INPUTCHANGE: (void) printf("got INPUTCHANGE, %d off graphics queue\n", val); /* ** input now directed to window with gid == val, 0 => no input */ current_win = which_window(val); break; case REDRAWICONIC: (void) printf("got REDRAWICONIC, %d off graphics queue\n", val); /* ** for window with gid == val, redraw the iconic form */ do_drawing("Iconic", val); break; case WINFREEZE: (void) printf("got WINFREEZE, %d off graphics queue\n", val); /* ** for window with gid == val, do iconic processing */ wins[which_window(val)].iconic = TRUE; break; case WINTHAW: (void) printf("got WINTHAW, %d off graphics queue\n", val); /* ** for window with gid == val, go back to normal processing */ wins[which_window(val)].iconic = FALSE; break; case WINSHUT: (void) printf("got WINSHUT, %d off graphics queue\n", val); /* ** user wants to dismiss window with gid == val */ wins[which_window(val)].gid = 0; winclose(val); break; case WINQUIT: (void) printf("got WINQUIT, %d off graphics queue\n", val); /* ** user wants to dismiss the whole process */ exit(0); break; default: (void) printf("got %d, %d off graphics queue\n", dev, val); break; } } void do_drawing(char *s, short val) { int win_index; winset(val); /* set to window that needs redrawing */ win_index = which_window(val); reshapeviewport(); ortho2(0.0, 10.0, 0.0, 10.0); /* ** fill window with its present color */ color(wins[win_index].color); clear(); /* ** set color to black and output character string in window */ color(0); cmov2i(1,3); charstr(s); if (wins[win_index].dblbuffered) { swapbuffers(); } } int which_window(int gid) { int i; int index = 0; /* assume window is closed */ for (i=1; i<=nwins; i++) { if (wins[i].gid == gid) { index = i; /* found valid window */ break; } } return index; } -------------------------------- cut here ----------------------------------- -- Tom Mackey (206) 865-6575 tomm@voodoo.boeing.com Boeing Computer Services ....uunet!bcstec!voodoo!tomm M/S 7K-20, P.O. Box 24346, Seattle, WA 98124-0346
msc@ramoth.esd.sgi.com (Mark Callow) (10/31/90)
In article <496@voodoo.UUCP>, tomm@voodoo.voodoo.uucp (Tom Mackey) writes: |> Here's the problem and question: If you run it so as to get |> several windows, and then "iconify" some of them, either by |> selecting the 'Stow' menu entry or by clicking on the stow window |> border button, and then try to tidy them either by selecting the |> 'Tidy' icon menu entry or the 'Tidy Icons' menu entry from the |> Windows toolchest, the iconified window is put in a strange state. This sounds like it might be a bug. You should be receiving a REDRAWICONIC since you've queued that event. There is no special tidy icon event. |> And another thing: If I close multiwin window by window, all but |> the last get a WINSHUT as expected, but the last close generates a |> WINQUIT instead! Pretty neat, but how do it know??? The window server (NeWS server) remembers all the windows your program opened and keeps track of them. We worked pretty hard to make this multiwindow stuff sensible. -- From the TARDIS of Mark Callow msc@ramoth.sgi.com, ...{ames,decwrl}!sgi!msc "There is much virtue in a window. It is to a human being as a frame is to a painting, as a proscenium to a play. It strongly defines its content."
tomm@uucp (Tom Mackey) (11/01/90)
In article <1990Oct30.234824.109@odin.corp.sgi.com> msc@sgi.com writes: >In article <496@voodoo.UUCP>, tomm@voodoo.voodoo.uucp (Tom Mackey) writes: >|> Here's the problem and question: If you run it so as to get >|> several windows, and then "iconify" some of them, either by >|> selecting the 'Stow' menu entry or by clicking on the stow window >|> border button, and then try to tidy them either by selecting the >|> 'Tidy' icon menu entry or the 'Tidy Icons' menu entry from the >|> Windows toolchest, the iconified window is put in a strange state. >This sounds like it might be a bug. You should be receiving a REDRAWICONIC >since you've queued that event. There is no special tidy icon event. I agree; and double-checked: no REDRAWICONIC event is received when I request a "Tidy." BTW, the square clock that iconifies to a working clock exhibits the same behavior, while the round and modern clocks which iconify to a "standard" shaded blue icon work correctly. It almost seems as if I need to link some special C-code with the PostScript code that handles iconification, or some special PostScript code with my function that redraws the icon. Or, as you mention, it might be a (GASP) bug! All in all, this is the first time I have dealt with window events at this level and am really enjoying it. I can imagine that a NeWS and GL hybrid would be capable of some way cool stuff. I just hope we don't lose too much when we all sink to the LCD of X! (Thats Lowest Common Denominator, BTW) >|> And another thing: If I close multiwin window by window, all but >|> the last get a WINSHUT as expected, but the last close generates a >|> WINQUIT instead! Pretty neat, but how do it know??? > >The window server (NeWS server) remembers all the windows your program opened >and keeps track of them. We worked pretty hard to make this multiwindow >stuff sensible. And I, for one, thank you for that! I just combined the more sophisticated event handling code from the trackball example with the multiwin program from the text, and it turned out pretty good. >-- >From the TARDIS of Mark Callow >msc@ramoth.sgi.com, ...{ames,decwrl}!sgi!msc >"There is much virtue in a window. It is to a human being as a frame is to >a painting, as a proscenium to a play. It strongly defines its content." Thanks for your reply, Mark! -- Tom Mackey (206) 865-6575 tomm@voodoo.boeing.com Boeing Computer Services ....uunet!bcstec!voodoo!tomm M/S 7K-20, P.O. Box 24346, Seattle, WA 98124-0346