From 084eaf695eec9ae1841ffce8401fe1e25bc72393 Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Fri, 2 Dec 1994 20:42:55 +0000 Subject: [PATCH] Numerous changes driven by implementation of PM interface. --- v7/src/microcode/os2conio.c | 190 ++++++++++++++++-------------------- v7/src/microcode/os2msg.c | 105 +++++++++++--------- v7/src/microcode/os2msg.h | 90 ++++++++++++++++- 3 files changed, 227 insertions(+), 158 deletions(-) diff --git a/v7/src/microcode/os2conio.c b/v7/src/microcode/os2conio.c index 160d979bf..258522ff1 100644 --- a/v7/src/microcode/os2conio.c +++ b/v7/src/microcode/os2conio.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2conio.c,v 1.2 1994/11/28 08:11:48 cph Exp $ +$Id: os2conio.c,v 1.3 1994/12/02 20:42:55 cph Exp $ Copyright (c) 1994 Massachusetts Institute of Technology @@ -32,30 +32,38 @@ Technology nor of any adaptation thereof in any advertising, promotional, or sales literature without prior written consent from MIT in each case. */ +#define USE_PMCON +/* #define USE_VIO */ +/* #define USE_PMIO */ + #include "os2.h" + +#ifdef USE_PMCON + +extern void OS2_initialize_pm_console (void); +extern int OS2_pm_console_getch (void); +extern void OS2_pm_console_write (const char *, size_t); + +#else #ifdef USE_PMIO + #include + +#endif #endif -typedef struct line_buffer_s -{ - msg_t * message; - struct line_buffer_s * next; -} line_buffer_t; - -static void console_thread (void *); +#ifdef USE_PMCON +#define getch OS2_pm_console_getch +#else #ifndef USE_PMIO -static int getch (void); +static int getch (void); #endif +#endif + +static void console_thread (void *); static void grab_console_lock (void); static void release_console_lock (void); -static void init_line_buffer (void); -static line_buffer_t * make_line_buffer (line_buffer_t *); -static void push_line_buffer (void); -static void pop_line_buffer (void); -static line_buffer_t * reverse_line_buffer (void); - static void process_input_char (char); static void do_rubout (void); static void add_to_line (char); @@ -78,23 +86,25 @@ static void write_output (const char *, size_t, int); static void write_output_1 (const char *, const char *); static unsigned int char_output_length (char); -#define LINEFEED '\012' - static HMTX console_lock; static int input_buffered_p; static int output_cooked_p; static qid_t console_writer_qid; static channel_context_t * console_context; -static line_buffer_t * line_buffer; +static readahead_buffer_t * line_buffer; void OS2_initialize_console (void) { +#ifdef USE_PMCON + OS2_initialize_pm_console (); +#else #ifdef USE_PMIO pmio_fontspec = "6.System VIO"; set_width (80); set_height (40); start_pmio (); +#endif #endif console_lock = (OS2_create_mutex_semaphore ()); input_buffered_p = 1; @@ -111,7 +121,7 @@ static void console_thread (void * arg) { grab_console_lock (); - init_line_buffer (); + line_buffer = (OS2_make_readahead_buffer ()); release_console_lock (); (void) OS2_thread_initialize (console_writer_qid); while (1) @@ -130,19 +140,21 @@ console_thread (void * arg) OS2_send_message (OS2_interrupt_qid, message); /* Flush buffers only for certain chars? */ flush_input (); + if (c == '\a') + write_char ('\a', 0); } } } OS2_endthread (); } -#ifndef USE_PMIO +#if ((!defined(USE_PMCON)) && (!defined(USE_PMIO))) static int getch (void) { while (1) { -#if 1 +#ifdef USE_VIO KBDKEYINFO info; XTD_API_CALL (kbd_char_in, ((&info), IO_WAIT, 0), @@ -182,62 +194,6 @@ release_console_lock (void) } static void -init_line_buffer (void) -{ - line_buffer = 0; - push_line_buffer (); -} - -static line_buffer_t * -make_line_buffer (line_buffer_t * next) -{ - line_buffer_t * buffer = (OS_malloc (sizeof (line_buffer_t))); - msg_t * message = (OS2_make_readahead ()); - (SM_READAHEAD_SIZE (message)) = 0; - (buffer -> message) = message; - (buffer -> next) = next; - return (buffer); -} - -static void -push_line_buffer (void) -{ - line_buffer = (make_line_buffer (line_buffer)); -} - -static void -pop_line_buffer (void) -{ - line_buffer_t * buffer = line_buffer; - OS2_destroy_message (buffer -> message); - line_buffer = (buffer -> next); - OS_free (buffer); -} - -static line_buffer_t * -reverse_line_buffer (void) -{ - line_buffer_t * this = line_buffer; - line_buffer_t * prev = 0; - line_buffer_t * next; - line_buffer = 0; - while (1) - { - next = (this -> next); - (this -> next) = prev; - if (next == 0) - break; - prev = this; - this = next; - } - push_line_buffer (); - return (this); -} - -#define LINE_BUFFER_SIZE (SM_READAHEAD_SIZE (line_buffer -> message)) -#define LINE_BUFFER_DATA (SM_READAHEAD_DATA (line_buffer -> message)) - -static void process_input_char (char c) { if (!input_buffered_p) @@ -249,7 +205,7 @@ process_input_char (char c) do_rubout (); break; case '\r': - do_self_insert (LINEFEED); + do_self_insert ('\n'); finish_line (); break; default: @@ -269,9 +225,7 @@ static void add_char_to_line_buffer (char c) { grab_console_lock (); - if (LINE_BUFFER_SIZE == SM_READAHEAD_MAX) - push_line_buffer (); - (LINE_BUFFER_DATA [LINE_BUFFER_SIZE ++]) = c; + OS2_readahead_buffer_insert (line_buffer, c); release_console_lock (); } @@ -279,19 +233,15 @@ static void do_rubout (void) { grab_console_lock (); - if (LINE_BUFFER_SIZE == 0) + if (OS2_readahead_buffer_emptyp (line_buffer)) { - if ((line_buffer -> next) == 0) - { - release_console_lock (); - write_char ('\a', 0); - return; - } - pop_line_buffer (); + release_console_lock (); + write_char ('\a', 0); + return; } { unsigned int n - = (char_output_length (LINE_BUFFER_DATA [-- LINE_BUFFER_SIZE])); + = (char_output_length (OS2_readahead_buffer_rubout (line_buffer))); unsigned int i; release_console_lock (); for (i = 0; (i < n); i += 1) @@ -306,15 +256,16 @@ do_rubout (void) static void finish_line (void) { - line_buffer_t * buffer; + msg_list_t * messages; grab_console_lock (); - buffer = (reverse_line_buffer ()); + messages = (OS2_readahead_buffer_read_all (line_buffer)); release_console_lock (); - while (buffer != 0) + while (messages != 0) { - send_readahead (buffer -> message); - buffer = (buffer -> next); - OS_free (buffer); + msg_list_t * element = messages; + messages = (messages -> next); + send_readahead (element -> message); + OS_free (element); } } @@ -349,7 +300,8 @@ console_operator (Tchannel channel, chop_t operation, { case chop_read: (* ((long *) arg3)) - = (channel_thread_read (channel, ((char *) arg1), ((size_t) arg2))); + = (OS2_channel_thread_read + (channel, ((char *) arg1), ((size_t) arg2))); break; case chop_write: write_output (((const char *) arg1), ((size_t) arg2), output_cooked_p); @@ -377,11 +329,17 @@ console_operator (Tchannel channel, chop_t operation, static void flush_input (void) { + msg_list_t * messages; grab_console_lock (); - while ((line_buffer -> next) != 0) - pop_line_buffer (); - LINE_BUFFER_SIZE = 0; + messages = (OS2_readahead_buffer_read_all (line_buffer)); release_console_lock (); + while (messages != 0) + { + msg_list_t * element = messages; + messages = (messages -> next); + OS2_destroy_message (element -> message); + OS_free (element); + } } static void @@ -413,6 +371,12 @@ write_char (char c, int cooked_p) write_output ((&c), 1, cooked_p); } +void +OS2_console_write (const char * data, size_t size) +{ + write_output (data, size, 1); +} + static void write_output (const char * data, size_t size, int cooked_p) { @@ -435,12 +399,12 @@ write_output (const char * data, size_t size, int cooked_p) out = output_translation; } c = (*scan++); - if (isprint (c)) + if ((isprint (c)) || (c == '\f') || (c == '\a')) (*out++) = c; - else if (c == LINEFEED) + else if (c == '\n') { (*out++) = '\r'; - (*out++) = c; + (*out++) = '\012'; } else if (c < 0x20) { @@ -456,16 +420,26 @@ write_output (const char * data, size_t size, int cooked_p) } } } - + static void write_output_1 (const char * scan, const char * end) { +#ifdef USE_PMCON + + OS2_pm_console_write (scan, (end - scan)); + +#else /* not USE_PMCON */ #ifdef USE_PMIO + put_raw ((end - scan), scan); + #else /* not USE_PMIO */ -#if 1 +#ifdef USE_VIO + STD_API_CALL (vio_wrt_tty, (((PCH) scan), (end - scan), 0)); -#else + +#else /* not USE_VIO */ + while (1) { ULONG n; @@ -476,8 +450,10 @@ write_output_1 (const char * scan, const char * end) if (scan == end) break; } -#endif + +#endif /* not USE_VIO */ #endif /* not USE_PMIO */ +#endif /* not USE_PMCON */ } static unsigned int diff --git a/v7/src/microcode/os2msg.c b/v7/src/microcode/os2msg.c index 990a80cc8..97174f91c 100644 --- a/v7/src/microcode/os2msg.c +++ b/v7/src/microcode/os2msg.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2msg.c,v 1.1 1994/11/28 03:42:58 cph Exp $ +$Id: os2msg.c,v 1.2 1994/12/02 20:42:46 cph Exp $ Copyright (c) 1994 Massachusetts Institute of Technology @@ -38,8 +38,6 @@ MIT in each case. */ static qid_t allocate_qid (void); static void OS2_initialize_message_lengths (void); -static void read_and_dispatch_nonblocking (tqueue_t *); -static void read_and_dispatch_one_blocking (tqueue_t *); static void write_subqueue (msg_t *); static msg_t * read_subqueue (qid_t); static int subqueue_emptyp (qid_t); @@ -51,20 +49,13 @@ static tqueue_t * make_scm_tqueue (void); static int read_scm_tqueue (tqueue_t *, int); static void write_scm_tqueue (tqueue_t *, msg_t *); static void process_interrupt_messages (void); -static int read_pm_tqueue (tqueue_t *, int); -static void write_pm_tqueue (tqueue_t *, msg_t *); -typedef struct msg_list_s -{ - msg_t * message; - struct msg_list_s * next; -} msg_list_t; - typedef struct { unsigned int allocatedp : 1; /* queue allocated? */ unsigned int openp : 1; /* queue open? */ qid_t twin; /* other end of connection */ + qid_receive_filter_t filter; /* filter for received messages */ tqueue_t * tqueue; /* thread queue for reception */ msg_list_t * subqueue_head; /* head of receiving subqueue */ msg_list_t * subqueue_tail; /* tail of receiving subqueue */ @@ -83,6 +74,7 @@ qid_t OS2_interrupt_qid; #define QID_TQUEUE(q) ((_QID (q)) . tqueue) #define QID_SUBQUEUE_HEAD(q) ((_QID (q)) . subqueue_head) #define QID_SUBQUEUE_TAIL(q) ((_QID (q)) . subqueue_tail) +#define QID_FILTER(q) ((_QID (q)) . filter) #define MSG_QUEUE_TYPE(m) 0 #define MSG_QUEUE_PRIORITY(m) 0 @@ -105,8 +97,10 @@ OS2_initialize_message_queues (void) } } OS2_initialize_message_lengths (); + SET_MSG_TYPE_LENGTH (mt_init, sm_init_t); SET_MSG_TYPE_LENGTH (mt_console_interrupt, sm_console_interrupt_t); SET_MSG_TYPE_LENGTH (mt_timer_event, sm_timer_event_t); + SET_MSG_TYPE_LENGTH (mt_generic_reply, sm_generic_reply_t); qid_lock = (OS2_create_mutex_semaphore ()); OS2_scheme_tqueue = (make_scm_tqueue ()); OS2_make_qid_pair ((&OS2_interrupt_qid_local), (&OS2_interrupt_qid)); @@ -189,6 +183,12 @@ OS2_close_qid (qid_t qid) (QID_ALLOCATEDP (qid)) = 0; OS2_release_mutex_semaphore (qid_lock); } + +void +OS2_set_qid_receive_filter (qid_t qid, qid_receive_filter_t filter) +{ + (QID_FILTER (qid)) = filter; +} /* Message Lengths */ @@ -267,7 +267,8 @@ OS2_receive_message (qid_t qid, int blockp) msg_t * message; while (1) { - read_and_dispatch_nonblocking (tqueue); + while (read_tqueue (tqueue, 0)) + ; if ((TQUEUE_TYPE (tqueue)) == tqt_scm) { process_interrupt_messages (); @@ -276,37 +277,51 @@ OS2_receive_message (qid_t qid, int blockp) message = (read_subqueue (qid)); if ((!blockp) || (message != 0)) break; - read_and_dispatch_one_blocking (tqueue); + (void) read_tqueue (tqueue, 1); } return (message); } -static void -read_and_dispatch_nonblocking (tqueue_t * tqueue) -{ - while (read_tqueue (tqueue, 0)) - ; +msg_t * +OS2_wait_for_message (qid_t qid, msg_type_t reply_type) +{ + msg_t * reply = (OS2_receive_message (qid, 1)); + if (OS2_error_message_p (reply)) + OS2_handle_error_message (reply); + if ((MSG_TYPE (reply)) != reply_type) + OS2_logic_error ("Incorrect reply message type."); + return (reply); } -static void -read_and_dispatch_one_blocking (tqueue_t * tqueue) +msg_t * +OS2_message_transaction (qid_t qid, msg_t * request, msg_type_t reply_type) { - (void) read_tqueue (tqueue, 1); + OS2_send_message (qid, request); + OS2_wait_for_message (qid, reply_type); } static void write_subqueue (msg_t * message) { qid_t qid = (MSG_SENDER (message)); - msg_list_t * tail = (QID_SUBQUEUE_TAIL (qid)); - msg_list_t * elt = (OS_malloc (sizeof (struct msg_list_s))); - (elt -> message) = message; - (elt -> next) = 0; - if (tail == 0) - (QID_SUBQUEUE_HEAD (qid)) = elt; - else - (tail -> next) = elt; - (QID_SUBQUEUE_TAIL (qid)) = elt; + qid_receive_filter_t filter = (QID_FILTER (qid)); + if (filter != 0) + { + message = ((* filter) (message)); + if (message == 0) + return; + } + { + msg_list_t * tail = (QID_SUBQUEUE_TAIL (qid)); + msg_list_t * elt = (OS_malloc (sizeof (struct msg_list_s))); + (elt -> message) = message; + (elt -> next) = 0; + if (tail == 0) + (QID_SUBQUEUE_HEAD (qid)) = elt; + else + (tail -> next) = elt; + (QID_SUBQUEUE_TAIL (qid)) = elt; + } } static msg_t * @@ -341,7 +356,7 @@ read_tqueue (tqueue_t * tqueue, int blockp) case tqt_scm: return (read_scm_tqueue (tqueue, blockp)); case tqt_pm: - return (read_pm_tqueue (tqueue, blockp)); + return (OS2_read_pm_tqueue (tqueue, blockp)); } } @@ -357,7 +372,7 @@ write_tqueue (tqueue_t * tqueue, msg_t * message) write_scm_tqueue (tqueue, message); break; case tqt_pm: - write_pm_tqueue (tqueue, message); + OS2_write_pm_tqueue (tqueue, message); break; } } @@ -381,6 +396,14 @@ OS2_make_std_tqueue (void) return (tqueue); } +void +OS2_close_std_tqueue (tqueue_t * tqueue) +{ + OS2_close_queue (STD_TQUEUE_QUEUE (tqueue)); + OS2_close_event_semaphore (STD_TQUEUE_EVENT (tqueue)); + OS_free (tqueue); +} + static int read_std_tqueue (tqueue_t * tqueue, int blockp) { @@ -446,8 +469,7 @@ read_scm_tqueue (tqueue_t * tqueue, int blockp) if (read_std_tqueue (tqueue, blockp)) { result = 1; - /* If blockp was set, after we have read one message we read - any remaining messages in non-blocking mode. */ + /* At most one message needs to be read in blocking mode. */ blockp = 0; } while (test_and_clear_attention_interrupt ()); @@ -464,7 +486,9 @@ write_scm_tqueue (tqueue_t * tqueue, msg_t * message) void OS2_handle_attention_interrupt (void) { - read_and_dispatch_nonblocking (QID_TQUEUE (OS2_interrupt_qid_local)); + tqueue_t * tqueue = (QID_TQUEUE (OS2_interrupt_qid_local)); + while (read_tqueue (tqueue, 0)) + ; process_interrupt_messages (); } @@ -493,14 +517,3 @@ process_interrupt_messages (void) OS2_destroy_message (message); } } - -static int -read_pm_tqueue (tqueue_t * tqueue, int blockp) -{ - return (0); -} - -static void -write_pm_tqueue (tqueue_t * tqueue, msg_t * message) -{ -} diff --git a/v7/src/microcode/os2msg.h b/v7/src/microcode/os2msg.h index ac02bae56..c6dbf4636 100644 --- a/v7/src/microcode/os2msg.h +++ b/v7/src/microcode/os2msg.h @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2msg.h,v 1.1 1994/11/28 03:42:59 cph Exp $ +$Id: os2msg.h,v 1.2 1994/12/02 20:42:38 cph Exp $ Copyright (c) 1994 Massachusetts Institute of Technology @@ -37,18 +37,84 @@ MIT in each case. */ typedef enum { + /* This is sent to acknowledge that the other end of a qid pair has + been opened. Sometimes it is necessary to wait until the + connection is established before proceeding. */ + mt_init, + + /* This is sent by a "readahead" thread whenever it has some data to + give to the other end of the connection. These messages are + generated asynchronously whenever the readahead is available. */ mt_readahead, + + /* This is sent by the receiver or a readahead message. It is used + to regulate the amount of readahead in the connection. + Typically, the readahead thread won't generate any more readahead + messages until the readahead_ack is received. */ mt_readahead_ack, + + /* This is a console interrupt event. It is generated automatically + by the console readahead thread (or the PM thread if the console + is implemented as a PM window), and causes a Scheme character + interrupt to be signalled in the interrupt-code register. */ mt_console_interrupt, + + /* This is a timer interrupt event. It is generated automatically + by the timer thread when the timer is active. */ + mt_timer_event, + + /* These are error messages. They are sent as a reply to a request + when an error is generated during the processing of the request. */ mt_error, - mt_kill_request, mt_syscall_error, - mt_timer_event, + + /* This is a generic reply that is used to acknowledge requests that + return no meaningful data other than that they have completed. */ + mt_generic_reply, + + /* This is a request/reply pair that asks the PM thread to create a + terminal window. */ + mt_twindow_open_request, + mt_twindow_open_reply, + + /* This requests the PM thread to close an existing terminal window. */ + mt_twindow_close_request, + + /* This requests the PM thread to write some characters on a + terminal window. */ + mt_twindow_write_request, + + /* This requests the PM thread to move the cursor of a terminal + window. */ + mt_twindow_move_cursor_request, + + /* This requests the PM thread to clear a terminal window. */ + mt_twindow_clear_request, + + /* This requests the PM thread to clear to the end of a line in a + terminal window. */ + mt_twindow_clear_eol_request, + + /* This requests the PM thread to scroll a rectangular region in a + terminal window. */ + mt_twindow_scroll_request, + + /* These are messages that are automatically generated by the PM + thread when the corresponding events occur. */ + mt_key_event, /* key press */ + mt_button_event, /* mouse button press */ + mt_close_event, /* window close */ + mt_visibility_event, /* window visibility change */ + mt_resize_event, /* window resized */ + + /* This requests the thread on the other end of the connection to + kill itself. At present this request is not used. */ + mt_kill_request, mt_supremum } msg_type_t; #define MSG_TYPE_SUP ((unsigned int) mt_supremum) #define MSG_TYPE_MAX (MSG_TYPE_SUP - 1) - + typedef unsigned char qid_t; #define QID_MAX (UCHAR_MAX - 1) #define QID_NONE UCHAR_MAX @@ -88,6 +154,8 @@ typedef struct } tqueue_t; #define TQUEUE_TYPE(q) (((tqueue_t *) (q)) -> type) +typedef msg_t * (* qid_receive_filter_t) (msg_t *); + extern tqueue_t * OS2_scheme_tqueue; extern qid_t OS2_interrupt_qid; @@ -95,19 +163,29 @@ extern void OS2_make_qid_pair (qid_t *, qid_t *); extern void OS2_open_qid (qid_t, tqueue_t *); extern int OS2_qid_openp (qid_t); extern void OS2_close_qid (qid_t); +extern void OS2_set_qid_receive_filter (qid_t, qid_receive_filter_t); extern msg_length_t OS2_message_type_length (msg_type_t); extern void OS2_set_message_type_length (msg_type_t, msg_length_t); extern msg_t * OS2_create_message (msg_type_t); extern void OS2_destroy_message (msg_t *); extern void OS2_send_message (qid_t, msg_t *); extern msg_t * OS2_receive_message (qid_t, int); +extern msg_t * OS2_wait_for_message (qid_t, msg_type_t); +extern msg_t * OS2_message_transaction (qid_t, msg_t *, msg_type_t); extern tqueue_t * OS2_make_std_tqueue (void); - +extern void OS2_close_std_tqueue (tqueue_t *); + #define MSG_LENGTH(m) (OS2_message_type_length (MSG_TYPE (m))) #define SET_MSG_TYPE_LENGTH(t, s) \ OS2_set_message_type_length ((t), (sizeof (s))) +typedef struct msg_list_s +{ + msg_t * message; + struct msg_list_s * next; +} msg_list_t; + typedef struct { DECLARE_MSG_HEADER_FIELDS; @@ -116,5 +194,7 @@ typedef struct #define SM_CONSOLE_INTERRUPT_CODE(m) (((sm_console_interrupt_t *) (m)) -> code) typedef msg_t sm_timer_event_t; +typedef msg_t sm_init_t; +typedef msg_t sm_generic_reply_t; #endif /* SCM_OS2MSG_H */ -- 2.25.1