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.