aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaroly Lorentey2004-01-02 02:54:17 +0000
committerKaroly Lorentey2004-01-02 02:54:17 +0000
commit7b00d185eba8e01f191a69740e3270c88f88159c (patch)
tree1bddf818e98404035261883f3cbfc5e4c80f40bf
parentdaf0170133e658c41f3ae2fc8558c5ab74227c1d (diff)
downloademacs-7b00d185eba8e01f191a69740e3270c88f88159c.tar.gz
emacs-7b00d185eba8e01f191a69740e3270c88f88159c.zip
MULTI_KBOARD support for ttys. Input-related bugfixes for X+tty sessions.
lib-src/emacsclient.c (pty_conversation): Fix errno check for read from fileno(in). src/config.in: Unconditionally define MULTI_KBOARD. src/frame.c (make_terminal_frame): Initialize f->kboard. src/keyboard.c (cmd_error_internal): Don't kill Emacs if a Quit was pressed on the tty of a X+tty session. (read_avail_input): Initialize nread to zero. Abort if there is no tty after a termcap read. (interrupt_signal)[USG]: Always reset signal handler. (init_keyboard): Always set signal handler for SIGINT/SIGQUIT if noninteractive. src/term.c (term_dummy_init): Initialize kboard to the initial_kboard. (term_init): Free component structures of the initial tty. Clear xmalloced structures. Moved rif initialization to syms_of_term. (term_init)[MULTI_KBOARD]: Initialize tty->kboard. (delete_tty)[MULTI_KBOARD]: Delete the keyboard. (syms_of_term): Initialize tty_display_method_template. src/termchar.h (tty_output)[MULTI_KBOARD]: Added kboard member. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-31
-rw-r--r--README.multi-tty223
-rw-r--r--lib-src/emacsclient.c2
-rw-r--r--src/.gdbinit2
-rw-r--r--src/config.in6
-rw-r--r--src/frame.c4
-rw-r--r--src/frame.h6
-rw-r--r--src/keyboard.c23
-rw-r--r--src/keyboard.h4
-rw-r--r--src/term.c56
-rw-r--r--src/termchar.h5
10 files changed, 212 insertions, 119 deletions
diff --git a/README.multi-tty b/README.multi-tty
index 96397405ca5..535ed4b3f7f 100644
--- a/README.multi-tty
+++ b/README.multi-tty
@@ -6,6 +6,22 @@ The ultimate goal of this branch is to implement support for opening
6multiple, different tty devices and simultaneous X and tty frames from 6multiple, different tty devices and simultaneous X and tty frames from
7a single Emacs session. 7a single Emacs session.
8 8
9Some use cases:
10
11Emacs is notoriously slow at startup, so most people use another
12editor or emacsclient for quick editing jobs from the console.
13Unfortunately, emacsclient was very awkward to use, because it did not
14support opening a new Emacs frame on the current virtual console.
15Now, with multi-tty support, it can do that. (Emacsclient starts up
16faster than vi!)
17
18Some Gnus users (including me) run Gnus in an X frame in its own Emacs
19instance, which they typically leave running for weeks. It would be
20nice if they could connect to this instance from a remote ssh session
21and check their messages without opening a remote X frame or resorting
22to gnus-slave.
23
24
9WHO IS DOING IT 25WHO IS DOING IT
10--------------- 26---------------
11 27
@@ -18,46 +34,66 @@ Retrieving the latest version of the branch:
18 tla register-archive lorentey@elte.hu--2004 http://lorentey.web.elte.hu/arch/2004/ 34 tla register-archive lorentey@elte.hu--2004 http://lorentey.web.elte.hu/arch/2004/
19 tla get lorentey@elte.hu--2004/emacs--multi-tty <directory> 35 tla get lorentey@elte.hu--2004/emacs--multi-tty <directory>
20 36
21(I use tla 1.1.) 37(I use a recent arch development snapshot, but any of the released
38versions of arch will do fine, I think.)
39
40If you don't have arch, the branch has a homepage from which you can
41download conventional patches against Emacs CVS HEAD:
22 42
43 http://lorentey.web.elte.hu/project/emacs.html
23 44
24STATUS 45STATUS
25------ 46------
26 47
27Basic multi-tty support is there; there are some rough edges, but it 48Multi-tty support is stable, I think most of the problems were fixed.
28already seems to be usable. Emacsclient has been extended to support 49(It still needs testing on other architectures, though.) Please let
29opening a new terminal frame. 50me know if you find any bugs in it. Emacsclient has been extended to
51support opening a new terminal frame.
30 52
31To try it out, compile the multi-tty branch with the following 53To try it out, compile and run the multi-tty branch with the following
32commands: 54commands:
33 55
34 mkdir +build 56 mkdir +build
35 cd +build 57 cd +build
36 ../configure 58 ../configure
37 make bootstrap 59 make bootstrap
60 src/emacs -nw
61 M-x server-start
38 62
39then start up the emacs server (src/emacs -nw, M-x server-start), and 63and then (from a shell prompt on another terminal) start emacsclient
40then (from a shell prompt on another terminal) start emacsclient with 64with
41 65
42 lib-src/emacsclient -f /optional/file/names... 66 lib-src/emacsclient -t /optional/file/names...
43 67
44You'll hopefully have two fully working, independent frames on 68You'll hopefully have two fully working, independent frames on
45separate terminals. (This seems to be very useful, emacsclient starts 69separate terminals. The new frame is closed automatically when you
46up even faster than vi!) :-) You can close the newly opened frame and 70have finished editing the specified files (C-x #), but delete-frame
47return to the shell without exiting Emacs by pressing C-x 5 0, i.e., 71(C-x 5 0) also works. Of course, you can create frames on more than
48delete-frame. Creating new frames on the same tty with C-x 5 2 72two tty devices.
49works exactly as before. Suspending Emacs is disabled at the moment.
50If you exit emacs, all terminals should be restored to their previous
51states.
52 73
53X support is (I hope) working, but at the moment there are problems 74Creating new frames on the same tty with C-x 5 2 works, and they
54with simultaneous X and tty devices, so don't do that. 75behave the same way as in previous Emacs versions. If you exit emacs,
76all terminals should be restored to their previous states.
55 77
56Mac, Windows and DOS support is broken, probably doesn't even 78This is work in progress, and probably full of bugs. You should
57compile -- this will be solved later. 79always run emacs from gdb, so that you'll have a live instance to
80debug if something goes wrong. Please send me your reports.
58 81
59Only tested on my GNU/Linux box. 82Problems:
60 83
84 * Suspending Emacs is disabled if there are multiple tty
85 devices. Also, there is no way to suspend emacsclient. This
86 will be fixed.
87
88 * X support is (I hope) working, but at the moment there are
89 problems with simultaneous X and tty devices, so don't do
90 that - start a separate Emacs with -nw and run the server
91 there.
92
93 * Mac, Windows and DOS support is broken, probably doesn't
94 even compile -- this will be solved later.
95
96 * Only tested on my GNU/Linux box.
61 97
62NEWS 98NEWS
63---- 99----
@@ -88,6 +124,78 @@ CHANGELOG
88 124
89See arch logs. 125See arch logs.
90 126
127THINGS TO DO
128------------
129
130** Fix rif issue with X-tty combo sessions. IMHO the best thing to do
131 is to get rid of that global variable (and use the value value in
132 display_method, which is guaranteed to be correct).
133
134** Fix faces on tty frames during X-tty combo sessions.
135
136** During an X-tty combo session, a (message "Hello") from a tty frame
137 goes to the X frame. Fix this.
138
139** Find out the best way to support suspending Emacs with multiple
140 ttys. My guess: disable it on the controlling tty, but from other
141 ttys pass it on to emacsclient somehow. (It is (I hope) trivial to
142 extend emacsclient to handle suspend/resume. A `kill -STOP' almost
143 works right now.)
144
145** Move baud_rate to tty_output.
146
147** Do tty output through term_hooks, like graphical display backends.
148
149** Implement support for starting an interactive Emacs session without
150 an initial frame. (The user would connect to it and open frames
151 later, with emacsclient.) Not necessarily a good idea.
152
153** Fix input from raw ttys (again).
154
155** Fix Mac support (I can't do this myself).
156
157** Fix W32 support (I can't do this myself).
158
159** Fix DOS support (I can't do this myself).
160
161** Do a grep on XXX and ?? for more issues.
162
163** Understand Emacs's low-level input system (it seems complicated) :-)
164
165** What does interrupt_input do? I tried to disable it for raw
166 secondary tty support, but it does not seem to do anything useful.
167 (Update: Look again. X unconditionally enables this, maybe that's
168 why raw terminal support is broken again. I really do need to
169 understand input.)
170
171** Make sure C-g goes to the right frame. This is hard, as SIGINT
172 doesn't have a tty parameter. :-(
173
174** I have seen a case when Emacs with multiple ttys fell into a loop
175 eating 100% of CPU time. Strace showed this loop:
176
177 getpid() = 30284
178 kill(30284, SIGIO) = 0
179 --- SIGIO (I/O possible) @ 0 (0) ---
180 ioctl(6, FIONREAD, [0]) = -1 EIO (Input/output error)
181 ioctl(5, FIONREAD, [0]) = -1 EIO (Input/output error)
182 ioctl(0, FIONREAD, [0]) = 0
183 sigreturn() = ? (mask now [])
184 gettimeofday({1072842297, 747760}, NULL) = 0
185 gettimeofday({1072842297, 747806}, NULL) = 0
186 select(9, [0 3 5 6], NULL, NULL, {0, 0}) = 2 (in [5 6], left {0, 0})
187 select(9, [0 3 5 6], NULL, NULL, {0, 0}) = 2 (in [5 6], left {0, 0})
188 gettimeofday({1072842297, 748245}, NULL) = 0
189
190 I have not been able to reproduce this.
191
192** Define a output_initial value for output_method for the initial
193 frame that is dumped with Emacs. Checking for this frame (e.g. in
194 cmd_error_internal) is ugly.
195
196** emacsclient -t from an Emacs term buffer does not work, complains
197 about face problems. This can even lock up Emacs (if the recursive
198 frame sets single_kboard).
91 199
92DIARY OF CHANGES 200DIARY OF CHANGES
93---------------- 201----------------
@@ -222,7 +330,7 @@ DIARY OF CHANGES
222 330
223 (Done, nothing to do. It seems that Emacs does not receive SIGHUP 331 (Done, nothing to do. It seems that Emacs does not receive SIGHUP
224 from secondary ttys, which is actually a good thing.) (Update: I 332 from secondary ttys, which is actually a good thing.) (Update: I
225 think it would be a bad idea to remove server-frames anyway.) 333 think it would be a bad idea to remove server-frames.)
226 334
227-- Change emacsclient/server.el to support the -t argument better, 335-- Change emacsclient/server.el to support the -t argument better,
228 i.e. automatically close the socket when the frame is closed. 336 i.e. automatically close the socket when the frame is closed.
@@ -316,75 +424,10 @@ DIARY OF CHANGES
316 the point of being unusable. The rif variable causes constant 424 the point of being unusable. The rif variable causes constant
317 core dumps. Handling input is indeed tricky.) 425 core dumps. Handling input is indeed tricky.)
318 426
319THINGS TO DO 427-- Rewrite multi-tty input in terms of MULTI_KBOARD.
320------------
321
322** Fix rif issue with X-tty combo sessions. IMHO the best thing to do
323 is to get rid of that global variable (and use the value value in
324 display_method, which is guaranteed to be correct).
325
326** Fix faces on tty frames during X-tty combo sessions.
327
328** Find out the best way to support suspending Emacs with multiple
329 ttys. My guess: disable it on the controlling tty, but from other
330 ttys pass it on to emacsclient somehow. (It is (I hope) trivial to
331 extend emacsclient to handle suspend/resume. A `kill -STOP' almost
332 works right now.)
333
334** Move baud_rate to tty_output.
335
336** Do tty output through term_hooks, like graphical display backends.
337
338** Implement support for starting an interactive Emacs session without
339 an initial frame. (The user would connect to it and open frames
340 later, with emacsclient.) Not necessarily a good idea.
341
342** Fix input from raw ttys (again).
343
344** Fix Mac support (I can't do this myself).
345
346** Fix W32 support (I can't do this myself).
347 428
348** Fix DOS support (I can't do this myself). 429 (Done. In fact, there was no need to rewrite anything, I just
349 430 added a kboard member to tty_display_info, and initialized the
350** Do a grep on XXX and ?? for more issues. 431 frame's kboard from there.)
351
352** Understand Emacs's low-level input system (it seems complicated)
353 :-) and maybe rewrite multi-tty input in terms of MULTI_KBOARD.
354 (Update: This backtrace from a tty-X combo session hints that this
355 may be necessary.)
356
357 #0 abort () at /home/lorentey/work/emacs/emacs--multi-tty/src/emacs.c:417
358 #1 0x081104fb in read_char (commandflag=0, nmaps=0, maps=0x0, prev_event=675499188, used_mouse_menu=0x0) at /home/lorentey/work/emacs/emacs--multi-tty/src/keyboard.c:2581
359 #2 0x0819f23e in read_filtered_event (no_switch_frame=1, ascii_required=0, error_nonascii=0, input_method=0) at /home/lorentey/work/emacs/emacs--multi-tty/src/lread.c:468
360 #3 0x0819387c in Fy_or_n_p (prompt=1759896324) at /home/lorentey/work/emacs/emacs--multi-tty/src/fns.c:3115
361 ...
362
363** What does interrupt_input do? I tried to disable it for raw
364 secondary tty support, but it does not seem to do anything useful.
365 (Update: Look again. X unconditionally enables this, maybe that's
366 why raw terminal support is broken again. I really do need to
367 understand input.)
368
369** Make sure C-g goes to the right frame. This is hard, as SIGINT
370 doesn't have a tty parameter. :-(
371
372** I have seen a case when Emacs with multiple ttys fell into a loop
373 eating 100% of CPU time. Strace showed this loop:
374
375 getpid() = 30284
376 kill(30284, SIGIO) = 0
377 --- SIGIO (I/O possible) @ 0 (0) ---
378 ioctl(6, FIONREAD, [0]) = -1 EIO (Input/output error)
379 ioctl(5, FIONREAD, [0]) = -1 EIO (Input/output error)
380 ioctl(0, FIONREAD, [0]) = 0
381 sigreturn() = ? (mask now [])
382 gettimeofday({1072842297, 747760}, NULL) = 0
383 gettimeofday({1072842297, 747806}, NULL) = 0
384 select(9, [0 3 5 6], NULL, NULL, {0, 0}) = 2 (in [5 6], left {0, 0})
385 select(9, [0 3 5 6], NULL, NULL, {0, 0}) = 2 (in [5 6], left {0, 0})
386 gettimeofday({1072842297, 748245}, NULL) = 0
387
388 I have not been able to reproduce this.
389 432
390;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d 433;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c
index 4d0a4462578..6f75bbd04fd 100644
--- a/lib-src/emacsclient.c
+++ b/lib-src/emacsclient.c
@@ -794,7 +794,7 @@ pty_conversation (FILE *in)
794 { 794 {
795 do { 795 do {
796 res = read (fileno (in), string, BUFSIZ-1); 796 res = read (fileno (in), string, BUFSIZ-1);
797 } while (res == EINTR); 797 } while (res < 0 && errno == EINTR);
798 if (res < 0) 798 if (res < 0)
799 { 799 {
800 reset_tty (); 800 reset_tty ();
diff --git a/src/.gdbinit b/src/.gdbinit
index ccc36694da8..145f4f4df87 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -383,7 +383,7 @@ set print sevenbit-strings
383 383
384show environment DISPLAY 384show environment DISPLAY
385show environment TERM 385show environment TERM
386set args -geometry 80x40+0+0 386#set args -geometry 80x40+0+0
387 387
388# Don't let abort actually run, as it will make 388# Don't let abort actually run, as it will make
389# stdio stop working and therefore the `pr' command above as well. 389# stdio stop working and therefore the `pr' command above as well.
diff --git a/src/config.in b/src/config.in
index 0fb4b3f3444..4fe82cd8f2d 100644
--- a/src/config.in
+++ b/src/config.in
@@ -863,6 +863,12 @@ Boston, MA 02111-1307, USA. */
863#define HAVE_MOUSE 863#define HAVE_MOUSE
864#endif 864#endif
865 865
866/* Multi-tty support relies on MULTI_KBOARD. It seems safe to turn it
867 on unconditionally. */
868#ifndef MULTI_KBOARD
869#define MULTI_KBOARD
870#endif
871
866/* Define USER_FULL_NAME to return a string 872/* Define USER_FULL_NAME to return a string
867 that is the user's full name. 873 that is the user's full name.
868 It can assume that the variable `pw' 874 It can assume that the variable `pw'
diff --git a/src/frame.c b/src/frame.c
index 0b407181a6b..d1c0a220afb 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -488,6 +488,7 @@ make_terminal_frame (tty_name, tty_type)
488 char name[20]; 488 char name[20];
489 489
490#ifdef MULTI_KBOARD 490#ifdef MULTI_KBOARD
491 /* Create the initial keyboard. */
491 if (!initial_kboard) 492 if (!initial_kboard)
492 { 493 {
493 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); 494 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
@@ -567,6 +568,9 @@ make_terminal_frame (tty_name, tty_type)
567 } 568 }
568 FRAME_TTY (f)->reference_count++; 569 FRAME_TTY (f)->reference_count++;
569 f->display_method = FRAME_TTY (f)->display_method; 570 f->display_method = FRAME_TTY (f)->display_method;
571#ifdef MULTI_KBOARD
572 f->kboard = FRAME_TTY (f)->kboard;
573#endif
570 } 574 }
571 575
572#ifdef CANNOT_DUMP 576#ifdef CANNOT_DUMP
diff --git a/src/frame.h b/src/frame.h
index 4a67744edaa..4bd52204886 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -292,8 +292,10 @@ struct frame
292 292
293#ifdef MULTI_KBOARD 293#ifdef MULTI_KBOARD
294 /* A pointer to the kboard structure associated with this frame. 294 /* A pointer to the kboard structure associated with this frame.
295 For termcap frames, this points to initial_kboard. For X frames, 295 For termcap frames, it will be the same as
296 it will be the same as display.x->display_info->kboard. */ 296 output_data.tty->display_info->kboard.
297 For X frames, it will be the same as
298 output_data.x->display_info->kboard. */
297 struct kboard *kboard; 299 struct kboard *kboard;
298#endif 300#endif
299 301
diff --git a/src/keyboard.c b/src/keyboard.c
index 532257e797f..d849b9ce4d6 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1205,7 +1205,8 @@ cmd_error_internal (data, context)
1205 running under a window system. */ 1205 running under a window system. */
1206 || (!NILP (Vwindow_system) 1206 || (!NILP (Vwindow_system)
1207 && !inhibit_window_system 1207 && !inhibit_window_system
1208 && FRAME_TERMCAP_P (sf)) 1208 && FRAME_TERMCAP_P (sf)
1209 && !FRAME_TTY (sf)->type) /* XXX This is ugly. */
1209 || noninteractive) 1210 || noninteractive)
1210 { 1211 {
1211 stream = Qexternal_debugging_output; 1212 stream = Qexternal_debugging_output;
@@ -6594,7 +6595,7 @@ read_avail_input (expected)
6594{ 6595{
6595 struct input_event buf[KBD_BUFFER_SIZE]; 6596 struct input_event buf[KBD_BUFFER_SIZE];
6596 register int i; 6597 register int i;
6597 int nread; 6598 int nread = 0;
6598 6599
6599 for (i = 0; i < KBD_BUFFER_SIZE; i++) 6600 for (i = 0; i < KBD_BUFFER_SIZE; i++)
6600 EVENT_INIT (buf[i]); 6601 EVENT_INIT (buf[i]);
@@ -6738,10 +6739,13 @@ read_avail_input (expected)
6738#endif /* not MSDOS */ 6739#endif /* not MSDOS */
6739#endif /* not WINDOWSNT */ 6740#endif /* not WINDOWSNT */
6740 6741
6742 if (!tty)
6743 abort ();
6744
6741 /* Select frame corresponding to the active tty. Note that the 6745 /* Select frame corresponding to the active tty. Note that the
6742 value of selected_frame is not reliable here, redisplay tends 6746 value of selected_frame is not reliable here, redisplay tends
6743 to temporarily change it. But tty should always be non-NULL. */ 6747 to temporarily change it. But tty should always be non-NULL. */
6744 frame = (tty ? tty->top_frame : selected_frame); 6748 frame = tty->top_frame;
6745 6749
6746 for (i = 0; i < nread; i++) 6750 for (i = 0; i < nread; i++)
6747 { 6751 {
@@ -10245,13 +10249,10 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
10245 struct frame *sf = SELECTED_FRAME (); 10249 struct frame *sf = SELECTED_FRAME ();
10246 10250
10247#if defined (USG) && !defined (POSIX_SIGNALS) 10251#if defined (USG) && !defined (POSIX_SIGNALS)
10248 if (!read_socket_hook && NILP (Vwindow_system)) 10252 /* USG systems forget handlers when they are used;
10249 { 10253 must reestablish each time */
10250 /* USG systems forget handlers when they are used; 10254 signal (SIGINT, interrupt_signal);
10251 must reestablish each time */ 10255 signal (SIGQUIT, interrupt_signal);
10252 signal (SIGINT, interrupt_signal);
10253 signal (SIGQUIT, interrupt_signal);
10254 }
10255#endif /* USG */ 10256#endif /* USG */
10256 10257
10257 cancel_echoing (); 10258 cancel_echoing ();
@@ -10626,7 +10627,7 @@ init_keyboard ()
10626 wipe_kboard (current_kboard); 10627 wipe_kboard (current_kboard);
10627 init_kboard (current_kboard); 10628 init_kboard (current_kboard);
10628 10629
10629 if (!noninteractive && !read_socket_hook && NILP (Vwindow_system)) 10630 if (!noninteractive)
10630 { 10631 {
10631 signal (SIGINT, interrupt_signal); 10632 signal (SIGINT, interrupt_signal);
10632#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) 10633#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
diff --git a/src/keyboard.h b/src/keyboard.h
index 6a8e08d41f3..6c6e0344771 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -21,7 +21,7 @@ Boston, MA 02111-1307, USA. */
21/* Length of echobuf field in each KBOARD. */ 21/* Length of echobuf field in each KBOARD. */
22 22
23/* Each KBOARD represents one logical input stream from which Emacs gets input. 23/* Each KBOARD represents one logical input stream from which Emacs gets input.
24 If we are using an ordinary terminal, it has one KBOARD object. 24 If we are using ordinary terminals, it has one KBOARD object for each terminal device.
25 Usually each X display screen has its own KBOARD, 25 Usually each X display screen has its own KBOARD,
26 but when two of them are on the same X server, 26 but when two of them are on the same X server,
27 we assume they share a keyboard and give them one KBOARD in common. 27 we assume they share a keyboard and give them one KBOARD in common.
@@ -152,7 +152,7 @@ struct kboard
152 }; 152 };
153 153
154#ifdef MULTI_KBOARD 154#ifdef MULTI_KBOARD
155/* Temporarily used before a frame has been opened, and for termcap frames */ 155/* Temporarily used before a frame has been opened. */
156extern KBOARD *initial_kboard; 156extern KBOARD *initial_kboard;
157 157
158/* In the single-kboard state, this is the kboard 158/* In the single-kboard state, this is the kboard
diff --git a/src/term.c b/src/term.c
index c8310b5b85b..b35a20a2ff0 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2189,6 +2189,7 @@ term_dummy_init (void)
2189 tty_list->output = stdout; 2189 tty_list->output = stdout;
2190 tty_list->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); 2190 tty_list->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
2191 tty_list->display_method = (struct display_method *) xmalloc (sizeof (struct display_method)); 2191 tty_list->display_method = (struct display_method *) xmalloc (sizeof (struct display_method));
2192 tty_list->kboard = initial_kboard;
2192 return tty_list; 2193 return tty_list;
2193} 2194}
2194 2195
@@ -2212,6 +2213,15 @@ term_init (Lisp_Object frame, char *name, char *terminal_type)
2212 the dummy terminal created for the initial frame. */ 2213 the dummy terminal created for the initial frame. */
2213 if (tty->type) 2214 if (tty->type)
2214 return tty; 2215 return tty;
2216
2217 /* Free up temporary structures. */
2218 if (tty->Wcm)
2219 xfree (tty->Wcm);
2220 if (tty->display_method)
2221 xfree (tty->display_method);
2222 if (tty->kboard != initial_kboard)
2223 abort ();
2224 tty->kboard = 0;
2215 } 2225 }
2216 else 2226 else
2217 { 2227 {
@@ -2221,20 +2231,18 @@ term_init (Lisp_Object frame, char *name, char *terminal_type)
2221 tty_list = tty; 2231 tty_list = tty;
2222 } 2232 }
2223 2233
2224 if (! tty->Wcm) 2234 tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
2225 tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); 2235 Wcm_clear (tty);
2226 2236
2227 if (! tty->display_method) 2237 /* Each termcap frame has its own display method. */
2228 tty->display_method = (struct display_method *) xmalloc (sizeof (struct display_method)); 2238 tty->display_method = (struct display_method *) xmalloc (sizeof (struct display_method));
2239 bzero (tty->display_method, sizeof (struct display_method));
2229 2240
2230 /* Initialize the common members in the new display method with our 2241 /* Initialize the common members in the new display method with our
2231 predefined template. */ 2242 predefined template. */
2232 *tty->display_method = tty_display_method_template; 2243 *tty->display_method = tty_display_method_template;
2233 f->display_method = tty->display_method; 2244 f->display_method = tty->display_method;
2234 2245
2235 /* Termcap-based displays don't support window-based redisplay. */
2236 f->display_method->rif = 0;
2237
2238 /* Make sure the frame is live; if an error happens, it must be 2246 /* Make sure the frame is live; if an error happens, it must be
2239 deleted. */ 2247 deleted. */
2240 f->output_method = output_termcap; 2248 f->output_method = output_termcap;
@@ -2278,7 +2286,7 @@ term_init (Lisp_Object frame, char *name, char *terminal_type)
2278 FrameCols (tty) = FRAME_COLS (f); 2286 FrameCols (tty) = FRAME_COLS (f);
2279 tty->specified_window = FRAME_LINES (f); 2287 tty->specified_window = FRAME_LINES (f);
2280 2288
2281 f->display_method->delete_in_insert_mode = 1; 2289 tty->display_method->delete_in_insert_mode = 1;
2282 2290
2283 UseTabs (tty) = 0; 2291 UseTabs (tty) = 0;
2284 FRAME_SCROLL_REGION_OK (f) = 0; 2292 FRAME_SCROLL_REGION_OK (f) = 0;
@@ -2509,7 +2517,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2509 } 2517 }
2510 2518
2511#if 0 /* This is not used anywhere. */ 2519#if 0 /* This is not used anywhere. */
2512 f->display_method->min_padding_speed = tgetnum ("pb"); 2520 tty->display_method->min_padding_speed = tgetnum ("pb");
2513#endif 2521#endif
2514 2522
2515 TabWidth (tty) = tgetnum ("tw"); 2523 TabWidth (tty) = tgetnum ("tw");
@@ -2723,6 +2731,19 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2723 FRAME_CHAR_INS_DEL_OK (f) = 0; 2731 FRAME_CHAR_INS_DEL_OK (f) = 0;
2724#endif 2732#endif
2725 2733
2734#ifdef MULTI_KBOARD
2735 tty->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
2736 init_kboard (tty->kboard);
2737 tty->kboard->next_kboard = all_kboards;
2738 all_kboards = tty->kboard;
2739 /* Don't let the initial kboard remain current longer than necessary.
2740 That would cause problems if a file loaded on startup tries to
2741 prompt in the mini-buffer. */
2742 if (current_kboard == initial_kboard)
2743 current_kboard = tty->kboard;
2744 tty->kboard->reference_count++;
2745#endif
2746
2726 /* Don't do this. I think termcap may still need the buffer. */ 2747 /* Don't do this. I think termcap may still need the buffer. */
2727 /* xfree (buffer); */ 2748 /* xfree (buffer); */
2728 2749
@@ -2735,7 +2756,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2735 tty_set_terminal_modes (tty); 2756 tty_set_terminal_modes (tty);
2736 2757
2737 return tty; 2758 return tty;
2738#endif /* WINDOWSNT */ 2759#endif /* not WINDOWSNT */
2739} 2760}
2740 2761
2741/* VARARGS 1 */ 2762/* VARARGS 1 */
@@ -2844,6 +2865,13 @@ delete_tty (struct tty_display_info *tty)
2844 if (tty->display_method) 2865 if (tty->display_method)
2845 xfree (tty->display_method); 2866 xfree (tty->display_method);
2846 2867
2868#ifdef MULTI_KBOARD
2869 if (tty->kboard && --tty->kboard->reference_count > 0)
2870 abort ();
2871 if (tty->kboard)
2872 delete_kboard (tty->kboard);
2873#endif
2874
2847 bzero (tty, sizeof (struct tty_display_info)); 2875 bzero (tty, sizeof (struct tty_display_info));
2848 xfree (tty); 2876 xfree (tty);
2849 deleting_tty = 0; 2877 deleting_tty = 0;
@@ -2897,9 +2925,13 @@ The function should accept no arguments. */);
2897 defsubr (&Sframe_tty_type); 2925 defsubr (&Sframe_tty_type);
2898 defsubr (&Sdelete_tty); 2926 defsubr (&Sdelete_tty);
2899 2927
2900 /* XXX tty_display_method_template initialization will go here. */
2901
2902 Fprovide (intern ("multi-tty"), Qnil); 2928 Fprovide (intern ("multi-tty"), Qnil);
2929
2930 /* Initialize the display method template. */
2931
2932 /* Termcap-based displays don't support window-based redisplay. */
2933 tty_display_method_template.rif = 0;
2934
2903} 2935}
2904 2936
2905 2937
diff --git a/src/termchar.h b/src/termchar.h
index c54c1dde061..5b9082917fb 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -182,6 +182,11 @@ struct tty_display_info
182 /* This is a copy of struct frame's display_method value; needed for 182 /* This is a copy of struct frame's display_method value; needed for
183 freeing up memory when deleting the tty. */ 183 freeing up memory when deleting the tty. */
184 struct display_method *display_method; 184 struct display_method *display_method;
185
186#ifdef MULTI_KBOARD
187 /* The terminal's keyboard object. */
188 struct kboard *kboard;
189#endif
185}; 190};
186 191
187/* A chain of structures for all tty devices currently in use. */ 192/* A chain of structures for all tty devices currently in use. */