diff options
author | Marcus Brinkmann <marcus@gnu.org> | 2002-09-08 21:55:59 +0000 |
---|---|---|
committer | Marcus Brinkmann <marcus@gnu.org> | 2002-09-08 21:55:59 +0000 |
commit | 18cfa8b70ce9a6a3572908115f98211f3fa9a367 (patch) | |
tree | 42fd94dea9b27bb7020154a39a834429e936a560 /utils | |
parent | 187b5b4b28eba6990f7e43a5288a71b62a271dd9 (diff) |
libcons/
2002-09-09 Marcus Brinkmann <marcus@gnu.org>
* vcons-remove.c: New file.
* Makefile (SRCS): Add vcons-destroy.c.
* cons.h: New type vcons_list_t.
(struct vcons_list): New structure.
(struct cons_notify): Remove VCONS member.
(struct vcons): Remove members NEXT, PREV and NOTIFY. Add the
notify structure to the top to make it possible to use a vcons as
a port. New member VCONS_ENTRY.
(struct cons): Change type of members vcons_list and vcons_last to
vcons_list_t. Remove member active.
(cons_vcons_add): Change prototype to match new definition.
(cons_vcons_remove): Likewise.
(cons_switch): Likewise.
(cons_lookup): Likewise.
(cons_vcons_open): Likewise.
(cons_vcons_destroy): New prototype.
* cons-lookup.c (cons_lookup): Change type of R_VCONS argument
vcons_list_t. Change type of previous_vcons and vcons variables
to vcons_list_t. Append _entry to all these variables.
Don't allocate and initialize a vcons_t, but a vcons_list_t.
After this has been added to the list, call cons_vcons_add.
* cons-switch.c: Do not include <error.h>
(cons_switch): Add arguments ACTIVE_ID and R_VCONS. New variable
ERR and VCONS_ENTRY. Remove variable ACTIVE. Do not keep track
of active console. Instead, look it up using ACTIVE_ID. Lock the
returned console. Call cons_vcons_open, not cons_vcons_activate.
* dir-changed.c (add_one): Change VCONS to VCONS_ENTRY and its
type from vcons_t to vcons_list_t to follow cons_lookup change.
(lookup_one): Likewise.
(cons_S_dir_changed): Likewise.
* file-changed.c (cons_S_file_changed): Cast NOTIFY to VCONS.
Check that NOTIFY->cons is not set instead that NOTIFY->vcons is.
* init-init.c (cons_init): Pass cons_vcons_destroy as
clean_routine to ports_create_class.
Don't initialize CONS->active, nor DIR_NOTIFY_PORT->vcons.
* vcons-add.c (cons_vcons_add): Change argument VCONS to CONS and
VCONS_ENTRY. Don't do anything here (the user must implement it
all).
* vcons-close.c: Don't include <errno.h>, <unistd.h>, <stdio.h>,
<sys/mman.h>, <sys/fcntl.h>, <mach.h>. Include <assert.h>,
<hurd/ports.h> and <cthreads.h>.
(cons_vcons_close): Clear VCONS->vcons_entry->vcons. Derefence
and destroy VCONS.
* vcons-open.c (cons_vcons_open): Change arguments from VCONS to
CONS, VCONS_ENTRY and R_VCONS. New variable VCONS. Set up VCONS
as a port, and request notification messages on that.
* vcons-remove.c: Do not include <errno.h>.
(cons_vcons_remove): Assert that VCONS_ENTRY does not have an open
VCONS.
utils/
2002-09-09 Marcus Brinkmann <marcus@gnu.org>
* console-ncurses.c: New global variable global_lock.
(main): Initialize global_lock.
(cons_vcons_activate): Removed.
(console_switch): New function.
(cons_vcons_add): New function.
(input_loop): Call console_switch, not cons_switch. Do not take
active_vcons lock but global_lock.
(cons_vcons_update): Take global lock.
(cons_vcons_set_cursor_pos): Likewise.
(cons_vcons_set_cursor_status): Likewise.
(cons_vcons_scroll): Likewise.
(cons_vcons_write): Likewise.
(cons_vcons_beep): Likewise.
(cons_vcons_flash): Likewise.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/ChangeLog | 17 | ||||
-rw-r--r-- | utils/console-ncurses.c | 178 |
2 files changed, 136 insertions, 59 deletions
diff --git a/utils/ChangeLog b/utils/ChangeLog index 904e5bd6..e5562a10 100644 --- a/utils/ChangeLog +++ b/utils/ChangeLog @@ -1,3 +1,20 @@ +2002-09-09 Marcus Brinkmann <marcus@gnu.org> + + * console-ncurses.c: New global variable global_lock. + (main): Initialize global_lock. + (cons_vcons_activate): Removed. + (console_switch): New function. + (cons_vcons_add): New function. + (input_loop): Call console_switch, not cons_switch. Do not take + active_vcons lock but global_lock. + (cons_vcons_update): Take global lock. + (cons_vcons_set_cursor_pos): Likewise. + (cons_vcons_set_cursor_status): Likewise. + (cons_vcons_scroll): Likewise. + (cons_vcons_write): Likewise. + (cons_vcons_beep): Likewise. + (cons_vcons_flash): Likewise. + 2002-08-29 Marcus Brinkmann <marcus@gnu.org> * console-ncurses.c (main): Call endwin () before bailing out diff --git a/utils/console-ncurses.c b/utils/console-ncurses.c index 1f12ff3c..fb0b4190 100644 --- a/utils/console-ncurses.c +++ b/utils/console-ncurses.c @@ -259,24 +259,68 @@ ucs4_to_altchar (wchar_t chr, chtype *achr) return 1; } +struct mutex global_lock; static vcons_t active_vcons = NULL; error_t -cons_vcons_activate (vcons_t vcons) +console_switch (int id, int delta) { - error_t err; - - assert (vcons); - assert (vcons != active_vcons); + error_t err = 0; + int active_id; + cons_t cons; + vcons_t vcons; - err = cons_vcons_open (vcons); - if (err) - return err; + mutex_lock (&global_lock); + if (!active_vcons) + { + mutex_unlock (&global_lock); + return 0; + } + cons = active_vcons->cons; + active_id = active_vcons->id; + + /* We must give up our global lock before we can call back into + libcons. This is because cons_switch will lock CONS, and as + other functions in libcons lock CONS while calling back into our + functions which take the global lock (like cons_vcons_add), we + would deadlock. Because of this, we can not refer to our active + console directly, but we must refer to it by name (ID). XXX + Likewise, we can not really refer to CONS directly, but the + current implementation guarantees an eternal life span for + CONS. */ + mutex_unlock (&global_lock); + err = cons_switch (cons, active_id, id, delta, &vcons); + if (!err) + { + mutex_lock (&global_lock); + if (active_vcons != vcons) + { + cons_vcons_close (active_vcons); + active_vcons = vcons; + } + mutex_unlock (&vcons->lock); + mutex_unlock (&global_lock); + } + return err; +} - if (active_vcons) - cons_vcons_close (active_vcons); - active_vcons = vcons; - return 0; +void +cons_vcons_add (cons_t cons, vcons_list_t vcons_entry) +{ + error_t err = 0; + mutex_lock (&global_lock); + if (!active_vcons) + { + vcons_t vcons; + err = cons_vcons_open (cons, vcons_entry, &vcons); + if (!err) + { + vcons_entry->vcons = vcons; + active_vcons = vcons; + mutex_unlock (&vcons->lock); + } + } + mutex_unlock (&global_lock); } any_t @@ -331,8 +375,7 @@ input_loop (any_t unused) case '9': /* Avoid a dead lock. */ mutex_unlock (&ncurses_lock); - /* XXX: We ignore any error here. */ - cons_switch (active_vcons->cons, 1 + (ret - '1'), 0); + console_switch (1 + (ret - '1'), 0); mutex_lock (&ncurses_lock); break; default: @@ -373,9 +416,9 @@ input_loop (any_t unused) mutex_unlock (&ncurses_lock); if (size) { + mutex_lock (&global_lock); if (active_vcons) { - mutex_lock (&active_vcons->lock); do { ret = write (active_vcons->input, buf, size); @@ -386,8 +429,8 @@ input_loop (any_t unused) } } while (size && (ret != -1 || errno == EINTR)); - mutex_unlock (&active_vcons->lock); } + mutex_unlock (&global_lock); } } } @@ -466,45 +509,55 @@ mvwputsn (conchar_t *str, size_t len, off_t x, off_t y) void cons_vcons_update (vcons_t vcons) { - if (vcons != active_vcons) - return; - refresh (); + mutex_lock (&global_lock); + if (vcons == active_vcons) + refresh (); + mutex_unlock (&global_lock); } void cons_vcons_set_cursor_pos (vcons_t vcons, uint32_t col, uint32_t row) { - if (vcons != active_vcons) - return; - mutex_lock (&ncurses_lock); - move (row, col); - mutex_unlock (&ncurses_lock); + mutex_lock (&global_lock); + if (vcons == active_vcons) + { + mutex_lock (&ncurses_lock); + move (row, col); + mutex_unlock (&ncurses_lock); + } + mutex_unlock (&global_lock); } void cons_vcons_set_cursor_status (vcons_t vcons, uint32_t status) { - if (vcons != active_vcons) - return; - mutex_lock (&ncurses_lock); - curs_set (status ? (status == 1 ? 1 : 2) : 0); - mutex_unlock (&ncurses_lock); + mutex_lock (&global_lock); + if (vcons == active_vcons) + { + mutex_lock (&ncurses_lock); + curs_set (status ? (status == 1 ? 1 : 2) : 0); + mutex_unlock (&ncurses_lock); + } + mutex_unlock (&global_lock); } void cons_vcons_scroll (vcons_t vcons, int delta) { assert (delta >= 0); - if (vcons != active_vcons) - return; - - mutex_lock (&ncurses_lock); - idlok (stdscr, TRUE); - scrollok (stdscr, TRUE); - scrl (delta); - idlok (stdscr, FALSE); - scrollok (stdscr, FALSE); - mutex_unlock (&ncurses_lock); + + mutex_lock (&global_lock); + if (vcons == active_vcons) + { + mutex_lock (&ncurses_lock); + idlok (stdscr, TRUE); + scrollok (stdscr, TRUE); + scrl (delta); + idlok (stdscr, FALSE); + scrollok (stdscr, FALSE); + mutex_unlock (&ncurses_lock); + } + mutex_unlock (&global_lock); } void @@ -514,36 +567,42 @@ cons_vcons_write (vcons_t vcons, conchar_t *str, size_t length, int x; int y; - if (vcons != active_vcons) - return; - - mutex_lock (&ncurses_lock); - getyx (stdscr, y, x); - mvwputsn (str, length, col, row); - wmove (stdscr, y, x); - mutex_unlock (&ncurses_lock); + mutex_lock (&global_lock); + if (vcons == active_vcons) + { + mutex_lock (&ncurses_lock); + getyx (stdscr, y, x); + mvwputsn (str, length, col, row); + wmove (stdscr, y, x); + mutex_unlock (&ncurses_lock); + } + mutex_unlock (&global_lock); } void cons_vcons_beep (vcons_t vcons) { - if (vcons != active_vcons) - return; - - mutex_lock (&ncurses_lock); - beep (); - mutex_unlock (&ncurses_lock); + mutex_lock (&global_lock); + if (vcons == active_vcons) + { + mutex_lock (&ncurses_lock); + beep (); + mutex_unlock (&ncurses_lock); + } + mutex_unlock (&global_lock); } void cons_vcons_flash (vcons_t vcons) { - if (vcons != active_vcons) - return; - - mutex_lock (&ncurses_lock); - flash (); - mutex_unlock (&ncurses_lock); + mutex_lock (&global_lock); + if (vcons == active_vcons) + { + mutex_lock (&ncurses_lock); + flash (); + mutex_unlock (&ncurses_lock); + } + mutex_unlock (&global_lock); } @@ -557,6 +616,7 @@ main (int argc, char *argv[]) argp_parse (&cons_startup_argp, argc, argv, 0, 0, 0); mutex_init (&ncurses_lock); + mutex_init (&global_lock); initscr (); start_color (); |