comparison src/terminal.c @ 84694:95e3b5b2f3ef

(get_terminal): Handle terminals. Make sure the terminal returned is live. (create_terminal): Use allocate_terminal. (mark_terminals): Move to alloc.c. (delete_terminal): Use terminal->name as liveness status. NULL out fields after freeing their contents. Don't deallocate the object. (Fframe_terminal): Use FRAME_TERMINAL. Return the terminal object rather than an int. (Fterminal_live_p): Accept non-integer arguments. (Fterminal_list): Return terminal objects rather than an ints.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Thu, 20 Sep 2007 21:32:07 +0000
parents 082696642669
children efbb243fc83d
comparison
equal deleted inserted replaced
84693:7ee574475f20 84694:95e3b5b2f3ef
203 struct terminal *result = NULL; 203 struct terminal *result = NULL;
204 204
205 if (NILP (terminal)) 205 if (NILP (terminal))
206 terminal = selected_frame; 206 terminal = selected_frame;
207 207
208 if (INTEGERP (terminal)) 208 if (TERMINALP (terminal))
209 { 209 result = XTERMINAL (terminal);
210
211 else if (INTEGERP (terminal))
212 {
213 /* FIXME: Get rid of the use of integers to represent terminals. */
210 struct terminal *t; 214 struct terminal *t;
211 215
212 for (t = terminal_list; t; t = t->next_terminal) 216 for (t = terminal_list; t; t = t->next_terminal)
213 { 217 {
214 if (t->id == XINT (terminal)) 218 if (t->id == XINT (terminal))
215 { 219 {
216 result = t; 220 result = t;
221 eassert (t->name != NULL);
217 break; 222 break;
218 } 223 }
219 } 224 }
220 } 225 }
221 else if (FRAMEP (terminal)) 226 else if (FRAMEP (terminal))
222 { 227 {
223 result = FRAME_TERMINAL (XFRAME (terminal)); 228 result = FRAME_TERMINAL (XFRAME (terminal));
224 } 229 }
225 230
231 if (result && !result->name)
232 result = NULL;
233
226 if (result == NULL && throw) 234 if (result == NULL && throw)
227 wrong_type_argument (Qterminal_live_p, terminal); 235 wrong_type_argument (Qterminal_live_p, terminal);
228 236
229 return result; 237 return result;
230 } 238 }
234 /* Create a new terminal object and add it to the terminal list. */ 242 /* Create a new terminal object and add it to the terminal list. */
235 243
236 struct terminal * 244 struct terminal *
237 create_terminal (void) 245 create_terminal (void)
238 { 246 {
239 struct terminal *terminal = (struct terminal *) xmalloc (sizeof (struct terminal)); 247 struct terminal *terminal = allocate_terminal ();
240 248
241 bzero (terminal, sizeof (struct terminal)); 249 terminal->name = NULL;
242 terminal->next_terminal = terminal_list; 250 terminal->next_terminal = terminal_list;
243 terminal_list = terminal; 251 terminal_list = terminal;
244 252
245 terminal->id = next_terminal_id++; 253 terminal->id = next_terminal_id++;
246 254
254 262
255 terminal->param_alist = Qnil; 263 terminal->param_alist = Qnil;
256 return terminal; 264 return terminal;
257 } 265 }
258 266
259 /* Mark the Lisp pointers in the terminal objects.
260 Called by the Fgarbage_collector. */
261
262 void
263 mark_terminals (void)
264 {
265 struct terminal *t;
266 for (t = terminal_list; t; t = t->next_terminal)
267 {
268 mark_object (t->param_alist);
269 }
270 }
271
272
273 /* Low-level function to close all frames on a terminal, remove it 267 /* Low-level function to close all frames on a terminal, remove it
274 from the terminal list and free its memory. */ 268 from the terminal list and free its memory. */
275 269
276 void 270 void
277 delete_terminal (struct terminal *terminal) 271 delete_terminal (struct terminal *terminal)
279 struct terminal **tp; 273 struct terminal **tp;
280 Lisp_Object tail, frame; 274 Lisp_Object tail, frame;
281 275
282 /* Protect against recursive calls. Fdelete_frame calls the 276 /* Protect against recursive calls. Fdelete_frame calls the
283 delete_terminal_hook when we delete our last frame. */ 277 delete_terminal_hook when we delete our last frame. */
284 if (terminal->deleted) 278 if (!terminal->name)
285 return; 279 return;
286 terminal->deleted = 1; 280 xfree (terminal->name);
281 terminal->name = NULL;
287 282
288 /* Check for live frames that are still on this terminal. */ 283 /* Check for live frames that are still on this terminal. */
289 FOR_EACH_FRAME (tail, frame) 284 FOR_EACH_FRAME (tail, frame)
290 { 285 {
291 struct frame *f = XFRAME (frame); 286 struct frame *f = XFRAME (frame);
298 for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal) 293 for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal)
299 if (! *tp) 294 if (! *tp)
300 abort (); 295 abort ();
301 *tp = terminal->next_terminal; 296 *tp = terminal->next_terminal;
302 297
303 if (terminal->keyboard_coding) 298 xfree (terminal->keyboard_coding);
304 xfree (terminal->keyboard_coding); 299 terminal->keyboard_coding = NULL;
305 if (terminal->terminal_coding) 300 xfree (terminal->terminal_coding);
306 xfree (terminal->terminal_coding); 301 terminal->terminal_coding = NULL;
307 if (terminal->name)
308 xfree (terminal->name);
309 302
310 #ifdef MULTI_KBOARD 303 #ifdef MULTI_KBOARD
311 if (terminal->kboard && --terminal->kboard->reference_count == 0) 304 if (terminal->kboard && --terminal->kboard->reference_count == 0)
312 delete_kboard (terminal->kboard); 305 {
306 delete_kboard (terminal->kboard);
307 terminal->kboard = NULL;
308 }
313 #endif 309 #endif
314
315 bzero (terminal, sizeof (struct terminal));
316 xfree (terminal);
317 } 310 }
318 311
319 DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0, 312 DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
320 doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal. 313 doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal.
321 TERMINAL may be a terminal id, a frame, or nil (meaning the selected 314 TERMINAL may be a terminal id, a frame, or nil (meaning the selected
362 if (NILP (frame)) 355 if (NILP (frame))
363 frame = selected_frame; 356 frame = selected_frame;
364 357
365 CHECK_LIVE_FRAME (frame); 358 CHECK_LIVE_FRAME (frame);
366 359
367 t = get_terminal (frame, 0); 360 t = FRAME_TERMINAL (XFRAME (frame));
368 361
369 if (!t) 362 if (!t)
370 return Qnil; 363 return Qnil;
371 else 364 else
372 return make_number (t->id); 365 {
366 Lisp_Object terminal;
367 XSETTERMINAL (terminal, t);
368 return terminal;
369 }
373 } 370 }
374 371
375 DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0, 372 DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0,
376 doc: /* Return non-nil if OBJECT is a terminal which has not been deleted. 373 doc: /* Return non-nil if OBJECT is a terminal which has not been deleted.
377 Value is nil if OBJECT is not a live display terminal. 374 Value is nil if OBJECT is not a live display terminal.
378 If object is a live display terminal, the return value indicates what 375 If object is a live display terminal, the return value indicates what
379 sort of output terminal it uses. See the documentation of `framep' for 376 sort of output terminal it uses. See the documentation of `framep' for
380 possible return values. 377 possible return values. */)
381
382 Display terminals are represented by their integer identifiers. */)
383 (object) 378 (object)
384 Lisp_Object object; 379 Lisp_Object object;
385 { 380 {
386 struct terminal *t; 381 struct terminal *t;
387 382
388 if (!INTEGERP (object))
389 return Qnil;
390
391 t = get_terminal (object, 0); 383 t = get_terminal (object, 0);
392 384
393 if (!t) 385 if (!t)
394 return Qnil; 386 return Qnil;
395 387
410 abort (); 402 abort ();
411 } 403 }
412 } 404 }
413 405
414 DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0, 406 DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0,
415 doc: /* Return a list of all terminal devices. 407 doc: /* Return a list of all terminal devices. */)
416 Terminal devices are represented by their integer identifiers. */)
417 () 408 ()
418 { 409 {
419 Lisp_Object terminals = Qnil; 410 Lisp_Object terminal, terminals = Qnil;
420 struct terminal *t; 411 struct terminal *t;
421 412
422 for (t = terminal_list; t; t = t->next_terminal) 413 for (t = terminal_list; t; t = t->next_terminal)
423 terminals = Fcons (make_number (t->id), terminals); 414 {
415 XSETTERMINAL (terminal, t);
416 terminals = Fcons (terminal, terminals);
417 }
424 418
425 return terminals; 419 return terminals;
426 } 420 }
427 421
428 DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0, 422 DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0,