*** Emacs/Emacs_main.m	Fri Nov 22 01:22:53 1991
--- Emacs_main.m	Fri Nov 29 18:33:35 1991
***************
*** 64,70 ****
      [submenu sizeToFit];
  
      /* A rather minimal main menu as well */
!     menu = [Menu newTitle:"Emacs"];
      [[menu addItem:"Info..."
  		action:@selector(showInfo:)
  		keyEquivalent:'\0']
--- 64,70 ----
      [submenu sizeToFit];
  
      /* A rather minimal main menu as well */
!     menu = [Menu newTitle:"NEmacs"];
      [[menu addItem:"Info..."
  		action:@selector(showInfo:)
  		keyEquivalent:'\0']
***************
*** 75,83 ****
      [menu addItem:"Hide"
  		action:@selector(hide:)
   		keyEquivalent:'h'];
!     [menu addItem:"Quit"
  		action:@selector(terminate:)
!  		keyEquivalent:'q'];
      [menu sizeToFit];
      [NXApp setMainMenu:menu];
  
--- 75,84 ----
      [menu addItem:"Hide"
  		action:@selector(hide:)
   		keyEquivalent:'h'];
!     [[menu addItem:"Quit"
  		action:@selector(terminate:)
!  		keyEquivalent:'q']
!                         setTarget:NXApp];
      [menu sizeToFit];
      [NXApp setMainMenu:menu];
  
*** Emacs/EtermApp.h	Fri Nov 22 01:22:54 1991
--- EtermApp.h	Fri Nov 29 18:43:27 1991
***************
*** 19,32 ****
  #import <appkit/appkit.h>
  #import <appkit/Application.h>
  #import "EtermView.h"
  
  @interface EtermApp : Application
  {
      EtermView *etermView;	/* "The" Emacs window */
!     char *fileToEdit;		/* File to edit when we fire up emacs */
  }
  
  - setEtermView:(id)anObject;
  - appDidInit:(id)sender;
  - (int)appOpenFile:(const char *)path type:(const char *)type;
  @end
--- 19,34 ----
  #import <appkit/appkit.h>
  #import <appkit/Application.h>
  #import "EtermView.h"
+ #import "Queue.h"
  
  @interface EtermApp : Application
  {
      EtermView *etermView;	/* "The" Emacs window */
!     Queue* fileQueue;
  }
  
  - setEtermView:(id)anObject;
+ - (Queue *)fileQueue;
  - appDidInit:(id)sender;
  - (int)appOpenFile:(const char *)path type:(const char *)type;
  @end
*** Emacs/EtermApp.m	Fri Nov 22 01:22:52 1991
--- EtermApp.m	Fri Dec  6 17:42:38 1991
***************
*** 17,25 ****
--- 17,33 ----
   */
  
  #import "EtermApp.h"
+ #import "String.h"
  
  @implementation EtermApp
  
+ + new
+ {
+   self = [super new];
+   fileQueue = [Queue new];
+   return self;
+ }
+ 
  - setEtermView:(id)anObject
  {
      etermView = anObject;
***************
*** 26,31 ****
--- 34,44 ----
      return self;
  }
  
+ - (Queue *)fileQueue
+ {
+   return fileQueue;
+ }
+ 
  /*
   * We're ready to start.  Size the window apropriately and fire up the
   * emacs process, possibly editing a file.
***************
*** 36,45 ****
  	int x, y;
  	int rows, columns;
  
! 	x = atoi(NXGetDefaultValue("Emacs", "WinLocX"));
! 	y = atoi(NXGetDefaultValue("Emacs", "WinLocY"));
! 	rows = atoi(NXGetDefaultValue("Emacs", "Rows"));
! 	columns = atoi(NXGetDefaultValue("Emacs", "Columns"));
  	[[etermView window] moveTo: (NXCoord)x: (NXCoord)y];
  	[etermView sizeWindowTo: columns: rows];
  	[[etermView window] getFrame : &frameRect];
--- 49,58 ----
  	int x, y;
  	int rows, columns;
  
! 	x = atoi(NXGetDefaultValue("NEmacs", "WinLocX"));
! 	y = atoi(NXGetDefaultValue("NEmacs", "WinLocY"));
! 	rows = atoi(NXGetDefaultValue("NEmacs", "Rows"));
! 	columns = atoi(NXGetDefaultValue("NEmacs", "Columns"));
  	[[etermView window] moveTo: (NXCoord)x: (NXCoord)y];
  	[etermView sizeWindowTo: columns: rows];
  	[[etermView window] getFrame : &frameRect];
***************
*** 48,54 ****
  		frameRect.origin.y = screenSize.height - frameRect.size.height;
  		[[etermView window] placeWindow: &frameRect];
  	}
! 	[etermView startEmacs: fileToEdit];
  /*	[[etermView window] display];	*/
  	return self;
  }
--- 61,67 ----
  		frameRect.origin.y = screenSize.height - frameRect.size.height;
  		[[etermView window] placeWindow: &frameRect];
  	}
! 	[etermView startEmacs];
  /*	[[etermView window] display];	*/
  	return self;
  }
***************
*** 70,80 ****
   */
  - (int)appOpenFile:(const char *)path type:(const char *)type
  {
!     if (fileToEdit) return NO;
  
!     fileToEdit = malloc(strlen(path)+1);
!     strcpy(fileToEdit, path);
!     return YES;
  }
  
  @end
--- 83,117 ----
   */
  - (int)appOpenFile:(const char *)path type:(const char *)type
  {
!   FILE* eventChannel;
  
!   if(eventChannel = [etermView eventChannel]) {
!       fprintf(eventChannel, "(find-file \"%s\")\n",path);
!       fflush(eventChannel);
!   }
!   else
!       [fileQueue put:[String new:path]];
!   return YES;
! }
! 
! - (BOOL)appAcceptsAnotherFile:sender
! {
!   return YES;
! }
! 
! - terminate:sender
! /*
!  * Overridden to be sure all documents get an opportunity to be saved
!  * before exiting the program.
!  */
! {
!   FILE* eventChannel;
! 
!   if(eventChannel = [etermView eventChannel]) {
!       fprintf(eventChannel, "(save-buffers-kill-emacs)\n");
!       fflush(eventChannel);
!   }
!   return self;
  }
  
  @end
*** Emacs/EtermView.h	Fri Nov 22 01:22:53 1991
--- EtermView.h	Fri Mar 13 00:02:55 1992
***************
*** 31,46 ****
      int masterChannel;		/* FD of /dev/pty device */
      int eventServerSocket;	/* FD listening for event connection */
      FILE *eventChannel;		/* file ptr of event socket */
  }
  
  + initialize;
  + new;
  - (FILE *)eventChannel;
  - setEventChannel: (FILE *)fp;
  - windowWillResize: sender toSize: (NXSize *)frameSize;
  - windowDidResize: sender;
  - sizeWindowTo: (int)newCols : (int)newLines;
! - startEmacs: (char *)withFile;
  - (BOOL)acceptsFirstResponder;
  - keyDown: (NXEvent *)theEvent;
  - mouseDown: (NXEvent *)theEvent;
--- 31,68 ----
      int masterChannel;		/* FD of /dev/pty device */
      int eventServerSocket;	/* FD listening for event connection */
      FILE *eventChannel;		/* file ptr of event socket */
+     id inputManager;            /* Client Input Manager object */
+     int imUpdate;
+     int caretpos;
+     struct {int x,y;} prevcaretpos;
+     unsigned short textbuf[512];
+     int attrbuf[512];
+     int textbuflen;
+     int maxtextbuflen;
+     char* inputstr;
+     int inputx,inputy,inputlen;
  }
  
  + initialize;
  + new;
+ - (int)respondsToIM:sender;
+ - (BOOL)imCanDisplay;
+ - imSetCommunicating:(BOOL)flag;
+ - imShowCaret:(int)pos;
+ - imHideCaret;
+ - imSetAttribute:(int)attribute from:(int)start to:(int)end;
+ - imResetAttribute:(int)attribute from:(int)start to:(int)end;
+ - imReplaceString:(const char *)aString from:(int)start to:(int)end with:(int)attribute color:(NXColor)color;
+ - imInputString:(const char *)aString;
+ - imFlush;
+ - showcaret;
+ - hidecaret;
  - (FILE *)eventChannel;
  - setEventChannel: (FILE *)fp;
  - windowWillResize: sender toSize: (NXSize *)frameSize;
  - windowDidResize: sender;
  - sizeWindowTo: (int)newCols : (int)newLines;
! - startEmacs;
  - (BOOL)acceptsFirstResponder;
  - keyDown: (NXEvent *)theEvent;
  - mouseDown: (NXEvent *)theEvent;
***************
*** 58,60 ****
--- 80,85 ----
  	(float *) widthPtr :
  	(int *) descenderPtr;
  @end
+ 
+ 
+ 
*** Emacs/EtermView.m	Fri Nov 22 01:22:53 1991
--- EtermView.m	Fri Mar 13 00:09:58 1992
***************
*** 26,34 ****
--- 26,38 ----
  #import <appkit/Text.h>
  #import <appkit/Application.h>
  #import <appkit/Pasteboard.h>
+ #import <appkit/ClientInputManager.h>
  #import <dpsclient/dpsclient.h>
  #import "EtermView.h"
  #import "etermSupport.h"
+ #import "display.h"
+ #import "String.h"
+ #import "Queue.h"
  
  extern char **environ;
  
***************
*** 38,46 ****
  #define MAXHEIGHT 300		/* gnu-emacs. */
  
  extern void *new_display_rock(EtermView *theView);
  extern void input_from_emacs(int fd, void *theDisplay);
  extern void kc_init(void);
- extern void obscure_cursor(void);
  extern int kc_keyforcode(int code, int flags);
  
  /*
--- 42,55 ----
  #define MAXHEIGHT 300		/* gnu-emacs. */
  
  extern void *new_display_rock(EtermView *theView);
+ void showcursor( void );
+ void hidecursor( void );
+ void redraw_tstring( int cx, int cy, int len );
  extern void input_from_emacs(int fd, void *theDisplay);
+ extern int cur_x( void );
+ extern int cur_y( void );
+ 
  extern void kc_init(void);
  extern int kc_keyforcode(int code, int flags);
  
  /*
***************
*** 65,70 ****
--- 74,81 ----
  {
      EtermView *view = (EtermView *)rock;
      int newfd = accept_server_connection(fd);
+     String* fname;
+     FILE* eventChannel;
  
      if (newfd == -1) return;
  
***************
*** 74,79 ****
--- 85,94 ----
      else {
  	[view setEventChannel: fdopen(newfd, "w")];
      }
+     eventChannel = [view eventChannel];
+     while( (fname = [[NXApp fileQueue] get]) != nil )
+       fprintf(eventChannel, "(find-file \"%s\")\n",[fname string]);
+     fflush(eventChannel);
  }
  
  @implementation EtermView
***************
*** 81,88 ****
  + initialize
  {
      static NXDefaultsVector etermDefaults = {
! 	{"NXFixedPitchFont", "Ohlfs"},
! 	{"NXFixedPitchFontSize", "10" },
  	{"Columns", "80" },
  	{"Rows", "24" },
  	{"WinLocX", "205"},
--- 96,103 ----
  + initialize
  {
      static NXDefaultsVector etermDefaults = {
! 	{"NXFixedPitchFont", "FixedGothicBBBCourier"},
! 	{"NXFixedPitchFontSize", "18.0" },
  	{"Columns", "80" },
  	{"Rows", "24" },
  	{"WinLocX", "205"},
***************
*** 90,96 ****
  	{NULL}
      };
  
!     NXRegisterDefaults("Emacs", etermDefaults);
      kc_init();
      
      return self;
--- 105,111 ----
  	{NULL}
      };
  
!     NXRegisterDefaults("NEmacs", etermDefaults);
      kc_init();
      
      return self;
***************
*** 108,132 ****
      [self setAutosizing:NX_WIDTHSIZABLE|NX_HEIGHTSIZABLE];
      [self notifyAncestorWhenFrameChanged:YES];
  
!     fontname = NXGetDefaultValue("Emacs", "NXFixedPitchFont");
!     fontsize = atoi(NXGetDefaultValue("Emacs", "NXFixedPitchFontSize"));
  
      /* TODO - Check non-zero, etc. */
  
      displayFont = [Font newFont: fontname size:(float)fontsize];
      
      NXTextFontInfo( displayFont , &ascender, &descender, &lineHeight);
  
      leading = -0.2 * lineHeight;
!     fontHeight = (int) ffontHeight = (lineHeight + leading);
!     fontWidth = (int) ffontWidth =  ([displayFont getWidthOf : "  "] -
! 				     [displayFont getWidthOf : " "]);
  
!     fontDescender = (int) (descender + leading);
  
      return self;
  }
  
  - (FILE *)eventChannel;
  {
      return eventChannel;
--- 123,371 ----
      [self setAutosizing:NX_WIDTHSIZABLE|NX_HEIGHTSIZABLE];
      [self notifyAncestorWhenFrameChanged:YES];
  
!     fontname = NXGetDefaultValue("NEmacs", "NXFixedPitchFont");
!     fontsize = atoi(NXGetDefaultValue("NEmacs", "NXFixedPitchFontSize"));
  
+     fontsize = 18;
      /* TODO - Check non-zero, etc. */
  
      displayFont = [Font newFont: fontname size:(float)fontsize];
+     [displayFont set];
      
      NXTextFontInfo( displayFont , &ascender, &descender, &lineHeight);
  
      leading = -0.2 * lineHeight;
!     ffontHeight = lineHeight /* + leading */ ;
!     ffontWidth =  ([displayFont getWidthOf : "  "] -
! 		     [displayFont getWidthOf : " "]);
!     fontHeight = ffontHeight + 0.5;
!     fontWidth = ffontWidth + 0.5;
!     fontDescender = (int) (descender /* + leading */);
  
!     inputManager = [NXApp inputManager];
!     textbuflen = maxtextbuflen = 0;
!     inputstr = NULL;
!     caretpos = -1;
!     prevcaretpos.x = -1;
!     imUpdate = 0;
!     return self;
! }
  
+ /*
+  * Client Input Manager Delegate
+  */
+ 
+ - (int)respondsToIM:sender
+ {
+   return IM_INLINEINPUT;
+ }
+ 
+ - (BOOL)imCanDisplay
+ {
+   return IM_INLINEINPUT;
+ }
+ 
+ - imSetCommunicating:(BOOL)flag
+ {
+   [self lockFocus];
+   [displayFont set];
+   if(flag == YES)
+     hidecursor();
+   else {
+     textbuflen = maxtextbuflen = 0;
+     showcursor();
+   }
+   [self unlockFocus];
+   return self;
+ }
+ 
+ static int convpos(unsigned short* textbuf,int pos)
+ {
+   int i,j;
+ 
+   for(i = j = 0 ; i < pos ; ++i,++j)
+     if(textbuf[i]&0xff00)
+       ++j;
+   return j;
+ }
+ 
+ - hidecaret
+ {
+   if(prevcaretpos.x != -1) {
+     [self lockFocus];
+     clear_rect(prevcaretpos.x,prevcaretpos.y,1,(int)ffontHeight - 1);
+     [self unlockFocus];
+   }
+   prevcaretpos.x = -1;
+   return self;
+ }
+ 
+ - showcaret
+ {
+   if(caretpos != -1) {
+     int x = (int)(cur_x()*ffontWidth) + BORDER_WIDTH;
+     int y = (int)(cur_y()*ffontHeight) + BORDER_WIDTH;
+ 
+     [self hidecaret];
+     prevcaretpos.x = x + (int)(convpos(textbuf,caretpos)*ffontWidth);
+     prevcaretpos.y = y + 1;
+     [self lockFocus];
+     line(prevcaretpos.x,prevcaretpos.y,0,(int)ffontHeight - 2);
+     [self unlockFocus];
+   }
+   return self;
+ }
+ 
+ - imShowCaret:(int)pos
+ {
+   caretpos = pos;
+   [self showcaret];
+   return self;
+ }
+ 
+ - imHideCaret
+ {
+   caretpos = -1;
+   [self hidecaret];
+   return self;
+ }
+ 
+ - imSetAttribute:(int)attribute
+ from:(int)start
+ to:(int)end
+ {
+   int i;
+ 
+   for( i = start ; i < end ; ++i )
+       attrbuf[i] |= attribute;
+   imUpdate = 1;
+   return self;
+ }
+ 
+ - imResetAttribute:(int)attribute
+ from:(int)start
+ to:(int)end
+ {
+   int i;
+ 
+   for( i = start ; i < end ; ++i )
+     attrbuf[i] &= ~attribute;
+   imUpdate = 1;
+   return self;
+ }
+ 
+ - imReplaceString:(const char *)aString
+ from:(int)start
+ to:(int)end
+ with:(int)attribute
+ color:(NXColor)color
+ {
+   register int i,j;
+   unsigned char* str = (unsigned char *)aString;
+   unsigned short buf[512];
+   int abuf[512];
+   
+   printf("imReplaceString:%s\n",aString);
+   for(i = end ; textbuf[i] ; ++i) {
+     buf[i - end] = textbuf[i];
+     abuf[i - end] = attrbuf[i];
+   }
+   buf[i - end] = 0;
+   for(i = start, j = 0 ; str[j] ; ++i,++j) {
+     if(str[j]&0x80) {
+       textbuf[i] = ((unsigned short)str[j] << 8) + str[j+1];
+       ++j;
+     }
+     else
+       textbuf[i] = str[j];
+     attrbuf[i] = attribute;
+   }
+   for(j = i; buf[j - i] ; ++j) {
+     textbuf[j] = buf[j - i];
+     attrbuf[j] = abuf[j - i];
+   }
+   textbuf[j] = 0;
+   textbuflen = j;
+   imUpdate = 1;
+   return self;
+ }
+ 
+ - imInputString:(const char *)aString
+ {
+     inputstr = malloc(strlen(aString)+1);
+     inputx = cur_x();
+     inputy = cur_y();
+     inputlen = maxtextbuflen;
+     strcpy(inputstr,aString);
+     textbuflen = 0;
+     maxtextbuflen = 0;
+     imUpdate = 1;
      return self;
  }
  
+ - imFlush
+ {
+     if(imUpdate) {
+ 	int x = (int)(cur_x()*ffontWidth) + BORDER_WIDTH;
+ 	int y = (int)(cur_y()*ffontHeight) + BORDER_WIDTH;
+ 	char buf[1024];
+ 	int i,j;
+ 
+ 	for( i = j = 0 ; i < textbuflen ; ++i )
+ 	    if(textbuf[i]&0xff00) {
+ 		buf[j++] = textbuf[i] >> 8;
+ 		buf[j++] = textbuf[i]&0xff;
+ 	    }
+ 	    else
+ 		buf[j++] = textbuf[i];
+ 	if(maxtextbuflen < j)
+ 	    maxtextbuflen = j;
+ 	[self lockFocus];
+ 	[displayFont set];
+ 	[self hidecaret];
+ 	clear_rect(x,y,(int)(maxtextbuflen*ffontWidth),(int)ffontHeight);
+ 	if(caretpos != -1)
+ 	    [self showcaret];
+ 	for( i = j = 0 ; i < textbuflen ; ++i ) {
+ 	    if(textbuf[i]&0xff00) {
+ 		if(attrbuf[i]&IM_UNDERLINE)
+ 		    line(x+(int)(j*ffontWidth),y+(int)ffontHeight - 1,(int)(2*ffontWidth) - 1,0);
+ 		if(attrbuf[i]&IM_HIGHLIGHT)
+ 		    highlight_rect(x+(int)(j*ffontWidth),y,(int)(2*ffontWidth),(int)ffontHeight);
+ 		j += 2;
+ 	    }
+ 	    else if(textbuf[i]) {
+ 		if(attrbuf[i]&IM_UNDERLINE)
+ 		    line(x+(int)(j*ffontWidth),y+(int)ffontHeight - 1,(int)ffontWidth - 1,0);
+ 		if(attrbuf[i]&IM_HIGHLIGHT)
+ 		    highlight_rect(x+(int)(j*ffontWidth),y,(int)(ffontWidth),(int)ffontHeight);
+ 		++j;
+ 	    }
+ 	}
+ 	draw_string(x,y + (int)ffontHeight - (int)fontDescender,buf,j );
+ 	if(j == 0)
+ 	    redraw_tstring(cur_x(), cur_y(), maxtextbuflen);
+ 	[self unlockFocus];
+ 	imUpdate = 0;
+     }
+     if(inputstr) {
+ 	int x = (int)(inputx*ffontWidth) + BORDER_WIDTH;
+ 	int y = (int)(inputy*ffontHeight) + BORDER_WIDTH;
+ 
+ 	[self lockFocus];
+ 	[displayFont set];
+ 	[self hidecaret];
+ 	clear_rect(x, y, (int)(ffontWidth*(inputlen)), (int)ffontHeight);
+ 	redraw_tstring(inputx, inputy, inputlen);
+ 	[self unlockFocus];
+ 	write_safely(masterChannel, inputstr, strlen(inputstr));
+ 	free(inputstr);
+ 	inputstr = NULL;
+ 	imUpdate = 1; /* don't touch this line */
+     }
+     return self;
+ }
+ 	
  - (FILE *)eventChannel;
  {
      return eventChannel;
***************
*** 204,211 ****
   */
  - sizeWindowTo: (int)newCols : (int)newLines
  {
-     NXRect contentRect, frameRect;
- 
      cols = newCols;
      lines = newLines;
      [window sizeWindow: (NXCoord) (int) (newCols * ffontWidth + BORDER_WIDTH*2) :
--- 443,448 ----
***************
*** 216,229 ****
  /*
   * Start up the child emacs process, perhaps on a file
   */
! - startEmacs: (char *)withFile
  {
      int master, slave, ptynumber;
      char **env;
      static char *args[] = {
! 	"emacs",
  	NULL,
! 	NULL
        };
    
      /* Grab a pty/tty pair */
--- 453,467 ----
  /*
   * Start up the child emacs process, perhaps on a file
   */
! - startEmacs
  {
      int master, slave, ptynumber;
      char **env;
+     String* fname;
      static char *args[] = {
! 	"nemacs",
  	NULL,
! 	NULL,
        };
    
      /* Grab a pty/tty pair */
***************
*** 240,249 ****
      /* Make sure the size is set correctly */
      [self windowDidResize: self];
  
!     args[1] = withFile;
  
      /* Fork off the Emacs */
!     fork_shell("/usr/bin/emacs", args, env, slave);
      (void) close(slave);
  
      DPSAddFD(master, input_from_emacs, new_display_rock(self), NX_RUNMODALTHRESHOLD);
--- 478,489 ----
      /* Make sure the size is set correctly */
      [self windowDidResize: self];
  
!     /* Put one file, if exists, to nemacs. The others are sent by eventChannel */
!     if((fname = [[NXApp fileQueue] get]) != nil )
!       args[1] = [fname string];
  
      /* Fork off the Emacs */
!     fork_shell("/usr/local/bin/nemacs", args, env, slave);
      (void) close(slave);
  
      DPSAddFD(master, input_from_emacs, new_display_rock(self), NX_RUNMODALTHRESHOLD);
***************
*** 265,280 ****
      char buf[1024];
      int i = 0;
      int code;
-     int start=0, n;
  
      if (theEvent->flags & NX_ALTERNATEMASK) {
! 	/* Handle ALT key as a META key */
! 	code = kc_keyforcode(theEvent->data.key.keyCode, theEvent->flags);
! 	if (code != -1) {
! 	    buf[i++] = code | 0x80;
! 	}
      }
!     else buf[i++] = theEvent->data.key.charCode;
  
      /* Grab as many keypressed events as we can from a modal event loop */
      while (i < sizeof(buf) &&
--- 505,541 ----
      char buf[1024];
      int i = 0;
      int code;
  
+     if ([inputManager imProcessEvent:theEvent from:self] != nil) {
+       obscure_cursor();
+       return self;
+     }
      if (theEvent->flags & NX_ALTERNATEMASK) {
!       /* Handle ALT key as a META key */
!       code = kc_keyforcode(theEvent->data.key.keyCode,theEvent->flags);
!       if(code != -1) {
! 	buf[i++] = 0x1b;
! 	buf[i++] = code;
!       }
      }
!     else if(theEvent->data.key.keyCode == 0x16) { /* UP ARROW */
! 	fprintf(eventChannel,"(previous-line 1)\n");
! 	fflush(eventChannel);
!     }
!     else if(theEvent->data.key.keyCode == 0x0f) { /* DOWN ARROW */
! 	fprintf(eventChannel,"(next-line 1)\n");
! 	fflush(eventChannel);
!     }
!     else if(theEvent->data.key.keyCode == 0x09) { /* LEFT ARROW */
! 	fprintf(eventChannel,"(backward-char)\n");
! 	fflush(eventChannel);
!     }
!     else if(theEvent->data.key.keyCode == 0x10) { /* RIGHT ARROW */
! 	fprintf(eventChannel,"(forward-char)\n");
! 	fflush(eventChannel);
!     }
!     else
!       buf[i++] = theEvent->data.key.charCode;
  
      /* Grab as many keypressed events as we can from a modal event loop */
      while (i < sizeof(buf) &&
***************
*** 283,296 ****
  	   !(theEvent->flags & NX_COMMANDMASK)) {
  	theEvent = [NXApp getNextEvent:NX_ALLEVENTS];
  	if (theEvent->flags & NX_ALTERNATEMASK) {
! 	    /* Handle ALT key as a META key */
! 	    code = kc_keyforcode(theEvent->data.key.keyCode, theEvent->flags);
! 	    if (code != -1) {
! 		buf[i++] = code | 0x80;
! 	    }
  	}
! 	else buf[i++] = theEvent->data.key.charCode;
!     }
  
      write_safely(masterChannel, buf, i);
      obscure_cursor();
--- 544,575 ----
  	   !(theEvent->flags & NX_COMMANDMASK)) {
  	theEvent = [NXApp getNextEvent:NX_ALLEVENTS];
  	if (theEvent->flags & NX_ALTERNATEMASK) {
! 	  /* Handle ALT key as a META key */
! 	  code = kc_keyforcode(theEvent->data.key.keyCode,theEvent->flags);
! 	  if(code != -1) {
! 	    buf[i++] = 0x1b;
! 	    buf[i++] = code;
! 	  }
  	}
! 	else if(theEvent->data.key.keyCode == 0x16) { /* UP ARROW */
! 	    fprintf(eventChannel,"(previous-line 1)\n");
! 	    fflush(eventChannel);
! 	}
! 	else if(theEvent->data.key.keyCode == 0x0f) { /* DOWN ARROW */
! 	    fprintf(eventChannel,"(next-line 1)\n");
! 	    fflush(eventChannel);
! 	}
! 	else if(theEvent->data.key.keyCode == 0x09) { /* LEFT ARROW */
! 	    fprintf(eventChannel,"(backward-char)\n");
! 	    fflush(eventChannel);
! 	}
! 	else if(theEvent->data.key.keyCode == 0x10) { /* RIGHT ARROW */
! 	    fprintf(eventChannel,"(forward-char)\n");
! 	    fflush(eventChannel);
! 	}
! 	else
! 	  buf[i++] = theEvent->data.key.charCode;
!       }
  
      write_safely(masterChannel, buf, i);
      obscure_cursor();
*** Emacs/keycode.c	Fri Nov 22 01:22:52 1991
--- keycode.c	Fri Nov 22 01:41:26 1991
***************
*** 44,63 ****
      char *mapping;
  
      if ((evs_fd = open("/dev/evs0", O_RDWR, 0)) < 0) {
! 	perror("Emacs: /dev/evs0");
  	return;
      }
      if (ioctl(evs_fd, EVSIOCKML, &map.size) < 0) {
! 	perror("Emacs: ioctl EVSIOCKML");
  	return;
      }
      map.mapping = (char*) malloc(map.size);
      if (ioctl(evs_fd, EVSIOCKM, &map) < 0) {
! 	perror("Emacs: ioctl EVSIOCKM");
  	return;
      }				/* Check mapping format. */
      if (map.mapping[0] || map.mapping[1]) {
! 	fprintf(stderr, "Emacs: unknown keyboard map format.\n");
  	return;
      }
  
--- 44,63 ----
      char *mapping;
  
      if ((evs_fd = open("/dev/evs0", O_RDWR, 0)) < 0) {
! 	perror("NEmacs: /dev/evs0");
  	return;
      }
      if (ioctl(evs_fd, EVSIOCKML, &map.size) < 0) {
! 	perror("NEmacs: ioctl EVSIOCKML");
  	return;
      }
      map.mapping = (char*) malloc(map.size);
      if (ioctl(evs_fd, EVSIOCKM, &map) < 0) {
! 	perror("NEmacs: ioctl EVSIOCKM");
  	return;
      }				/* Check mapping format. */
      if (map.mapping[0] || map.mapping[1]) {
! 	fprintf(stderr, "NEmacs: unknown keyboard map format.\n");
  	return;
      }
  
*** Emacs/display.pswm	Fri Nov 22 01:22:53 1991
--- display.pswm	Tue Mar 10 17:25:11 1992
***************
*** 33,41 ****
  #define STRING_FUNCTION 5
  #define Ctl(a) ((a) & 0x1f)
  
! static id pasteboard;
! 
! struct display {
      EtermView *view;
      int cursor_x, cursor_y;
      int state;
--- 33,39 ----
  #define STRING_FUNCTION 5
  #define Ctl(a) ((a) & 0x1f)
  
! struct display 	{
      EtermView *view;
      int cursor_x, cursor_y;
      int state;
***************
*** 44,51 ****
      char *string_buffer;
      int string_buffer_len;
      int string_char;
! };
  
  /*
   * Create the information necessary for handling a new display.
   * The return value is the "rock" that should be given to
--- 42,53 ----
      char *string_buffer;
      int string_buffer_len;
      int string_char;
!     unsigned char window_buffer[300][300];
! }; 
  
+ static id pasteboard;
+ static struct display* this_display;
+ 
  /*
   * Create the information necessary for handling a new display.
   * The return value is the "rock" that should be given to
***************
*** 58,69 ****
  {
      struct display *new_display;
  
!     new_display = malloc(sizeof(struct display));
      if (!new_display) {
  	fprintf(stderr, "Emacs: Virtual memory exhausted\n");
  	exit(1);
      }
! 
      new_display->view = view;
      new_display->cursor_x = new_display->cursor_y = 0;
      new_display->state = NORMAL;
--- 60,71 ----
  {
      struct display *new_display;
  
!     this_display = new_display = malloc(sizeof(struct display));
      if (!new_display) {
  	fprintf(stderr, "Emacs: Virtual memory exhausted\n");
  	exit(1);
      }
!     bzero(new_display->window_buffer,sizeof(new_display->window_buffer));
      new_display->view = view;
      new_display->cursor_x = new_display->cursor_y = 0;
      new_display->state = NORMAL;
***************
*** 89,95 ****
  0 setgray
  endps
  
! defineps static clear_rect(int x, y, w, h)
  x y w h Clear compositerect
  endps
  
--- 91,97 ----
  0 setgray
  endps
  
! defineps clear_rect(int x, y, w, h)
  x y w h Clear compositerect
  endps
  
***************
*** 99,106 ****
  1 setalpha
  endps
  
  defineps static show_cursor(int x, y, w, h)
! x y w h Xor compositerect
  endps
  
  defineps static copy_rect(int sx, sy, dx, dy, w, h)
--- 101,118 ----
  1 setalpha
  endps
  
+ defineps highlight_rect(int x, y, w, h)
+ x y w h Highlight compositerect
+ endps
+ 
+ defineps line(int x, y, w, h)
+ x y moveto
+ w h rlineto
+ stroke
+ endps
+ 
  defineps static show_cursor(int x, y, w, h)
! x y w h Highlight compositerect
  endps
  
  defineps static copy_rect(int sx, sy, dx, dy, w, h)
***************
*** 107,113 ****
  sx sy w h gstate dx dy Copy composite
  endps
  
! defineps static draw_string(int x, y; char s[n]; int n)
  x y moveto
  (s) show
  endps
--- 119,125 ----
  sx sy w h gstate dx dy Copy composite
  endps
  
! defineps draw_string(int x, y; char s[n]; int n)
  x y moveto
  (s) show
  endps
***************
*** 128,133 ****
--- 140,198 ----
  #define SIZE_X(a) ((int) ((a) * ffontWidth))
  #define SIZE_Y(a) ((int) ((a) * ffontHeight))
  
+ static int cursor_state = 1;
+ 
+ void showcursor( void )
+ {
+     EtermView *view = this_display->view;
+     float ffontHeight, ffontWidth;
+     int fontDescender;
+ 
+     [view getDisplayFont:&ffontHeight :&ffontWidth :&fontDescender];
+     show_cursor(POS_X(this_display->cursor_x), POS_Y(this_display->cursor_y), 
+ 		this_display->window_buffer[this_display->cursor_y][this_display->cursor_x]&0x80 ?
+ 		(int)(ffontWidth*2) : (int)ffontWidth,
+ 		(int)ffontHeight);
+     cursor_state = 1;
+ }
+ 
+ void hidecursor( void )
+ {
+     EtermView *view = this_display->view;
+     float ffontHeight, ffontWidth;
+     int fontDescender;
+ 
+     [view getDisplayFont:&ffontHeight :&ffontWidth :&fontDescender];
+     show_cursor(POS_X(this_display->cursor_x), POS_Y(this_display->cursor_y), 
+ 		this_display->window_buffer[this_display->cursor_y][this_display->cursor_x]&0x80 ?
+ 		(int)(ffontWidth*2) : (int)ffontWidth,
+ 		(int)ffontHeight);
+     cursor_state = 0;
+ }
+ 
+ static int is_kanji1st(char* s, int n)
+ {
+   int flg = 0;
+   int i;
+ 
+   for(i = 0 ; i <= n ; ++i)
+     if(s[i]&0x80)
+       flg = !flg;
+   return flg;
+ }
+ 
+ void redraw_tstring( int cx, int cy, int len )
+ {
+     EtermView *view = this_display->view;
+     float ffontHeight, ffontWidth;
+     int fontDescender;
+ 
+     [view getDisplayFont:&ffontHeight :&ffontWidth :&fontDescender];
+     if(is_kanji1st(this_display->window_buffer[cy],cx+len-1))
+ 	++len;
+     draw_string(POS_X (cx),POS_Y (cy+1) - (int) fontDescender , &this_display->window_buffer[cy][cx], len);
+ }
+ 
  void input_from_emacs(int fd, void *rock)
  {
      struct display *display = (struct display *)rock;
***************
*** 135,143 ****
      float ffontHeight, ffontWidth;
      int fontHeight, fontWidth;
      int fontDescender;
!     char buf[1024+1];
      int n;
!     register char c;
      EtermView *view = display->view;
      int cursor_x = display->cursor_x, cursor_y = display->cursor_y;
      int state = display->state;
--- 200,208 ----
      float ffontHeight, ffontWidth;
      int fontHeight, fontWidth;
      int fontDescender;
!     unsigned char buf[300*300+1];
      int n;
!     register unsigned char c;
      EtermView *view = display->view;
      int cursor_x = display->cursor_x, cursor_y = display->cursor_y;
      int state = display->state;
***************
*** 148,154 ****
      int string_char = display->string_char;
      int x;
  
- 
      n = read(fd, buf, sizeof(buf)-1);
      if (n < 1) {
  	[NXApp terminate:nil];
--- 213,218 ----
***************
*** 164,170 ****
      setup();
  
      /* Remove old cursor */
!     show_cursor(POS_X(cursor_x), POS_Y(cursor_y), fontWidth, fontHeight);
  
      for (x = 0; x < n; x++) {
  	if ((c = buf[x]) == '\0' && state != STRING)
--- 228,238 ----
      setup();
  
      /* Remove old cursor */
!     if(cursor_state)
! 	    show_cursor(POS_X(cursor_x), POS_Y(cursor_y), 
! 		display->window_buffer[cursor_y][cursor_x]&0x80 ?
! 		  fontWidth*2 : fontWidth,
! 		fontHeight);
  
      for (x = 0; x < n; x++) {
  	if ((c = buf[x]) == '\0' && state != STRING)
***************
*** 188,196 ****
--- 256,266 ----
  				  POS_X (cursor_x + count), POS_Y (cursor_y),
  				  SIZE_X (screen_x - cursor_x - count),
  				  SIZE_Y (1));
+ 		    	bcopy(&display->window_buffer[cursor_y][cursor_x],&display->window_buffer[cursor_y][cursor_x+count],screen_x - cursor_x - count);
  		    }
  		    clear_rect(POS_X (cursor_x), POS_Y (cursor_y),
  			       SIZE_X (count), SIZE_Y (1));
+ 		    bzero(&display->window_buffer[cursor_y][cursor_x],count);
  
  		    if (standout_mode)
  		      grey_rect(POS_X (cursor_x), POS_Y (cursor_y),
***************
*** 197,205 ****
  				SIZE_X (count), SIZE_Y (1));
  
  		    draw_string(POS_X (cursor_x),
! 				POS_Y (cursor_y+1) - (int) fontDescender,
  				&buf[start], count);
! 
  		    start += count;
  		    if (do_newline) {
  			cursor_x = 0;
--- 267,275 ----
  				SIZE_X (count), SIZE_Y (1));
  
  		    draw_string(POS_X (cursor_x),
! 				POS_Y (cursor_y+1) - (int) fontDescender ,
  				&buf[start], count);
! 		    bcopy(buf+start,&display->window_buffer[cursor_y][cursor_x],count);
  		    start += count;
  		    if (do_newline) {
  			cursor_x = 0;
***************
*** 256,261 ****
--- 326,332 ----
  	      /* clear_to_end_of_line (); */
  	      clear_rect (POS_X (cursor_x), POS_Y (cursor_y),
  			  SIZE_X (screen_x - cursor_x), SIZE_Y (1));
+ 	      bzero(&display->window_buffer[cursor_y][cursor_x],screen_x - cursor_x);
  	      break;
  #if 0
  	    case Ctl('l'):
***************
*** 326,333 ****
--- 397,406 ----
  		  copy_rect (POS_X (cursor_x + prefix), POS_Y (cursor_y),
  			      POS_X (cursor_x), POS_Y (cursor_y),
  			      SIZE_X (screen_x - cursor_x - 1), SIZE_Y (1));
+ 		  bcopy(&display->window_buffer[cursor_y][cursor_x + prefix],&display->window_buffer[cursor_y][cursor_x],screen_x - cursor_x - 1);
  		  clear_rect (POS_X (screen_x - prefix), POS_Y (cursor_y),
  			      SIZE_X (prefix), SIZE_Y (1));
+ 		  bzero(&display->window_buffer[cursor_y][screen_x-prefix],prefix);
  	      }
  	      goto normal_state;
  #if 0
***************
*** 337,360 ****
--- 410,443 ----
  #endif
  	    case Ctl('k'):
  	      if (prefix > 0) {
+ 		  int y;
  		  /* delete_lines (prefix); */
  		  copy_rect(POS_X (0), POS_Y (cursor_y + prefix),
  			    POS_X (0), POS_Y (cursor_y),
  			    SIZE_X (screen_x),
  			    SIZE_Y (screen_y - cursor_y - prefix));
+ 		  for(y = cursor_y ; y < screen_y - prefix ; ++y)
+ 			bcopy(&display->window_buffer[y+prefix][0],&display->window_buffer[y][0],screen_x);
  		  clear_rect(POS_X (0), POS_Y (screen_y - prefix),
  			     SIZE_X (screen_x), SIZE_Y (prefix));
+ 		  for(y = screen_y - prefix ; y < screen_y ; ++y)
+ 			bzero(&display->window_buffer[y][0],screen_x);
  	      }
  	      goto normal_state;
  	    case Ctl('o'):
  	      if (prefix > 0) {
+ 		int y;
  		  /* insert_lines (prefix); */
  		  copy_rect(POS_X (0), POS_Y (cursor_y),
  			    POS_X (0), POS_Y (cursor_y + prefix),
  			    SIZE_X (screen_x),
  			    SIZE_Y (screen_y - cursor_y - prefix));
+ 		  for(y = screen_y - prefix - 1 ; y >= cursor_y ; --y)
+ 			bcopy(&display->window_buffer[y][0],&display->window_buffer[y+prefix][0],screen_x);
  		  clear_rect(POS_X (0), POS_Y (cursor_y),
  			     SIZE_X (screen_x), SIZE_Y (prefix));
+ 		  for(y = cursor_y ; y < cursor_y + prefix ; ++y)
+ 			bzero(&display->window_buffer[y][0],screen_x);
  	      }
  	      goto normal_state;
  	    case Ctl('q'):
***************
*** 371,378 ****
--- 454,463 ----
  		  copy_rect(POS_X (cursor_x), POS_Y (cursor_y),
  			    POS_X (cursor_x + prefix), POS_Y (cursor_y),
  			    SIZE_X (screen_x - cursor_x - prefix), SIZE_Y (1));
+                   bcopy(&display->window_buffer[cursor_y][cursor_x],&display->window_buffer[cursor_y][cursor_x+prefix],screen_x - cursor_x - prefix);
  		  clear_rect(POS_X (cursor_x), POS_Y (cursor_y),
  			     SIZE_X (prefix), SIZE_Y (1));
+                     bzero(&display->window_buffer[cursor_y][cursor_x],prefix);
  	      }
  	      goto normal_state;
  	    case '.':
***************
*** 411,416 ****
--- 496,506 ----
  			 SIZE_Y(screen_y)+2*BORDER_WIDTH);
  	      clear_rect(POS_X(0), POS_Y(0),
  			 SIZE_X(screen_x), SIZE_Y(screen_y));
+ 	      {
+ 		int y;
+ 	      	for(y = 0 ; y < screen_y ; ++y)
+ 	              bzero(&display->window_buffer[y][0],screen_x);
+ 	      }
  	      cursor_x = cursor_y = 0;
  	      insert_mode = standout_mode = 0;
  	      break;
***************
*** 418,423 ****
--- 508,518 ----
  	      /* clear_to_end_of_screen (); */
  	      clear_rect(POS_X (0), POS_Y (cursor_y),
  			 SIZE_X (screen_x), SIZE_Y (screen_y - cursor_y));
+ 	      {
+ 		int y;
+ 	      	for(y = cursor_y ; y < screen_y ; ++y)
+ 	              bzero(&display->window_buffer[y][0],screen_x);
+ 	      }
  	      break;
  	  default:
  	      invalid ();
***************
*** 479,487 ****
      }
  
      /* Display cursor */
!     show_cursor(POS_X(cursor_x), POS_Y(cursor_y), fontWidth, fontHeight);
  
-     [view unlockFocus];
      display->cursor_x = cursor_x;
      display->cursor_y = cursor_y;
      display->state = state;
--- 574,585 ----
      }
  
      /* Display cursor */
!     if(cursor_state)
! 	show_cursor(POS_X(cursor_x), POS_Y(cursor_y), 
! 		display->window_buffer[cursor_y][cursor_x]&0x80 ?
! 		  fontWidth*2 : fontWidth,
! 		fontHeight);
  
      display->cursor_x = cursor_x;
      display->cursor_y = cursor_y;
      display->state = state;
***************
*** 491,495 ****
--- 589,605 ----
      display->second_prefix = second_prefix;
      display->string_buffer_len = string_buffer_len;
      display->string_char = string_char;
+     [view showcaret];
+     [view imFlush];
+     [view unlockFocus];
  }
  
+ int cur_x( void )
+ {
+     return this_display->cursor_x;
+ }
+ 
+ int cur_y( void )
+ {
+     return this_display->cursor_y;
+ }
