home *** CD-ROM | disk | FTP | other *** search
- /* Postscript code for terminal emulator.
-
- For legal stuff see the file COPYRIGHT. */
-
- #import <appkit/Application.h>
- #import <appkit/Pasteboard.h>
- #import <appkit/publicWraps.h>
- #import <libc.h>
- #import <stdlib.h>
-
- #import "EtermView.h"
-
- /* 2.0 doesn't do transparency in windows correctly. */
- #define TRANSPARENCYBUG
-
- #define NORMAL 0
- #define PREFIX 1
- #define SECOND_PREFIX 2
- #define ESCAPE 3
- #define STRING 4
- #define STRING_FUNCTION 5
- #define Ctl(a) ((a) & 0x1f)
-
- struct display
- {
- EtermView *view;
- int cursor_x, cursor_y;
- int state;
- int insert_mode, standout_mode;
- int prefix, second_prefix;
- 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 DPSAddFD () as the value to
- give to input_from_emacs ()
-
- (A "rock" is the CMU term for an item you hide information underneath.) */
- void *
- new_display_rock (EtermView *view)
- {
- 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;
- new_display->prefix = new_display->second_prefix = 0;
- new_display->string_buffer_len = 1024;
- new_display->string_buffer = malloc(1024);
- if (!new_display->string_buffer)
- {
- fprintf (stderr, "Emacs: Virtual memory exhausted\n");
- exit (1);
- }
- new_display->string_char = 0;
-
- return (void *) new_display;
- }
-
- defineps static setup()
- 0 setgray
- emacs:fixedfont setfont
- endps
-
- #ifdef TRANSPARENCYBUG
- #define white_rect(x, y, w, h) clear_rect(x, y, w, h)
-
- defineps static clear_rect(int x, y, w, h)
- 1 setgray
- x y w h rectfill
- 0 setgray
- endps
-
- defineps static grey_rect(int x, y, w, h)
- 0.6666 setgray
- x y w h rectfill
- 0 setgray
- endps
-
- defineps static show_cursor(int x, y, w, h)
- x y w h Highlight compositerect
- endps
-
- #else /* TRANSPARENCYBUG */
-
- defineps static white_rect(int x, y, w, h)
- 1 setgray
- x y w h rectfill
- 0 setgray
- endps
-
- defineps static clear_rect(int x, y, w, h)
- x y w h Clear compositerect
- endps
-
- defineps static grey_rect(int x, y, w, h)
- 0.333 setalpha
- x y w h rectfill
- 1 setalpha
- endps
-
- defineps static show_cursor(int x, y, w, h)
- x y w h Xor compositerect
- endps
-
- #endif /* TRANSPARENCY_BUG */
-
- defineps static copy_rect(int sx, sy, dx, dy, w, h)
- 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
-
- defineps obscure_cursor()
- obscurecursor
- endps
-
- defineps fix_font(int width)
- currentfont dup dup
- dup /FontMatrix get 0 get 1 exch div width mul /newwidth exch def
- length 1 add dict /newfntdict exch def
- { 1 index /FID ne
- {newfntdict 3 1 roll put}
- {pop pop}
- ifelse
- } forall
- /CharStrings get
- dup length dict exch
- { pop 1 index exch newwidth put }
- forall
- newfntdict /Metrics 3 -1 roll put
- /emacs:fixedfont /fixedfont newfntdict definefont def
- endps
-
- defineps set_font()
- /emacs:fixedfont currentfont def
- endps
-
- static void
- invalid ()
- {
- #ifdef DEBUG
- abort();
- #endif
- }
-
- #define POS_X(a) (SIZE_X (a) + BORDER_WIDTH)
- #define POS_Y(a) (SIZE_Y (a) + BORDER_WIDTH)
- #define SIZE_X(a) ((int) ((a) * fontWidth))
- #define SIZE_Y(a) ((int) ((a) * fontHeight))
-
- void
- input_from_emacs (int fd, void *rock)
- {
- struct display *display = (struct display *) rock;
- int screen_x, screen_y;
- 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;
- int insert_mode = display->insert_mode;
- int standout_mode = display->standout_mode;
- int prefix = display->prefix, second_prefix = display->second_prefix;
- int string_buffer_len = display->string_buffer_len;
- int string_char = display->string_char;
- int x;
-
- n = read(fd, buf, sizeof (buf) - 1);
- if (n <= 0) {
- if (errno == EWOULDBLOCK) return;
- [NXApp terminate: nil];
- }
-
- [view emacsOn];
- [view lockFocus];
- [view getDimensions: &screen_y : &screen_x];
- [view getDisplayFont: &fontHeight : &fontWidth : &fontDescender];
-
- 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)
- continue;
- switch (state)
- {
- case NORMAL:
- if (c >= ' ')
- {
- /* So we print deletes. Big deal. */
- int start = x;
- int count;
- int do_newline;
-
- while (++x < n && buf[x] >= ' ');
-
- while (count = x - start)
- {
- if (do_newline = (count + cursor_x >= screen_x))
- count = screen_x - cursor_x;
-
- if (insert_mode)
- {
- copy_rect (POS_X (cursor_x), POS_Y (cursor_y),
- POS_X (cursor_x + count), POS_Y (cursor_y),
- SIZE_X (screen_x - cursor_x - count),
- SIZE_Y (1));
- }
- clear_rect (POS_X (cursor_x), POS_Y (cursor_y),
- SIZE_X (count), SIZE_Y (1));
-
- if (standout_mode)
- grey_rect (POS_X (cursor_x), POS_Y (cursor_y),
- 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;
- cursor_y++;
- }
- else
- cursor_x += count;
- }
- --x;
- break;
- }
- switch (c)
- {
- case Ctl ('a'):
- case Ctl ('m'):
- /* Emacs outputs a '\r' on exiting --jgm */
- cursor_x = 0;
- break;
- case Ctl ('b'):
- if (cursor_x > 0)
- --cursor_x;
- break;
- #if 0
- case Ctl ('c'):
- do_paste (0);
- break;
- case Ctl ('e'):
- if (EventChannel != -1)
- transmitting_events = TRUE;
- break;
- #endif
- case Ctl ('f'):
- if (++cursor_x >= screen_x)
- cursor_x = 0;
- break;
- case Ctl ('g'):
- NXBeep ();
- break;
- #if 0
- case Ctl ('h'):
- if (cursor_x > 0)
- {
- --cursor_x;
- delete_chars (1);
- }
- break;
- #endif
- case Ctl ('i'):
- insert_mode = !insert_mode;
- break;
- case Ctl ('j'):
- cursor_x = 0;
- cursor_y++;
- break;
- case Ctl ('k'):
- /* clear_to_end_of_line (); */
- clear_rect (POS_X (cursor_x), POS_Y (cursor_y),
- SIZE_X (screen_x - cursor_x), SIZE_Y (1));
- break;
- #if 0
- case Ctl ('l'):
- do_redraw ();
- break;
- #endif
- case Ctl ('n'):
- if (cursor_y < screen_y)
- cursor_y++;
- break;
- case Ctl ('p'):
- if (cursor_y > 0)
- --cursor_y;
- break;
- case Ctl ('q'):
- state = STRING;
- string_char = 0;
- break;
- case Ctl ('s'):
- standout_mode = !standout_mode;
- break;
- case Ctl ('u'):
- prefix = 0;
- state = PREFIX;
- break;
- #if 0
- case Ctl ('y'):
- wm_GiveupInputFocus();
- break;
- case Ctl ('z'):
- [NXApp hide:view];
- break;
- #endif
- case Ctl ('['):
- state = ESCAPE;
- break;
- case Ctl ('t'):
- /* Not implemented yet. Besides, no one will ever use it. */
- default:
- invalid ();
- break;
- }
- break;
- case PREFIX:
- switch (c)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- prefix = prefix * 10 + c - '0';
- break;
- case '-':
- prefix = -prefix;
- break;
- #if 0
- case Ctl ('a'):
- transmitting_events = FALSE;
- close (EventChannel);
- EventChannel = -1;
- goto normal_state;
- case Ctl ('c'):
- do_paste (prefix);
- goto normal_state;
- #endif
- case Ctl ('d'):
- if (prefix > 0)
- {
- /* Delete_chars (prefix); */
- 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));
- clear_rect (POS_X (screen_x - prefix), POS_Y (cursor_y),
- SIZE_X (prefix), SIZE_Y (1));
- }
- goto normal_state;
- #if 0
- case Ctl ('e'):
- transmitting_events = FALSE;
- goto normal_state;
- #endif
- case Ctl ('k'):
- if (prefix > 0)
- {
- /* 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));
- clear_rect (POS_X (0), POS_Y (screen_y - prefix),
- SIZE_X (screen_x), SIZE_Y (prefix));
- }
- goto normal_state;
- case Ctl ('o'):
- if (prefix > 0)
- {
- /* 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));
- clear_rect (POS_X (0), POS_Y (cursor_y),
- SIZE_X (screen_x), SIZE_Y (prefix));
- }
- goto normal_state;
- case Ctl ('q'):
- state = STRING;
- string_char = 0;
- break;
- case Ctl ('u'):
- second_prefix = 0;
- state = SECOND_PREFIX;
- break;
- case '_':
- /* Insert_spaces (prefix); */
- if (prefix > 0)
- {
- 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));
- clear_rect (POS_X (cursor_x), POS_Y (cursor_y),
- SIZE_X (prefix), SIZE_Y (1));
- }
- goto normal_state;
- case '.':
- cursor_x = prefix < screen_x ? prefix : 0;
- goto normal_state;
- default:
- invalid ();
- normal_state:
- state = NORMAL;
- break;
- }
- break;
- case SECOND_PREFIX:
- switch (c)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- second_prefix = second_prefix * 10 + c - '0';
- break;
- case '.':
- cursor_x = second_prefix < screen_x ? second_prefix : 0;
- cursor_y = prefix < screen_y ? prefix : 0;
- state = NORMAL;
- break;
- default:
- invalid ();
- state = NORMAL;
- break;
- }
- break;
- case ESCAPE:
- switch (c)
- {
- case 'c':
- /* clear_screen (); */
- white_rect (0, 0, SIZE_X (screen_x) + 2 * BORDER_WIDTH,
- SIZE_Y(screen_y) + 2 * BORDER_WIDTH);
- #ifndef TRANSPARENCYBUG
- clear_rect (POS_X (0), POS_Y (0),
- SIZE_X (screen_x), SIZE_Y (screen_y));
- #endif
- cursor_x = cursor_y = 0;
- insert_mode = standout_mode = 0;
- break;
- case 'k':
- /* Clear_to_end_of_screen (); */
- clear_rect (POS_X (0), POS_Y (cursor_y),
- SIZE_X (screen_x), SIZE_Y (screen_y - cursor_y));
- break;
- default:
- invalid ();
- break;
- }
- state = NORMAL;
- break;
- case STRING:
- if (string_char == string_buffer_len)
- {
- string_buffer_len += 1024;
- display->string_buffer = realloc(display->string_buffer,
- string_buffer_len);
- if (!display->string_buffer)
- {
- fprintf (stderr, "Emacs: Virtual memory exhausted\n");
- exit (1);
- }
- }
- if ((display->string_buffer[string_char++] = c) == '\377')
- state = STRING_FUNCTION;
- break;
- case STRING_FUNCTION:
- {
- display->string_buffer[--string_char] = '\0';
- switch (c)
- {
- case 'c':
- {
- id pBoard = [view pasteboard];
- [pBoard declareTypes:&NXAsciiPboardType num:1
- owner:NULL];
- [pBoard writeType:NXAsciiPboardType
- data:display->string_buffer length:string_char];
- [view pasteboardWritten];
- break;
- }
- #if 0
- case 'e':
- write (MasterChannel, display->string_buffer, string_char);
- break;
- case 'f':
- change_font (display->string_buffer);
- do_redraw ();
- break;
- #endif
- case 't':
- [view setTitle: display->string_buffer];
- break;
- #if 0
- case 'p':
- wm_SetProgramName (display->string_buffer);
- break;
- case 'm':
- wm_AddMenu (display->string_buffer);
- break;
- #endif
- default:
- invalid();
- break;
- }
- state = NORMAL;
- }
- }
- }
-
- /* 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;
- display->insert_mode = insert_mode;
- display->standout_mode = standout_mode;
- display->prefix = prefix;
- display->second_prefix = second_prefix;
- display->string_buffer_len = string_buffer_len;
- display->string_char = string_char;
- }
-