This is EtermApp.m in view mode; [Download] [Up]
/*
* Copyright 1990, John G. Myers
*
* This program 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 1, or (at your option)
* any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#import "EtermApp.h"
/* You'll find this variable in Emacs_main.m.
* Yeah, it's ugly, but it would be less so if the Emacs front end
* used Interface Builder more to begin with. We'll get there someday.
* Anyway, who am I to criticize?
*/
extern id servicesMenu;
@implementation EtermApp
- setEtermView:(id)anObject;
{
etermView = anObject;
}
- etermView
{
return etermView;
}
/*
* We're ready to start. Size the window apropriately and fire up the
* emacs process, possibly editing a file.
*/
- appDidInit:(id)sender
{
NXRect frameRect;
int x, y;
int rows, columns;
DPSSetDeadKeysEnabled(DPSGetCurrentContext(),NO);
rows = atoi(NXGetDefaultValue("Emacs", "Rows"));
columns = atoi(NXGetDefaultValue("Emacs", "Columns"));
[etermView sizeWindowTo: columns: rows];
[[etermView window] getFrame : &frameRect];
x = atoi(NXGetDefaultValue("Emacs", "WinLocX"));
y = screenSize.height -
frameRect.size.height -
atoi(NXGetDefaultValue("Emacs", "WinLocY"));
if (x + frameRect.size.width > screenSize.width)
x = screenSize.width - frameRect.size.width;
if (y < 0) y = 0;
if (x < 0) x = 0;
if (y > screenSize.height - frameRect.size.height)
y = screenSize.height - frameRect.size.height;
[[etermView window] moveTo: (NXCoord)x: (NXCoord)y];
[self registerForServicesMenu];
[self setServicesMenu:servicesMenu]; /* a global from main! sheesh! */
[etermView startEmacs: fileToEdit];
if (!strcmp(NXGetDefaultValue("Emacs", "NXAutoLaunch"), "YES") &&
!strcmp(NXGetDefaultValue("Emacs", "HideOnAutoLaunch"), "YES")) {
[self hide: nil];
}
return self;
}
/*
* Intercept the Quit command and replace it with C-x C-c.
*/
-terminate:(id)sender
{
if (sender && [etermView quitEmacs]) return self;
return [super terminate:sender];
}
/*
* Stash the name of a file in an instance variable so we
* can give it to the child emacs when we fire it up.
*
* TODO: Later versions may want to send an "(event-open "foo")"
* message if the child emacs is already started. So far, I
* haven't found out how to get Emacs to get open requests for
* text files, yet get Edit to eat RTF files. Also, it's not clear
* whether all (or most) users of Emacs will want it to replace
* Edit that way.
*
* We should probably also handle multiple appOpenFile:type: messages
* before the appDidInit: message.
*/
- (int)appOpenFile:(const char *)path type:(const char *)type
{
if (fileToEdit) return NO;
fileToEdit = malloc(strlen(path)+1);
strcpy(fileToEdit, path);
return YES;
}
/*
* Services menu support (adapted from Draw).
*
* Hacked by Geoffrey S. Knauth, Marble Associates.
* Thanks to Denise Biscoe for pointing out that Emacs
* did not support Services.
*/
- registerForServicesMenu
{
static BOOL registered = NO;
const char *validSendTypes[2];
if (!registered) {
registered = YES;
validSendTypes[0] = NXAsciiPboardType;
validSendTypes[1] = NULL;
[NXApp registerServicesMenuSendTypes:validSendTypes
andReturnTypes:NULL];
}
return self;
}
- validRequestorForSendType:(NXAtom) sendType andReturnType:(NXAtom)returnType
{
return (sendType == NXAsciiPboardType && (!returnType || !*returnType)) ?
self : nil;
}
- (BOOL) writeSelectionToPasteboard:pboard types:(NXAtom *)types
{
static char *nilsel = "nil_Selection__Do_Cmd_Copy";
int nilsellen = strlen(nilsel);
char *data;
int length;
id otherpb = [etermView pasteboard];
while (types && *types)
if (*types == NXAsciiPboardType) break; else types++;
if (types && *types)
{
if (otherpb &&
[otherpb readType:NXAsciiPboardType data:&data length:&length])
{
[pboard declareTypes:&NXAsciiPboardType num:1 owner:self];
[pboard writeType:NXAsciiPboardType data:data length:length];
vm_deallocate(task_self(), (vm_address_t)data, (vm_size_t)length);
}
else
{
/* You may ask, "Why on Earth do you want to send out
* that crazy nil selection string?" The reason is that an
* empty pasteboard will cause an error panel to appear
* that only says there was an error performing the Service.
* The message is not very helpful. I'm trying to provide
* the user with usable feedback. The way the NeXT front end
* to Emacs is implemented, there is no selection active when
* you mark a region, or when you do a M-w. Only the NeXT
* Copy command seems to save the region in the pasteboard
* belonging to the etermView. If I figure out another way
* to make the user's life easier, I will.
*/
[pboard declareTypes:&NXAsciiPboardType num:1 owner:self];
[pboard writeType:NXAsciiPboardType data:nilsel length:nilsellen];
}
return YES;
}
return NO;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.