home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / code / xlisp_20.sit / macint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-07-29  |  12.9 KB  |  669 lines

  1. /* macint.c - macintosh interface routines for xlisp */
  2.  
  3. #include <MacTypes.h>
  4. #include <Quickdraw.h>  
  5. #include <WindowMgr.h>
  6. #include <EventMgr.h>
  7. #include <DialogMgr.h>
  8. #include <MenuMgr.h>
  9. #include <PackageMgr.h>
  10. #include <StdFilePkg.h>
  11. #include <MemoryMgr.h>
  12. #include <DeskMgr.h>
  13. #include <FontMgr.h>
  14. #include <ControlMgr.h>
  15. #include <SegmentLdr.h>
  16. #include <FileMgr.h>
  17.  
  18. /* program limits */
  19. #define SCRH        40    /* maximum screen height */
  20. #define SCRW        100    /* maximum screen width */
  21. #define CHARMAX     100    /* maximum number of buffered characters */
  22. #define TIMEON        40    /* cursor on time */
  23. #define TIMEOFF        20    /* cursor off time */
  24.  
  25. /* useful definitions */
  26. #define MenuBarHeight    20
  27. #define TitleBarHeight    20
  28. #define SBarWidth    16
  29. #define MinWidth    80
  30. #define MinHeight    40
  31. #define ScreenMargin    2
  32. #define TextMargin    4
  33. #define GHeight        232
  34.  
  35. /* menu id's */
  36. #define appleID        1
  37. #define fileID        256
  38. #define editID        257
  39. #define controlID    258
  40.  
  41. /* externals */
  42. extern char *s_unbound;
  43. extern char *PtoCstr();
  44.  
  45. /* screen dimensions */
  46. int screenWidth;
  47. int screenHeight;
  48.  
  49. /* command window (normal screen) */
  50. int nHorizontal,nVertical,nWidth,nHeight;
  51.  
  52. /* command window (split screen) */
  53. int sHorizontal,sVertical,sWidth,sHeight;
  54.  
  55. /* graphics window */
  56. int gHorizontal,gVertical,gWidth,gHeight;
  57.  
  58. /* menu handles */
  59. MenuHandle appleMenu;
  60. MenuHandle fileMenu;
  61. MenuHandle editMenu;
  62. MenuHandle controlMenu;
  63.  
  64. /* misc variables */
  65. OSType filetypes[] = { 'TEXT' };
  66.  
  67. /* font information */
  68. int tmargin,lmargin;
  69. int xinc,yinc;
  70.  
  71. /* command window */
  72. WindowRecord cwrecord;
  73. WindowPtr cwindow;
  74.  
  75. /* graphics window */
  76. WindowRecord gwrecord;
  77. WindowPtr gwindow;
  78.  
  79. /* window mode */
  80. int splitmode;
  81.  
  82. /* cursor variables */
  83. long cursortime;
  84. int cursorstate;
  85. int x,y;
  86.  
  87. /* screen buffer */
  88. char screen[SCRH*SCRW],*topline,*curline;
  89. int scrh,scrw;
  90.  
  91. /* type ahead buffer */
  92. char charbuf[CHARMAX],*inptr,*outptr;
  93. int charcnt;
  94.  
  95. macinit()
  96. {
  97.     /* initialize the toolbox */
  98.     InitGraf(&thePort);
  99.     InitFonts();
  100.     InitWindows();
  101.     InitMenus();
  102.     TEInit();
  103.     InitDialogs(0L);
  104.     InitCursor();
  105.  
  106.     /* setup the menu bar */
  107.     SetupMenus();
  108.  
  109.     /* get the size of the screen */
  110.     screenWidth  = screenBits.bounds.right  - screenBits.bounds.left;
  111.     screenHeight = screenBits.bounds.bottom - screenBits.bounds.top;
  112.  
  113.     /* Create the graphics and control windows */
  114.     gwindow = GetNewWindow(129,&gwrecord,-1L);
  115.     cwindow = GetNewWindow(128,&cwrecord,-1L);
  116.  
  117.     /* establish the command window as the current port */
  118.     SetPort(cwindow);
  119.  
  120.     /* compute the size of the normal command window */
  121.     nHorizontal = ScreenMargin;
  122.     nVertical = MenuBarHeight + TitleBarHeight + ScreenMargin - 2;
  123.     nWidth = screenWidth - (ScreenMargin * 2) - 1;
  124.     nHeight = screenHeight - MenuBarHeight - TitleBarHeight - (ScreenMargin * 2);
  125.  
  126.     /* compute the size of the split command window */
  127.     sHorizontal = nHorizontal;
  128.     sVertical = nVertical + GHeight + 1;
  129.     sWidth = nWidth;
  130.     sHeight = nHeight - GHeight - 1;
  131.  
  132.     /* compute the size of the graphics window */
  133.     gHorizontal = nHorizontal;
  134.     gVertical = MenuBarHeight + ScreenMargin;
  135.     gWidth = screenWidth - (ScreenMargin * 2);
  136.     gHeight = GHeight;
  137.  
  138.     /* move and size the graphics window */
  139.     MoveWindow(gwindow,gHorizontal,gVertical,0);
  140.     SizeWindow(gwindow,gWidth,gHeight,0);
  141.  
  142.     /* setup the font, size and writing mode for the command window */
  143.     TextFont(monaco); TextSize(9); TextMode(srcCopy);
  144.  
  145.     /* setup command mode */
  146.     scrsplit(FALSE);
  147.  
  148.     /* disable the Cursor */
  149.     cursorstate = -1;
  150.  
  151.     /* setup the input ring buffer */
  152.     inptr = outptr = charbuf;
  153.     charcnt = 0;
  154.     
  155.     /* lock the font in memory */
  156.     SetFontLock(-1);
  157. }
  158.  
  159. SetupMenus()
  160. {
  161.     appleMenu = GetMenu(appleID);    /* setup the apple menu */
  162.     AddResMenu(appleMenu,'DRVR');
  163.     InsertMenu(appleMenu,0);
  164.     fileMenu = GetMenu(fileID);        /* setup the file menu */
  165.     InsertMenu(fileMenu,0);
  166.     editMenu = GetMenu(editID);        /* setup the edit menu */
  167.     InsertMenu(editMenu,0);
  168.     controlMenu = GetMenu(controlID);    /* setup the control menu */
  169.     InsertMenu(controlMenu,0);
  170.     DrawMenuBar();
  171. }
  172.  
  173. int scrgetc()
  174. {
  175.     CursorOn();
  176.     while (charcnt == 0)
  177.     DoEvent();
  178.     CursorOff();
  179.     return (scrnextc());
  180. }
  181.  
  182. int scrnextc()
  183. {
  184.     int ch;
  185.     if (charcnt > 0) {
  186.     ch = *outptr++; charcnt--;
  187.     if (outptr >= &charbuf[CHARMAX])
  188.         outptr = charbuf;
  189.     }
  190.     else {
  191.     charcnt = 0;
  192.     ch = -1;
  193.     }
  194.     return (ch);
  195. }
  196.  
  197. scrputc(ch)
  198.   int ch;
  199. {
  200.     switch (ch) {
  201.     case '\r':
  202.     x = 0;
  203.     break;
  204.     case '\n':
  205.     nextline(&curline);
  206.     if (++y >= scrh) {
  207.         y = scrh - 1;
  208.         scrollup();
  209.     }
  210.     break;
  211.     case '\t':
  212.     do { scrputc(' '); } while (x & 7);
  213.     break;
  214.     case '\010':
  215.     if (x) x--;
  216.     break;
  217.     default:
  218.     if (ch >= 0x20 && ch < 0x7F) {
  219.         scrposition(x,y);
  220.         DrawChar(ch);
  221.         curline[x] = ch;
  222.         if (++x >= scrw) {
  223.         nextline(&curline);
  224.         if (++y >= scrh) {
  225.             y = scrh - 1;
  226.             scrollup();
  227.         }
  228.         x = 0;
  229.         }
  230.     }
  231.     break;
  232.     }
  233. }
  234.  
  235. scrdelete()
  236. {
  237.     scrputc('\010');
  238.     scrputc(' ');
  239.     scrputc('\010');
  240. }
  241.  
  242. scrclear()
  243. {
  244.     curline = screen;
  245.     for (y = 0; y < SCRH; y++)
  246.     for (x = 0; x < SCRW; x++)
  247.         *curline++ = ' ';
  248.     topline = curline = screen;
  249.     x = y = 0;
  250. }
  251.  
  252. scrflush()
  253. {
  254.     inptr = outptr = charbuf;
  255.     charcnt = -1;
  256.     osflush();
  257. }
  258.  
  259. scrposition(x,y)
  260.   int x,y;
  261. {
  262.     MoveTo((x * xinc) + lmargin,(y * yinc) + tmargin);
  263. }
  264.  
  265. DoEvent()
  266. {
  267.     EventRecord myEvent;
  268.     
  269.     SystemTask();
  270.     CursorUpdate();
  271.  
  272.     while (GetNextEvent(everyEvent,&myEvent))
  273.     switch (myEvent.what) {
  274.         case mouseDown:
  275.         DoMouseDown(&myEvent);
  276.         break;
  277.         case keyDown:
  278.         case autoKey:
  279.         DoKeyPress(&myEvent);
  280.         break;
  281.         case activateEvt:
  282.         DoActivate(&myEvent);
  283.         break;
  284.         case updateEvt:
  285.         DoUpdate(&myEvent);
  286.         break;
  287.         }
  288. }
  289.  
  290. DoMouseDown(myEvent)
  291.   EventRecord *myEvent;
  292. {
  293.     WindowPtr whichWindow;
  294.  
  295.     switch (FindWindow(myEvent->where,&whichWindow)) {
  296.     case inMenuBar:
  297.     DoMenuClick(myEvent);
  298.     break;
  299.     case inSysWindow:
  300.     SystemClick(myEvent,whichWindow);
  301.     break;
  302.     case inDrag:
  303.     DoDrag(myEvent,whichWindow);
  304.     break;
  305.     case inGoAway:
  306.     DoGoAway(myEvent,whichWindow);
  307.     break;
  308.     case inGrow:
  309.     DoGrow(myEvent,whichWindow);
  310.     break;
  311.     case inContent:
  312.     DoContent(myEvent,whichWindow);
  313.     break;
  314.     }
  315. }
  316.  
  317. DoMenuClick(myEvent)
  318.   EventRecord *myEvent;
  319. {
  320.     long choice;
  321.     if (choice = MenuSelect(myEvent->where))
  322.     DoCommand(choice);
  323. }
  324.  
  325. DoDrag(myEvent,whichWindow)
  326.   EventRecord *myEvent;
  327.   WindowPtr whichWindow;
  328. {
  329.     Rect dragRect;
  330.     SetRect(&dragRect,0,MenuBarHeight,screenWidth,screenHeight);
  331.     InsetRect(&dragRect,ScreenMargin,ScreenMargin);
  332.     DragWindow(whichWindow,myEvent->where,&dragRect);
  333. }
  334.  
  335. DoGoAway(myEvent,whichWindow)
  336.   EventRecord *myEvent;
  337.   WindowPtr whichWindow;
  338. {
  339.     if (TrackGoAway(whichWindow,myEvent->where))
  340.     wrapup();
  341. }
  342.  
  343. DoGrow(myEvent,whichWindow)
  344.   EventRecord *myEvent;
  345.   WindowPtr whichWindow;
  346. {
  347.     Rect sizeRect;
  348.     long newSize;
  349.     if (whichWindow != FrontWindow() && whichWindow != gwindow)
  350.     SelectWindow(whichWindow);
  351.     else {
  352.     SetRect(&sizeRect,MinWidth,MinHeight,screenWidth,screenHeight-MenuBarHeight);
  353.     newSize = GrowWindow(whichWindow,myEvent->where,&sizeRect);
  354.     if (newSize) {
  355.         EraseRect(&whichWindow->portRect);
  356.         SizeWindow(whichWindow,LoWord(newSize),HiWord(newSize),-1);
  357.         InvalRect(&whichWindow->portRect);
  358.         SetupScreen();
  359.         scrflush();
  360.     }
  361.     }
  362. }
  363.  
  364. DoContent(myEvent,whichWindow)
  365.   EventRecord *myEvent;
  366.   WindowPtr whichWindow;
  367. {
  368.     if (whichWindow != FrontWindow() && whichWindow != gwindow)
  369.     SelectWindow(whichWindow);
  370. }
  371.  
  372. DoKeyPress(myEvent)
  373.   EventRecord *myEvent;
  374. {
  375.     long choice;
  376.     
  377.     if (FrontWindow() == cwindow) {
  378.     if (myEvent->modifiers & 0x100) {
  379.         if (choice = MenuKey((char)myEvent->message))
  380.         DoCommand(choice);
  381.     }
  382.     else {
  383.         if (charcnt < CHARMAX) {
  384.         *inptr++ = myEvent->message & 0xFF; charcnt++;
  385.         if (inptr >= &charbuf[CHARMAX])
  386.             inptr = charbuf;
  387.         }
  388.     }
  389.     }
  390. }
  391.  
  392. DoActivate(myEvent)
  393.   EventRecord *myEvent;
  394. {
  395.     WindowPtr whichWindow;
  396.     whichWindow = (WindowPtr)myEvent->message;
  397.     SetPort(whichWindow);
  398.     if (whichWindow == cwindow)
  399.     DrawGrowIcon(whichWindow);
  400. }
  401.  
  402. DoUpdate(myEvent)
  403.   EventRecord *myEvent;
  404. {
  405.     WindowPtr whichWindow;
  406.     GrafPtr savePort;
  407.     GetPort(&savePort);
  408.     whichWindow = (WindowPtr)myEvent->message;
  409.     SetPort(whichWindow);
  410.     BeginUpdate(whichWindow);
  411.     EraseRect(&whichWindow->portRect);
  412.     if (whichWindow == cwindow) {
  413.     DrawGrowIcon(whichWindow);
  414.     RedrawScreen();
  415.     }
  416.     EndUpdate(whichWindow);
  417.     SetPort(savePort);
  418. }
  419.  
  420. DoCommand(choice)
  421.   long choice;
  422. {
  423.     int theMenu,theItem;
  424.     
  425.     /* decode the menu choice */
  426.     theMenu = HiWord(choice);
  427.     theItem = LoWord(choice);
  428.     
  429.     CursorOff();
  430.     HiliteMenu(theMenu);
  431.     switch (theMenu) {
  432.     case appleID:
  433.     DoAppleMenu(theItem);
  434.     break;
  435.     case fileID:
  436.     DoFileMenu(theItem);
  437.     break;
  438.     case editID:
  439.     DoEditMenu(theItem);
  440.     break;
  441.     case controlID:
  442.     DoControlMenu(theItem);
  443.     break;
  444.     }
  445.     HiliteMenu(0);
  446.     CursorOn();
  447. }
  448.  
  449. pascal aboutfilter(theDialog,theEvent,itemHit)
  450.   DialogPtr theDialog; EventRecord *theEvent; int *itemHit;
  451. {
  452.     return (theEvent->what == mouseDown ? -1 : 0);
  453. }
  454.  
  455. DoAppleMenu(theItem)
  456.   int theItem;
  457. {
  458.     DialogRecord mydialog;
  459.     char name[256];
  460.     GrafPtr gp;
  461.     int n;
  462.  
  463.     switch (theItem) {
  464.     case 1:
  465.     GetNewDialog(129,&mydialog,-1L);
  466.     ModalDialog(aboutfilter,&n);
  467.     CloseDialog(&mydialog);
  468.     break;
  469.     default:
  470.     GetItem(appleMenu,theItem,name);
  471.     GetPort(&gp);
  472.     OpenDeskAcc(name);
  473.     SetPort(gp);
  474.     break;
  475.     }
  476. }
  477.  
  478. pascal int filefilter(pblock)
  479.   ParmBlkPtr pblock;
  480. {
  481.     unsigned char *p; int len;
  482.     p = pblock->fileParam.ioNamePtr; len = *p++ &0xFF;
  483.     return (len >= 4 && strncmp(p+len-4,".lsp",4) == 0 ? 0 : -1);
  484. }
  485.  
  486. DoFileMenu(theItem)
  487.   int theItem;
  488. {
  489.     SFReply loadfile;
  490.     Point p;
  491.  
  492.     switch (theItem) {
  493.     case 1:    /* load */
  494.     case 2:    /* load noisily */
  495.     p.h = 100; p.v = 100;
  496.     SFGetFile(p,"\P",filefilter,-1,filetypes,0L,&loadfile);
  497.     if (loadfile.good) {
  498.         HiliteMenu(0);
  499.         SetVol(0L,loadfile.vRefNum);
  500.         if (xlload(PtoCstr(loadfile.fName),1,(theItem == 1 ? 0 : 1)))
  501.         scrflush();
  502.         else
  503.         xlabort("load error");
  504.     }
  505.     break;
  506.     case 4:    /* quit */
  507.     wrapup();
  508.     }
  509. }
  510.  
  511. DoEditMenu(theItem)
  512.   int theItem;
  513. {
  514.     switch (theItem) {
  515.     case 1:    /* undo */
  516.     case 3:    /* cut */
  517.     case 4:    /* copy */
  518.     case 5:    /* paste */
  519.     case 6:    /* clear */
  520.     SystemEdit(theItem-1);
  521.     break;
  522.     }
  523. }
  524.  
  525. DoControlMenu(theItem)
  526.   int theItem;
  527. {
  528.     scrflush();
  529.     HiliteMenu(0);
  530.     switch (theItem) {
  531.     case 1:    /* break */
  532.     xlbreak("user break",s_unbound);
  533.     break;
  534.     case 2:    /* continue */
  535.     xlcontinue();
  536.     break;
  537.     case 3:    /* clean-up error */
  538.     xlcleanup();
  539.     break;
  540.     case 4:    /* Cancel input */
  541.     xlabort("input canceled");
  542.     break;
  543.     case 5:    /* Top Level */
  544.     xltoplevel();
  545.     break;
  546.     case 7:    /* split screen */
  547.     scrsplit(splitmode ? FALSE : TRUE);
  548.     break;
  549.     }
  550. }
  551.  
  552. scrsplit(split)
  553.   int split;
  554. {
  555.     ShowHide(cwindow,0);
  556.     if (split) {
  557.     CheckItem(controlMenu,7,-1);
  558.     ShowHide(gwindow,-1);
  559.     MoveWindow(cwindow,sHorizontal,sVertical,-1);
  560.     SizeWindow(cwindow,sWidth,sHeight,-1);
  561.     InvalRect(&cwindow->portRect);
  562.     SetupScreen();
  563.     }
  564.     else {
  565.     CheckItem(controlMenu,7,0);
  566.     ShowHide(gwindow,0);
  567.     MoveWindow(cwindow,nHorizontal,nVertical,-1);
  568.     SizeWindow(cwindow,nWidth,nHeight,-1);
  569.     InvalRect(&cwindow->portRect);
  570.     SetupScreen();
  571.     }
  572.     ShowHide(cwindow,-1);
  573.     splitmode = split;
  574. }
  575.  
  576. SetupScreen()
  577. {
  578.     FontInfo info;
  579.     Rect *pRect;
  580.  
  581.     /* get font information */
  582.     GetFontInfo(&info);
  583.  
  584.     /* compute the top and bottom margins */
  585.     tmargin = TextMargin + info.ascent;
  586.     lmargin = TextMargin;
  587.  
  588.     /* compute the x and y increments */
  589.     xinc = info.widMax;
  590.     yinc = info.ascent + info.descent + info.leading;
  591.  
  592.     /* compute the character dimensions of the screen */
  593.     pRect = &cwindow->portRect;
  594.     scrh = (pRect->bottom - (2 * TextMargin) - (SBarWidth - 1)) / yinc;
  595.     if (scrh > SCRH) scrh = SCRH;
  596.     scrw = (pRect->right - (2 * TextMargin) - (SBarWidth - 1)) / xinc;
  597.     if (scrw > SCRW) scrw = SCRW;
  598.     
  599.     /* clear the screen */
  600.     scrclear();
  601. }
  602.  
  603. CursorUpdate()
  604. {
  605.     if (cursorstate != -1)
  606.     if (cursortime < TickCount()) {
  607.         scrposition(x,y);
  608.         if (cursorstate) {
  609.         DrawChar(' ');
  610.         cursortime = TickCount() + TIMEOFF;
  611.         cursorstate = 0;
  612.         }
  613.         else {
  614.         DrawChar('_');
  615.         cursortime = TickCount() + TIMEON;
  616.         cursorstate = 1;
  617.         }
  618.     }
  619. }
  620.  
  621. CursorOn()
  622. {
  623.     cursortime = TickCount();
  624.     cursorstate = 0;
  625. }
  626.  
  627. CursorOff()
  628. {
  629.     if (cursorstate == 1) {
  630.     scrposition(x,y);
  631.     DrawChar(' ');
  632.     }
  633.     cursorstate = -1;
  634. }
  635.  
  636. RedrawScreen()
  637. {
  638.     char *Line; int y;
  639.     Line = topline;
  640.     for (y = 0; y < scrh; y++) {
  641.     scrposition(0,y);
  642.     DrawText(Line,0,scrw);
  643.     nextline(&Line);
  644.     }
  645. }
  646.  
  647. nextline(pline)
  648.   char **pline;
  649. {
  650.     if ((*pline += SCRW) >= &screen[SCRH*SCRW])
  651.     *pline = screen;
  652. }
  653.  
  654. scrollup()
  655. {
  656.     RgnHandle updateRgn;
  657.     Rect rect;
  658.     int x;
  659.     updateRgn = NewRgn();
  660.     rect = cwindow->portRect;
  661.     rect.bottom -= SBarWidth - 1;
  662.     rect.right -= SBarWidth - 1;
  663.     ScrollRect(&rect,0,-yinc,updateRgn);
  664.     DisposeRgn(updateRgn);
  665.     for (x = 0; x < SCRW; x++)
  666.     topline[x] = ' ';
  667.     nextline(&topline);
  668. }
  669.