archie/tk4.2/mac/tkMacMenus.c

338 lines
7.1 KiB
C
Raw Normal View History

2024-05-27 16:40:40 +02:00
/*
* tkMacMenus.c --
*
* These calls set up and manage the menubar for the
* Macintosh version of Tk.
*
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* SCCS: @(#) tkMacMenus.c 1.27 96/09/05 11:21:55
*/
#include "tcl.h"
#include "tclMacInt.h"
#include "tk.h"
#include "tkInt.h"
#include "tkMacInt.h"
/*
* The define Status defined by Xlib.h conflicts with the function Status
* defined by Devices.h. We undefine it here to compile.
*/
#undef Status
#include <Devices.h>
#include <Menus.h>
#include <Memory.h>
#include <SegLoad.h>
#include <StandardFile.h>
#include <ToolUtils.h>
#define kAppleMenu 256
#define kAppleAboutItem 1
#define kFileMenu 2
#define kEditMenu 3
#define kSourceItem 1
#define kCloseItem 2
#define kQuitItem 4
#define EDIT_CUT 1
#define EDIT_COPY 2
#define EDIT_PASTE 3
#define EDIT_CLEAR 4
static Tcl_Interp * gInterp; /* Interpreter for this application. */
static MenuHandle gAppleM; /* Handles to menus */
static MenuHandle gFileM; /* Handles to menus */
static MenuHandle gEditM; /* Handles to menus */
Tk_Window Tk_TopCoordsToWindow _ANSI_ARGS_((Tk_Window tkwin, int rootX,
int rootY, int *newX, int *newY));
static void GenerateEditEvent _ANSI_ARGS_((int flag));
static void SourceDialog _ANSI_ARGS_((void));
/*
*----------------------------------------------------------------------
*
* TkMacHandleMenuSelect --
*
* Handles events that occur in the Menu bar.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
TkMacHandleMenuSelect(mResult, optionKeyPressed)
long mResult;
int optionKeyPressed;
{
short theItem = LoWord(mResult);
short theMenu = HiWord(mResult);
Str255 name;
Tk_Window tkwin;
Window window;
if (mResult == 0) {
return;
}
switch (theMenu) {
case kAppleMenu:
switch (theItem) {
case kAppleAboutItem:
{
Tcl_CmdInfo dummy;
if (optionKeyPressed || gInterp == NULL ||
Tcl_GetCommandInfo(gInterp,
"tkAboutDialog", &dummy) == 0) {
TkAboutDlg();
} else {
Tcl_Eval(gInterp, "tkAboutDialog");
}
break;
}
default:
GetItem(gAppleM, theItem, name);
HiliteMenu(0);
OpenDeskAcc(name);
return;
}
break;
case kFileMenu:
switch (theItem) {
case kSourceItem:
/* TODO: source script */
SourceDialog();
break;
case kCloseItem:
/* Send close event */
window = TkMacGetXWindow(FrontWindow());
tkwin = Tk_IdToWindow(tkDisplayList->display, window);
TkGenWMDestroyEvent(tkwin);
break;
case kQuitItem:
/* Exit */
if (optionKeyPressed || gInterp == NULL) {
Tcl_Exit(0);
} else {
Tcl_Eval(gInterp, "exit");
}
break;
}
break;
case kEditMenu:
/*
* This implementation just send keysyms
* the Tk thinks are associated with function keys that
* do Cut, Copy & Paste on a Sun keyboard.
*/
GenerateEditEvent(theItem);
break;
default:
/*
* This will eventually evoke Tcl scripts
* TODO: come up with frame work for this...
*/
break;
}
/*
* Finally we unhighlight the menu.
*/
HiliteMenu(0);
} /* TkMacHandleMenuSelect */
/*
*----------------------------------------------------------------------
*
* TkMacInitMenus --
*
* This procedure initializes the Macintosh menu bar.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
TkMacInitMenus(interp)
Tcl_Interp *interp;
{
Handle mbarH;
gInterp = interp;
/*
* At this point, InitMenus() should have already been called.
*/
mbarH = (Handle) GetMenuBar();
if (mbarH == NULL) {
panic("memory - menu bar");
}
gAppleM = NewMenu(256, "\p\024");
if (gAppleM == NULL) {
panic("memory - menus");
}
InsertMenu(gAppleM, 0);
AppendMenu(gAppleM, "\pAbout Tcl & Tk<54>");
AppendMenu(gAppleM, "\p(-");
AddResMenu(gAppleM, 'DRVR');
gFileM = NewMenu(kFileMenu, "\pFile");
if (gFileM == NULL) {
panic("memory - menus");
}
InsertMenu(gFileM, 0);
AppendMenu(gFileM, "\pSource<EFBFBD>");
AppendMenu(gFileM, "\pClose/W");
AppendMenu(gFileM, "\p(-");
AppendMenu(gFileM, "\pQuit/Q");
gEditM = NewMenu(kEditMenu, "\pEdit");
if (gEditM == NULL) {
panic("memory - menus");
}
InsertMenu(gEditM, 0);
AppendMenu(gEditM, "\pCut/X");
AppendMenu(gEditM, "\pCopy/C");
AppendMenu(gEditM, "\pPaste/V");
AppendMenu(gEditM, "\pClear");
DrawMenuBar();
DisposeHandle(mbarH);
return;
}
/*
*----------------------------------------------------------------------
*
* GenerateEditEvent --
*
* Takes an edit menu item and posts the corasponding a virtual
* event to Tk's event queue.
*
* Results:
* None.
*
* Side effects:
* May place events of queue.
*
*----------------------------------------------------------------------
*/
static void
GenerateEditEvent(flag)
int flag;
{
XVirtualEvent event;
Point where;
Tk_Window tkwin;
/*
* We send the event to the focus window.
*/
tkwin = (Tk_Window) tkDisplayList->focusWinPtr;
if (tkwin == NULL) {
return;
}
event.type = VirtualEvent;
event.serial = Tk_Display(tkwin)->request;
event.send_event = false;
event.display = Tk_Display(tkwin);
event.event = Tk_WindowId(tkwin);
event.root = XRootWindow(Tk_Display(tkwin), 0);
event.subwindow = None;
event.time = TkMacGenerateTime();
GetMouse(&where);
tkwin = Tk_TopCoordsToWindow(tkwin, where.h, where.v,
&event.x, &event.y);
LocalToGlobal(&where);
event.x_root = where.h;
event.y_root = where.v;
event.state = TkMacButtonKeyState();
event.state = 0;
event.same_screen = true;
switch (flag) {
case EDIT_CUT:
event.name = Tk_GetUid("Cut");
break;
case EDIT_COPY:
event.name = Tk_GetUid("Copy");
break;
case EDIT_PASTE:
event.name = Tk_GetUid("Paste");
break;
case EDIT_CLEAR:
event.name = Tk_GetUid("Clear");
break;
}
Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}
/*
*----------------------------------------------------------------------
*
* SourceDialog --
*
* Presents a dialog to the user for selecting a Tcl file. The
* selected file will be sourced into the main interpreter.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
SourceDialog()
{
StandardFileReply reply;
OSType fileTypes[1];
OSErr err;
int length;
Handle path;
if (gInterp == NULL) {
return;
}
fileTypes[0] = 'TEXT';
StandardGetFile(NULL, 1, fileTypes, &reply);
if (reply.sfGood == false) {
return;
}
err = FSpPathFromLocation(&reply.sfFile, &length, &path);
if (err == noErr) {
HLock(path);
Tcl_EvalFile(gInterp, *path);
HUnlock(path);
DisposeHandle(path);
}
}