home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / toswinsc.zoo / window.c < prev    next >
C/C++ Source or Header  |  1992-10-27  |  15KB  |  757 lines

  1. /*
  2.  * Copyright 1992 Eric R. Smith. All rights reserved.
  3.  * Redistribution is permitted only if the distribution
  4.  * is not for profit, and only if all documentation
  5.  * (including, in particular, the file "copying")
  6.  * is included in the distribution in unmodified form.
  7.  * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
  8.  * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
  9.  * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
  10.  * RISK.
  11.  */
  12. #include <stdlib.h>
  13. #include <gemfast.h>
  14. #include <aesbind.h>
  15. #include <vdibind.h>
  16. #include <osbind.h>
  17. #include <string.h>
  18. #include "xgem.h"
  19.  
  20. #define WF_BEVENT    24
  21.  
  22. #define IM_RESERVE    12345
  23. #define IM_RELEASE    12346
  24.  
  25. /*
  26.  * global variables
  27.  */
  28.  
  29. /* current top window */
  30. WINDOW *gl_topwin;
  31. extern WINDOW *focuswin;
  32.  
  33. /* list of all windows in system */
  34. WINDOW *gl_winlist;
  35.  
  36. /* do we want graf_{grow,shrink}box effects? */
  37. int win_flourishes = 1;
  38.  
  39. /*
  40.  * some dummy functions for windows
  41.  */
  42.  
  43. static void
  44. clear_win(v, x, y, w, h)
  45.     WINDOW *v;
  46.     int x,y,w,h;
  47. {
  48.     int temp[4];
  49.  
  50.     vsf_color(vdi_handle, 0);
  51.     temp[0] = x;
  52.     temp[1] = y;
  53.     temp[2] = x + w - 1;
  54.     temp[3] = y + h - 1;
  55.     v_bar(vdi_handle, temp);
  56.     vsf_color(vdi_handle, 1);
  57. }
  58.  
  59. static void
  60. top_win(w)
  61.     WINDOW *w;
  62. {
  63.     gl_topwin = w;
  64.     wind_set(w->wi_handle, WF_TOP, 0, 0, 0, 0);
  65. }
  66.  
  67. static void
  68. close_win(w)
  69.     WINDOW *w;
  70. {
  71.     destroy_window(w);
  72. }
  73.  
  74. static void
  75. full_win(v)
  76.     WINDOW *v;
  77. {
  78.     int newx, newy, neww, newh;
  79.  
  80.     if (v->flags & WFULLED) {
  81.         wind_get(v->wi_handle, WF_PREVXYWH, &newx, &newy, &neww,
  82.              &newh);
  83.     } else {
  84.         wind_get(v->wi_handle, WF_FULLXYWH, &newx, &newy, &neww,
  85.             &newh);
  86.     }
  87.  
  88.     wind_set(v->wi_handle, WF_CURRXYWH, newx, newy, neww, newh);
  89.     wind_get(v->wi_handle, WF_WORKXYWH, &v->wi_x, &v->wi_y, &v->wi_w,
  90.         &v->wi_h);
  91.  
  92.     v->flags ^= WFULLED;
  93. }
  94.  
  95. static void
  96. move_win(v, x, y, w, h)
  97.     WINDOW *v;
  98.     int x, y, w, h;
  99. {
  100.     int fullx, fully, fullw, fullh;
  101.  
  102.     wind_get(v->wi_handle, WF_FULLXYWH, &fullx, &fully, &fullw, &fullh);
  103.  
  104.     if (w > fullw) w = fullw;
  105.     if (h > fullh) h = fullh;
  106.  
  107.     if (w != fullw || h != fullh)
  108.         v->flags &= ~WFULLED;
  109.  
  110.     wind_set(v->wi_handle, WF_CURRXYWH, x, y, w, h);
  111.     wind_get(v->wi_handle, WF_WORKXYWH, &v->wi_x, &v->wi_y,
  112.         &v->wi_w, &v->wi_h);
  113. }
  114.  
  115. static void
  116. size_win(v, x, y, w, h)
  117.     WINDOW *v;
  118.     int x, y, w, h;
  119. {
  120.     move_win(v, x, y, w, h);
  121. }
  122.  
  123. static void
  124. noslid(w, m)
  125.     WINDOW *w;
  126.     int m;
  127. {
  128. }
  129.  
  130. static int
  131. nokey(w, code)
  132.     WINDOW *w;
  133.     int code;
  134. {
  135.     return 0;
  136. }
  137.  
  138. static int
  139. nomouse(w, clicks, x, y, shift, mbuttons)
  140.     WINDOW *w;
  141.     int clicks, x, y, shift, mbuttons;
  142. {
  143.     return 0;
  144. }
  145.  
  146. static int
  147. iconmouse(v, clicks, x, y, shift, mbuttons)
  148.     WINDOW *v;
  149.     int clicks, x, y, shift, mbuttons;
  150. {
  151.     int w, h;
  152.  
  153.     if (mbuttons) {
  154. /* wait for a little bit */
  155.         evnt_timer(140L);
  156.         graf_mkstate(&x, &y, &mbuttons, &shift);
  157.         if (x < v->wi_x || x > v->wi_x + v->wi_w || y < v->wi_y ||
  158.             y > v->wi_y + v->wi_w)
  159.             return 1;
  160.         if (mbuttons) {        /* button still down */
  161.             wind_update(BEG_MCTRL);
  162.             graf_mouse(FLAT_HAND, 0L);
  163.             wind_get(v->wi_handle, WF_CURRXYWH, &x, &y, &w, &h);
  164.             graf_dragbox(w, h, x, y, xdesk, ydesk, wdesk, hdesk,
  165.                 &x, &y);
  166.             graf_mouse(ARROW, 0L);
  167.             wind_update(END_MCTRL);
  168.             (*v->moved)(v, x, y, w, h);
  169.             return 1;
  170.         }
  171.     }
  172.     (*v->fulled)(v);    /* un-iconify the window */
  173.     return 1;
  174. }
  175.  
  176. /* turn a window into an icon */
  177.  
  178. static void
  179. uniconify_win(v)
  180.     WINDOW *v;
  181. {
  182.     static int mbuf[8];
  183.     int newx, newy, neww, newh;
  184.     int id = appl_find("ICONMGR ");
  185.  
  186.     if (!(v->flags & WICONIFIED)) return;
  187.     if (id >= 0) {
  188.         mbuf[0] = IM_RELEASE;
  189.         mbuf[1] = gl_apid;
  190.         mbuf[2] = 0;
  191.         mbuf[3] = v->icon_slot;
  192.         appl_write(id, 16, mbuf);
  193.     }
  194.     v->fulled = v->oldfulled;
  195.     v->mouseinp = v->oldmouse;
  196.     v->flags &= ~WICONIFIED;
  197.  
  198.     if (win_flourishes) {
  199.         graf_growbox(v->wi_x, v->wi_y, v->wi_w, v->wi_h,
  200.                  v->prevx, v->prevy, v->prevw, v->prevh);
  201.     }
  202.     wind_calc(WC_BORDER, v->old_wkind, v->prevx, v->prevy, v->prevw,
  203.             v->prevh, &newx, &newy, &neww, &newh);
  204.     change_window_gadgets(v, v->old_wkind);
  205.     (*v->sized)(v, newx, newy, neww, newh);
  206.  
  207. /* button events should top the window */
  208.     wind_set(v->wi_handle, WF_BEVENT, 0x0000, 0, 0, 0);
  209.     (*v->topped)(v);
  210. }
  211.  
  212. static void
  213. iconify_win(v, slot, x, y, w, h)
  214.     WINDOW *v;
  215.     int slot, x, y, w, h;
  216. {
  217.     if (v->flags & WICONIFIED)
  218.         return;
  219.     v->flags &= ~WFULLED;
  220.     v->flags |= WICONIFIED;
  221.     v->oldfulled = v->fulled;
  222.     v->oldmouse = v->mouseinp;
  223.     v->icon_slot = slot;
  224.     v->old_wkind = v->wi_kind;
  225.  
  226.     v->prevx = v->wi_x;
  227.     v->prevy = v->wi_y;
  228.     v->prevw = v->wi_w;
  229.     v->prevh = v->wi_h;
  230.     change_window_gadgets(v, 0);
  231.     if (win_flourishes) {
  232.         graf_shrinkbox(x, y, w, h, v->prevx, v->prevy, v->prevw,
  233.                 v->prevh);
  234.     }
  235.     (*v->sized)(v, x, y, w, h);
  236.  
  237. /* we don't want the window topped inadvertently */
  238.     wind_set(v->wi_handle, WF_BEVENT, 0x0001, 0, 0, 0);
  239.     v->fulled = uniconify_win;
  240.     v->mouseinp = iconmouse;
  241.     new_topwin(1);
  242. }
  243.  
  244. /*
  245.  * Create a new window with title "title," initial/full size x, y, w, h,
  246.  * and gadgets given by "kind." Returns a pointer to the new window,
  247.  * or NULL if an error occurs. The window is not actually opened,
  248.  * however.
  249.  */
  250.  
  251. /* used to "stagger" opening positions of windows */
  252. #define WOFF_INC gl_hbox
  253. #define WOFF_MAX 64
  254.  
  255. static int winoff = 0;
  256.  
  257. WINDOW *
  258. create_window(title, kind, wx, wy, ww, wh)
  259.     const char *title;
  260.     int kind, wx, wy, ww, wh;
  261. {
  262.     WINDOW *v;
  263.     int fullx, fully, fullw, fullh;
  264.     int centerwin = 0;
  265.  
  266.     if (title) {
  267.         title = strdup(title);
  268.     }
  269.  
  270.     v = malloc(sizeof(WINDOW));
  271.     if (!v) return v;
  272.  
  273.     v->wi_handle = -1;    /* not open yet */
  274.     v->wi_kind = kind;
  275.  
  276.     if (wx == 0 && wy == 0) centerwin = 1;
  277.     if (wx < xdesk) wx = xdesk;
  278.     if (wy < ydesk) wy = ydesk;
  279.  
  280. /* calculate max. window size needed for a working area of ww x wh */
  281.     wind_calc(WC_WORK, v->wi_kind, wx, wy, wdesk, hdesk,
  282.          &v->wi_x, &v->wi_y, &v->wi_w, &v->wi_h);
  283.     wind_calc(WC_BORDER, v->wi_kind, v->wi_x, v->wi_y, ww, wh,
  284.          &fullx, &fully, &fullw, &fullh);
  285.  
  286.     if (fullw > wdesk)
  287.         fullw = wdesk;
  288.     if (fullh > hdesk)
  289.         fullh = hdesk;
  290.  
  291.     if (centerwin) {
  292.         fullx = xdesk;
  293.         fully = ydesk;
  294.     }
  295.  
  296.  
  297.     fullx += winoff;
  298.     fully += winoff;
  299.     winoff += WOFF_INC;
  300.     if (winoff > WOFF_MAX) {
  301.         winoff = 0;
  302.     }
  303.  
  304.     v->wi_title = (char *)title;
  305.     v->wi_fullx = fullx;
  306.     v->wi_fully = fully;
  307.     v->wi_fullw = fullw;
  308.     v->wi_fullh = fullh;
  309.  
  310.     wind_calc(WC_WORK, v->wi_kind, fullx, fully, fullw, fullh,
  311.           &v->wi_x, &v->wi_y, &v->wi_w, &v->wi_h);
  312.  
  313.     v->wtype = GENERIC_WIN;
  314.     v->extra = (void *)0;
  315.     v->icon_slot = -1;
  316.     v->flags = 0;
  317.  
  318.     v->draw = clear_win;
  319.     v->topped = top_win;
  320.     v->closed = close_win;
  321.     v->fulled = full_win;
  322.     v->sized = size_win;
  323.     v->moved = move_win;
  324.     v->arrowed = noslid;
  325.     v->hslid = noslid;
  326.     v->vslid = noslid;
  327.     v->keyinp = nokey;
  328.     v->mouseinp = nomouse;
  329.     v->iconify = iconify_win;
  330.     v->oldfulled = v->fulled;
  331.     v->oldmouse = nomouse;
  332.  
  333.     v->menu = 0;
  334.     v->infostr = 0;
  335.  
  336.     v->next = gl_winlist;
  337.     gl_winlist = v;
  338.     return v;
  339. }
  340.  
  341. WINDOW *
  342. open_window(v)
  343.     WINDOW *v;
  344. {
  345.     int wx, wy, ww, wh;
  346.  
  347.     if (v->wi_handle >= 0)        /* already open?? */
  348.         return v;
  349.  
  350.     v->wi_handle = wind_create(v->wi_kind, v->wi_fullx, v->wi_fully,
  351.                 v->wi_fullw, v->wi_fullh);
  352.  
  353.     if (v->wi_handle < 0)
  354.         return 0;
  355.  
  356.     wind_set(v->wi_handle, WF_BEVENT, 0x0000, 0, 0, 0);
  357.     if (v->wi_kind & NAME) {
  358.         if (v->wi_title)
  359.             wind_set(v->wi_handle, WF_NAME, v->wi_title);
  360.         else
  361.             wind_set(v->wi_handle, WF_NAME, "Untitled");
  362.     }
  363.     if (v->wi_kind & INFO) {
  364.         if (v->infostr) {
  365.             wind_set(v->wi_handle, WF_INFO, v->infostr);
  366.         } else {
  367.             wind_set(v->wi_handle, WF_INFO, "");
  368.         }
  369.     }
  370.  
  371.     wind_calc(WC_BORDER, v->wi_kind, v->wi_x, v->wi_y, v->wi_w, v->wi_h,
  372.         &wx, &wy, &ww, &wh);
  373.  
  374.     if (win_flourishes)
  375.         graf_growbox(wx + ww/2, wy + wh/2, gl_wbox ,gl_hbox,
  376.                  wx, wy, ww, wh);
  377.  
  378.     wind_open(v->wi_handle, wx, wy, ww, wh);
  379.  
  380.     (*v->topped)(v);
  381. /* set scroll bars, etc. correctly */
  382.     (*v->sized)(v, wx, wy, ww, wh);
  383.     return v;
  384. }
  385.  
  386. void
  387. close_window(v)
  388.     WINDOW *v;
  389. {
  390.     int i, dummy;
  391.  
  392.     if (v->wi_handle < 0)    /* already closed? */
  393.         return;
  394.  
  395.     wind_close(v->wi_handle);
  396.     if (win_flourishes)
  397.         graf_shrinkbox(v->wi_x + v->wi_w/2, v->wi_y + v->wi_h/2,
  398.             gl_wbox, gl_hbox, v->wi_x, v->wi_y, v->wi_w, v->wi_h);
  399.     wind_delete(v->wi_handle);
  400.     v->wi_handle = -1;
  401.  
  402. /* reset gl_topwin */
  403.     gl_topwin = 0;
  404.     wind_get(0, WF_TOP, &i, &dummy, &dummy, &dummy);
  405.     for (v = gl_winlist; v; v = v->next) {
  406.         if (v->wi_handle == i)
  407.             break;
  408.     }
  409.     if (v && !(v->flags & WICONIFIED))
  410.         (*v->topped)(v);
  411. }
  412.  
  413. /*
  414.  * destroy a window
  415.  */
  416.  
  417. void
  418. destroy_window(v)
  419.     WINDOW *v;
  420. {
  421.     WINDOW **ptr, *w;
  422.     extern void unloadmenu();
  423.  
  424.     if (v->wi_handle >= 0) {
  425.         close_window(v);
  426.     }
  427.  
  428.     if (v->wi_title)
  429.         free(v->wi_title);
  430.  
  431.     if (v->infostr)
  432.         free(v->infostr);
  433.  
  434. /* find v in the window list, and unlink it */
  435.     ptr = &gl_winlist;
  436.     w = *ptr;
  437.     while (w) {
  438.         if (w == v) {
  439.             *ptr = v->next;
  440.             break;
  441.         }
  442.         ptr = &w->next;
  443.         w = *ptr;
  444.     }
  445. /* maybe we should have an error here if v isn't found */
  446.  
  447.     free(v);
  448. }
  449.  
  450. /*
  451.  * redraw all parts of a window that lie within the rectangle
  452.  * xc, yc, wc, hc
  453.  */
  454.  
  455. void
  456. redraw_window(v, xc, yc, wc, hc)
  457.     WINDOW *v;
  458.     int xc, yc, wc, hc;
  459. {
  460.     GRECT    t1, t2;
  461.     int temp[4];
  462.  
  463.     wind_update(TRUE);
  464.     hide_mouse();
  465.     t2.g_x = xc;
  466.     t2.g_y = yc;
  467.     t2.g_w = wc;
  468.     t2.g_h = hc;
  469.     wind_get(v->wi_handle, WF_FIRSTXYWH,
  470.          &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  471.  
  472.     while (t1.g_w && t1.g_h) {
  473.         if (rc_intersect(&t2, &t1)) {
  474.             temp[0] = t1.g_x;
  475.             temp[1] = t1.g_y;
  476.             temp[2] = temp[0]+t1.g_w-1;
  477.             temp[3] = temp[1]+t1.g_h-1;
  478.             vs_clip(vdi_handle, 1, temp);
  479.             (*v->draw)(v, t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  480.           }
  481.         wind_get(v->wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y,
  482.              &t1.g_w, &t1.g_h);
  483.     }
  484.     show_mouse();
  485.     wind_update(FALSE);
  486. }
  487.  
  488. /*
  489.  * find a window
  490.  */
  491.  
  492. WINDOW *
  493. which_window(x)
  494.     int x;
  495. {
  496.     WINDOW *w;
  497.  
  498.     if (x < 0) return 0;
  499.  
  500.     for (w = gl_winlist; w; w = w->next)
  501.         if (w->wi_handle == x)
  502.             return w;
  503.     return 0;
  504. }
  505.  
  506. /*
  507.  * handle an evnt_multi message dealing with windows
  508.  */
  509.  
  510. void
  511. handle_window(msgbuff)
  512.     int *msgbuff;
  513. {
  514.     WINDOW *v;
  515.  
  516.     v = which_window(msgbuff[3]);
  517.     if (!v) {    /* hmmm, not our window? */
  518.         return;
  519.     }
  520.  
  521.     switch(msgbuff[0]) {
  522.     case WM_REDRAW:
  523.         redraw_window(v, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  524.         break;
  525.     case WM_TOPPED:
  526.         (*v->topped)(v);
  527.         break;
  528.     case WM_SIZED:
  529.         (*v->sized)(v, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  530.         break;
  531.     case WM_MOVED:
  532.         (*v->moved)(v, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  533.         break;
  534.     case WM_FULLED:
  535.         (*v->fulled)(v);
  536.         break;
  537.     case WM_ARROWED:
  538.         (*v->arrowed)(v, msgbuff[4]);
  539.         break;
  540.     case WM_HSLID:
  541.         (*v->hslid)(v, msgbuff[4]);
  542.         break;
  543.     case WM_VSLID:
  544.         (*v->vslid)(v, msgbuff[4]);
  545.         break;
  546.     case WM_CLOSED:
  547.         (*v->closed)(v);
  548.         break;
  549.     }
  550. }
  551.  
  552. int
  553. window_key(keycode, shift)
  554.     int keycode, shift;
  555. {
  556.     MENU *m;
  557.     ENTRY *e;
  558.     WINDOW *w;
  559.  
  560.     w = focuswin;    /* set in evnt_loop */
  561.  
  562.     if (w) {
  563. /* first, check for window specific menu shortcut keys */
  564.         for (m = w->menu; m; m = m->next) {
  565.             for (e = m->contents; e; e = e->next) {
  566.                 if (e->keycode == keycode) {
  567.                     (*e->func)(e->arg);
  568.                     return 1;
  569.                 }
  570.             }
  571.         }
  572.  
  573. /* otherwise, pass the key along to the general window handling thing */
  574.         return (*w->keyinp)(w, keycode, shift);
  575.     }
  576.     else
  577.         return 0;
  578. }
  579.  
  580. int
  581. window_click(clicks, x, y, kshift, mbutton)
  582.     int clicks, x, y, kshift, mbutton;
  583. {
  584.     WINDOW *w;
  585.  
  586. /* find the window that got clicked in (if any) */
  587.     w = find_window(x, y);
  588.     if (w) {
  589.         return (*w->mouseinp)(w, clicks, x, y, kshift, mbutton);
  590.     }
  591.     return 0;
  592. }
  593.  
  594. /*
  595.  * close and delete all windows
  596.  */
  597.  
  598. void
  599. end_windows()
  600. {
  601.     WINDOW *v;
  602.  
  603.     v = gl_winlist;
  604.     while (v) {
  605.         gl_winlist = v->next;
  606.         if (v->wi_handle >= 0) {
  607.             wind_close(v->wi_handle);
  608.             wind_delete(v->wi_handle);
  609.         }
  610.         free(v);
  611.         v = gl_winlist;
  612.     }
  613. }
  614.  
  615. /*
  616.  * force a redraw of a whole window
  617.  */
  618.  
  619. void
  620. force_redraw(v)
  621.     WINDOW *v;
  622. {
  623.     redraw_window(v, v->wi_x, v->wi_y, v->wi_w, v->wi_h);
  624.     if (v->wtype == TEXT_WIN)
  625.         mark_clean(v->extra);
  626. }
  627.  
  628. /*
  629.  * find out which window lies under the point (x,y). Returns a pointer
  630.  * to the window, or NULL
  631.  */
  632.  
  633. WINDOW *
  634. find_window(x, y)
  635.     int x, y;
  636. {
  637.     int wx, wy, ww, wh;
  638.     WINDOW *w;
  639.  
  640.     wind_update(1);    /* lock the screen -- we don't want it changing */
  641.     for (w = gl_winlist; w; w = w->next) {
  642.         if (w->wi_handle < 0) continue;
  643.         wind_get(w->wi_handle, WF_FIRSTXYWH, &wx, &wy, &ww, &wh);
  644.         while (ww && wh) {
  645.             if (x >= wx && x <= wx + ww &&
  646.                 y >= wy && y <= wy + wh)
  647.                 goto found_window;
  648.             wind_get(w->wi_handle, WF_NEXTXYWH, &wx, &wy, &ww, &wh);
  649.         }
  650.     }
  651. found_window:
  652.     wind_update(0);
  653.     return w;    /* w will be null if no window found */
  654. }
  655.  
  656. void
  657. change_window_gadgets(w, newkind)
  658.     WINDOW *w;
  659.     int newkind;
  660. {
  661.     int reopen = 0;
  662.     int nx, ny, nw, nh;
  663.     int oldflourishes;
  664.  
  665.     if (newkind == w->wi_kind) return;    /* no change */
  666.  
  667.     oldflourishes = win_flourishes;
  668.     win_flourishes = 0;
  669.  
  670.     if (w->wi_handle >= 0) {
  671.         wind_close(w->wi_handle);
  672.         wind_delete(w->wi_handle);
  673.         w->wi_handle = -1;
  674.         reopen = 1;
  675.     }
  676.  
  677.     wind_calc(WC_WORK, w->wi_kind, w->wi_fullx, w->wi_fully, w->wi_fullw,
  678.             w->wi_fullh, &nx, &ny, &nw, &nh);
  679.     wind_calc(WC_BORDER, newkind, nx, ny, nw, nh, &nx,
  680.             &ny, &w->wi_fullw, &w->wi_fullh);
  681.  
  682.     if (w->wi_fullw > wdesk)
  683.         w->wi_fullw = wdesk;
  684.     if (w->wi_fullh > hdesk)
  685.         w->wi_fullh = hdesk;
  686.  
  687.     if (w->wi_fullx < xdesk)
  688.         w->wi_fullx = xdesk;
  689.     if (w->wi_fully < ydesk)
  690.         w->wi_fully = ydesk;
  691.  
  692.     wind_calc(WC_BORDER, w->wi_kind, w->wi_x, w->wi_y, w->wi_w, w->wi_h,
  693.             &nx, &ny, &nw, &nh);
  694.     if (nw > w->wi_fullw)
  695.         nw = w->wi_fullw;
  696.     if (nh > w->wi_fullh)
  697.         nh = w->wi_fullh;
  698.  
  699.     wind_calc(WC_WORK, newkind, nx, ny, nw, nh, &w->wi_x, &w->wi_y,
  700.             &w->wi_w, &w->wi_h);
  701.  
  702.     w->wi_kind = newkind;
  703.  
  704.     if (reopen) {
  705.         open_window(w);
  706.     }
  707.     win_flourishes = oldflourishes;
  708. }
  709.  
  710. /*
  711.  * new_topwin: reset the top window so that it doesn't match the current
  712.  * top window (if that's possible). If force == 0, then we allow the current
  713.  * window to remain on top, otherwise we pretend that no window is on
  714.  * top
  715.  */
  716.  
  717. void
  718. new_topwin(force)
  719.     int force;
  720. {
  721.     WINDOW *w;
  722.     int mbuf[8];
  723.  
  724.     w = gl_topwin;
  725.     if (!w) return;
  726.     for(;;) {
  727.         w = w->next;
  728.         if (!w) w = gl_winlist;
  729.         if (w->wi_handle >= 0 && !(w->flags & WICONIFIED)) break;
  730.         if (w == gl_topwin) break;
  731.     }
  732.     if (w != gl_topwin) {
  733.         mbuf[0] = WM_TOPPED;
  734.         mbuf[1] = gl_apid;
  735.         mbuf[2] = 0;
  736.         mbuf[3] = w->wi_handle;
  737.         mbuf[4] = mbuf[5] = mbuf[6] = mbuf[7] = 0;
  738.         appl_write(gl_apid, 16, mbuf);
  739.     } else if (force) {
  740.         gl_topwin = 0;
  741.     }
  742. }
  743.  
  744. /* set a window title */
  745.  
  746. void
  747. title_window(w, title)
  748.     WINDOW *w; char *title;
  749. {
  750.     if (w->wi_title)
  751.         free(w->wi_title);
  752.     w->wi_title = strdup(title);
  753.     if (w->wi_handle >= 0 && (w->wi_kind & NAME)) {
  754.         wind_set(w->wi_handle, WF_NAME, w->wi_title);
  755.     }
  756. }
  757.