304 lines · 7.9 KB · C
RawDownload
/*    Copyright 2017 Wolfgang Thaller.     This file is part of Retro68.     Retro68 is free software: you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or    (at your option) any later version.     Retro68 is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.     You should have received a copy of the GNU General Public License    along with Retro68.  If not, see <http://www.gnu.org/licenses/>.*/ #include <Quickdraw.h>#include <Windows.h>#include <Menus.h>#include <Fonts.h>#include <Resources.h>#include <TextEdit.h>#include <TextUtils.h>#include <Dialogs.h>#include <Devices.h>     // in wdef.cextern pascal long MyWindowDefProc(short varCode, WindowRef window, short message, long param); static Rect initialWindowRect, nextWindowRect; enum{    kMenuApple = 128,    kMenuFile,    kMenuEdit}; enum{    kItemAbout = 1,     kItemNewDoc = 1,    kItemNewRounded = 2,    kItemNewCustomFromStub = 3,    kItemNewCustomFromRes = 4,    kItemClose = 5,    kItemQuit = 7}; void MakeNewWindow(ConstStr255Param title, short procID){    if(nextWindowRect.bottom > qd.screenBits.bounds.bottom        || nextWindowRect.right > qd.screenBits.bounds.right)    {        nextWindowRect = initialWindowRect;    }     WindowRef w = NewWindow(NULL, &nextWindowRect, title, true, procID, (WindowPtr) -1, true, 0);     OffsetRect(&nextWindowRect, 15, 15);} void InitCustomWDEF(void){/* The 10-byte code resource stub trick. * * The bytes in this resource are 68K machine code for *     move.l L1(pc), -(sp)    | 2F3A 0004 *     rts                     | 4E75 * L1: dc.l 0x00000000         | 0000 0000 * * The application loads this resource and replaces the final four bytes * with the address of MyWindowDefProc. */     Handle h = GetResource('WDEF', 128);    HLock(h);    *(WindowDefUPP*)(*h + 6) = NewWindowDefUPP(&MyWindowDefProc);    // note: for 68K, the above is equivalent to:    //    *(WindowDefProcPtr*)(*h + 6) = &MyWindowDefProc;    // for PPC, it creates a routine descriptor data structure to get out of the emulator again.     // On PPC only, we could also bypass the emulator by putting the routine descriptor into the resource,    // and putting the pointer to the code into it here. This wouldn't work for the 68K version of this code, though.        // By the way, this was the only part of this file relevant for dealing    // with custom WDEFs.} void ShowAboutBox(void){    WindowRef w = GetNewWindow(128, NULL, (WindowPtr) - 1);    MoveWindow(w,        qd.screenBits.bounds.right/2 - w->portRect.right/2,        qd.screenBits.bounds.bottom/2 - w->portRect.bottom/2,        false);    ShowWindow(w);    SetPort(w);     Handle h = GetResource('TEXT', 128);    HLock(h);    Rect r = w->portRect;    InsetRect(&r, 10,10);    TETextBox(*h, GetHandleSize(h), &r, teJustLeft);     ReleaseResource(h);    while(!Button())        ;    while(Button())        ;    FlushEvents(everyEvent, 0);    DisposeWindow(w);} void UpdateMenus(void){    MenuRef m = GetMenu(kMenuFile);    WindowRef w = FrontWindow();    if(w) // Close menu item: enabled if there is a window        EnableItem(m,kItemClose);    else        DisableItem(m,kItemClose);     m = GetMenu(kMenuEdit);    if(w && GetWindowKind(w) < 0)    {          // Desk accessory in front: Enable edit menu items        EnableItem(m,1);        EnableItem(m,3);        EnableItem(m,4);        EnableItem(m,5);        EnableItem(m,6);    }    else    {           // Application window or nothing in front, disable edit menu        DisableItem(m,1);        DisableItem(m,3);        DisableItem(m,4);        DisableItem(m,5);        DisableItem(m,6);    } } void DoMenuCommand(long menuCommand){    Str255 str;    WindowRef w;    short menuID = menuCommand >> 16;    short menuItem = menuCommand & 0xFFFF;    if(menuID == kMenuApple)    {        if(menuItem == kItemAbout)            ShowAboutBox();        else        {            GetMenuItemText(GetMenu(128), menuItem, str);            OpenDeskAcc(str);        }    }    else if(menuID == kMenuFile)    {        switch(menuItem)        {            case kItemNewDoc:                GetIndString(str,128,1);                MakeNewWindow(str, documentProc); // plain document window                break;            case kItemNewRounded:                GetIndString(str,128,2);                MakeNewWindow(str, 16); // rounded document window                break;            case kItemNewCustomFromStub:                GetIndString(str,128,3);                MakeNewWindow(str, 128*16); // custom window, loaded via 10-byte stub                break;            case kItemNewCustomFromRes:                GetIndString(str,128,4);                MakeNewWindow(str, 129*16); // custom window, compiled as resource                break;             case kItemClose:    // close                w = FrontWindow();                if(w)                {                    if(GetWindowKind(w) < 0)                        CloseDeskAcc(GetWindowKind(w));                    else                        DisposeWindow(FrontWindow());                }                break;             case kItemQuit:                ExitToShell();                break;        }    }    else if(menuID == kMenuEdit)    {        if(!SystemEdit(menuItem - 1))        {            // edit command not handled by desk accessory        }    }     HiliteMenu(0);} void DoUpdate(WindowRef w){    SetPort(w);    BeginUpdate(w);     Rect r;    SetRect(&r, 20,20,120,120);    FrameOval(&r);     OffsetRect(&r, 32, 32);    FillRoundRect(&r, 16, 16, &qd.ltGray);    FrameRoundRect(&r, 16, 16);     OffsetRect(&r, 32, 32);    FillRect(&r, &qd.gray);    FrameRect(&r);     MoveTo(100,100);    DrawString("\pHello, world.");     EndUpdate(w);} int main(void){    InitGraf(&qd.thePort);    InitFonts();    InitWindows();    InitMenus();    TEInit();    InitDialogs(NULL);     SetMenuBar(GetNewMBar(128));    AppendResMenu(GetMenu(128), 'DRVR');    DrawMenuBar();     InitCustomWDEF();     InitCursor();     Rect r;    SetRect(&initialWindowRect,20,60,400,260);    nextWindowRect = initialWindowRect;     for(;;)    {        EventRecord e;        WindowRef win;                SystemTask();        if(GetNextEvent(everyEvent, &e))        {            switch(e.what)            {                case keyDown:                    if(e.modifiers & cmdKey)                    {                        UpdateMenus();                        DoMenuCommand(MenuKey(e.message & charCodeMask));                    }                    break;                case mouseDown:                    switch(FindWindow(e.where, &win))                    {                        case inGoAway:                            if(TrackGoAway(win, e.where))                                DisposeWindow(win);                            break;                        case inDrag:                            DragWindow(win, e.where, &qd.screenBits.bounds);                            break;                        case inMenuBar:                            UpdateMenus();                            DoMenuCommand( MenuSelect(e.where) );                            break;                        case inContent:                            SelectWindow(win);                            break;                        case inSysWindow:                            SystemClick(&e, win);                            break;                    }                    break;                case updateEvt:                    DoUpdate((WindowRef)e.message);                    break;            }        }    }    return 0;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t