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 / glue2.cp < prev    next >
Encoding:
Text File  |  1995-06-25  |  22.3 KB  |  773 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.     glue2.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.  
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include "env.h"
  24. #include "memory.h"
  25. #include "macio.h"
  26. #include "tclprim.proto.h"
  27.  
  28. #undef class
  29. #include "Constants.h"
  30. #include "CDataFile.h"
  31. #include "CGraphicsPane.h"
  32. #include "CTextPane.h"
  33. #include "CSelectPane.h"
  34. #include "CLStWindow.h"
  35. #include "CLStApp.h"
  36. #include "CLStSwitchboard.h"
  37. #include "CLStScrollPane.h"
  38. #include "LStResources.h"
  39. #include "glue.h"
  40.  
  41. extern short        gClicks;
  42. extern CLStApp        *gSmalltalk;
  43.  
  44. #define uchar    unsigned char        // Just laziness :-)
  45.  
  46.  
  47. //===================================================================================
  48. // Set the font in the given TextEdit to the font specified in fontName.
  49. //===================================================================================
  50. void setFont (TEXTEDIT *tp, char *fontName)
  51. {
  52.     Str255    str;
  53.     Rect    margin = {0, 0, 0, 0};
  54.     
  55.     strcpy ((char *)str, fontName);
  56.     CtoPstr ((char *)str);
  57.     ((CTextPane *)tp)->SetFontName (str);
  58.                             // Force a dummy re-size which will re-calculate number 
  59.                             // of complete lines available, thereby ensuring that 
  60.                             // the last line doesn't get clipped vertically.
  61.     ((CTextPane *)tp)->ResizeFrame  (&margin);
  62.     ((CTextPane *)tp)->AdjustBounds ();    
  63. }
  64.  
  65.  
  66. //===================================================================================
  67. // Set the font size in the given TextEdit to that specified by fontSize.
  68. //===================================================================================
  69. void setFontSize (TEXTEDIT *tp, short fontSize)
  70. {
  71.     Rect    margin = {0, 0, 0, 0};
  72.     
  73.     ((CTextPane *)tp)->SetFontSize  (fontSize);
  74.     ((CTextPane *)tp)->ResizeFrame  (&margin);
  75.     ((CTextPane *)tp)->AdjustBounds ();    
  76. }
  77.  
  78.  
  79. //===================================================================================
  80. // Set the type face in the given TextEdit to that specified by typeFace.
  81. //
  82. // Note that in Smalltalk the following faces are available:
  83. //        1 - plain, 
  84. //        2 - bold, 
  85. //        3 - italic, 
  86. //        4 - underline
  87. //
  88. // and are specified by the numbers given NOT the Mac system constants.
  89. //
  90. //===================================================================================
  91. void setTypeFace (TEXTEDIT *tp, short typeFace)
  92. {
  93.     Rect    margin = {0, 0, 0, 0};
  94.     
  95.     switch (typeFace) {
  96.         case 1:
  97.             typeFace = normal;
  98.             break;
  99.         case 2:
  100.             typeFace = bold;
  101.             break;
  102.         case 3:
  103.             typeFace = italic;
  104.             break;
  105.         case 4:
  106.             typeFace = underline;
  107.             break;
  108.         default:
  109.             typeFace = normal;
  110.     }
  111.     ((CTextPane *)tp)->SetFontStyle (typeFace);
  112.     ((CTextPane *)tp)->ResizeFrame  (&margin);
  113.     ((CTextPane *)tp)->AdjustBounds ();
  114. }
  115.  
  116.  
  117. //===================================================================================
  118. // Replace the currently selected text in the given TextEdit by the text specified.
  119. //===================================================================================
  120. void tereplace (TEXTEDIT *tp, char *str)
  121. {
  122.     short        i;
  123.     long        selStart, selEnd;
  124.     TEHandle    teh = ((CTextPane *)tp)->macTE;
  125.     
  126.     for (i = 0; i < strlen (str); i++)    // Convert all LFs to CRs
  127.         if (str [i] == '\n')            // -- probably unnecessary in majority of cases.
  128.             str [i] = '\r';
  129.             
  130.     ((CTextPane *)tp)->GetSelection (&selStart, &selEnd);
  131.  
  132.     if (selEnd > selStart) {
  133.         ((CTextPane *)tp)->SetSelection (selEnd, selEnd, FALSE);
  134.     }
  135.  
  136.     ((CTextPane *)tp)->InsertTextPtr ((Ptr)str, (long)strlen (str), TRUE);
  137.     ((CTextPane *)tp)->AdjustBounds ();
  138. }
  139.  
  140.  
  141. //===================================================================================
  142. // Replace all the text in a text pane with the given text.
  143. //===================================================================================
  144. void replaceAllText (TEXTEDIT *tp, char *str)
  145. {
  146.     short        i;
  147.     
  148.     for (i = 0; i < strlen (str); i++)            // Convert all LFs to CRs
  149.         if (str [i] == '\n')
  150.             str [i] = '\r';
  151.             
  152.     ((CTextPane *)tp)->ReplaceContents (str);
  153.     ((CTextPane *)tp)->AdjustBounds ();
  154. }
  155.  
  156.  
  157. //===================================================================================
  158. // Delete all the text in a text pane.
  159. //===================================================================================
  160. void deleteAllText (TEXTEDIT *tp)
  161. {
  162.     ((CTextPane *)tp)->DeleteContents ();
  163.     ((CTextPane *)tp)->AdjustBounds ();
  164. }
  165.  
  166.  
  167. //===================================================================================
  168. // Return current size of pane.
  169. //===================================================================================
  170. void getPaneSize (TEXTEDIT *tp, short *width, short *height)
  171. {
  172.     long    w, h;
  173.     
  174.     ((CPane *)tp)->GetPixelExtent (&w, &h);
  175.     *width  = (short)w;
  176.     *height = (short)h;
  177. }
  178.  
  179.  
  180. #define getSizingOptions(x,y,x1,y1)    if (x)                     \
  181.                                         x1 = sizELASTIC;    \
  182.                                     else                    \
  183.                                         x1 = sizFIXEDLEFT;    \
  184.                                     if (y)                    \
  185.                                         y1 = sizELASTIC;    \
  186.                                     else                    \
  187.                                         y1 = sizFIXEDLEFT
  188.  
  189. //===================================================================================
  190. // Add a basic pane to a window.
  191. //===================================================================================
  192. TEXTEDIT *addScrollPane (WINDOW *win, short left, short top, short right, short bottom,
  193.                             short horizOption, short vertOption)
  194. {
  195.     CLStScrollPane    *scrollPane;
  196.     short            w = right - left,
  197.                     h = bottom - top;
  198.  
  199.     scrollPane = new (CLStScrollPane);
  200.     scrollPane->IScrollPane ((CLStWindow *)win->window, (CDocument *)(win->document),
  201.                              w, h, left, top,
  202.                              (SizingOption)horizOption, (SizingOption)vertOption, 
  203.                              TRUE, TRUE, TRUE);
  204.     return (char *)scrollPane;
  205. }
  206.  
  207.  
  208. //===================================================================================
  209. // Add a selection pane to a window.
  210. //===================================================================================
  211. TEXTEDIT *addSelPane (WINDOW *win, short left, short top, short right, short bottom,
  212.                        short horizElastic, short vertElastic, short lineLength)
  213. {
  214.     CSelectPane        *selPane;
  215.     CLStScrollPane    *scrollPane;
  216.     LongPt            origin   = {0L, 0L};
  217.     SizingOption    horizOption,  vertOption;
  218.  
  219.     getSizingOptions (horizElastic, vertElastic, horizOption, vertOption);
  220.     scrollPane = (CLStScrollPane *)addScrollPane (win, left, top, right, bottom, 
  221.                                                   horizOption, vertOption);
  222.     selPane = new (CSelectPane);
  223.     selPane->ISelectPane (scrollPane, (CDocument *)(win->document), 
  224.                           horizOption, vertOption, lineLength);
  225.     ((CDocument *)(win->document))->itsMainPane = selPane;
  226.     ((CDocument *)(win->document))->itsGopher   = selPane;
  227.  
  228.     scrollPane->InstallPanorama (selPane);
  229.     selPane->ScrollTo   (&origin, TRUE);        // Ensure everything is visible
  230.     
  231.     return (char *)selPane;
  232. }
  233.  
  234.  
  235. //===================================================================================
  236. // Add a text pane to a window
  237. //===================================================================================
  238. TEXTEDIT *addTextPane (WINDOW *win, short left, short top, short right, short bottom,
  239.                        short horizElastic, short vertElastic, short lineLength)
  240. {
  241.     CTextPane        *textPane;
  242.     CLStScrollPane    *scrollPane;
  243.     LongPt            origin   = {0L, 0L};
  244.     SizingOption    horizOption,  vertOption;
  245.  
  246.     getSizingOptions (horizElastic, vertElastic, horizOption, vertOption);
  247.     scrollPane = (CLStScrollPane *)addScrollPane (win, left, top, right, bottom, 
  248.                                                   horizOption, vertOption);
  249.     textPane = new (CTextPane);
  250.     textPane->ITextPane (scrollPane, (CDocument *)(win->document), 
  251.                          horizOption, vertOption, lineLength);
  252.     ((CDocument *)(win->document))->itsMainPane = textPane;
  253.     ((CDocument *)(win->document))->itsGopher   = textPane;
  254.  
  255.     scrollPane->InstallPanorama (textPane);
  256.     textPane->ScrollTo   (&origin, TRUE);        // Ensure everything is visible
  257.     
  258.     return (char *)textPane;
  259. }
  260.  
  261.  
  262. //===================================================================================
  263. // Stub function provided for StdWin compatibility.
  264. //===================================================================================
  265. TEXTEDIT *tecreate (WINDOW *win, int left, int top, int right, int bottom)
  266. {
  267.     return addTextPane (win, left, top, right, bottom, TRUE, TRUE, 2000);
  268. }
  269.  
  270.  
  271. //===================================================================================
  272. // Add a graphics pane to a window
  273. //===================================================================================
  274. TEXTEDIT *addGraphicsPane (WINDOW *win, short left, short top, short right, short bottom,
  275.                            short horizElastic, short vertElastic)
  276. {
  277.     CGraphicsPane    *gPane;
  278.     CLStScrollPane    *scrollPane;
  279.     LongPt            origin   = {0L, 0L};
  280.     SizingOption    horizOption,  vertOption;
  281.  
  282.     getSizingOptions (horizElastic, vertElastic, horizOption, vertOption);
  283.     scrollPane = (CLStScrollPane *)addScrollPane (win, left, top, right, bottom, 
  284.                                                   horizOption, vertOption);
  285.     gPane = new (CGraphicsPane);
  286.     gPane->IGraphicsPane (scrollPane, (CDocument *)(win->document), 
  287.                          horizOption, vertOption);
  288.     ((CDocument *)(win->document))->itsMainPane = gPane;
  289.     ((CDocument *)(win->document))->itsGopher   = gPane;
  290.  
  291.     scrollPane->InstallPanorama (gPane);
  292.     gPane->ScrollTo   (&origin, TRUE);        // Ensure everything is visible
  293.     
  294.     return (char *)gPane;
  295. }
  296.  
  297.  
  298. //===================================================================================
  299. // Stub function provided for StdWin compatibility.
  300. //===================================================================================
  301. Boolean teevent (TEXTEDIT *tp, EVENT *e)
  302. {
  303.     return FALSE;
  304. }
  305.  
  306.  
  307. //===================================================================================
  308. // Scroll the text, if necessary, to ensure that the selected area is visible in the
  309. // text pane.
  310. //===================================================================================
  311. void scrollToSelection (TEXTEDIT *tp)
  312. {
  313.     ((CTextPane *)tp)->ScrollToSelection ();
  314. }
  315.  
  316.  
  317. //===================================================================================
  318. // Set the text selection to the given character positions.
  319. //===================================================================================
  320. void setTextSelection (TEXTEDIT *tp, long startPos, long endPos)
  321. {
  322.     ((CTextPane *)tp)->SetSelection (startPos, endPos, TRUE);
  323. }
  324.  
  325.  
  326. //===================================================================================
  327. // Return the start and end character positions of the current text selection.
  328. //===================================================================================
  329. void getTextSelection (TEXTEDIT *tp, long *startPos, long *endPos)
  330. {
  331.     ((CTextPane *)tp)->GetSelection (startPos, endPos);
  332. }
  333.  
  334.  
  335. //===================================================================================
  336. // tegettext - return all the text associated with the current TE.
  337. //===================================================================================
  338.  
  339. #define MAXBUF        8 * 1024
  340. uchar buf [MAXBUF];
  341.  
  342. char *tegettext (TEXTEDIT *tp)
  343. {
  344.     Handle    th;
  345.     short    i, j;
  346.     long    maxText;
  347.     
  348.     maxText = ((CTextPane *)tp)->GetLength ();
  349.     
  350.     th = ((CTextPane *)tp)->GetTextHandle ();
  351.     if (maxText > MAXBUF - 1)
  352.         maxText = MAXBUF - 1;
  353.         
  354.     BlockMove (*th, buf, maxText);
  355.     buf [maxText] = '\0';
  356.         
  357.     return (char *)buf;
  358. }
  359.  
  360.  
  361. //===================================================================================
  362. // Return the text inside the selected area (if there is any)
  363. //===================================================================================
  364. char *teGetSelectedText (TEXTEDIT *tp)
  365. {
  366.     long    selStart, selEnd;
  367.     short    i;
  368.     char     *cp;
  369.     
  370.     cp = (char *)*(((CTextPane *)tp)->GetTextHandle ());
  371.     ((CTextPane *)tp)->GetSelection (&selStart, &selEnd);
  372.  
  373.     if (selEnd <= selStart) {
  374.         buf [0] = '\0';
  375.         return (char *)buf;
  376.     }
  377.     
  378.     for (i = 0; i < MAXBUF; i++) {
  379.         if (selStart == selEnd)
  380.             break;
  381.         buf [i] = cp [selStart++];
  382.     } 
  383.     buf [i] = '\0';
  384.     return (char *)buf;
  385. }
  386.  
  387.  
  388. //===================================================================================
  389. // Draw the contents of the given TextEdit.
  390. //===================================================================================
  391. void tedraw (register TEXTEDIT *tp)
  392. {
  393.     Rect        area;
  394.     LongRect    lr, margin = {0, 0, 0, 0};
  395.     
  396.     ((CTextPane *)tp)->GetAperture  (&lr);
  397.     ((CTextPane *)tp)->FrameToQDR   (&lr, &area);
  398.     ((CTextPane *)tp)->Draw         (&area);
  399. }
  400.  
  401.  
  402. //===================================================================================
  403. // Save the text of a TextEdit to the given file.
  404. //===================================================================================
  405. void saveTE (TEXTEDIT *tp, short fileNum)
  406. {
  407.     CDataFile        *fil;
  408.     FILE            *fd;
  409.     CharsHandle        teh;
  410.     
  411.     teh = TEGetText (((CTextPane *)tp)->macTE);
  412.     
  413.     fil  = new (CDataFile);
  414.     fil->IDataFile ();
  415.     fd   = getFilePointer (fileNum);
  416.     fil->refNum = fd->fileRef;
  417.     fil->WriteAll ((Handle)teh);
  418. }
  419.  
  420.  
  421. //===================================================================================
  422. // Load the text of a TextEdit from the given file.
  423. //===================================================================================
  424. void loadTE (TEXTEDIT *tp, short fileNum)
  425. {
  426.     CDataFile    *fil;
  427.     FILE        *fd;
  428.     Handle        hndl, h;
  429.     
  430.     fil  = new (CDataFile);
  431.     fil->IDataFile ();
  432.     fd   = getFilePointer (fileNum);
  433.     fil->refNum = fd->fileRef;
  434.     hndl = fil->ReadAll ();
  435.     ((CTextPane *)tp)->ReplaceContents (hndl);    // Parameter type changed to handle - v3.1.5
  436.     ((CTextPane *)tp)->AdjustBounds ();
  437.     h = *hndl;                                    // Safe handle disposal added for v3.1.5
  438.     if (h) {
  439.         DisposHandle (hndl);
  440.     }
  441. }
  442.  
  443.  
  444. //===================================================================================
  445. // Send an Open Document AppleEvent to the specified app using the specified file.
  446. //===================================================================================
  447. OSErr sendOpenDocEvent (long theAppSig, SFReply *theSFReply)
  448. {
  449.     AppleEvent        aEvent;
  450.     FSSpec            theFile;
  451.     WDPBRec            wdInfo;
  452.     OSErr            err;
  453.     AEDescList        docList;
  454.     AEDesc            docDesc, sigDesc;
  455.     AERecord        aeRec;
  456.     Boolean            disposeCheck [4] = {FALSE, FALSE, FALSE, FALSE};
  457.  
  458.     err = AECreateDesc   (typeApplSignature, &theAppSig, (Size)sizeof(long), 
  459.                            &sigDesc);
  460.     if (err)
  461.         goto sendOpenDocEvent_exit;
  462.         
  463.     disposeCheck [0] = TRUE;
  464.     err = AECreateAppleEvent (kCoreEventClass, kAEOpenDocuments, &sigDesc, 
  465.                               kAutoGenerateReturnID, kAnyTransactionID, &aEvent);
  466.     if (err)
  467.         goto sendOpenDocEvent_exit;
  468.         
  469.     disposeCheck [1] = TRUE;
  470.     wdInfo.ioNamePtr  = NULL;                    // Convert SFReply to FSSpec
  471.     wdInfo.ioVRefNum  = theSFReply->vRefNum;
  472.     wdInfo.ioWDIndex  = 0;
  473.     wdInfo.ioWDProcID = 0;
  474.     err = PBGetWDInfo (&wdInfo, FALSE);
  475.     if (err)
  476.         goto sendOpenDocEvent_exit;
  477.         
  478.     theFile.vRefNum  = wdInfo.ioWDVRefNum;
  479.     theFile.parID    = wdInfo.ioWDDirID;
  480.     BlockMove (theSFReply->fName, theFile.name, (long)theSFReply->fName [0] + 1);
  481.     
  482.     err = AECreateList (NULL, 0, FALSE, &docList);
  483.     if (err)
  484.         goto sendOpenDocEvent_exit;
  485.  
  486.     disposeCheck [2] = TRUE;
  487.     err = AECreateDesc (typeFSS, &theFile, (Size)sizeof (FSSpec), &docDesc);
  488.     if (err)
  489.         goto sendOpenDocEvent_exit;
  490.  
  491.     disposeCheck [3] = TRUE;
  492.     err = AEPutDesc (&docList, 0L, &docDesc);
  493.     if (err)
  494.         goto sendOpenDocEvent_exit;
  495.  
  496.     err = AEPutParamDesc (&aEvent, keyDirectObject, &docList);
  497.     if (err)
  498.         goto sendOpenDocEvent_exit;
  499.  
  500.     err = AESend (&aEvent, NULL, kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer,
  501.                   kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  502.                   
  503. sendOpenDocEvent_exit:
  504.     if (disposeCheck [1])
  505.         AEDisposeDesc (&aEvent);
  506.     if (disposeCheck [2])
  507.         AEDisposeDesc (&docList);
  508.     if (disposeCheck [3])
  509.         AEDisposeDesc (&docDesc);
  510.     if (err)
  511.         return err;
  512.         
  513.     return 0L;
  514. }
  515.  
  516.  
  517. //===================================================================================
  518. // Translate the info provided after an Open Document event has been received into
  519. // the full path and file type that Smalltalk currently likes. (I really will have
  520. // to get Smalltalk used to dealing with directory IDs one of these days...) Return
  521. // FALSE if info not present.
  522. //===================================================================================
  523. Boolean getFileInfo (char *fullPath, long *fType)
  524. {
  525.     if (gSmalltalk->theFile.fType == 0L)
  526.         return FALSE;
  527.         
  528.     *fType = (long)gSmalltalk->theFile.fType;
  529.     getPathNameFromWD ((long)gSmalltalk->theFile.vRefNum, fullPath);
  530.     PtoCstr     (gSmalltalk->theFile.fName);
  531.     strcat      (fullPath, (char *)gSmalltalk->theFile.fName);
  532.     CtoPstr     ((char *)gSmalltalk->theFile.fName);
  533.     return TRUE;
  534. }
  535.  
  536.  
  537. //===================================================================================
  538. // Process any AppleEvents sent by the Finder when the application is first launched.
  539. // I handle these separately from other events so I can load a system image before
  540. // Smalltalk itself is started. 
  541. //
  542. // Only HighLevelEvents are processed; anything else is ignored.
  543. //===================================================================================
  544. Boolean processStartUpEvent (char *buf)
  545. {
  546.     EventRecord        event;
  547.     long            fType;
  548.     short            i = 255;
  549.     OSErr            err;
  550.  
  551.     while (i) {
  552.         if (WaitNextEvent (highLevelEventMask, &event, 0, NULL) ) {
  553.             if (AEProcessAppleEvent (&event))
  554.                 return FALSE;                        // Error case.
  555.                 
  556.             if (getFileInfo (buf, &fType)) {
  557.                 if (fType == kSysImageType)
  558.                     return TRUE;
  559.                 else {        // Not a sys. image so requeue Event for handling later
  560.                     err = sendOpenDocEvent (kCreator, &gSmalltalk->theFile);
  561.                     return FALSE;
  562.                 }
  563.             }
  564.         }
  565.         i--;
  566.     }
  567. }
  568.  
  569. void printLog (char *msg);
  570. //===================================================================================
  571. // Get a user event from the system and translate it into StdWin format.
  572. //===================================================================================
  573. Point    lastMouse = {-32767, -32767};
  574.  
  575. void wgetevent (EVENT *ep)
  576. {
  577.      EventRecord    *macEvent;
  578.      Point        wp;
  579.     char        theChar;
  580.     Byte        keyCode;
  581.     WindowPtr    w;
  582.  
  583.      gSmalltalk->lastEvent.what = 0;
  584.      gSmalltalk->theFile.fType  = 0L;
  585.      
  586.      gSmalltalk->Process1Event ();
  587.      if (gSmalltalk->menuID == 0xffff) {
  588.          ep->type = WE_QUIT;
  589.          return;
  590.      }
  591.      if (gSmalltalk->lastEvent.what == 0) {
  592.          ep->type = WE_NULL;
  593.         return;
  594.     }
  595.          
  596.      macEvent = &(gSmalltalk->lastEvent);
  597.     
  598.     wp = macEvent->where;
  599.     GlobalToLocal (&wp);
  600.     if (lastMouse.h == -32767 && lastMouse.v == -32767)
  601.         lastMouse = wp;
  602.  
  603.         
  604.     w = FrontWindow ();
  605.     if (w)
  606.         ep->window = ((CLStWindow *)GetWRefCon (w))->theLStWindow;
  607.     else
  608.         ep->window = NULL;
  609.         
  610.     switch (macEvent->what) {
  611.         case mouseDown:
  612.             processMouseDown (macEvent, ep);
  613.             break;
  614.         case mouseUp:
  615.             ep->type = WE_MOUSE_UP;
  616.             ep->u.where.h      = wp.h;
  617.             ep->u.where.v      = wp.v;
  618.             ep->u.where.clicks = 1;
  619.             ep->u.where.button = 1;
  620.             ep->u.where.mask   = 0;
  621.             break;
  622.         case keyDown:
  623.         case autoKey:
  624.             theChar = macEvent->message & charCodeMask;
  625.             keyCode = (macEvent->message & keyCodeMask) >> 8;
  626.             if (macEvent->modifiers & cmdKey)
  627.                 break;
  628.             switch (keyCode) {
  629.                 case kEscapeOrClear:
  630.                 case kLeftCursor:
  631.                 case kRightCursor:
  632.                 case kUpCursor:
  633.                 case kDownCursor:
  634.                 case KeyHome:
  635.                 case KeyEnd:
  636.                 case KeyPageUp:
  637.                 case KeyPageDown:
  638.                 case KeyEscape:
  639.                 case KeyClear:
  640.                 case KeyHelp:
  641.                 case KeyFwdDelete:
  642.                 case KeyF1:
  643.                 case KeyF2:
  644.                 case KeyF3:
  645.                 case KeyF4:
  646.                 case KeyF5:
  647.                 case KeyF6:
  648.                 case KeyF7:
  649.                 case KeyF8:
  650.                 case KeyF9:
  651.                 case KeyF10:
  652.                 case KeyF11:
  653.                 case KeyF12:
  654.                 case KeyF13:
  655.                 case KeyF14:
  656.                 case KeyF15:
  657.                     ep->type       = WE_KEY;
  658.                     ep->u.key.code = keyCode;
  659.                     ep->u.key.mask = WM_META;
  660.                     break;
  661.                 case KeyLeftCursor:
  662.                 case KeyRightCursor:
  663.                 case KeyUpCursor:
  664.                 case KeyDownCursor:
  665.                     ep->type      = WE_COMMAND;
  666.                     ep->u.command = WC_LEFT;
  667.                     break;
  668.                 case kEnterKey:
  669.                     ep->type      = WE_COMMAND;
  670.                     ep->u.command = WC_RETURN;
  671.                     break;
  672.                 default:
  673.                     ep->type        = WE_CHAR;
  674.                     ep->u.character = theChar;
  675.             }
  676.             break;
  677.         case updateEvt:
  678.             {
  679.              WindowPtr    w = FrontWindow ();
  680.             Rect         r = (**(((WindowRecord *)w)->updateRgn)).rgnBBox;
  681.              
  682.             ep->type          = WE_DRAW;
  683.             ep->u.area.left   = r.left;
  684.             ep->u.area.top    = r.top;
  685.             ep->u.area.right  = r.right;
  686.             ep->u.area.bottom = r.bottom;
  687.             break;
  688.             }
  689.         case activateEvt:
  690.             ep->type = WE_ACTIVATE;
  691.             break;
  692.         case kHighLevelEvent:            /* Process AppleEvent */
  693.              ep->type = WE_EXTERN;
  694.             break;
  695.         default:
  696.             if (   (wp.h != lastMouse.h) 
  697.                 || (wp.v != lastMouse.v) ) {
  698.                 ep->type           = WE_MOUSE_MOVE;
  699.                 ep->u.where.h      = wp.h;
  700.                 ep->u.where.v      = wp.v;
  701.                 lastMouse          = wp;
  702.                 ep->u.where.clicks = gClicks;
  703.                 ep->u.where.button = 1;
  704.                 ep->u.where.mask   = 0;
  705.             }
  706.             else
  707.                 ep->type = WE_NULL;
  708.     }
  709.     lastMouse = wp;
  710. }
  711.  
  712.  
  713. //===================================================================================
  714. // Special processing for mouseDown events.
  715. //===================================================================================
  716. void processMouseDown (EventRecord *macEvent, EVENT *ep)
  717. {    
  718.     if (gSmalltalk->winPart != inContent && gSmalltalk->winPart == inSysWindow)
  719.         return;
  720.         
  721.     switch (gSmalltalk->winPart) {
  722.         case inMenuBar:
  723.             ep->type     = WE_MENU;
  724.             if (gSmalltalk->menuID > kSTMenuBase) {
  725.                 ep->u.m.id   = gSmalltalk->menuID - kSTMenuBase;
  726.                 ep->u.m.item = gSmalltalk->menuItem;     // Was: ' = gSmalltalk->menuItem - 1;'
  727.                                                         // - changed for v3.1.5
  728.             }
  729.             else {
  730.                 ep->type     = WE_NULL;
  731.                 ep->u.m.id   = 0; 
  732.                 ep->u.m.item = 0;
  733.             }
  734.             break;
  735.         case inDrag:
  736.             ep->type = WE_MOVE;
  737.             break;
  738.         case inGrow:
  739.             ep->type = WE_SIZE;
  740.             break;
  741.         case inGoAway:
  742.             ep->type = WE_CLOSE;
  743.             break;
  744.         default:
  745.         {
  746.             WINDOW        *w;
  747.             GrafPtr        aPort;
  748.             
  749.             ep->type           = WE_MOUSE_DOWN;
  750.             if (ep->window != NULL)
  751.                 ((CLStWindow *)(ep->window->window))->Prepare ();
  752.             GlobalToLocal (&(macEvent->where));        // Return point in _window_ co-ords.
  753.             ep->u.where.h      = macEvent->where.h;
  754.             ep->u.where.v      = macEvent->where.v;
  755.             ep->u.where.clicks = gClicks;
  756.             if (macEvent->modifiers & optionKey)
  757.                 ep->u.where.button = 2;        // Simulate a 2 button mouse with help of 'option' key
  758.             else
  759.                 ep->u.where.button = 1;
  760.             ep->u.where.mask   = 0;
  761.         }
  762.     }
  763. }
  764.  
  765.  
  766. //===================================================================================
  767. // Stub function provided for StdWin compatibility.
  768. //===================================================================================
  769. void wsettimer (WINDOW *win, int deciseconds)
  770. {
  771.     return;
  772. }
  773.