home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / stdwin.d < prev    next >
Encoding:
Text File  |  1994-12-18  |  41.5 KB  |  1,323 lines

  1. # STDWIN-Interface fⁿr CLISP
  2. # Bruno Haible, Matthias Lindner 29.8.1993
  3.  
  4. #include "lispbibl.c"
  5.  
  6. # If STDWIN is not defined, we are compiling this as a separate module.
  7. #ifndef STDWIN
  8. #define STDWIN_MODULE
  9. #endif
  10.  
  11. #ifdef STDWIN_MODULE
  12.  
  13. struct {
  14.   object stdwin_drawproc_alist;
  15. }
  16. module__stdwin__object_tab;
  17.  
  18. uintC module__stdwin__object_tab_size = sizeof(module__stdwin__object_tab)/sizeof(object);
  19.  
  20. #define OM(name)  (module__stdwin__object_tab.name)
  21.  
  22. #else
  23.  
  24. #define OM(name)  O(name)
  25.  
  26. #endif
  27.  
  28. #if defined(STDWIN) || defined(STDWIN_MODULE)
  29.  
  30. #include <stdwin.h>  # "stdwin/H/stdwin.h"
  31.  
  32.  
  33. #                           Foreign Function Interface
  34. #                           ==========================
  35.  
  36. # We call library functions that can do callbacks. When we pass a parameter
  37. # to such a library function, maybe it first does a callback - which may
  38. # involve garbage collection - and only then looks at the parameter.
  39. # Therefore all the parameters, especially strings, must be located in
  40. # areas that are not moved by garbage collection.
  41.  
  42. # with_string_0(string,asciz,statement);
  43. # copies the contents of string (which should be a Lisp string) to a safe area
  44. # (zero-terminating it), binds the variable asciz pointing to it, and
  45. # executes the statement.
  46.   #define with_string_0(string,ascizvar,statement)  \
  47.     { var uintL ascizvar##_len;                                     \
  48.       var reg2 uintB* ptr1 = unpack_string(string,&ascizvar##_len); \
  49.      {var DYNAMIC_ARRAY(,ascizvar##_data,uintB,ascizvar##_len+1);   \
  50.       {var reg1 uintB* ptr2 = &ascizvar##_data[0];                  \
  51.        var reg3 uintL count;                                        \
  52.        dotimesL(count,ascizvar##_len, { *ptr2++ = *ptr1++; } );     \
  53.        *ptr2 = '\0';                                                \
  54.       }                                                             \
  55.       {var char* ascizvar = (char*) &ascizvar##_data[0];            \
  56.        statement                                                    \
  57.       }                                                             \
  58.       FREE_DYNAMIC_ARRAY(ascizvar##_data);                          \
  59.     }}
  60.  
  61. # with_string(string,charptr,len,statement);
  62. # copies the contents of string (which should be a Lisp string) to a safe area,
  63. # binds the variable charptr pointing to it and the variable len to its length,
  64. # and executes the statement.
  65.   #define with_string(string,charptrvar,lenvar,statement)  \
  66.     { var uintL lenvar;                                      \
  67.       var reg2 uintB* ptr1 = unpack_string(string,&lenvar);  \
  68.      {var DYNAMIC_ARRAY(,charptrvar##_data,uintB,lenvar);    \
  69.       {var reg1 uintB* ptr2 = &charptrvar##_data[0];         \
  70.        var reg3 uintL count;                                 \
  71.        dotimesL(count,lenvar, { *ptr2++ = *ptr1++; } );      \
  72.       }                                                      \
  73.       {var char* charptrvar = (char*) &charptrvar##_data[0]; \
  74.        statement                                             \
  75.       }                                                      \
  76.       FREE_DYNAMIC_ARRAY(charptrvar##_data);                 \
  77.     }}
  78.  
  79.  
  80. #                           Initialization and clean-up
  81. #                           +++++++++++++++++++++++++++
  82.  
  83. # We free the programmer from the duty to call (STDWIN::WINIT).
  84.  
  85. local boolean initialized = FALSE; # tells whether winit() has been called
  86.  
  87. local void initialize (void);
  88. local void initialize()
  89.   { begin_call();
  90.     winit();
  91.     wmenusetdeflocal(TRUE); # change STDWIN's default behaviour for menus
  92.     end_call();
  93.     OM(stdwin_drawproc_alist) = NIL;
  94.     initialized = TRUE;
  95.   }
  96.  
  97. # (STDWIN::INIT) calls winit().
  98. LISPFUNN(stdwin_init,0)
  99. {
  100.   if (!initialized) initialize();
  101.   value1 = NIL; mv_count=1; # returns NIL
  102. }
  103.  
  104. # (STDWIN::DONE) calls wdone().
  105. LISPFUNN(stdwin_done,0)
  106. {
  107.   if (initialized)
  108.     { begin_call();
  109.       wdone();
  110.       end_call();
  111.       initialized = FALSE;
  112.     }
  113.   value1 = NIL; mv_count=1; # returns NIL
  114. }
  115.  
  116. # check_init(); checks that STDWIN has been initialized.
  117.   #define check_init()  \
  118.     if (!initialized) initialize()
  119.  
  120. #                         Creating and destroying windows
  121. #                         +++++++++++++++++++++++++++++++
  122.  
  123. # OM(stdwin_drawproc_alist) is a list of conses (win . drawproc),
  124. # where drawproc is the Lisp function for redrawing the window win.
  125.  
  126. # Looks up a given window in OM(stdwin_drawproc_alist):
  127.   local object find_win (void* win);
  128.   local object find_win(win)
  129.     var reg3 void* win;
  130.     { var reg2 object key = type_untype_object(machine_type,win);
  131.       var reg1 object l;
  132.       for (l = OM(stdwin_drawproc_alist); consp(l); l = Cdr(l))
  133.         { if (eq(Car(Car(l)),key)) { return Car(l); } }
  134.       return NIL;
  135.     }
  136.  
  137. # General redrawing function:
  138.   local void drawproc (WINDOW* win, int left, int top, int right, int bottom);
  139.   local void drawproc(win,left,top,right,bottom)
  140.     var reg3 WINDOW* win;
  141.     var reg4 int left;
  142.     var reg5 int top;
  143.     var reg6 int right;
  144.     var reg7 int bottom;
  145.     { begin_callback();
  146.      {var reg1 object acons = find_win(win);
  147.       if (consp(acons))
  148.         { var reg2 object fun = Cdr(acons);
  149.           if (!nullp(fun))
  150.             { pushSTACK(fun);
  151.               pushSTACK(type_untype_object(machine_type,win));
  152.               pushSTACK(L_to_I(left)); pushSTACK(L_to_I(top));
  153.               pushSTACK(L_to_I(right)); pushSTACK(L_to_I(bottom));
  154.               funcall(STACK_5,5);
  155.               skipSTACK(1);
  156.         }   }
  157.       end_callback();
  158.     }}
  159.  
  160. # (STDWIN::DRAWPROC-ALIST) returns the OM(stdwin_drawproc_alist).
  161. # Why should this be useful?? Remove!??
  162. LISPFUNN(stdwin_drawproc_alist,0)
  163. { value1 = OM(stdwin_drawproc_alist); mv_count=1; }
  164.  
  165. # (STDWIN::WOPEN title drawproc) calls wopen().
  166. LISPFUNN(stdwin_wopen,2)
  167. { if (!mstringp(STACK_1)) { STACK_1 = O(leer_string); }
  168.   # Pre-allocate the conses for the alist:
  169.   pushSTACK(allocate_cons()); pushSTACK(allocate_cons());
  170.   check_init();
  171.  {var reg3 WINDOW* win;
  172.   with_string_0(STACK_(1+2),title,
  173.     { begin_call();
  174.       win = wopen(title,(nullp(STACK_(0+2)) ? NULL : drawproc));
  175.       end_call();
  176.     });
  177.   {var reg1 object acons = popSTACK();
  178.    var reg2 object newcons = popSTACK();
  179.    if (win==NULL)
  180.      { value1 = NIL; }
  181.      else
  182.      { value1 = Car(acons) = type_untype_object(machine_type,win);
  183.        Cdr(acons) = STACK_0;
  184.        Car(newcons) = acons;
  185.        Cdr(newcons) = OM(stdwin_drawproc_alist);
  186.        OM(stdwin_drawproc_alist) = newcons;
  187.   }  }
  188.   mv_count=1;
  189.   skipSTACK(2);
  190. }}
  191.  
  192. # (STDWIN::WCLOSE win) calls wclose().
  193. LISPFUNN(stdwin_wclose,1)
  194. { var reg3 object arg = popSTACK();
  195.   check_init();
  196.  {var reg2 WINDOW* win = (WINDOW*)TheMachine(arg);
  197.   var reg1 object acons = find_win(win);
  198.   if (consp(acons))
  199.     { OM(stdwin_drawproc_alist) = deleteq(OM(stdwin_drawproc_alist),acons);
  200.       begin_call();
  201.       wclose(win);
  202.       end_call();
  203.     }
  204.   value1 = NIL; mv_count=1; # returns NIL
  205. }}
  206.  
  207. # test_window(arg) checks that an argument is an STDWIN window, and returns it.
  208.   local WINDOW* test_window (object arg);
  209.   local WINDOW* test_window(arg)
  210.     var reg2 object arg;
  211.     { var reg1 WINDOW* win = (WINDOW*)TheMachine(arg);
  212.       check_init();
  213.       if (nullp(find_win(win)))
  214.         { pushSTACK(arg);
  215.           pushSTACK(TheSubr(subr_self)->name);
  216.           fehler(error, # type_error ??
  217.                  DEUTSCH ? "~: Argument ~ ist kein STDWIN:WINDOW." :
  218.                  ENGLISH ? "~: argument ~ is not a STDWIN:WINDOW" :
  219.                  FRANCAIS ? "~ : L'argument ~ n'est pas de type STDWIN:WINDOW." :
  220.                  ""
  221.                 );
  222.         }
  223.       return win;
  224.     }
  225.  
  226. #                          Changing defaults
  227. #                          -----------------
  228.  
  229. # (STDWIN::SCROLLBAR-P) calls wgetdefscrollbars().
  230. LISPFUNN(stdwin_scrollbar_p,0)
  231. { var int h_p;
  232.   var int v_p;
  233.   check_init();
  234.   begin_call();
  235.   wgetdefscrollbars(&h_p,&v_p);
  236.   end_call();
  237.   value1 = (h_p ? T : NIL); value2 = (v_p ? T : NIL); mv_count=2;
  238. }
  239.  
  240. # (STDWIN::SET-SCROLLBAR-P horizontal-bar-p vertical-bar-p) calls wsetdefscrollbars().
  241. LISPFUNN(stdwin_set_scrollbar_p,2)
  242. { var reg2 int h_p = (nullp(STACK_1) ? FALSE : TRUE);
  243.   var reg1 int v_p = (nullp(STACK_0) ? FALSE : TRUE);
  244.   check_init();
  245.   begin_call();
  246.   wsetdefscrollbars(h_p,v_p);
  247.   end_call();
  248.   STACK_to_mv(2); # returns two values: h_p and v_p
  249. }
  250.  
  251. # (STDWIN::DEFAULT-WINDOW-SIZE) calls wgetdefwinsize().
  252. LISPFUNN(stdwin_default_window_size,0)
  253. { var int w;
  254.   var int h;
  255.   check_init();
  256.   begin_call();
  257.   wgetdefwinsize(&w,&h);
  258.   end_call();
  259.   pushSTACK(L_to_I(w)); pushSTACK(L_to_I(h));
  260.   STACK_to_mv(2); # returns two values: w and h
  261. }
  262.  
  263. # (STDWIN::SET-DEFAULT-WINDOW-SIZE width height) calls wsetdefwinsize().
  264. LISPFUNN(stdwin_set_default_window_size,2)
  265. { var reg2 sintL w = I_to_L(STACK_1);
  266.   var reg1 sintL h = I_to_L(STACK_0);
  267.   check_init();
  268.   begin_call();
  269.   wsetdefwinsize(w,h);
  270.   end_call();
  271.   STACK_to_mv(2); # returns two values: w and h
  272. }
  273.  
  274. # (STDWIN::DEFAULT-WINDOW-POSITION) calls wgetdefwinpos().
  275. LISPFUNN(stdwin_default_window_position,0)
  276. { var int x;
  277.   var int y;
  278.   check_init();
  279.   begin_call();
  280.   wgetdefwinpos(&x,&y);
  281.   end_call();
  282.   pushSTACK(L_to_I(x)); pushSTACK(L_to_I(y));
  283.   STACK_to_mv(2); # returns two values: x and y
  284. }
  285.  
  286. # (STDWIN::SET-DEFAULT-WINDOW-POSITION x y) calls wsetdefwinpos().
  287. LISPFUNN(stdwin_set_default_window_position,2)
  288. { var reg2 sintL x = I_to_L(STACK_1);
  289.   var reg1 sintL y = I_to_L(STACK_0);
  290.   check_init();
  291.   begin_call();
  292.   wsetdefwinpos(x,y);
  293.   end_call();
  294.   STACK_to_mv(2); # returns two values: x and y
  295. }
  296.  
  297. #                              The output model
  298. #                              ++++++++++++++++
  299.  
  300. # (STDWIN::SCREEN-SIZE) calls wgetscrsize().
  301. # (STDWIN::WINDOW-SIZE win) calls wgetwinsize().
  302. # (STDWIN::WINDOW-POSITION win) calls wgetwinpos().
  303. # (STDWIN::WINDOW-DOCUMENT-SIZE win) calls wgetdocsize().
  304. # (STDWIN::SET-WINDOW-DOCUMENT-SIZE win width height) calls wsetdocsize().
  305. # (STDWIN::WINDOW-TITLE win) calls wgettitle().
  306. # (STDWIN::SET-WINDOW-TITLE win string) calls wsettitle().
  307. # (STDWIN::SET-WINDOW-CURSOR win string) calls wfetchcursor() and wsetwincursor().
  308.  
  309. # (STDWIN::SCREEN-SIZE) calls wgetscrsize().
  310. LISPFUNN(stdwin_screen_size,0)
  311. { var int w;
  312.   var int h;
  313.   check_init();
  314.   begin_call();
  315.   wgetscrsize(&w,&h);
  316.   end_call();
  317.   pushSTACK(L_to_I(w)); pushSTACK(L_to_I(h));
  318.   STACK_to_mv(2); # returns two values: w and h
  319. }
  320.  
  321. # (STDWIN::WINDOW-SIZE win) calls wgetwinsize().
  322. LISPFUNN(stdwin_window_size,1)
  323. { var reg2 object arg = popSTACK();
  324.   var reg1 WINDOW* win = test_window(arg);
  325.   var int w;
  326.   var int h;
  327.   begin_call();
  328.   wgetwinsize(win,&w,&h);
  329.   end_call();
  330.   pushSTACK(L_to_I(w)); pushSTACK(L_to_I(h));
  331.   STACK_to_mv(2); # returns two values: w and h
  332. }
  333.  
  334. # (STDWIN::WINDOW-POSITION win) calls wgetwinpos().
  335. LISPFUNN(stdwin_window_position,1)
  336. { var reg2 object arg = popSTACK();
  337.   var reg1 WINDOW* win = test_window(arg);
  338.   var int x;
  339.   var int y;
  340.   begin_call();
  341.   wgetwinpos(win,&x,&y);
  342.   end_call();
  343.   pushSTACK(L_to_I(x)); pushSTACK(L_to_I(y));
  344.   STACK_to_mv(2); # returns two values: x and y
  345. }
  346.  
  347. # (STDWIN::WINDOW-DOCUMENT-SIZE win) calls wgetdocsize().
  348. LISPFUNN(stdwin_window_document_size,1)
  349. { var reg2 object arg = popSTACK();
  350.   var reg1 WINDOW* win = test_window(arg);
  351.   var int w;
  352.   var int h;
  353.   begin_call();
  354.   wgetdocsize(win,&w,&h);
  355.   end_call();
  356.   pushSTACK(L_to_I(w)); pushSTACK(L_to_I(h));
  357.   STACK_to_mv(2); # returns two values: w and h
  358. }
  359.  
  360. # (STDWIN::SET-WINDOW-DOCUMENT-SIZE win width height) calls wsetdocsize().
  361. LISPFUNN(stdwin_set_window_document_size,3)
  362. { var reg3 WINDOW* win = test_window(STACK_2);
  363.   var reg2 sintL w = I_to_L(STACK_1);
  364.   var reg1 sintL h = I_to_L(STACK_0);
  365.   begin_call();
  366.   wsetdocsize(win,w,h);
  367.   end_call();
  368.   STACK_to_mv(2); # returns two values: w and h
  369.   skipSTACK(1);
  370. }
  371.  
  372. # (STDWIN::WINDOW-TITLE win) calls wgettitle().
  373. LISPFUNN(stdwin_window_title,1)
  374. { var reg2 object arg = popSTACK();
  375.   var reg1 WINDOW* win = test_window(arg);
  376.   var reg3 char* title;
  377.   begin_call();
  378.   title = wgettitle(win);
  379.   end_call();
  380.   value1 = (title==NULL ? NIL : asciz_to_string(title)); mv_count=1;
  381. }
  382.  
  383. # (STDWIN::SET-WINDOW-TITLE win string) calls wsettitle().
  384. LISPFUNN(stdwin_set_window_title,2)
  385. { var reg4 WINDOW* win = test_window(STACK_1);
  386.   if (!mstringp(STACK_0)) { fehler_string(STACK_0); }
  387.   with_string_0(STACK_0,title,
  388.     { begin_call();
  389.       wsettitle(win,title);
  390.       end_call();
  391.     });
  392.   value1 = STACK_0; mv_count=1; # returns the string
  393.   skipSTACK(2);
  394. }
  395.  
  396. # (STDWIN::SET-WINDOW-CURSOR win string) calls wfetchcursor() and wsetwincursor().
  397. LISPFUNN(stdwin_set_window_cursor,2)
  398. { var reg4 WINDOW* win = test_window(STACK_1);
  399.   if (!mstringp(STACK_0)) { fehler_string(STACK_0); }
  400.   with_string_0(STACK_0,cursor_name,
  401.     { begin_call();
  402.      {var reg5 CURSOR* cur = wfetchcursor(cursor_name);
  403.       if (cur == NULL)
  404.         { end_call();
  405.           pushSTACK(STACK_0);
  406.           pushSTACK(TheSubr(subr_self)->name);
  407.           fehler(error,
  408.                  DEUTSCH ? "~: Argument ~ benennt keinen Cursor-Typ." :
  409.                  ENGLISH ? "~: argument ~ does not name a cursor type" :
  410.                  FRANCAIS ? "~ : L'argument ~ n'est pas le nom d'un CURSOR." :
  411.                  ""
  412.                 );
  413.         }
  414.       wsetwincursor(win,cur);
  415.       end_call();
  416.     }});
  417.   value1 = STACK_0; mv_count=1; # returns the string
  418.   skipSTACK(2);
  419. }
  420.  
  421. # (STDWIN::WINDOW-SHOW win left top right bottom) calls wshow().
  422. # (STDWIN::WINDOW-ORIGIN win) calls wgetorigin().
  423. # (STDWIN::SET-WINDOW-ORIGIN win x y) calls wsetorigin().
  424. # (STDWIN::WINDOW-CHANGE win left top right bottom) calls wchange().
  425. # (STDWIN::WINDOW-UPDATE win) calls wupdate().
  426.  
  427. # (STDWIN::WINDOW-SHOW win left top right bottom) calls wshow().
  428. LISPFUNN(stdwin_window_show,5)
  429. { var reg5 WINDOW* win = test_window(STACK_4);
  430.   var reg4 sintL left   = I_to_L(STACK_3);
  431.   var reg3 sintL top    = I_to_L(STACK_2);
  432.   var reg2 sintL right  = I_to_L(STACK_1);
  433.   var reg1 sintL bottom = I_to_L(STACK_0);
  434.   begin_call();
  435.   wshow(win,left,top,right,bottom);
  436.   end_call();
  437.   skipSTACK(5);
  438.   value1 = NIL; mv_count=1; # returns NIL
  439. }
  440.  
  441. # (STDWIN::WINDOW-ORIGIN win) calls wgetorigin().
  442. LISPFUNN(stdwin_window_origin,1)
  443. { var reg2 object arg = popSTACK();
  444.   var reg1 WINDOW* win = test_window(arg);
  445.   var int x;
  446.   var int y;
  447.   begin_call();
  448.   wgetorigin(win,&x,&y);
  449.   end_call();
  450.   pushSTACK(L_to_I(x)); pushSTACK(L_to_I(y));
  451.   STACK_to_mv(2); # returns two values: x and y
  452. }
  453.  
  454. # (STDWIN::SET-WINDOW-ORIGIN win x y) calls wsetorigin().
  455. LISPFUNN(stdwin_set_window_origin,3)
  456. { var reg3 WINDOW* win = test_window(STACK_2);
  457.   var reg2 sintL x = I_to_L(STACK_1);
  458.   var reg1 sintL y = I_to_L(STACK_0);
  459.   begin_call();
  460.   wsetorigin(win,x,y);
  461.   end_call();
  462.   STACK_to_mv(2); # returns two values: x and y
  463.   skipSTACK(1);
  464. }
  465.  
  466. # (STDWIN::WINDOW-CHANGE win left top right bottom) calls wchange().
  467. LISPFUNN(stdwin_window_change,5)
  468. { var reg5 WINDOW* win = test_window(STACK_4);
  469.   var reg4 sintL left   = I_to_L(STACK_3);
  470.   var reg3 sintL top    = I_to_L(STACK_2);
  471.   var reg2 sintL right  = I_to_L(STACK_1);
  472.   var reg1 sintL bottom = I_to_L(STACK_0);
  473.   begin_call();
  474.   wchange(win,left,top,right,bottom);
  475.   end_call();
  476.   skipSTACK(5);
  477.   value1 = NIL; mv_count=1; # returns NIL
  478. }
  479.  
  480. # (STDWIN::WINDOW-UPDATE win) calls wupdate().
  481. LISPFUNN(stdwin_window_update,1)
  482. { var reg1 WINDOW* win = test_window(popSTACK());
  483.   begin_call();
  484.   wupdate(win);
  485.   end_call();
  486.   value1 = NIL; mv_count=1; # returns NIL
  487. }
  488.  
  489. #                           Drawing in a document
  490. #                           +++++++++++++++++++++
  491.  
  492. #                          Preparation for drawing
  493. #                          -----------------------
  494.  
  495. # (STDWIN::BEGIN-DRAWING win) calls wbegindrawing().
  496. # (STDWIN::END-DRAWING win) calls wenddrawing().
  497.  
  498. # (STDWIN::BEGIN-DRAWING win) calls wbegindrawing().
  499. LISPFUNN(stdwin_begin_drawing,1)
  500. { var reg1 WINDOW* win = test_window(popSTACK());
  501.   begin_call();
  502.   wbegindrawing(win);
  503.   end_call();
  504.   value1 = NIL; mv_count=0; # returns nothing
  505. }
  506.  
  507. # (STDWIN::END-DRAWING win) calls wenddrawing().
  508. LISPFUNN(stdwin_end_drawing,1)
  509. { var reg1 WINDOW* win = test_window(popSTACK());
  510.   begin_call();
  511.   wenddrawing(win);
  512.   end_call();
  513.   value1 = NIL; mv_count=0; # returns nothing
  514. }
  515.  
  516. # These cannot be used: they are not implemented in STDWIN-ALFA.
  517. # (STDWIN::CLIP left top right bottom) calls wcliprect().
  518. # (STDWIN::NOCLIP) calls wnoclip().
  519.  
  520. #                           Graphical primitives
  521. #                           --------------------
  522.  
  523. # (STDWIN::DRAW-LINE x1 y1 x2 y2) calls wdrawline().
  524. LISPFUNN(stdwin_draw_line,4)
  525. { var reg4 sintL x1 = I_to_L(STACK_3);
  526.   var reg3 sintL y1 = I_to_L(STACK_2);
  527.   var reg2 sintL x2 = I_to_L(STACK_1);
  528.   var reg1 sintL y2 = I_to_L(STACK_0);
  529.   check_init();
  530.   begin_call();
  531.   wdrawline(x1,y1,x2,y2);
  532.   end_call();
  533.   skipSTACK(4);
  534.   value1 = NIL; mv_count=1; # returns NIL
  535. }
  536.  
  537. # (STDWIN::XOR-LINE x1 y1 x2 y2) calls wxorline().
  538. LISPFUNN(stdwin_xor_line,4)
  539. { var reg4 sintL x1 = I_to_L(STACK_3);
  540.   var reg3 sintL y1 = I_to_L(STACK_2);
  541.   var reg2 sintL x2 = I_to_L(STACK_1);
  542.   var reg1 sintL y2 = I_to_L(STACK_0);
  543.   check_init();
  544.   begin_call();
  545.   wxorline(x1,y1,x2,y2);
  546.   end_call();
  547.   skipSTACK(4);
  548.   value1 = NIL; mv_count=1; # returns NIL
  549. }
  550.  
  551. # (STDWIN::DRAW-BOX left top right bottom) calls wdrawbox().
  552. LISPFUNN(stdwin_draw_box,4)
  553. { var reg4 sintL left   = I_to_L(STACK_3);
  554.   var reg3 sintL top    = I_to_L(STACK_2);
  555.   var reg2 sintL right  = I_to_L(STACK_1);
  556.   var reg1 sintL bottom = I_to_L(STACK_0);
  557.   check_init();
  558.   begin_call();
  559.   wdrawbox(left,top,right,bottom);
  560.   end_call();
  561.   skipSTACK(4);
  562.   value1 = NIL; mv_count=1; # returns NIL
  563. }
  564.  
  565. # (STDWIN::PAINT left top right bottom) calls wpaint().
  566. LISPFUNN(stdwin_paint,4)
  567. { var reg4 sintL left   = I_to_L(STACK_3);
  568.   var reg3 sintL top    = I_to_L(STACK_2);
  569.   var reg2 sintL right  = I_to_L(STACK_1);
  570.   var reg1 sintL bottom = I_to_L(STACK_0);
  571.   check_init();
  572.   begin_call();
  573.   wpaint(left,top,right,bottom);
  574.   end_call();
  575.   skipSTACK(4);
  576.   value1 = NIL; mv_count=1; # returns NIL
  577. }
  578.  
  579. # (STDWIN::INVERT left top right bottom) calls winvert().
  580. LISPFUNN(stdwin_invert,4)
  581. { var reg4 sintL left   = I_to_L(STACK_3);
  582.   var reg3 sintL top    = I_to_L(STACK_2);
  583.   var reg2 sintL right  = I_to_L(STACK_1);
  584.   var reg1 sintL bottom = I_to_L(STACK_0);
  585.   check_init();
  586.   begin_call();
  587.   winvert(left,top,right,bottom);
  588.   end_call();
  589.   skipSTACK(4);
  590.   value1 = NIL; mv_count=1; # returns NIL
  591. }
  592.  
  593. # (STDWIN::ERASE left top right bottom) calls werase().
  594. LISPFUNN(stdwin_erase,4)
  595. { var reg4 sintL left   = I_to_L(STACK_3);
  596.   var reg3 sintL top    = I_to_L(STACK_2);
  597.   var reg2 sintL right  = I_to_L(STACK_1);
  598.   var reg1 sintL bottom = I_to_L(STACK_0);
  599.   check_init();
  600.   begin_call();
  601.   werase(left,top,right,bottom);
  602.   end_call();
  603.   skipSTACK(4);
  604.   value1 = NIL; mv_count=1; # returns NIL
  605. }
  606.  
  607. # (STDWIN::SHADE left top right bottom percent) calls wpercent().
  608. LISPFUNN(stdwin_shade,5)
  609. { var reg4 sintL left   = I_to_L(STACK_4);
  610.   var reg3 sintL top    = I_to_L(STACK_3);
  611.   var reg2 sintL right  = I_to_L(STACK_2);
  612.   var reg1 sintL bottom = I_to_L(STACK_1);
  613.   if (mfloatp(STACK_0))
  614.     { # percent := (round (* percent 100))
  615.       pushSTACK(fixnum(100)); funcall(L(mal),2);
  616.       pushSTACK(value1); funcall(L(round),1);
  617.       pushSTACK(value1);
  618.     }
  619.  {var reg5 sintL percent = I_to_L(STACK_0);
  620.   check_init();
  621.   begin_call();
  622.   wshade(left,top,right,bottom,percent);
  623.   end_call();
  624.   skipSTACK(5);
  625.   value1 = NIL; mv_count=1; # returns NIL
  626. }}
  627.  
  628. # (STDWIN::DRAW-CIRCLE x y radius) calls wdrawcircle().
  629. LISPFUNN(stdwin_draw_circle,3)
  630. { var reg3 sintL x = I_to_L(STACK_2);
  631.   var reg2 sintL y = I_to_L(STACK_1);
  632.   var reg1 sintL radius = I_to_L(STACK_0);
  633.   check_init();
  634.   begin_call();
  635.   wdrawcircle(x,y,radius);
  636.   end_call();
  637.   skipSTACK(3);
  638.   value1 = NIL; mv_count=1; # returns NIL
  639. }
  640.  
  641. # (STDWIN::XOR-CIRCLE x y radius) calls wxorcircle().
  642. LISPFUNN(stdwin_xor_circle,3)
  643. { var reg3 sintL x = I_to_L(STACK_2);
  644.   var reg2 sintL y = I_to_L(STACK_1);
  645.   var reg1 sintL radius = I_to_L(STACK_0);
  646.   check_init();
  647.   begin_call();
  648.   wxorcircle(x,y,radius);
  649.   end_call();
  650.   skipSTACK(3);
  651.   value1 = NIL; mv_count=1; # returns NIL
  652. }
  653.  
  654. # (STDWIN::FILL-CIRCLE x y radius) calls wfillcircle().
  655. LISPFUNN(stdwin_fill_circle,3)
  656. { var reg3 sintL x = I_to_L(STACK_2);
  657.   var reg2 sintL y = I_to_L(STACK_1);
  658.   var reg1 sintL radius = I_to_L(STACK_0);
  659.   check_init();
  660.   begin_call();
  661.   wfillcircle(x,y,radius);
  662.   end_call();
  663.   skipSTACK(3);
  664.   value1 = NIL; mv_count=1; # returns NIL
  665. }
  666.  
  667. # (STDWIN::DRAW-ARC x y rx ry angle1 angle2) calls wdrawelarc().
  668. LISPFUNN(stdwin_draw_arc,3)
  669. { var reg6 sintL x = I_to_L(STACK_5);
  670.   var reg5 sintL y = I_to_L(STACK_4);
  671.   var reg4 sintL rx = I_to_L(STACK_3);
  672.   var reg3 sintL ry = I_to_L(STACK_2);
  673.   var reg2 sintL angle1 = I_to_L(STACK_1);
  674.   var reg1 sintL angle2 = I_to_L(STACK_0);
  675.   check_init();
  676.   begin_call();
  677.   wdrawelarc(x,y,rx,ry,angle1,angle2);
  678.   end_call();
  679.   skipSTACK(6);
  680.   value1 = NIL; mv_count=1; # returns NIL
  681. }
  682.  
  683. # (STDWIN::XOR-ARC x y rx ry angle1 angle2) calls wxorelarc().
  684. LISPFUNN(stdwin_xor_arc,3)
  685. { var reg6 sintL x = I_to_L(STACK_5);
  686.   var reg5 sintL y = I_to_L(STACK_4);
  687.   var reg4 sintL rx = I_to_L(STACK_3);
  688.   var reg3 sintL ry = I_to_L(STACK_2);
  689.   var reg2 sintL angle1 = I_to_L(STACK_1);
  690.   var reg1 sintL angle2 = I_to_L(STACK_0);
  691.   check_init();
  692.   begin_call();
  693.   wxorelarc(x,y,rx,ry,angle1,angle2);
  694.   end_call();
  695.   skipSTACK(6);
  696.   value1 = NIL; mv_count=1; # returns NIL
  697. }
  698.  
  699. # (STDWIN::FILL-ARC x y rx ry angle1 angle2) calls wfillelarc().
  700. LISPFUNN(stdwin_fill_arc,3)
  701. { var reg6 sintL x = I_to_L(STACK_5);
  702.   var reg5 sintL y = I_to_L(STACK_4);
  703.   var reg4 sintL rx = I_to_L(STACK_3);
  704.   var reg3 sintL ry = I_to_L(STACK_2);
  705.   var reg2 sintL angle1 = I_to_L(STACK_1);
  706.   var reg1 sintL angle2 = I_to_L(STACK_0);
  707.   check_init();
  708.   begin_call();
  709.   wfillelarc(x,y,rx,ry,angle1,angle2);
  710.   end_call();
  711.   skipSTACK(6);
  712.   value1 = NIL; mv_count=1; # returns NIL
  713. }
  714.  
  715. #                       Text drawing primitives
  716. #                       -----------------------
  717.  
  718. # (STDWIN::DRAW-CHAR x y char) calls wdrawchar().
  719. LISPFUNN(stdwin_draw_char,3)
  720. { var reg2 sintL x = I_to_L(STACK_2);
  721.   var reg1 sintL y = I_to_L(STACK_1);
  722.   if (!string_char_p(STACK_0)) { fehler_string_char(STACK_0); }
  723.   check_init();
  724.   begin_call();
  725.   wdrawchar(x,y,char_code(STACK_0));
  726.   end_call();
  727.   skipSTACK(3);
  728.   value1 = NIL; mv_count=1; # returns NIL
  729. }
  730.  
  731. # (STDWIN::DRAW-TEXT x y string) calls wdrawtext().
  732. LISPFUNN(stdwin_draw_text,3)
  733. { var reg6 sintL x = I_to_L(STACK_2);
  734.   var reg5 sintL y = I_to_L(STACK_1);
  735.   var reg1 object string = STACK_0;
  736.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  737.   check_init();
  738.   with_string(string,chars,len,
  739.     if (len > 0)
  740.       { begin_call();
  741.         wdrawtext(x,y,chars,len);
  742.         end_call();
  743.       }
  744.     );
  745.   skipSTACK(3);
  746.   value1 = NIL; mv_count=1; # returns NIL
  747. }
  748.  
  749. #                       Text measuring primitives
  750. #                       -------------------------
  751.  
  752. # (STDWIN::LINE-HEIGHT) calls wlineheight().
  753. LISPFUNN(stdwin_line_height,0)
  754. { check_init();
  755.   begin_call();
  756.  {var reg1 sintL h = wlineheight();
  757.   end_call();
  758.   value1 = L_to_I(h); mv_count=1;
  759. }}
  760.  
  761. # (STDWIN::CHAR-WIDTH char) calls wcharwidth().
  762. LISPFUNN(stdwin_char_width,1)
  763. { var reg1 object ch = popSTACK();
  764.   if (!string_char_p(ch))
  765.     { pushSTACK(ch); # Wert fⁿr Slot DATUM von TYPE-ERROR
  766.       pushSTACK(S(string_char)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  767.       pushSTACK(ch); pushSTACK(TheSubr(subr_self)->name);
  768.       fehler(type_error,
  769.              DEUTSCH ? "~: Argument ~ ist kein String-Char." :
  770.              ENGLISH ? "~: argument ~ is not a string-char" :
  771.              FRANCAIS ? "~: L'argument ~ n'est pas un caractΦre de type STRING-CHAR." :
  772.              ""
  773.             );
  774.     }
  775.   check_init();
  776.   begin_call();
  777.  {var reg2 sintL w = wcharwidth(char_code(ch));
  778.   end_call();
  779.   value1 = L_to_I(w); mv_count=1;
  780. }}
  781.  
  782. # (STDWIN::TEXT-WIDTH string) calls wtextwidth().
  783. LISPFUNN(stdwin_text_width,1)
  784. { var reg1 object string = popSTACK();
  785.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  786.  {var reg4 sintL w;
  787.   check_init();
  788.   with_string(string,chars,len,
  789.     { begin_call();
  790.       w = wtextwidth(chars,len);
  791.       end_call();
  792.     });
  793.   value1 = L_to_I(w); mv_count=1;
  794. }}
  795.  
  796. # (STDWIN::TEXT-BREAK string width) calls wtextbreak().
  797. LISPFUNN(stdwin_text_break,2)
  798. { var reg1 object string = STACK_1;
  799.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  800.  {var reg6 sintL width = I_to_L(STACK_0);
  801.   var reg4 sintL w;
  802.   check_init();
  803.   with_string(string,chars,len,
  804.     { begin_call();
  805.       w = wtextbreak(chars,len,width);
  806.       end_call();
  807.     });
  808.   value1 = L_to_I(w); mv_count=1;
  809.   skipSTACK(2);
  810. }}
  811.  
  812. #                             Text style
  813. #                             ----------
  814.  
  815. # (STDWIN::SET-TEXT-FONT font-name font-style font-size) sets the current font.
  816. LISPFUNN(stdwin_set_text_font,3)
  817. { var reg4 object string = STACK_2;
  818.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  819.  {var reg5 sintL style = I_to_L(STACK_1);
  820.   var reg6 sintL size = I_to_L(STACK_0);
  821.   check_init();
  822.   with_string_0(string,fontname,
  823.     { begin_call();
  824.       wsetfont(fontname);
  825.       switch (style)
  826.         { case 0: wsetplain();      break;
  827.           case 1: wsethilite();     break;
  828.           case 2: wsetinverse();    break;
  829.           case 3: wsetitalic();     break;
  830.           case 4: wsetbold();       break;
  831.           case 5: wsetbolditalic(); break;
  832.           case 6: wsetunderline();  break;
  833.           default: break;
  834.         }
  835.       wsetsize(size);
  836.       end_call();
  837.     });
  838.   skipSTACK(3);
  839.   value1 = NIL; mv_count=1; # returns NIL
  840. }}
  841.  
  842. #                               Events
  843. #                               ++++++
  844.  
  845. # returns an event as a set of multiple values (no consing!)
  846. # return_event(event);
  847.   local Values return_event (EVENT* ep);
  848.   local Values return_event(ep)
  849.     var reg1 EVENT* ep;
  850.     { # cf. stdwin/H/stdwin.h, definition of 'struct _event'
  851.       var reg2 uintC mvcount;
  852.       pushSTACK(L_to_I(ep->type));
  853.       pushSTACK(type_untype_object(machine_type,ep->window));
  854.       # the next values provide more specific information
  855.       switch (ep->type)
  856.         { case WE_CHAR:
  857.             pushSTACK(L_to_I(ep->u.character));
  858.             mvcount=3; break;
  859.           case WE_COMMAND:
  860.             pushSTACK(L_to_I(ep->u.command));
  861.             mvcount=3; break;
  862.           case WE_MENU:
  863.             pushSTACK(L_to_I(ep->u.m.id));
  864.             pushSTACK(L_to_I(ep->u.m.item));
  865.             mvcount=4; break;
  866.           case WE_DRAW:
  867.             pushSTACK(L_to_I(ep->u.area.left));
  868.             pushSTACK(L_to_I(ep->u.area.top));
  869.             pushSTACK(L_to_I(ep->u.area.right - ep->u.area.left));
  870.             pushSTACK(L_to_I(ep->u.area.bottom - ep->u.area.top));
  871.             mvcount=6; break;
  872.           case WE_MOUSE_DOWN: case WE_MOUSE_MOVE: case WE_MOUSE_UP:
  873.             pushSTACK(L_to_I(ep->u.where.h));
  874.             pushSTACK(L_to_I(ep->u.where.v));
  875.             pushSTACK(L_to_I(ep->u.where.clicks));
  876.             pushSTACK(L_to_I(ep->u.where.button));
  877.             pushSTACK(L_to_I(ep->u.where.mask));
  878.             mvcount=7; break;
  879.           case WE_LOST_SEL:
  880.             pushSTACK(L_to_I(ep->u.sel));
  881.             mvcount=3; break;
  882.           case WE_KEY:
  883.             pushSTACK(L_to_I(ep->u.key.code));
  884.             pushSTACK(L_to_I(ep->u.key.mask));
  885.             mvcount=4; break;
  886.           default:
  887.             mvcount=2; break;
  888.         }
  889.       STACK_to_mv(mvcount);
  890.     }
  891.  
  892. #                           The input model
  893. #                           +++++++++++++++
  894.  
  895. # (STDWIN::GET-EVENT) calls wgetevent().
  896. # (STDWIN::GET-EVENT-NO-HANG) calls wpollevent().
  897.  
  898. # (STDWIN::GET-EVENT) calls wgetevent().
  899. LISPFUNN(stdwin_get_event,0)
  900. { check_init();
  901.  {var EVENT event;
  902.   begin_call();
  903.   wgetevent(&event);
  904.   end_call();
  905.   return_event(&event);
  906. }}
  907.  
  908. # (STDWIN::GET-EVENT-NO-HANG) calls wpollevent().
  909. LISPFUNN(stdwin_get_event_no_hang,0)
  910. { check_init();
  911.  {var EVENT event;
  912.   begin_call();
  913.   wpollevent(&event);
  914.   end_call();
  915.   return_event(&event);
  916. }}
  917.  
  918. #                  Getting and setting the active window
  919. #                  +++++++++++++++++++++++++++++++++++++
  920.  
  921. # (STDWIN::ACTIVE-WINDOW) calls wgetactive().
  922. # (STDWIN::SET-ACTIVE-WINDOW win) calls wsetactive().
  923.  
  924. # (STDWIN::ACTIVE-WINDOW) calls wgetactive().
  925. LISPFUNN(stdwin_active_window,0)
  926. { var reg1 WINDOW* win;
  927.   check_init();
  928.   begin_call();
  929.   win = wgetactive();
  930.   end_call();
  931.   value1 = (nullp(find_win(win)) ? NIL : type_untype_object(machine_type,win));
  932.   mv_count=1;
  933. }
  934.  
  935. # (STDWIN::SET-ACTIVE-WINDOW win) calls wsetactive().
  936. LISPFUNN(stdwin_set_active_window,1)
  937. { var reg1 WINDOW* win = test_window(STACK_0);
  938.   begin_call();
  939.   wsetactive(win);
  940.   end_call();
  941.   value1 = popSTACK(); mv_count=1; # returns win
  942. }
  943.  
  944. #                                  Menus
  945. #                                  +++++
  946.  
  947. # The documentation says that the menu id's should be in the range [1..255] and
  948. # unique within the application. We therefore manage the menu id's here.
  949.   #define menu_id_MAX  255
  950.   local unsigned int menu_id_max = 0; # maximum menu id that has been used for now
  951.   local MENU* menu_id[1+menu_id_MAX]; # menu_id[1..menu_id_max] are in use
  952.  
  953. # (STDWIN::MENU-CREATE title) calls wmenucreate().
  954. LISPFUNN(stdwin_menu_create,1)
  955. { var reg2 object string = popSTACK();
  956.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  957.   check_init();
  958.   # find a free menu id:
  959.  {var reg1 unsigned int id;
  960.   for (id = menu_id_max; id > 0; id--) { if (menu_id[id] == NULL) break; }
  961.   if (id == 0)
  962.     { if (menu_id_max < menu_id_MAX)
  963.         { id = ++menu_id_max; menu_id[id] = NULL; }
  964.         else
  965.         { pushSTACK(TheSubr(subr_self)->name);
  966.           fehler(error,
  967.                  DEUTSCH ? "~: STDWIN begrenzt die Anzahl der aktiven Menⁿs." :
  968.                  ENGLISH ? "~: STDWIN limits the number of active menus" :
  969.                  FRANCAIS ? "~ : STDWIN n'a qu'un nombre limitΘ de menus." :
  970.                  ""
  971.                 );
  972.     }   }
  973.   with_string_0(string,title,
  974.     { begin_call();
  975.       menu_id[id] = wmenucreate(id,title);
  976.       end_call();
  977.     });
  978.   value1 = fixnum(id); mv_count=1;
  979. }}
  980.  
  981. # test_menu(arg) checks that an argument is an STDWIN menu, and returns its id.
  982.   local int test_menu (object arg);
  983.   local int test_menu(arg)
  984.     var reg2 object arg;
  985.     { if (posfixnump(arg))
  986.         { var reg1 uintL id = posfixnum_to_L(arg);
  987.           if ((id > 0) && (id <= menu_id_max))
  988.             { var reg3 MENU* mp = menu_id[id];
  989.               if (!(mp == NULL))
  990.                 { return id; }
  991.         }   }
  992.       pushSTACK(arg);
  993.       pushSTACK(TheSubr(subr_self)->name);
  994.       fehler(error,
  995.              DEUTSCH ? "~: Argument ~ ist kein STDWIN:MENU." :
  996.              ENGLISH ? "~: argument ~ is not a STDWIN:MENU" :
  997.              FRANCAIS ? "~ : L'argument ~ n'est pas de type STDWIN:MENU." :
  998.              ""
  999.             );
  1000.    }
  1001.  
  1002. # (STDWIN::MENU-DELETE menu) calls wmenudelete().
  1003. LISPFUNN(stdwin_menu_delete,1)
  1004. { var reg1 int id = test_menu(popSTACK());
  1005.   begin_call();
  1006.   wmenudelete(menu_id[id]);
  1007.   end_call();
  1008.   if (id==menu_id_max) { menu_id_max--; } else { menu_id[id] = NULL; }
  1009.   value1 = NIL; mv_count=1; # returns NIL
  1010. }
  1011.  
  1012. # (STDWIN::MENU-ATTACH window menu) calls wmenuattach().
  1013. LISPFUNN(stdwin_menu_attach,2)
  1014. { var reg2 WINDOW* win = test_window(STACK_1);
  1015.   var reg1 int id = test_menu(STACK_0);
  1016.   begin_call();
  1017.   wmenuattach(win,menu_id[id]);
  1018.   end_call();
  1019.   skipSTACK(2);
  1020.   value1 = NIL; mv_count=1; # returns NIL
  1021. }
  1022.  
  1023. # (STDWIN::MENU-DETACH window menu) calls wmenudetach().
  1024. LISPFUNN(stdwin_menu_detach,2)
  1025. { var reg2 WINDOW* win = test_window(STACK_1);
  1026.   var reg1 int id = test_menu(STACK_0);
  1027.   begin_call();
  1028.   wmenudetach(win,menu_id[id]);
  1029.   end_call();
  1030.   skipSTACK(2);
  1031.   value1 = NIL; mv_count=1; # returns NIL
  1032. }
  1033.  
  1034. # (STDWIN::MENU-SIZE menu) returns the number of items in a menu.
  1035. LISPFUNN(stdwin_menu_size,1)
  1036. { var reg1 int id = test_menu(popSTACK());
  1037.   value1 = L_to_I(((_FAKEMENU*)(menu_id[id]))->nitems); mv_count=1;
  1038. }
  1039.  
  1040. # (STDWIN::MENU-ADD-ITEM menu label shortcut) calls wmenuadditem().
  1041. LISPFUNN(stdwin_menu_add_item,3)
  1042. { var reg2 int id = test_menu(STACK_2);
  1043.   var reg1 object string = STACK_1;
  1044.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  1045.   if (!string_char_p(STACK_0)) # auch #\Control-x etc. zulassen??
  1046.     { fehler_string_char(STACK_0); }
  1047.  {var reg3 int sc = char_code(STACK_0);
  1048.   var reg4 int result;
  1049.   with_string_0(string,label,
  1050.     { begin_call();
  1051.       result = wmenuadditem(menu_id[id],label,sc);
  1052.       end_call();
  1053.     });
  1054.   skipSTACK(3);
  1055.   value1 = L_to_I(result); mv_count=1; # returns the item's number
  1056. }}
  1057.  
  1058. # test_item(id,arg) checks that an argument is a valid menu item.
  1059.   local int test_item (int id, object arg);
  1060.   local int test_item(id,arg)
  1061.     var reg1 int id;
  1062.     var reg1 object arg;
  1063.     { if (posfixnump(arg))
  1064.         { var reg1 uintL item = posfixnum_to_L(arg);
  1065.           if (item < ((_FAKEMENU*)(menu_id[id]))->nitems)
  1066.             { return item; }
  1067.         }
  1068.       pushSTACK(arg);
  1069.       pushSTACK(TheSubr(subr_self)->name);
  1070.       fehler(error,
  1071.              DEUTSCH ? "~: Argument ~ ist kein STDWIN:MENU-ITEM." :
  1072.              ENGLISH ? "~: argument ~ is not a STDWIN:MENU-ITEM" :
  1073.              FRANCAIS ? "~ : L'argument ~ n'est pas de type STDWIN:MENU-ITEM." :
  1074.              ""
  1075.             );
  1076.     }
  1077.  
  1078. # (STDWIN::SET-MENU-ITEM-LABEL menu item-number label) calls wmenusetitem().
  1079. LISPFUNN(stdwin_set_menu_item_label,3)
  1080. { var reg1 object string = STACK_0;
  1081.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  1082.  {var reg2 int id = test_menu(STACK_2);
  1083.   var reg3 int item = test_item(id,STACK_1);
  1084.   with_string_0(string,label,
  1085.     { begin_call();
  1086.       wmenusetitem(menu_id[id],item,label);
  1087.       end_call();
  1088.     });
  1089.   value1 = STACK_0; mv_count=1; # returns the string
  1090.   skipSTACK(3);
  1091. }}
  1092.  
  1093. # (STDWIN::MENU-ITEM-ENABLE menu item-number) calls wmenuenable().
  1094. LISPFUNN(stdwin_menu_item_enable,2)
  1095. { var reg1 int id = test_menu(STACK_1);
  1096.   var reg2 int item = test_item(id,STACK_0);
  1097.   begin_call();
  1098.   wmenuenable(menu_id[id],item,TRUE);
  1099.   end_call();
  1100.   value1 = T; mv_count=1; # returns T
  1101.   skipSTACK(2);
  1102. }
  1103.  
  1104. # (STDWIN::MENU-ITEM-DISABLE menu item-number) calls wmenuenable().
  1105. LISPFUNN(stdwin_menu_item_disable,2)
  1106. { var reg1 int id = test_menu(STACK_1);
  1107.   var reg2 int item = test_item(id,STACK_0);
  1108.   begin_call();
  1109.   wmenuenable(menu_id[id],item,FALSE);
  1110.   end_call();
  1111.   value1 = NIL; mv_count=1; # returns NIL
  1112.   skipSTACK(2);
  1113. }
  1114.  
  1115. # (STDWIN::SET-MENU-ITEM-CHECKMARK menu item-number flag) calls wmenucheck().
  1116. LISPFUNN(stdwin_set_menu_item_checkmark,3)
  1117. { var reg1 int id = test_menu(STACK_2);
  1118.   var reg2 int item = test_item(id,STACK_1);
  1119.   var reg3 int flag = (nullp(STACK_0) ? FALSE : TRUE);
  1120.   begin_call();
  1121.   wmenucheck(menu_id[id],item,flag);
  1122.   end_call();
  1123.   value1 = STACK_0; mv_count=1; # returns flag
  1124.   skipSTACK(3);
  1125. }
  1126.  
  1127. #                            Dialogue tools
  1128. #                            ++++++++++++++
  1129.  
  1130. # (STDWIN::USER-MESSAGE message) calls wmessage().
  1131. LISPFUNN(stdwin_user_message,1)
  1132. { var reg1 object string = popSTACK();
  1133.   if (!stringp(string)) { fehler_string(string); } # mu▀ ein String sein
  1134.   check_init();
  1135.   with_string_0(string,message,
  1136.     { begin_call();
  1137.       wmessage(message);
  1138.       end_call();
  1139.     });
  1140.   value1 = NIL; mv_count=1; # returns NIL
  1141. }
  1142.  
  1143. # (STDWIN::USER-ASK question [default-reply]) calls waskstr().
  1144. LISPFUN(stdwin_user_ask,1,1,norest,nokey,0,NIL)
  1145. { var reg8 object string1 = STACK_1;
  1146.   if (!stringp(string1)) { fehler_string(string1); } # mu▀ ein String sein
  1147.  {var reg7 object string2 = (mstringp(STACK_0) ? STACK_0 : O(leer_string));
  1148.   check_init();
  1149.   with_string_0(string1,question,
  1150.     { with_string(string2,default_chars,default_len,
  1151.         { var reg6 uintL reply_len = default_len + 10000; # reicht hoffentlich
  1152.           # Buffer fⁿr die Antwort reservieren:
  1153.           var DYNAMIC_ARRAY(,reply_chars,char,reply_len);
  1154.           # default in reply umkopieren:
  1155.           { var reg2 char* ptr1 = default_chars;
  1156.             var reg1 char* ptr2 = reply_chars;
  1157.             var reg3 uintL count;
  1158.             dotimesL(count,default_len, { *ptr2++ = *ptr1++; } );
  1159.             *ptr2 = '\0';
  1160.           }
  1161.           begin_call();
  1162.          {var reg1 int result = waskstr(question,reply_chars,reply_len);
  1163.           end_call();
  1164.           value1 = (result ? asciz_to_string(reply_chars) : NIL); mv_count=1;
  1165.           FREE_DYNAMIC_ARRAY(reply_chars);
  1166.         }});
  1167.     });
  1168.   skipSTACK(2);
  1169. }}
  1170.  
  1171. #endif
  1172.  
  1173. #ifdef STDWIN_MODULE
  1174.  
  1175. #                  STDWIN as a linkable module for CLISP
  1176. #                  =====================================
  1177.  
  1178. #undef LISPFUN
  1179. #define LISPFUN LISPFUN_F
  1180. #undef LISPSYM
  1181. #define LISPSYM(name,printname,package)  { package, printname },
  1182. #define stdwin  "STDWIN"
  1183.  
  1184. subr_ module__stdwin__subr_tab [62] = {
  1185.   LISPFUNN(stdwin_init,0)
  1186.   LISPFUNN(stdwin_done,0)
  1187.   LISPFUNN(stdwin_drawproc_alist,0)
  1188.   LISPFUNN(stdwin_wopen,2)
  1189.   LISPFUNN(stdwin_wclose,1)
  1190.   LISPFUNN(stdwin_scrollbar_p,0)
  1191.   LISPFUNN(stdwin_set_scrollbar_p,2)
  1192.   LISPFUNN(stdwin_default_window_size,0)
  1193.   LISPFUNN(stdwin_set_default_window_size,2)
  1194.   LISPFUNN(stdwin_default_window_position,0)
  1195.   LISPFUNN(stdwin_set_default_window_position,2)
  1196.   LISPFUNN(stdwin_screen_size,0)
  1197.   LISPFUNN(stdwin_window_size,1)
  1198.   LISPFUNN(stdwin_window_position,1)
  1199.   LISPFUNN(stdwin_window_document_size,1)
  1200.   LISPFUNN(stdwin_set_window_document_size,3)
  1201.   LISPFUNN(stdwin_window_title,1)
  1202.   LISPFUNN(stdwin_set_window_title,2)
  1203.   LISPFUNN(stdwin_set_window_cursor,2)
  1204.   LISPFUNN(stdwin_window_show,5)
  1205.   LISPFUNN(stdwin_window_origin,1)
  1206.   LISPFUNN(stdwin_set_window_origin,3)
  1207.   LISPFUNN(stdwin_window_change,5)
  1208.   LISPFUNN(stdwin_window_update,1)
  1209.   LISPFUNN(stdwin_begin_drawing,1)
  1210.   LISPFUNN(stdwin_end_drawing,1)
  1211.   LISPFUNN(stdwin_draw_line,4)
  1212.   LISPFUNN(stdwin_xor_line,4)
  1213.   LISPFUNN(stdwin_draw_box,4)
  1214.   LISPFUNN(stdwin_paint,4)
  1215.   LISPFUNN(stdwin_invert,4)
  1216.   LISPFUNN(stdwin_erase,4)
  1217.   LISPFUNN(stdwin_shade,5)
  1218.   LISPFUNN(stdwin_draw_circle,3)
  1219.   LISPFUNN(stdwin_xor_circle,3)
  1220.   LISPFUNN(stdwin_fill_circle,3)
  1221.   LISPFUNN(stdwin_draw_arc,3)
  1222.   LISPFUNN(stdwin_xor_arc,3)
  1223.   LISPFUNN(stdwin_fill_arc,3)
  1224.   LISPFUNN(stdwin_draw_char,3)
  1225.   LISPFUNN(stdwin_draw_text,3)
  1226.   LISPFUNN(stdwin_line_height,0)
  1227.   LISPFUNN(stdwin_char_width,1)
  1228.   LISPFUNN(stdwin_text_width,1)
  1229.   LISPFUNN(stdwin_text_break,2)
  1230.   LISPFUNN(stdwin_set_text_font,3)
  1231.   LISPFUNN(stdwin_get_event,0)
  1232.   LISPFUNN(stdwin_get_event_no_hang,0)
  1233.   LISPFUNN(stdwin_active_window,0)
  1234.   LISPFUNN(stdwin_set_active_window,1)
  1235.   LISPFUNN(stdwin_menu_create,1)
  1236.   LISPFUNN(stdwin_menu_delete,1)
  1237.   LISPFUNN(stdwin_menu_attach,2)
  1238.   LISPFUNN(stdwin_menu_detach,2)
  1239.   LISPFUNN(stdwin_menu_size,1)
  1240.   LISPFUNN(stdwin_menu_add_item,3)
  1241.   LISPFUNN(stdwin_set_menu_item_label,3)
  1242.   LISPFUNN(stdwin_menu_item_enable,2)
  1243.   LISPFUNN(stdwin_menu_item_disable,2)
  1244.   LISPFUNN(stdwin_set_menu_item_checkmark,3)
  1245.   LISPFUNN(stdwin_user_message,1)
  1246.   LISPFUN(stdwin_user_ask,1,1,norest,nokey,0,NIL)
  1247. };
  1248.  
  1249. uintC module__stdwin__subr_tab_size = 62;
  1250.  
  1251. subr_initdata module__stdwin__subr_tab_initdata[62] = {
  1252.   LISPSYM(stdwin_init,"INIT",stdwin)
  1253.   LISPSYM(stdwin_done,"DONE",stdwin)
  1254.   LISPSYM(stdwin_drawproc_alist,"DRAWPROC-ALIST",stdwin)
  1255.   LISPSYM(stdwin_wopen,"WOPEN",stdwin)
  1256.   LISPSYM(stdwin_wclose,"WCLOSE",stdwin)
  1257.   LISPSYM(stdwin_scrollbar_p,"SCROLLBAR-P",stdwin)
  1258.   LISPSYM(stdwin_set_scrollbar_p,"SET-SCROLLBAR-P",stdwin)
  1259.   LISPSYM(stdwin_default_window_size,"DEFAULT-WINDOW-SIZE",stdwin)
  1260.   LISPSYM(stdwin_set_default_window_size,"SET-DEFAULT-WINDOW-SIZE",stdwin)
  1261.   LISPSYM(stdwin_default_window_position,"DEFAULT-WINDOW-POSITION",stdwin)
  1262.   LISPSYM(stdwin_set_default_window_position,"SET-DEFAULT-WINDOW-POSITION",stdwin)
  1263.   LISPSYM(stdwin_screen_size,"SCREEN-SIZE",stdwin)
  1264.   LISPSYM(stdwin_window_size,"WINDOW-SIZE",stdwin)
  1265.   LISPSYM(stdwin_window_position,"WINDOW-POSITION",stdwin)
  1266.   LISPSYM(stdwin_window_document_size,"WINDOW-DOCUMENT-SIZE",stdwin)
  1267.   LISPSYM(stdwin_set_window_document_size,"SET-WINDOW-DOCUMENT-SIZE",stdwin)
  1268.   LISPSYM(stdwin_window_title,"WINDOW-TITLE",stdwin)
  1269.   LISPSYM(stdwin_set_window_title,"SET-WINDOW-TITLE",stdwin)
  1270.   LISPSYM(stdwin_set_window_cursor,"SET-WINDOW-CURSOR",stdwin)
  1271.   LISPSYM(stdwin_window_show,"WINDOW-SHOW",stdwin)
  1272.   LISPSYM(stdwin_window_origin,"WINDOW-ORIGIN",stdwin)
  1273.   LISPSYM(stdwin_set_window_origin,"SET-WINDOW-ORIGIN",stdwin)
  1274.   LISPSYM(stdwin_window_change,"WINDOW-CHANGE",stdwin)
  1275.   LISPSYM(stdwin_window_update,"WINDOW-UPDATE",stdwin)
  1276.   LISPSYM(stdwin_begin_drawing,"BEGIN-DRAWING",stdwin)
  1277.   LISPSYM(stdwin_end_drawing,"END-DRAWING",stdwin)
  1278.   LISPSYM(stdwin_draw_line,"DRAW-LINE",stdwin)
  1279.   LISPSYM(stdwin_xor_line,"XOR-LINE",stdwin)
  1280.   LISPSYM(stdwin_draw_box,"DRAW-BOX",stdwin)
  1281.   LISPSYM(stdwin_paint,"PAINT",stdwin)
  1282.   LISPSYM(stdwin_invert,"INVERT",stdwin)
  1283.   LISPSYM(stdwin_erase,"ERASE",stdwin)
  1284.   LISPSYM(stdwin_shade,"SHADE",stdwin)
  1285.   LISPSYM(stdwin_draw_circle,"DRAW-CIRCLE",stdwin)
  1286.   LISPSYM(stdwin_xor_circle,"XOR-CIRCLE",stdwin)
  1287.   LISPSYM(stdwin_fill_circle,"FILL-CIRCLE",stdwin)
  1288.   LISPSYM(stdwin_draw_arc,"DRAW-ARC",stdwin)
  1289.   LISPSYM(stdwin_xor_arc,"XOR-ARC",stdwin)
  1290.   LISPSYM(stdwin_fill_arc,"FILL-ARC",stdwin)
  1291.   LISPSYM(stdwin_draw_char,"DRAW-CHAR",stdwin)
  1292.   LISPSYM(stdwin_draw_text,"DRAW-TEXT",stdwin)
  1293.   LISPSYM(stdwin_line_height,"LINE-HEIGHT",stdwin)
  1294.   LISPSYM(stdwin_char_width,"CHAR-WIDTH",stdwin)
  1295.   LISPSYM(stdwin_text_width,"TEXT-WIDTH",stdwin)
  1296.   LISPSYM(stdwin_text_break,"TEXT-BREAK",stdwin)
  1297.   LISPSYM(stdwin_set_text_font,"SET-TEXT-FONT",stdwin)
  1298.   LISPSYM(stdwin_get_event,"GET-EVENT",stdwin)
  1299.   LISPSYM(stdwin_get_event_no_hang,"GET-EVENT-NO-HANG",stdwin)
  1300.   LISPSYM(stdwin_active_window,"ACTIVE-WINDOW",stdwin)
  1301.   LISPSYM(stdwin_set_active_window,"SET-ACTIVE-WINDOW",stdwin)
  1302.   LISPSYM(stdwin_menu_create,"MENU-CREATE",stdwin)
  1303.   LISPSYM(stdwin_menu_delete,"MENU-DELETE",stdwin)
  1304.   LISPSYM(stdwin_menu_attach,"MENU-ATTACH",stdwin)
  1305.   LISPSYM(stdwin_menu_detach,"MENU-DETACH",stdwin)
  1306.   LISPSYM(stdwin_menu_size,"MENU-SIZE",stdwin)
  1307.   LISPSYM(stdwin_menu_add_item,"MENU-ADD-ITEM",stdwin)
  1308.   LISPSYM(stdwin_set_menu_item_label,"SET-MENU-ITEM-LABEL",stdwin)
  1309.   LISPSYM(stdwin_menu_item_enable,"MENU-ITEM-ENABLE",stdwin)
  1310.   LISPSYM(stdwin_menu_item_disable,"MENU-ITEM-DISABLE",stdwin)
  1311.   LISPSYM(stdwin_set_menu_item_checkmark,"SET-MENU-ITEM-CHECKMARK",stdwin)
  1312.   LISPSYM(stdwin_user_message,"USER-MESSAGE",stdwin)
  1313.   LISPSYM(stdwin_user_ask,"USER-ASK",stdwin)
  1314. };
  1315.  
  1316. void module__stdwin__init_function(module)
  1317.   var module_* module;
  1318.   { OM(stdwin_drawproc_alist) = NIL;
  1319.   }
  1320.  
  1321. #endif
  1322.  
  1323.