_doswin.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:21k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _doswin.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/impl/doswin.h>
  12. #include <LEDA/bitmaps/leda_icon.xbm>
  13. //------------------------------------------------------------------------------
  14. // event handling, window manager, etc ...                                    
  15. //------------------------------------------------------------------------------
  16. static char read_kbd()
  17. {
  18. #if defined(__EMX__)
  19.    return _read_kbd(0,0,0); 
  20. #else
  21.    return (kbhit()) ? getch() : 0; 
  22. #endif
  23.  }
  24. const int root_color = blue2; 
  25. const int label_col0 = grey2;
  26. const int label_col1 = grey2; 
  27. const int  win_max = 16;
  28. DosWindow  win_stack[win_max];
  29. int        win_top = 0;
  30. #define BORDER_W 5
  31. #define HEADER_W 20 
  32. static int display = 0;
  33. static int mouse_installed=0;
  34. static int mouse_two_buttons=0;
  35. static DosWindow root_win = 0;
  36. static DosWindow active_win = 0;
  37. static int pointer_shape = 0;
  38. static int pointer_visible = 0;
  39. static int mouse_x = 320;
  40. static int mouse_y = 240;
  41. static int event_buffer_e = -1;
  42. static int event_buffer_val;
  43. static DosWindow event_buffer_win;
  44. static int last_event_e;
  45. static int last_event_val;
  46. static DosWindow last_event_win;
  47. static int save_mode;
  48. static int save_lw;
  49. static int save_ls;
  50. static void show_pointer()
  51. { if (!pointer_visible) 
  52.      draw_pointer(mouse_x,mouse_y,pointer_shape); 
  53.   pointer_visible = 1;
  54.  }
  55. static void hide_pointer()
  56. { if (pointer_visible) 
  57.      draw_pointer(mouse_x,mouse_y,pointer_shape); 
  58.   pointer_visible = 0;
  59.  }
  60. static void set_pointer_shape(int shape)
  61. { if (pointer_shape != shape) 
  62.   { hide_pointer();
  63.     pointer_shape = shape;
  64.     show_pointer();
  65.   }
  66.  }
  67. static void put_header(DosWindow win)
  68. { char str[80];
  69.   int n = (win->width - 40)/text_width("H");
  70.   strncpy(str,win->header,n);
  71.   str[n] = 0;
  72.   put_ctext(root_win->id,win->x0 + win->width/2 + 20, win->y0 + 10 ,str,0);
  73.  }
  74. static void set_header(DosWindow win, const char* s)
  75. { int save_co = set_color(win->label_col);
  76.   int save_mo = set_mode(0);
  77.   put_header(win);
  78.   if (s != win->header) strcpy(win->header,s);
  79.   set_color(1);
  80.   put_header(win);
  81.   set_color(save_co);
  82.   set_mode(save_mo);
  83.  }
  84. void set_header(Window win, const char* s) { set_header(win_stack[win],s); }
  85. void draw_window(DosWindow win, int clear_win = 1)
  86. {
  87.   int bw  = win->xpos - win->x0 - 2;
  88.   int lw  = win->ypos - win->y0 - 2;
  89.   int bw1 = 2*(bw+1);
  90.   int x0 = win->x0;
  91.   int y0 = win->y0;
  92.   int x1 = win->x1;
  93.   int y1 = win->y1;
  94.   int save_mode = set_mode(0);
  95.   if (clear_win)
  96.   { set_color(win->bg_col);
  97.     box(root_win->id,x0,y0,x1,y1);
  98.    }
  99.   set_color(win->label_col);
  100.   box(root_win->id,x0+bw,y0+bw,x1-bw,y0+lw);
  101.   box(root_win->id,x0,y0+bw1,x0+bw,y1-bw1);
  102.   box(root_win->id,x1-bw,y0+bw1,x1,y1-bw1);
  103.   box(root_win->id,x0+bw1,y1-bw,x1-bw1,y1);
  104.   box(root_win->id,x0+bw1,y0,x1-bw1,y0+bw);
  105.   set_color(1);
  106.   rectangle(root_win->id,x0,y0,x1,y1);
  107.   line(root_win->id,x0+bw,y0+bw,x0+bw1,y0+bw);
  108.   line(root_win->id,x0+bw1,y0+bw,x0+bw1,y0+1);
  109.   line(root_win->id,x0+bw1,y0+1,x1-bw1,y0+1);
  110.   line(root_win->id,x1-bw1,y0+1,x1-bw1,y0+bw);
  111.   line(root_win->id,x1-bw1,y0+bw,x1-bw,y0+bw);
  112.   line(root_win->id,x1-bw,y0+bw,x1-bw,y0+bw1);
  113.   line(root_win->id,x1-bw,y0+bw1,x1-1,y0+bw1);
  114.   line(root_win->id,x1-1,y0+bw1,x1-1,y1-bw1);
  115.   line(root_win->id,x1-1,y1-bw1,x1-bw,y1-bw1);
  116.   line(root_win->id,x1-bw,y1-bw1,x1-bw,y1-bw);
  117.   line(root_win->id,x1-bw,y1-bw,x1-bw1,y1-bw);
  118.   line(root_win->id,x1-bw1,y1-bw,x1-bw1,y1-1);
  119.   line(root_win->id,x1-bw1,y1-1,x0+bw1,y1-1);
  120.   line(root_win->id,x0+bw1,y1-1,x0+bw1,y1-bw);
  121.   line(root_win->id,x0+bw1,y1-bw,x0+bw,y1-bw);
  122.   line(root_win->id,x0+bw,y1-bw,x0+bw,y1-bw1);
  123.   line(root_win->id,x0+bw,y1-bw1,x0+1,y1-bw1);
  124.   line(root_win->id,x0+1,y1-bw1,x0+1,y0+bw1);
  125.   line(root_win->id,x0+1,y0+bw1,x0+bw,y0+bw1);
  126.   line(root_win->id,x0+bw,y0+bw1,x0+bw,y0+bw);
  127.   rectangle(root_win->id, win->xpos-1, win->ypos-1,
  128.                       win->xpos+win->width, win->ypos+win->height);
  129.   // iconize-button
  130.   set_color(0);
  131.   box(root_win->id,x0+13,y0+3,x0+27,y0+15);
  132.   set_color(1);
  133.   rectangle(root_win->id,x0+13,y0+3,x0+27,y0+15);
  134.   line(root_win->id,x0+14,y0+16,x0+28,y0+16);
  135.   line(root_win->id,x0+28,y0+4,x0+28,y0+15);
  136.   line(root_win->id,x0+17,y0+6,x0+23,y0+6);
  137.   line(root_win->id,x0+16,y0+6,x0+20,y0+13);
  138.   line(root_win->id,x0+17,y0+6,x0+20,y0+13);
  139.   line(root_win->id,x0+24,y0+6,x0+20,y0+13);
  140.   line(root_win->id,x0+23,y0+6,x0+20,y0+13);
  141.   set_header(win->id,win->header);
  142.   set_mode(save_mode);
  143. }
  144. Window open_window(int x,int y,int width,int height,int bg,
  145.                    const char* header, const char* label)
  146.   if (win_top > 0)  // deactivate top window
  147.   { DosWindow w = win_stack[win_top];
  148.     w->label_col = label_col0;
  149.     draw_window(w,0);
  150.    }
  151.   DosWindow win = new dos_window;
  152.   win_stack[++win_top] = win;
  153.   win->id = win_top;
  154.   strcpy(win->header," ");
  155.   strcpy(win->label,label);
  156.   win->bg_col = bg;
  157.   win->label_col = label_col0;
  158.   width  += 2*BORDER_W;
  159.   height += HEADER_W+BORDER_W;
  160.   win->x0 = x;
  161.   win->y0 = y;
  162.   win->x1 = x+width-1;
  163.   win->y1 = y+height-1;
  164.   win->xpos = x+BORDER_W;
  165.   win->ypos = y+HEADER_W;
  166.   win->width = width - 2*BORDER_W; 
  167.   win->height = height - HEADER_W - BORDER_W;
  168.   win->iconized = 0;
  169.   win->save_x0 = 3;
  170.   win->save_y0 = 3 + 150*(win_top-1);
  171.   win->save_x1 = win->save_x0 + 128 + 2*BORDER_W;
  172.   win->save_y1 = win->save_y0 + 128 + HEADER_W + BORDER_W;
  173.   win->save_bg_col = white;
  174.   win->redraw = 0;
  175.   win->image_buf = create_pixrect(root_win->id,win->x0,win->y0,win->x1,win->y1);
  176.   draw_window(win);
  177.   set_header(win->id,header);
  178.   return win->id;
  179. }
  180. void clear_window(Window w)
  181. { DosWindow win = win_stack[w];
  182.   int save_col  = set_color(win->bg_col);
  183.   int save_mode = set_mode(0);
  184.   box(w,0,0,win->width-1,win->height-1);
  185.   set_color(save_col);
  186.   set_mode(save_mode);
  187.   
  188.   while (w < win_top) 
  189.   { w++;
  190.     DosWindow win = win_stack[w]; 
  191.     draw_window(win);
  192.     if (win->redraw) (*(win->redraw))();
  193.    }
  194.  }
  195. void close_window(Window w)
  196. { if (w != win_top) return;  /* can close top window only */
  197.   DosWindow win = win_stack[w];
  198.   insert_pixrect(root_win->id,win->x0,win->y0,win->image_buf);
  199.   delete_pixrect(win->image_buf);
  200.   win_top--;
  201.   delete win;
  202.  }
  203. void set_read_gc()
  204. { save_mode = set_mode(1);
  205.   save_ls   = set_line_style(0);
  206.   save_lw   = set_line_width(1);
  207.   set_color(1);
  208.   show_pointer();
  209.  }
  210. void reset_gc()
  211. { hide_pointer();
  212.   set_mode(save_mode);
  213.   set_line_style(save_ls);
  214.   set_line_width(save_lw);
  215.  }
  216. #define UP  72
  217. #define DO  80
  218. #define LE  75
  219. #define RI  77
  220. static int handle_next_event(Window* win, int *val, int *x, int *y)
  221. {
  222.   int  e =  no_event;
  223.   int  i;
  224.   DosWindow w;
  225.   union REGISTERS key_regs;
  226.   union REGISTERS mouse_regs;
  227.   if (event_buffer_e != -1)
  228.   { *val = event_buffer_val;
  229.     w = event_buffer_win;
  230.     *win = w->id;
  231.     *x = mouse_x - w->xpos;
  232.     *y = mouse_y - w->ypos;
  233.     last_event_e = event_buffer_e;
  234.     last_event_val = event_buffer_val;
  235.     last_event_win = event_buffer_win;
  236.     event_buffer_e = -1;
  237.     return last_event_e;
  238.    }
  239.   mouse_regs.x.cx = 8*mouse_x;
  240.   mouse_regs.x.dx = 8*mouse_y;
  241.   char c;
  242.   if ((c = read_kbd()) > 0)
  243.   { 
  244.     int step = 16;
  245.     if (c==27) 
  246.     { close_display();
  247.       exit(0);
  248.      }
  249.     if (c != 0)   /* ascii char */
  250.        { *val = c;
  251.          e = key_press_event;
  252.         }
  253.     else          /* cursor or function key  */
  254.        { 
  255.          c = getch();
  256.          switch(c) {
  257.          case  LE: mouse_regs.x.cx -= step;
  258.                    e = motion_event;
  259.                    break;
  260.          case  RI: mouse_regs.x.cx += step;
  261.                    e = motion_event;
  262.                    break;
  263.          case  UP: mouse_regs.x.dx -= step;
  264.                    e = motion_event;
  265.                    break;
  266.          case  DO: mouse_regs.x.dx += step;
  267.                    e = motion_event;
  268.                    break;
  269.         }
  270.         /* set cursor position */
  271.         mouse_regs.x.ax=04;
  272.         int_86(0x33,&mouse_regs,&mouse_regs);
  273.       }
  274.    } /* kbhit */
  275.  else
  276.   if (mouse_installed)
  277.   { 
  278.     int but;
  279.     /* check for button press and release events */
  280. //INT 33 - MS MOUSE - RETURN BUTTON PRESS DATA
  281. // AX = 0005h
  282. // BX = button
  283. //     0000h left
  284. //     0001h right
  285. //     0002h middle (Mouse Systems/Logitech mouse)
  286. //Return: AX = 1 if button pressed
  287. //   BX = number of times specified button has been pressed since last call
  288. //   CX = column at time specified button was last pressed
  289. //   DX = row at time specified button was last pressed
  290. //INT 33 - MS MOUSE - RETURN BUTTON RELEASE DATA
  291. // AX = 0006h
  292. // BX = button
  293. //     0000h left
  294. //     0001h right
  295. //     0002h middle (Mouse Systems/Logitech mouse)
  296. //Return: AX = 1 if button released
  297. //   BX = # of times specified button has been released since last call
  298. //   CX = column at time specified button was last released
  299. //   DX = row at time specified button was last released
  300.     for(but=0; but < 3; but++)
  301.     { 
  302.       mouse_regs.x.ax=5;
  303.       mouse_regs.x.bx=but;
  304.       int_86(0x33,&mouse_regs,&mouse_regs);
  305.       if (mouse_regs.x.bx)
  306.       { e = button_press_event;
  307.         break;
  308.        }
  309.       mouse_regs.x.ax=6;
  310.       mouse_regs.x.bx=but;
  311.       int_86(0x33,&mouse_regs,&mouse_regs);
  312.       if (mouse_regs.x.bx)
  313.       { e = button_release_event;
  314.         break;
  315.        }
  316.      }
  317.     if (but < 3) 
  318.     { 
  319.       if (but == 0) *val = 1;   // left
  320.       if (but == 1) *val = 3;   // right
  321.       if (but == 2) *val = 2;   // middle
  322.       //INT 16 - GET KEYBOARD SHIFT KEY STATES
  323.       //          AH = 0002h
  324.       //  OUTPUT: AL  bit 0    right shift
  325.       //              bit 1    left shift
  326.       //              bit 2    ctrl
  327.       //              bit 3    alt
  328.       key_regs.h.ah=0x02;
  329.       int_86(0x16,&key_regs,&key_regs);
  330.       // ALT key simulates middle button  (two-button mouse)
  331.       if (key_regs.h.al & 8) *val = 2;       // alt
  332.       if (key_regs.h.al & 3) *val = -*val;   // shift
  333.       if (key_regs.h.al & 4) *val += 3;      // ctrl
  334.      }
  335.    // INT 33 MS-MOUSE GET CURSOR POSITION
  336.    mouse_regs.x.ax=03;
  337.    int_86(0x33,&mouse_regs,&mouse_regs);
  338.   }
  339.   if (mouse_regs.x.cx/8 != mouse_x || mouse_regs.x.dx/8 != mouse_y)
  340.   { if (e==no_event) e = motion_event;
  341.     hide_pointer();
  342.     mouse_y = mouse_regs.x.dx/8;
  343.     mouse_x = mouse_regs.x.cx/8;
  344.     show_pointer();
  345.    }
  346.   for(i = win_top; i >= 0; i--)
  347.   { w = win_stack[i];
  348.     if (mouse_x >= w->x0  && mouse_x <= w->x1 &&
  349.         mouse_y >= w->y0  && mouse_y <= w->y1 )  break;
  350.    }
  351.   *win = w->id;
  352.   *x = mouse_x - w->xpos;
  353.   *y = mouse_y - w->ypos;
  354.   if (e != no_event)
  355.   { last_event_e   = e;
  356.     last_event_val = *val;
  357.     last_event_win = w;
  358.    }
  359.   return e;
  360.  }
  361. void put_back_event() 
  362. { event_buffer_e   = last_event_e;  
  363.   event_buffer_val = last_event_val; 
  364.   event_buffer_win = last_event_win; 
  365.  }
  366. static void change_geometry(DosWindow win, int x0, int y0, int x1, int y1)
  367. {
  368.   if (x0==win->x0 && y0==win->y0 && x1==win->x1 && y1==win->y1) return;
  369.   int w = x1-x0+1;
  370.   int h = y1-y0+1;
  371.   hide_pointer();
  372.   insert_pixrect(root_win->id,win->x0,win->y0,win->image_buf);
  373.   delete_pixrect(win->image_buf);
  374.   win->x0 = x0;
  375.   win->y0 = y0;
  376.   win->x1 = x1;
  377.   win->y1 = y1;
  378.   win->xpos = x0+BORDER_W;
  379.   win->ypos = y0+HEADER_W;
  380.   win->width = w - 2*BORDER_W; 
  381.   win->height = h - HEADER_W - BORDER_W;
  382.   win->image_buf = create_pixrect(root_win->id,win->x0,win->y0,win->x1,win->y1);
  383.   draw_window(win);
  384.   show_pointer();
  385. }
  386. static void iconize(DosWindow win)
  387. { Window w;
  388.   int val,x,y;
  389.   box(root_win->id,win->x0+14,win->y0+4,win->x0+26,win->y0+14);
  390.   while (handle_next_event(&w,&val,&x,&y) != button_release_event);
  391.   box(root_win->id,win->x0+14,win->y0+4,win->x0+26,win->y0+14);
  392.   int x0 = win->save_x0;
  393.   int y0 = win->save_y0;
  394.   int x1 = win->save_x1;
  395.   int y1 = win->save_y1;
  396.   int bg = win->save_bg_col;
  397.   win->save_x0 = win->x0;
  398.   win->save_y0 = win->y0;
  399.   win->save_x1 = win->x1;
  400.   win->save_y1 = win->y1;
  401.   win->save_bg_col = win->bg_col;
  402.   win->bg_col =  bg;
  403.   change_geometry(win,x0,y0,x1,y1);
  404.   win->iconized = 1-win->iconized;
  405.   if (win->iconized) 
  406.      insert_bitmap(win->id, leda_icon_width, leda_icon_height,
  407.                    (char*)leda_icon_bits);
  408.  }
  409. static void move_win(DosWindow win, int *x, int *y)
  410. { int xp0 = win->x0;
  411.   int yp0 = win->y0;
  412.   int xp1 = win->x1;
  413.   int yp1 = win->y1;
  414.   int wi  = xp1-xp0+1;
  415.   int he  = yp1-yp0+1;
  416.   int xb  = win->xpos - xp0;
  417.   int yb  = win->ypos - yp0;
  418.   int xc = mouse_x; /* absolute cursor coordinates */
  419.   int yc = mouse_y; 
  420.   int dx = xc-xp0;  /* relative to upper left corner */
  421.   int dy = yc-yp0;
  422.   Window w;
  423.   int e,val;
  424.   rectangle(root_win->id,xp0-1,yp0-1,xp1+1,yp1+1);
  425.   do { e = handle_next_event(&w,&val,x,y);
  426.       if (mouse_x != xc || mouse_y != yc)
  427.        { int rx0 = mouse_x-dx-1;
  428.          int ry0 = mouse_y-dy-1;
  429.          int rx1 = mouse_x-dx+wi;
  430.          int ry1 = mouse_y-dy+he;
  431.          rectangle(root_win->id,rx0,ry0,rx1,ry1);
  432.          rectangle(root_win->id,xc-dx-1,yc-dy-1,xc-dx+wi,yc-dy+he);
  433.          xc = mouse_x;
  434.          yc = mouse_y;
  435.        }
  436.      } while (e != button_release_event);
  437.   xc -= dx;
  438.   yc -= dy;
  439.   rectangle(root_win->id,xc-1,yc-1,xc+wi,yc+he);
  440.   if (win_top > 1)  /* move panel */
  441.   { change_geometry(win,xc,yc,xc+wi-1,yc+he-1);
  442.     if (win->iconized) 
  443.        insert_bitmap(win->id, leda_icon_width, leda_icon_height,
  444.                      (char*)leda_icon_bits);
  445.     return;
  446.    }
  447.   if (xc < 0) xc = 0;
  448.   if (yc < 0) yc = 0;
  449.   if (xc + wi > DISP_MAX_X) xc = DISP_MAX_X - wi;
  450.   if (yc + he > DISP_MAX_Y) yc = DISP_MAX_Y - he;
  451.   xc -= xc % 8;
  452.   xc += xp0 % 8;
  453.   hide_pointer();
  454.   copy_pixrect(root_win->id,xp0,yp0+1,xp0+wi,yp0+he-1,xc,yc+1);
  455.   show_pointer();
  456.   set_mode(0);
  457.   set_color(root_color);
  458.   if (xc > xp0) 
  459.      box(root_win->id,xp0,yp0,xc-1,yp1);
  460.   else
  461.      box(root_win->id,xc+wi,yp0,xp1,yp1);
  462.   if (yc > yp0) 
  463.      box(root_win->id,xp0,yp0,xp1,yc-1);
  464.   else
  465.      box(root_win->id,xp0,yc+he,xp1,yp1);
  466.   set_color(1);
  467.   rectangle(root_win->id,xc,yc,xc+wi-1,yc+he-1);
  468.   set_mode(1);
  469.   win->x0 = xc; 
  470.   win->y0 = yc; 
  471.   win->x1 = xc+wi-1; 
  472.   win->y1 = yc+he-1; 
  473.   win->xpos = xc+xb; 
  474.   win->ypos = yc+yb; 
  475. }
  476. static void resize_win(DosWindow win, int* x, int* y, int pos)
  477. { int xp0 = win->x0;
  478.   int yp0 = win->y0;
  479.   int xp1 = win->x1;
  480.   int yp1 = win->y1;
  481.   int xb  = win->xpos - xp0;
  482.   int yb  = win->ypos - yp0;
  483.   
  484.   int xc  = mouse_x; /* absolute cursor coordinates */
  485.   int yc  = mouse_y;
  486.   Window w;
  487.   int e,val,dx,dy;
  488.   rectangle(root_win->id,xp0-1,yp0-1,xp1+1,yp1+1);
  489.   switch(pos) {
  490.   
  491.    case 0: dx = xp0-xc;          /* upper left */
  492.            dy = yp0-yc;
  493.            break;
  494.    case 1: dx = xp1-xc;          /* upper right */
  495.            dy = yp0-yc;
  496.            break;
  497.    case 2: dx = xp1-xc;          /* lower right */
  498.            dy = yp1-yc;
  499.            break;
  500.    case 3: dx = xp0-xc;          /* lower left */
  501.            dy = yp1-yc;
  502.            break;
  503.    }
  504.   do { e = handle_next_event(&w,&val,x,y);
  505.        if (mouse_x != xc || mouse_y != yc)
  506.         { 
  507.           switch(pos) {
  508.           case 0: rectangle(root_win->id,mouse_x+dx-1,mouse_y+dy-1,xp1+1,yp1+1);
  509.                   rectangle(root_win->id,xc+dx-1,yc+dy-1,xp1+1,yp1+1);
  510.                   break;
  511.           
  512.           case 1: rectangle(root_win->id,xp0-1,mouse_y+dy-1,mouse_x+dx+1,yp1+1);
  513.                   rectangle(root_win->id,xp0-1,yc+dy-1,xc+dx+1,yp1+1);
  514.                   break;
  515.           case 2: rectangle(root_win->id,xp0-1,yp0-1,mouse_x+dx+1,mouse_y+dy+1);
  516.                   rectangle(root_win->id,xp0-1,yp0-1,xc+dx+1,yc+dy+1);
  517.                   break;
  518.              
  519.           case 3: rectangle(root_win->id,mouse_x+dx-1,yp0-1,xp1+1,mouse_y+dy+1);
  520.                   rectangle(root_win->id,xc+dx-1,yp0-1,xp1+1,yc+dy+1);
  521.                   break;
  522.           
  523.            }
  524.           xc = mouse_x;
  525.           yc = mouse_y;
  526.         }
  527.      } while (e != button_release_event);
  528.    xc += dx;
  529.    yc += dy;
  530.    switch(pos) {
  531.    case 0: win->x0 = xc; 
  532.            win->y0 = yc; 
  533.            break;
  534.                 
  535.    case 1: win->x1 = xc; 
  536.            win->y0 = yc; 
  537.            break;
  538.               
  539.    case 2: win->x1 = xc; 
  540.            win->y1 = yc; 
  541.            break;
  542.    case 3: win->x0 = xc; 
  543.            win->y1 = yc; 
  544.            break;
  545.            
  546.    }
  547.   win->xpos = win->x0 + xb;
  548.   win->ypos = win->y0 + yb;
  549.   win->width  = win->x1 - win->x0 - 2*xb + 1; 
  550.   win->height = win->y1 - win->y0 - xb - yb + 1; 
  551.   rectangle(root_win->id,win->x0-1,win->y0-1,win->x1+1,win->y1+1);
  552.   hide_pointer();
  553.   insert_pixrect(root_win->id,xp0,yp0,win->image_buf);
  554.   delete_pixrect(win->image_buf);
  555.   win->image_buf = create_pixrect(root_win->id,win->x0,win->y0,win->x1,win->y1);
  556.   draw_window(win);
  557.   show_pointer();
  558.   *x = win->width;
  559.   *y = win->height;
  560. }
  561. int check_next_event(Window* w, int* val, int* x, int *y, unsigned long* t)
  562. {
  563.   // non-blocking
  564.   
  565.   // a primitive window manager active while searching for next event
  566.   int cx[4];
  567.   int cy[4];
  568.   int bw = BORDER_W;
  569.   int lw = HEADER_W;
  570.   int e = handle_next_event(w,val,x,y);
  571.   if (*w != active_win->id)
  572.   {  hide_pointer();
  573.      active_win->label_col = label_col0;
  574.      if (active_win->id == win_top) draw_window(active_win,0);
  575.      active_win = win_stack[*w];
  576.      active_win->label_col = label_col1;
  577.      if (active_win->id == win_top) draw_window(active_win,0);
  578.      show_pointer();
  579.    }
  580.   DosWindow win = win_stack[*w];
  581.   int x0 = win->x0;
  582.   int y0 = win->y0;
  583.   int x1 = win->x1;
  584.   int y1 = win->y1;
  585.   cx[0] = x0;
  586.   cy[0] = y0;
  587.   cx[1] = x1-6;
  588.   cy[1] = y0;
  589.   cx[2] = x1-6;
  590.   cy[2] = y1-6;
  591.   cx[3] = x0;
  592.   cy[3] = y1-6;
  593.   if ( (x0 <= mouse_x && mouse_x <= x0+bw) 
  594.     || (x1 >= mouse_x && mouse_x >= x1-bw)
  595.     || (y0 <= mouse_y && mouse_y <= y0+lw)
  596.     || (y1 >= mouse_y && mouse_y >= y1-bw))
  597.     {
  598.       // pointer on window boundary: move or resize window
  599.      if (win != win_stack[win_top])  /* only top window can be changed  */
  600.      { set_pointer_shape(0);
  601.        return no_event;
  602.       }
  603.      for(int i=0; i<4; i++)
  604.        if ( cy[i] <= mouse_y && mouse_y <= cy[i]+6 &&
  605.             cx[i] <= mouse_x && mouse_x <= cx[i]+6 )
  606.        { set_pointer_shape(1);
  607.          if (e == button_press_event && ! win->iconized) 
  608.          { if (win->iconized)
  609.              e = no_event;
  610.            else
  611.              resize_win(win,x,y,i);
  612.            e = configure_event;
  613.           }
  614.           return e;
  615.         }
  616.     set_pointer_shape(0);
  617.    
  618.     if (x0+13 <= mouse_x && mouse_x <= x0+27 &&
  619.         y0+3  <= mouse_y && mouse_y <= y0+15 && e == button_press_event)
  620.     { iconize(win);
  621.       return (win->iconized) ? no_event : configure_event;
  622.      }
  623.     if (e== button_press_event) 
  624.     { move_win(win,x,y);
  625.       if (win_top==1 || win->iconized)  
  626.          return handle_next_event(w,val,x,y);  
  627.       else
  628.          return configure_event;
  629.      }
  630.     e = no_event;
  631.   }  // if pointer on window boundary
  632.   set_pointer_shape(0);
  633.  
  634.   return e;
  635. }
  636. int get_next_event(Window* win, int* val, int* x, int *y, unsigned long* t)
  637. { // blocking
  638.   int e = no_event;
  639.   while (e == no_event) e = check_next_event(win,val,x,y,t);
  640.   return e;
  641.  }
  642. void open_display()
  643. { REGISTERS regs;
  644.   if (display) return;
  645.   display = 1;
  646.   init_graphics(1,root_color);
  647.   //INT 33 - MS MOUSE - RESET DRIVER AND READ STATUS
  648.   //    AX = 0000h
  649.   //Return: AX = status
  650.   //     0000h hardware/driver not installed
  651.   //     FFFFh hardware/driver installed
  652.   //     BX = number of buttons
  653.   //     FFFFh two buttons
  654.   //     0000h other than two
  655.   //     0003h Mouse Systems/Logitech mouse
  656.   regs.x.ax=0x00;
  657.   int_86(0x33,&regs,&regs);
  658.   mouse_installed = (regs.x.ax == 0x0ffff);
  659.   mouse_two_buttons = (regs.x.bx == 0x0ffff);
  660.   //INT 33 - MS MOUSE - DEFINE HORIZONTAL CURSOR RANGE = 0..DISP_MAX_X
  661.   regs.x.ax=0x07;
  662.   regs.x.cx=0;
  663.   regs.x.dx=8*DISP_MAX_X;
  664.   int_86(0x33,&regs,&regs);
  665.   //INT 33 - MS MOUSE - DEFINE VERTICAL CURSOR RANGE = 0..DISP_MAX_Y
  666.   regs.x.ax=0x08;
  667.   regs.x.cx=0;
  668.   regs.x.dx=8*DISP_MAX_Y;
  669.   int_86(0x33,&regs,&regs);
  670.   //INT 33 - MS MOUSE - DEFINE MICKEY/PIXEL RATIO = 1
  671.   regs.x.ax=0x0F;
  672.   regs.x.cx=1;
  673.   regs.x.dx=1;
  674.   int_86(0x33,&regs,&regs);
  675.   //INT 33 - MS MOUSE - SET CURSOR POSITION
  676.   mouse_x = DISP_MAX_X/2;
  677.   mouse_y = DISP_MAX_Y/2;
  678.   regs.x.cx = 8*mouse_x;
  679.   regs.x.dx = 8*mouse_y;
  680.   regs.x.ax=04;
  681.   int_86(0x33,&regs,&regs);
  682.   root_win = new dos_window;
  683.   active_win = root_win;
  684.   root_win->id = 0;
  685.   win_stack[0] = root_win;
  686.   win_top = 0;
  687.   root_win->x0 = -1000;
  688.   root_win->y0 = -1000;
  689.   root_win->x1 =  1000;
  690.   root_win->y1 =  1000;
  691.   root_win->xpos = 0;
  692.   root_win->ypos = 0;
  693.   root_win->width  = display_width();
  694.   root_win->height = display_height();
  695.   root_win->bg_col = root_color;
  696.   set_color(root_color);
  697.   box(root_win->id,0,0,DISP_MAX_X,DISP_MAX_Y);
  698.   set_color(black);
  699. }
  700. void close_display()
  701. { init_graphics(0,0);
  702.   delete root_win;
  703.  }
  704. int  window_width(Window win)  { return win_stack[win]->width; }
  705. int  window_height(Window win) { return win_stack[win]->height; }
  706. void window_position(Window win,int* x,int* y) 
  707. { *x = win_stack[win]->x0; 
  708.   *y = win_stack[win]->y0; 
  709.  }