home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1997: The Complete Utilities Toolkit / macworld-complete-utilities-1997.iso / Programming / Little Smalltalk v3.1.5 / C Source / Sources / glue1.cp < prev    next >
Encoding:
Text File  |  1995-06-24  |  22.4 KB  |  752 lines  |  [TEXT/KAHL]

  1. /*
  2.     Little Smalltalk, version 3
  3.     Written by Tim Budd, Oregon State University, June 1988
  4.  
  5.     Symantec Think Class Library interface code 
  6.         ©Julian Barkway, April 1994, all rights reserved. 
  7.     
  8.     glue1.cp 
  9.     --------
  10.     
  11.     This is the interface between Little Smalltalk and the Symantec Think 
  12.     Class Library (v1.1.3). Where possible, I have retained the StdWin 
  13.     function names and parameters used in the original Little Smalltalk (v3) 
  14.     (although certain structures now refer to TCL objects) in order to assist 
  15.     porting. 
  16.     
  17.     Glue1.cp contains functions relating to windows, menus, graphics and dialogues.
  18.     Glue2.cp contains text, event handling and general purpose functions.
  19.     
  20.     Version History
  21.     ---------------
  22.     3.1.4 - First general release
  23.     3.1.5 - Modified to allow specification of non-closeable windows (wopentosize() only)
  24.             Modified to allow command key shortcuts for menu options
  25. */
  26.  
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include "Callbacks.proto.h"
  31. #include "TBUtilities.h"
  32. #include "Constants.h"
  33. #include "Global.h"
  34. #include "CBartender.h"
  35. #include "CLStWindow.h"
  36. #include "CLStApp.h"
  37. #include "CLStDoc.h"
  38. #include "CGraphicsPane.h"
  39. #include "LStResources.h"
  40. #include "env.h"
  41. #include "memory.h"
  42. #include "macio.h"
  43. #include "tclprim.proto.h"
  44.  
  45.                     // 'class' was redefined as 'klass' in order to avoid conflicts 
  46.                     // with the synonymous Think-C reserved word. Now the new definition 
  47.                     // must be removed in order to use TCL functions...
  48. #undef class
  49. #include "glue.h"
  50.  
  51. extern CBartender    *gBartender;
  52. extern CLStApp        *gSmalltalk;
  53.  
  54. #define uchar    unsigned char
  55.  
  56. //===================================================================================
  57. // Initialise the host windowing facility.
  58. //===================================================================================
  59. void winit (void)
  60. {
  61.     gSmalltalk = new (CLStApp);
  62.     gSmalltalk->ILStApp ();
  63.     if (gSystem.systemVersion < 0x0700) {
  64.         wperror ("Sorry, but System-7 or later is required to run Little Smalltalk.");
  65.         abort ();
  66.     }
  67. }
  68.  
  69.  
  70. //===================================================================================
  71. // Return the current version number as a 'C' string.
  72. //===================================================================================
  73. void getVersionNumber (char *str)
  74. {
  75.     PtoCstr (gSmalltalk->versionStr);
  76.     strcpy  (str, gSmalltalk->versionStr);
  77.     CtoPstr (gSmalltalk->versionStr);
  78. }
  79.  
  80.  
  81. //===================================================================================
  82. // Perform any necessary shut-down protocol for the host windowing facility.
  83. //===================================================================================
  84. void wdone (void)
  85. {
  86.     return;
  87. }
  88.  
  89.  
  90. //===================================================================================
  91. // Display a message to the user.
  92. //===================================================================================
  93. void wmessage (char *prompt)
  94. {
  95.     gSmalltalk->DoMessageAlert (prompt);
  96. }
  97.  
  98.  
  99. //===================================================================================
  100. // Display an error alert to the user.
  101. //===================================================================================
  102. void wperror (char *name)
  103. {
  104.     CtoPstr        (name);
  105.     ParamText      ((uchar *)name, NULL, NULL, NULL);
  106.     PositionDialog ('ALRT', ALRTgeneral);
  107.     InitCursor     ();
  108.     Alert          (ALRTgeneral, NULL);
  109.     PtoCstr        ((uchar *)name);
  110. }
  111.  
  112.  
  113. //=====================================================================================
  114. // Put up a prompt requesting some text from the user.
  115. //=====================================================================================
  116. Boolean waskstr (char *prompt, char *buf, int len)
  117. {
  118.     DialogPtr            theDialog;
  119.     GrafPtr                savePort;
  120.     short                itemHit, iType;
  121.     Handle                iText;
  122.     Rect                iRect;
  123.     Str255                boxText;
  124.     Boolean                rc;    
  125.     
  126.     GetPort (&savePort);
  127.     theDialog = GetNewDialog (kAskStringDLOG, 0L, (WindowPtr)-1L);
  128.     if (!theDialog) {
  129.         SetPort (savePort);
  130.         return (FALSE);
  131.     }
  132.  
  133.     CtoPstr   (prompt);
  134.     ParamText ((uchar *)prompt, NULL, NULL, NULL);
  135.     
  136.     GetDItem (theDialog, 5, &iType, &iText, &iRect);
  137.     SetDItem (theDialog, 5, iType, (Handle)highlightButton, &iRect);
  138.     GetDItem (theDialog, 4, &iType, &iText, &iRect);
  139.     
  140.     while (itemHit != OK && itemHit != Cancel) {
  141.         ModalDialog (defaultButtonFilter, &itemHit );
  142.     }
  143.     if (itemHit == Cancel)
  144.         rc = FALSE;
  145.     else {
  146.         GetIText (iText, boxText); 
  147.         PtoCstr (boxText);
  148.         strcpy (buf, (char *)boxText);        
  149.         rc = TRUE;
  150.     }    
  151.  
  152.     DisposDialog (theDialog);
  153.     SetPort      (savePort);
  154.     PtoCstr      ((uchar *)prompt);
  155.     return rc;
  156. }
  157.  
  158.  
  159. //===================================================================================
  160. // Display a message to the user requiring a Yes, No or Cancel response.
  161. //===================================================================================
  162. int waskync    (char *prompt, int def)
  163. {
  164.     return ((int)gSmalltalk->DoYNCAlert (prompt));
  165. }
  166.  
  167.  
  168. //===================================================================================
  169. // Display the standard file name requester. 
  170. // ---Parameter ftype added to StdWin function prototype.
  171. //===================================================================================
  172. Boolean waskfile (char *prompt, char *buf, int len, Boolean newFile, short ftype)
  173. {
  174.     WindowRecord        *w;
  175.     CLStWindow            *stWin;
  176.     CLStDoc                *doc;
  177.     StandardFileReply    fileStuff;
  178.     SFTypeList            fileTypes;
  179.     short                numTypes = 1;
  180.  
  181.     w = (WindowRecord *)FrontWindow ();
  182.     if (! w)
  183.         doc = new (CLStDoc);
  184.     else {
  185.         stWin = (CLStWindow *)GetWRefCon ((WindowPtr)w);
  186.         doc   = (CLStDoc *)(stWin->theLStWindow)->document;
  187.     }
  188.     
  189.     if (newFile)
  190.         doc->AskFileName (prompt, newFile, &fileStuff, NULL, 0);
  191.     else {    
  192.         stFileTypeToMac (ftype, fileTypes [0]);
  193.         if (fileTypes [0] == 0L) {
  194.             numTypes = -1;    /* If type not specified, then don't apply filtering */
  195.             doc->AskFileName (prompt, newFile, &fileStuff, NULL, numTypes);
  196.         }
  197.         else
  198.             doc->AskFileName (prompt, newFile, &fileStuff, fileTypes, numTypes);
  199.     }
  200.     if (fileStuff.sfGood == FALSE) 
  201.         return FALSE;
  202.     
  203.     PtoCstr     (fileStuff.sfFile.name);
  204.     getPathName (fileStuff.sfFile.vRefNum, fileStuff.sfFile.parID, buf);
  205.     strcat      (buf, (char *)fileStuff.sfFile.name);
  206.     return TRUE;
  207. }
  208.  
  209.  
  210. //===================================================================================
  211. // Enable (un-dim) an entire menu
  212. //===================================================================================
  213. void wmenuenable (MENU *mp, int item, int flag)
  214. {
  215.     if (flag)
  216.         EnableItem ((MenuHandle)mp, item + 1);
  217.     else
  218.         DisableItem ((MenuHandle)mp, item + 1);
  219. }
  220.  
  221.  
  222. //===================================================================================
  223. // Create a new menu.
  224. //===================================================================================
  225. MENU *wmenucreate (int id, char *title)
  226. {
  227.     MenuHandle        mh;
  228.     
  229.     id += kSTMenuBase;    // Our MENU resource ids start at 50. Smalltalk uses 1 - 15
  230.                         // Unfortunately, TCL also uses 1 - 5, hence this kludge.
  231.     gBartender->AddMenu (id, FALSE, 0);
  232.     ((CBartender *)gBartender)->SetDimOption (id, dimNONE);
  233.     mh = gBartender->FindMacMenu (id);
  234.     (*mh)->menuID = id;
  235.     return (MenuPtr)mh;
  236. }
  237.  
  238.  
  239. //===================================================================================
  240. // Create a pop-up menu. Pop-up menus are not handled through TCL and are created
  241. // without the need for a resource file entry.
  242. //===================================================================================
  243. MENU *popUpMenuCreate (short menuID)
  244. {
  245.     menuID += kSTPopMenuBase;
  246.     return (MenuPtr)NewMenu (menuID, "\p");
  247. }
  248.  
  249.  
  250. //===================================================================================
  251. // Attach a menu to a window.
  252. //===================================================================================
  253. void wmenuattach (WINDOW *win, MENU *mp)
  254. {
  255.     MenuHandle    mh;
  256.     short        menuID;
  257.     
  258.     mh     = (MenuHandle)mp;
  259.     menuID = (*mh)->menuID;
  260.     ((CBartender *)gBartender)->InsertInBar (menuID, 0);
  261. }
  262.  
  263.  
  264. //===================================================================================
  265. // Detach a menu from a window.
  266. //===================================================================================
  267. void wmenudetach (WINDOW *win, MENU *mp)
  268. {
  269.     MenuHandle    mh;
  270.     short        menuID;
  271.     
  272.     mh     = (MenuHandle)mp;
  273.     menuID = (*mh)->menuID;
  274.     gBartender->DeleteFromBar (menuID);
  275. }
  276.  
  277.  
  278. //===================================================================================
  279. // Check mark an item.
  280. //===================================================================================
  281. void wmenucheck    (MENU *mp, int item, int flag)
  282. {
  283.     CheckItem ((MenuHandle)mp, item + 1, flag);
  284. }
  285.  
  286.  
  287. //===================================================================================
  288. // Stub function for StdWin compatibility.
  289. //===================================================================================
  290. void wmenusetdeflocal (Boolean local)
  291. {
  292.     return;
  293. }
  294.  
  295.  
  296. //===================================================================================
  297. // Append an item to the end of a menu.
  298. // Modified to process command-key shortcuts (v3.1.5)
  299. //===================================================================================
  300. int wmenuadditem (MENU *mp, char *text, int shortcut)
  301. {
  302.     char    str [2] = {0, 0};
  303.     
  304.     if (shortcut && shortcut > 0) {
  305.         str [0] = (char)shortcut;
  306.         strcat (text, "/");
  307.         strcat (text, str);
  308.     }
  309.     CtoPstr (text);
  310.     AppendMenu ((MenuHandle)mp, (uchar *)text);
  311.     PtoCstr ((uchar *)text);
  312.     return (1);
  313. }
  314.  
  315.  
  316. //===================================================================================
  317. // Select an item from a pop-up menu displayed at top, left.  Not a StdWin function. 
  318. //===================================================================================
  319. void selectFromPopUpMenu (MENU *mp, short top, short left, short *menu, short *item)
  320. {
  321.     MenuHandle    mh;
  322.     long        selection;
  323.     Point        p;
  324.  
  325.     mh = (MenuHandle)mp;
  326.     p.h = left;
  327.     p.v = top;
  328.     ((CLStWindow *)GetWRefCon (FrontWindow () ))->Prepare ();
  329.     LocalToGlobal (&p);
  330.     InsertMenu (mh, hierMenu);
  331.     selection = PopUpMenuSelect (mh, p.v, p.h, 1);
  332.  
  333.     if (HiWord (selection ) == 0)
  334.         *menu = *item = 0;
  335.     else {
  336.         *menu = HiWord (selection);
  337.         *item = LoWord (selection);
  338.     }        
  339. }
  340.  
  341.  
  342. //===================================================================================
  343. // Completely dispose of a menu.
  344. //===================================================================================
  345. void wmenudelete (MENU *mp)
  346. {
  347.     MenuHandle    mh;
  348.     short        menuID;
  349.     
  350.     mh     = (MenuHandle)mp;
  351.     menuID = (*mh)->menuID;
  352.     gBartender->RemoveMenu (menuID);
  353. }
  354.  
  355.  
  356. //===================================================================================
  357. // Remove a menu item.
  358. //===================================================================================
  359. void removeMenuItem (MENU *mp, short menuItem)
  360. {
  361.     DelMenuItem ((MenuHandle)mp, menuItem);
  362. }
  363.  
  364.  
  365. //===================================================================================
  366. // Return four values representing the pixel co-ords of the left, top, right and 
  367. // bottom of the maximum available screen are respectively.
  368. //===================================================================================
  369. void getMaxScreenArea (short *left, short *top, short *right, short *bottom)
  370. {
  371.     *left   = screenBits.bounds.left;
  372.     *top    = screenBits.bounds.top;
  373.     *right  = screenBits.bounds.right;
  374.     *bottom = screenBits.bounds.bottom;
  375. }
  376.  
  377.  
  378. //===================================================================================
  379. // Return the named cursor from a resource or the system. 
  380. //===================================================================================
  381. CURSOR *wfetchcursor (char *name)
  382. {
  383.     CursHandle csrH;
  384.     
  385.     if (strcmp (name, "ibeam") == 0)
  386.         csrH = GetCursor (iBeamCursor);
  387.     else if (strcmp (name, "cross") == 0)
  388.         csrH = GetCursor (crossCursor);
  389.     else if (strcmp (name, "plus") == 0)
  390.         csrH = GetCursor (plusCursor);
  391.     else if (strcmp (name, "watch") == 0)
  392.         csrH = GetCursor (watchCursor);
  393.     else if (strcmp (name, "arrow") == 0)
  394.         csrH = (CursHandle)0xffffffffL;    /* A fairly unlikely handle. We'll use it as a flag. */
  395.     else
  396.         csrH = (CursHandle) GetNamedResource ('CURS', (uchar *)name);
  397.     
  398.     return (CURSOR *)csrH;
  399. }
  400.  
  401.  
  402. //===================================================================================
  403. // Set the current cursor to the given cursor. (Window is irrelevant here).
  404. //===================================================================================
  405. void wsetwincursor (WINDOW *win, CURSOR *cursor)
  406. {
  407.     Cursor    csr;
  408.     
  409.     if ((long)cursor == 0xffffffffL) {
  410.         InitCursor ();
  411.         return;
  412.     }
  413.     
  414.     HLock ((Handle)cursor);
  415.     csr = **((CursHandle)cursor);
  416.     HUnlock ((Handle)cursor);
  417.     SetCursor (&csr);
  418. }
  419.  
  420.  
  421. //===================================================================================
  422. // Restore the standard arrow pointer.
  423. //===================================================================================
  424. void setArrowCursor (void)
  425. {
  426.     InitCursor ();
  427. }
  428.  
  429.  
  430. //===================================================================================
  431. // Query the dirty status of a document.
  432. //===================================================================================
  433. Boolean docDirty (WINDOW *win)
  434. {
  435.     return ((CDocument *)win->document)->dirty;
  436. }
  437.  
  438.  
  439. //===================================================================================
  440. // Change the size of the given document.
  441. //===================================================================================
  442. void wsetdocsize (WINDOW *win, int docwidth, int docheight)
  443. {
  444.     ((CLStWindow *)win->window)->ChangeSize (docwidth, docheight);
  445. }
  446.  
  447.  
  448. //===================================================================================
  449. // Mark the given window as active.
  450. //===================================================================================
  451. void wsetactive    (WINDOW *win)
  452. {
  453.     ((CLStWindow *)win->window)->Activate ();
  454. }
  455.  
  456.  
  457. //===================================================================================
  458. // Open a window. Note that drawproc is redundant.
  459. //===================================================================================
  460. WINDOW *wopen (char *title, void (*drawproc)(WINDOW *win, int top, int left,
  461.                                               int bottom, int right) )
  462. {
  463.     CLStDoc    *doc;
  464.     WINDOW    *w;
  465.     
  466.     w   = (WINDOW *)malloc ((size_t)sizeof (WINDOW));
  467.     w->document = (char *)new (CLStDoc);
  468.     ((CLStDoc *)w->document)->ILStDoc (gSmalltalk, FALSE);
  469.     w->window   = (char *)((CLStDoc *)w->document)->BuildWindow (title, NULL, NULL, FALSE);
  470.     ((CLStWindow *)w->window)->theLStWindow = w;
  471.     return w;
  472. }
  473.  
  474.  
  475. //===================================================================================
  476. // Open a window, given its location and size. Note: if the left, top and/or the
  477. // width/height parameter pairs are zero, values will be provided by the underlying
  478. // TCL routine.
  479. // Amended for v3.1.5 to allow specification of non-closeable windows.
  480. //===================================================================================
  481. WINDOW *wopentosize (char *title, int left, int top, int width, int height, Boolean noClose)
  482. {
  483.     CLStDoc    *doc;
  484.     WINDOW    *w;
  485.     Point    wPosition, wSize, *p, *s;
  486.     
  487.     w   = (WINDOW *)malloc ((size_t)sizeof (WINDOW));
  488.     w->document = (char *)new (CLStDoc);
  489.     ((CLStDoc *)w->document)->ILStDoc (gSmalltalk, FALSE);
  490.     if (left == 0 && top == 0)
  491.         p = NULL;
  492.     else {
  493.         wPosition.h = left;
  494.         wPosition.v = top;
  495.         p           = &wPosition;
  496.     }
  497.     if (width == 0 && height == 0)
  498.         s = NULL;
  499.     else {
  500.         wSize.h     = width;
  501.         wSize.v     = height;
  502.         s           = &wSize;
  503.     }
  504.     w->window   = (char *)((CLStDoc *)w->document)->BuildWindow (title, p, s, noClose);
  505.     ((CLStWindow *)w->window)->theLStWindow = w;
  506.     return w;
  507. }
  508.  
  509.  
  510. //===================================================================================
  511. // Close a window.
  512. //===================================================================================
  513. void wclose    (WINDOW *win)
  514. {
  515.     ((CLStWindow *)win->window)->Remove ();
  516. }
  517.  
  518.  
  519. //===================================================================================
  520. // Return the current size of a window.
  521. //===================================================================================
  522. void wgetwinsize (WINDOW *win, int *pwidth, int *pheight)
  523. {
  524.     LongRect    lr;
  525.     
  526.     ((CLStWindow *)win->window)->GetAperture (&lr);
  527.  
  528.     *pwidth  = lr.right - lr.left;
  529.     *pheight = lr.bottom - lr.top;
  530. }
  531.  
  532.  
  533. //===================================================================================
  534. // Return the current position (in global co-ordinates) of a window.
  535. //===================================================================================
  536. void wgetwinpos (WINDOW *win, int *h, int *v)
  537. {
  538.     Point        pt;
  539.     GrafPort    *port;
  540.  
  541.     port = ((CLStWindow *)(win->window))->macPort;
  542.     pt.h = port->portRect.left;
  543.     pt.v = port->portRect.top;
  544.     ((CLStWindow *)(win->window))->Prepare ();
  545.     LocalToGlobal(&pt);
  546.     *h = pt.h;
  547.     *v = pt.v;
  548. }
  549.  
  550.  
  551. //===================================================================================
  552. // Bring a window to the 'front'.
  553. //===================================================================================
  554. void windowToFront (WINDOW *win)
  555. {
  556.     ((CLStWindow *)(win->window))->Select ();
  557. }
  558.  
  559.  
  560. //===================================================================================
  561. // Set a window's title.
  562. //===================================================================================
  563. void wsettitle (WINDOW *win, Str255 title)
  564. {
  565.     ((CLStWindow *)win->window)->SetTitle (title);
  566. }
  567.  
  568.  
  569. //===================================================================================
  570. // Stub function provided for StdWin compatitbility.
  571. //===================================================================================
  572. void wsetorigin (WINDOW *win, int orgh, int orgv)
  573. {
  574.     return;
  575. }
  576.  
  577.  
  578. //===================================================================================
  579. // Notify the system that we wish to commence a drawing operation.
  580. // - Slightly altered from the StdWin prototype to enable drawing to be 
  581. //   directed to a specific pane.
  582. //===================================================================================
  583. void wbegindrawing (TEXTEDIT *pane)
  584. {
  585.     ((CPane *)pane)->Prepare ();
  586. }
  587.  
  588.  
  589. //===================================================================================
  590. // Stub function provided for StdWin compatitbility.
  591. //===================================================================================
  592. void wenddrawing (TEXTEDIT *pane)
  593. {
  594.     return;
  595. }
  596.  
  597.  
  598. //===================================================================================
  599. // Beep the beeper.
  600. //===================================================================================
  601. void wfleep    (void)
  602. {
  603.     SysBeep (0);
  604. }
  605.  
  606.  
  607. //===================================================================================
  608. // Set the shading pattern for future drawing calls.
  609. //
  610. // Note: behaviour changed from StdWin prototype. Will now set the percentage
  611. //       of grey to be used in all drawing operations. Use wpaint () to colour
  612. //       a rectangle with the current pattern. This allows rather more flexibility.
  613. //
  614. //       5 percentage ranges are allowed corresponding to the five predefined 
  615. //       Mac Toolbox 'colours' as follows:
  616. //
  617. //        0 - 19% = white
  618. //       20 - 39% = ltGray
  619. //       40 - 59% = gray
  620. //       60 - 79% = dkGray
  621. //       80%+     = black
  622. //===================================================================================
  623. void wshade    (int left, int top, int right, int bottom, int perc)
  624. {
  625.     PatPtr    pat;
  626.     
  627.     if (perc >= 0 && perc < 20) {
  628.         pat = (PatPtr)white;
  629.     }
  630.     else if (perc > 20 && perc < 39) {
  631.         pat = (PatPtr)ltGray;
  632.     }
  633.     else if (perc > 40 && perc < 59) {
  634.         pat = (PatPtr)gray;
  635.     }
  636.     else if (perc > 60 && perc < 79) {
  637.         pat = (PatPtr)dkGray;
  638.     }
  639.     else {
  640.         pat = (PatPtr)black;
  641.     }
  642.     PenPat ((uchar const *)pat);
  643. }
  644.  
  645.  
  646. //===================================================================================
  647. // Erase the given rectangle.
  648. //===================================================================================
  649. void werase (int left, int top, int right, int bottom)
  650. {
  651.     Rect    r;
  652.     
  653.     SetRect     (&r, left, top, right, bottom);
  654.     EraseRect    (&r);
  655. }
  656.  
  657.  
  658. //===================================================================================
  659. // Draw a circle.
  660. //===================================================================================
  661. void wdrawcircle (int h, int v, int radius)
  662. {
  663.     Rect    r;
  664.     
  665.     SetRect     (&r, h - radius, v - radius, h + radius, v + radius);
  666.     FrameOval    (&r);
  667. }
  668.  
  669.  
  670. //===================================================================================
  671. // Draw a line from the current pen position to the given co-ordinates.
  672. //===================================================================================
  673. void drawLineTo (int h, int v)
  674. {
  675.     LineTo (h, v);
  676. }
  677.  
  678.  
  679. //===================================================================================
  680. // Move the pen position to the given co-ordinates.
  681. //===================================================================================
  682. void moveTo (short h, short v)
  683. {
  684.     MoveTo (h, v);
  685. }
  686.  
  687.  
  688. //===================================================================================
  689. // Draw a pixel at the given co-ordinates.
  690. //===================================================================================
  691. void drawPixel (short h, short v)
  692. {
  693.     MoveTo (h, v);
  694.     LineTo (h, v);
  695. }
  696.  
  697.  
  698. //===================================================================================
  699. // Draw a box corresponding to the given co-ordinates.
  700. //===================================================================================
  701. void wdrawbox (int left, int top, int right, int bottom)
  702. {
  703.     Rect    r;
  704.     
  705.     SetRect     (&r, left, top, right, bottom);
  706.     FrameRect    (&r);
  707. }
  708.  
  709.  
  710. //===================================================================================
  711. // Invert all the pixels in a rectangular area.
  712. //===================================================================================
  713. void winvert (int left, int top, int right, int bottom)
  714. {
  715.     Rect    r;
  716.     
  717.     SetRect     (&r, left, top, right, bottom);
  718.     InvertRect    (&r);
  719. }
  720.  
  721.  
  722. //===================================================================================
  723. // Fill a rectangle with the current pattern.
  724. //===================================================================================
  725. void wpaint    (int left, int top, int right, int bottom)
  726. {
  727.     Rect    r;
  728.     
  729.     SetRect     (&r, left, top, right, bottom);
  730.     PaintRect    (&r);
  731. }
  732.  
  733.  
  734. //===================================================================================
  735. // Draw a character string at the given location.
  736. //===================================================================================
  737. void wdrawtext (int h, int v, char *str, int len)
  738. {
  739.     MoveTo        (h, v);
  740.     DrawText    (str, 0, len);
  741. }
  742.  
  743.  
  744. //===================================================================================
  745. // Draw a single character at the given location.
  746. //===================================================================================
  747. void wdrawchar (int h, int v, int c)
  748. {
  749.     MoveTo        (h, v);
  750.     DrawChar    ((char)c);
  751. }
  752.