Many changes to support Edwin. Converging on a final design for the
authorChris Hanson <org/chris-hanson/cph>
Mon, 19 Dec 1994 22:32:49 +0000 (22:32 +0000)
committerChris Hanson <org/chris-hanson/cph>
Mon, 19 Dec 1994 22:32:49 +0000 (22:32 +0000)
OS/2 support.

15 files changed:
v7/src/microcode/os2.c
v7/src/microcode/os2.h
v7/src/microcode/os2api.h
v7/src/microcode/os2conio.c
v7/src/microcode/os2cthrd.c
v7/src/microcode/os2env.c
v7/src/microcode/os2fs.c
v7/src/microcode/os2io.c
v7/src/microcode/os2msg.c
v7/src/microcode/os2msg.h
v7/src/microcode/os2pm.c
v7/src/microcode/os2pm.h
v7/src/microcode/os2pmcon.c
v7/src/microcode/os2top.c
v7/src/microcode/os2utl/makefile

index c6ab6d8d0b95e9b46f7a40441084116f3d1c9e2d..962cd8437495543596d97b02e7ff88013922808b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2.c,v 1.1 1994/11/28 03:42:53 cph Exp $
+$Id: os2.c,v 1.2 1994/12/19 22:30:05 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -59,10 +59,12 @@ OS_free (void * ptr)
 }
 \f
 HMTX
-OS2_create_mutex_semaphore (void)
+OS2_create_mutex_semaphore (PSZ name, int sharedp)
 {
   HMTX result;
-  STD_API_CALL (dos_create_mutex_sem, (0, (&result), 0, 0));
+  STD_API_CALL
+    (dos_create_mutex_sem,
+     (name, (&result), (sharedp ? DC_SEM_SHARED : 0), 0));
   return (result);
 }
 
@@ -85,10 +87,12 @@ OS2_release_mutex_semaphore (HMTX s)
 }
 
 HEV
-OS2_create_event_semaphore (void)
+OS2_create_event_semaphore (PSZ name, int sharedp)
 {
   HEV result;
-  STD_API_CALL (dos_create_event_sem, (0, (&result), 0, 0));
+  STD_API_CALL
+    (dos_create_event_sem,
+     (name, (&result), (sharedp ? DC_SEM_SHARED : 0), 0));
   return (result);
 }
 
@@ -194,6 +198,6 @@ OS2_logic_error_1 (const char * description,
                   unsigned int line)
 {
   outf_fatal ("\nFatal error in file \"%s\", line %d:\n%s\nGet a wizard.\n",
-             description, file, line);
+             file, line, description);
   termination_init_error ();
 }
index ac42c56759ed2b2ec92a33a1d011e11d5514db1f..ccbcd2829636033987a9b79cffc7d7306ae369e8 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2.h,v 1.2 1994/12/02 20:43:13 cph Exp $
+$Id: os2.h,v 1.3 1994/12/19 22:30:20 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -41,6 +41,10 @@ MIT in each case. */
 #include "osscheme.h"
 #include "syscall.h"
 
+/* Defined by "scheme.h" and conflicts with definition in <os2.h>.
+   Scheme's definition not needed in OS/2 files.  */
+#undef END_OF_CHAIN
+
 #define INCL_DOS
 #define INCL_DOSERRORS
 #define INCL_KBD
@@ -66,12 +70,12 @@ MIT in each case. */
 #define FILE_ANY                                                       \
   (FILE_NORMAL | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED)
 
-extern HMTX OS2_create_mutex_semaphore  (void);
+extern HMTX OS2_create_mutex_semaphore  (PSZ, int);
 extern void OS2_close_mutex_semaphore   (HMTX);
 extern void OS2_request_mutex_semaphore (HMTX);
 extern void OS2_release_mutex_semaphore (HMTX);
 
-extern HEV   OS2_create_event_semaphore (void);
+extern HEV   OS2_create_event_semaphore (PSZ, int);
 extern void  OS2_close_event_semaphore  (HEV);
 extern int   OS2_post_event_semaphore   (HEV);
 extern ULONG OS2_reset_event_semaphore  (HEV);
index 4bb21139254eb329c148df2bf79afe6c39e524c7..7df6d89be9818ab799f80da307cf33158ff1f153 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2api.h,v 1.1 1994/11/28 03:42:54 cph Exp $
+$Id: os2api.h,v 1.2 1994/12/19 22:30:46 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -80,6 +80,8 @@ extern APIRET dos_post_event_sem (HEV);
 extern APIRET dos_query_current_dir (ULONG, PBYTE, PULONG);
 extern APIRET dos_query_current_disk (PULONG, PULONG);
 extern APIRET dos_query_file_info (HFILE, ULONG, PVOID, ULONG);
+extern APIRET dos_query_fs_attach (PSZ, ULONG, ULONG, PFSQBUFFER2, PULONG);
+extern APIRET dos_query_fs_info (ULONG, ULONG, PVOID, ULONG);
 extern APIRET dos_query_h_type (HFILE, PULONG, PULONG);
 extern APIRET dos_query_n_p_h_state (HPIPE, PULONG);
 extern APIRET dos_query_path_info (PSZ, ULONG, PVOID, ULONG);
@@ -131,6 +133,8 @@ extern APIRET vio_wrt_tty (PCH, USHORT, HVIO);
 #define dos_query_current_dir  DosQueryCurrentDir
 #define dos_query_current_disk DosQueryCurrentDisk
 #define dos_query_file_info    DosQueryFileInfo
+#define dos_query_fs_attach    DosQueryFSAttach
+#define dos_query_fs_info      DosQueryFSInfo
 #define dos_query_h_type       DosQueryHType
 #define dos_query_n_p_h_state  DosQueryNPHState
 #define dos_query_path_info    DosQueryPathInfo
@@ -180,6 +184,8 @@ extern APIRET vio_wrt_tty (PCH, USHORT, HVIO);
 #define syscall_dos_query_current_dir  syscall_DosQueryCurrentDir
 #define syscall_dos_query_current_disk syscall_DosQueryCurrentDisk
 #define syscall_dos_query_file_info    syscall_DosQueryFileInfo
+#define syscall_dos_query_fs_attach    syscall_DosQueryFSAttach
+#define syscall_dos_query_fs_info      syscall_DosQueryFSInfo
 #define syscall_dos_query_h_type       syscall_DosQueryHType
 #define syscall_dos_query_n_p_h_state  syscall_DosQueryNPHState
 #define syscall_dos_query_path_info    syscall_DosQueryPathInfo
index 258522ff14c95bbb4e2410442a26ab2eb15fcc3b..73d10a7ae90bd0eacb60311030832ca2f1dccd37 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2conio.c,v 1.3 1994/12/02 20:42:55 cph Exp $
+$Id: os2conio.c,v 1.4 1994/12/19 22:30:47 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -106,7 +106,7 @@ OS2_initialize_console (void)
   start_pmio ();
 #endif
 #endif
-  console_lock = (OS2_create_mutex_semaphore ());
+  console_lock = (OS2_create_mutex_semaphore (0, 0));
   input_buffered_p = 1;
   output_cooked_p = 1;
   console_context = (OS2_make_channel_context ());
index 368b5ee8b9d6708ad0de58c5d975fb87b9ce16b9..546fc05c77816d07156d727678e135099e62115d 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2cthrd.c,v 1.2 1994/12/02 20:41:49 cph Exp $
+$Id: os2cthrd.c,v 1.3 1994/12/19 22:30:49 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -86,7 +86,7 @@ OS2_channel_thread_read (Tchannel channel, char * buffer, size_t size)
     {
       if (CHANNEL_NONBLOCKING (channel))
        {
-         message = (OS2_receive_message (qid, 0));
+         message = (OS2_receive_message (qid, 0, 1));
          if (message == 0)
            {
              (CHANNEL_CONTEXT_READAHEAD (context)) = 0;
@@ -94,7 +94,7 @@ OS2_channel_thread_read (Tchannel channel, char * buffer, size_t size)
            }
        }
       else
-       message = (OS2_receive_message (qid, 1));
+       message = (OS2_receive_message (qid, 1, 1));
       /* Acknowledge the message so that the readahead thread will
         know that it is safe to start reading some more.  */
       OS2_send_message (qid, (OS2_make_readahead_ack ()));
index 9cabb48ae7a3cbe7138faea9e61b45142cc5a06f..ba8a29c6f15a75b28706c8c02013999bceee3d6c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2env.c,v 1.1 1994/11/28 03:42:56 cph Exp $
+$Id: os2env.c,v 1.2 1994/12/19 22:31:27 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -33,7 +33,6 @@ promotional, or sales literature without prior written consent from
 MIT in each case. */
 
 #include "scheme.h"
-#undef END_OF_CHAIN
 #include "os2.h"
 #include "osenv.h"
 #include <time.h>
@@ -158,7 +157,7 @@ static TID timer_tid;
 static void
 initialize_timer (void)
 {
-  timer_event = (OS2_create_event_semaphore ());
+  timer_event = (OS2_create_event_semaphore (0, 1));
   timer_handle_valid = 0;
   timer_tid = (OS2_beginthread (timer_thread, 0, 0));
 }
@@ -195,14 +194,14 @@ OS_real_timer_set (clock_t first, clock_t interval)
   if (interval != 0)
     {
       STD_API_CALL (dos_start_timer, (interval,
-                                     ((HSEM) (&timer_event)),
+                                     ((HSEM) timer_event),
                                      (&timer_handle)));
       timer_handle_valid = 1;
     }
   else if (first != 0)
     {
       STD_API_CALL (dos_async_timer, (first,
-                                     ((HSEM) (&timer_event)),
+                                     ((HSEM) timer_event),
                                      (&timer_handle)));
       timer_handle_valid = 1;
     }
index 659233b7cea90a3bab8f2c6cd9afd8724a1ee33d..bc98b9382439ffeb6b84d432a9db996b8ad6b6bc 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2fs.c,v 1.1 1994/11/28 03:42:57 cph Exp $
+$Id: os2fs.c,v 1.2 1994/12/19 22:31:28 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -42,19 +42,50 @@ MIT in each case. */
 
 static const char * make_pathname (const char *, const char *);
 static const char * filename_extension (const char *);
+extern char * OS2_drive_type (char);
 extern char * OS2_remove_trailing_backslash (const char *);
 \f
 FILESTATUS3 *
 OS2_read_file_status (const char * filename)
 {
+  char name [CCHMAXPATH];
   static FILESTATUS3 info;
+  unsigned int flen = (strlen (filename));
+  FASTCOPY (filename, name, flen);
+  /* Strip trailing backslash.  */
+  if ((flen > 0) && ((name [flen - 1]) == '\\'))
+    flen -= 1;
+  (name [flen]) = '\0';
+  /* Canonicalize various forms of reference to root directory.  */
+  if ((flen == 5)
+      && (isalpha (name [0]))
+      && ((name [1]) == ':')
+      && ((name [2]) == '\\')
+      && ((name [3]) == '.')
+      && ((name [4]) == '.'))
+    (name [4]) = '\0';
+  else if ((flen == 2)
+          && (isalpha (name [0]))
+          && ((name [1]) == ':'))
+    {
+      (name [2]) = '\\';
+      (name [3]) = '.';
+      (name [4]) = '\0';
+    }
+  else if (flen == 0)
+    {
+      (name [0]) = '\\';
+      (name [1]) = '.';
+      (name [2]) = '\0';
+    }
   XTD_API_CALL
     (dos_query_path_info,
-     ((OS2_remove_trailing_backslash (filename)),
-      FIL_STANDARD, (&info), (sizeof (info))),
+     (name, FIL_STANDARD, (&info), (sizeof (info))),
      {
        if ((rc == ERROR_FILE_NOT_FOUND)
           || (rc == ERROR_PATH_NOT_FOUND)
+          || (rc == ERROR_INVALID_PATH)
+          || (rc == ERROR_INVALID_FSD_NAME)
           /* ERROR_ACCESS_DENIED can occur if the file is a symbolic
              link on a unix system mounted via NFS, and if the
              symbolic link points to a nonexistent file.  */
@@ -93,18 +124,14 @@ OS_file_access (const char * filename, unsigned int mode)
     return (0);
   if (((mode & W_OK) != 0) && (((info -> attrFile) & FILE_READONLY) != 0))
     return (0);
-  if ((mode & X_OK) != 0)
+  if (((mode & X_OK) != 0) && (((info -> attrFile) & FILE_DIRECTORY) == 0))
     {
-      if (((info -> attrFile) & FILE_DIRECTORY) != 0)
+      const char * extension = (filename_extension (filename));
+      if (! (((stricmp (extension, ".exe")) == 0)
+            || ((stricmp (extension, ".com")) == 0)
+            || ((stricmp (extension, ".cmd")) == 0)
+            || ((stricmp (extension, ".bat")) == 0)))
        return (0);
-      {
-       const char * extension = (filename_extension (filename));
-       if (! (((stricmp (extension, ".exe")) == 0)
-              || ((stricmp (extension, ".com")) == 0)
-              || ((stricmp (extension, ".cmd")) == 0)
-              || ((stricmp (extension, ".bat")) == 0)))
-         return (0);
-      }
     }
   return (1);
 }
@@ -112,8 +139,39 @@ OS_file_access (const char * filename, unsigned int mode)
 int
 OS_file_directory_p (const char * filename)
 {
-  FILESTATUS3 * info = (OS2_read_file_status (filename));
-  return ((info == 0) ? 0 : (((info -> attrFile) & FILE_DIRECTORY) != 0));
+  if (((strlen (filename)) == 3)
+      && (isalpha (filename [0]))
+      && ((filename [1]) == ':')
+      && ((filename [2]) == '\\'))
+    return ((OS2_drive_type (filename [0])) != 0);
+  else
+    {
+      FILESTATUS3 * info = (OS2_read_file_status (filename));
+      return ((info == 0) ? 0 : (((info -> attrFile) & FILE_DIRECTORY) != 0));
+    }
+}
+
+char *
+OS2_drive_type (char drive_letter)
+{
+  char name [3];
+  static char cbuf [(sizeof (FSQBUFFER2)) + (3 * CCHMAXPATH)];
+  FSQBUFFER2 * buffer = ((FSQBUFFER2 *) cbuf);
+  ULONG size = (sizeof (cbuf));
+  APIRET rc;
+  (name [0]) = drive_letter;
+  (name [1]) = ':';
+  (name [2]) = '\0';
+  (void) DosError (FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR);
+  rc = (dos_query_fs_attach (name, 0, FSAIL_QUERYNAME, buffer, (& size)));
+  (void) DosError (FERR_ENABLEEXCEPTION | FERR_ENABLEHARDERR);
+  if (rc != NO_ERROR)
+    OS2_error_system_call (rc, syscall_dos_query_fs_attach);
+  return
+    ((((buffer -> iType) == FSAT_LOCALDRV)
+      || ((buffer -> iType) == FSAT_REMOTEDRV))
+     ? ((buffer -> szName) + (buffer -> cbName) + 1)
+     : 0);
 }
 
 const char *
@@ -180,7 +238,7 @@ OS_directory_delete (const char * directory_name)
 \f
 typedef struct
 {
-  const char * search_pattern;
+  char allocatedp;
   HDIR handle;
   FILEFINDBUF3 info;
   ULONG count;
@@ -197,7 +255,7 @@ OS2_initialize_directory_reader (void)
 }
 
 static unsigned int
-allocate_dir_search_state (const char * search_pattern)
+allocate_dir_search_state (void)
 {
   if (n_dir_search_states == 0)
     {
@@ -208,9 +266,9 @@ allocate_dir_search_state (const char * search_pattern)
       {
        dir_search_state * scan = dir_search_states;
        dir_search_state * end = (scan + n_dir_search_states);
-       ((scan++) -> search_pattern) = search_pattern;
+       ((scan++) -> allocatedp) = 1;
        while (scan < end)
-         ((scan++) -> search_pattern) = 0;
+         ((scan++) -> allocatedp) = 0;
       }
       return (0);
     }
@@ -218,9 +276,9 @@ allocate_dir_search_state (const char * search_pattern)
     dir_search_state * scan = dir_search_states;
     dir_search_state * end = (scan + n_dir_search_states);
     while (scan < end)
-      if (((scan++) -> search_pattern) == 0)
+      if (! ((scan++) -> allocatedp))
        {
-         ((--scan) -> search_pattern) = search_pattern;
+         ((--scan) -> allocatedp) = 1;
          return (scan - dir_search_states);
        }
   }
@@ -234,9 +292,9 @@ allocate_dir_search_state (const char * search_pattern)
     {
       dir_search_state * scan = (states + result);
       dir_search_state * end = (states + n_states);
-      ((scan++) -> search_pattern) = search_pattern;
+      ((scan++) -> allocatedp) = 1;
       while (scan < end)
-       ((scan++) -> search_pattern) = 0;
+       ((scan++) -> allocatedp) = 0;
     }
     dir_search_states = states;
     n_dir_search_states = n_states;
@@ -245,14 +303,7 @@ allocate_dir_search_state (const char * search_pattern)
 }
 
 #define REFERENCE_DIR_SEARCH_STATE(index) (& (dir_search_states[(index)]))
-#define DEALLOCATE_DIR_SEARCH_STATE(state)                             \
-{                                                                      \
-  if ((state -> search_pattern) != 0)                                  \
-    {                                                                  \
-      OS_free ((void *) (state -> search_pattern));                    \
-      (state -> search_pattern) = 0;                                   \
-    }                                                                  \
-}
+#define DEALLOCATE_DIR_SEARCH_STATE(state) ((state) -> allocatedp) = 0
 \f
 int
 OS_directory_valid_p (long index)
@@ -260,20 +311,29 @@ OS_directory_valid_p (long index)
   return
     ((0 <= index)
      && (index < n_dir_search_states)
-     && (((REFERENCE_DIR_SEARCH_STATE (index)) -> search_pattern) != 0));
+     && ((REFERENCE_DIR_SEARCH_STATE (index)) -> allocatedp));
 }
 
 unsigned int
 OS_directory_open (const char * search_pattern)
 {
-  unsigned int index = (allocate_dir_search_state (search_pattern));
+  static char pattern [CCHMAXPATH];
+  unsigned int index = (allocate_dir_search_state ());
   dir_search_state * s = (REFERENCE_DIR_SEARCH_STATE (index));
+  strcpy (pattern, search_pattern);
+  {
+    unsigned int len = (strlen (pattern));
+    if ((len > 0) && ((pattern [len - 1]) == '\\'))
+      strcat (pattern, "*");
+    else if (OS_file_directory_p (pattern))
+      strcat (pattern, "\\*");
+  }
   (s -> handle) = HDIR_CREATE;
   (s -> count) = 1;
   XTD_API_CALL
     (dos_find_first,
-     (((char *) (s -> search_pattern)), (& (s -> handle)), FILE_ANY,
-      (& (s -> info)), (sizeof (s -> info)), (& (s -> count)), FIL_STANDARD),
+     (pattern, (& (s -> handle)), FILE_ANY, (& (s -> info)),
+      (sizeof (s -> info)), (& (s -> count)), FIL_STANDARD),
      {
        if (rc == ERROR_NO_MORE_FILES)
         {
index 158432682d296afaef2ad0083459f3799bd09f19..25ab024be731ac73a8c8fefe7be78ee55275d87c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2io.c,v 1.1 1994/11/28 03:42:57 cph Exp $
+$Id: os2io.c,v 1.2 1994/12/19 22:31:30 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -43,7 +43,7 @@ static enum channel_type handle_channel_type (LHANDLE);
 size_t OS_channel_table_size;
 struct channel * OS2_channel_table;
 Tchannel * OS2_channel_pointer_table;
-const int OS_have_select_p = 0;
+const int OS_have_select_p = 1;
 
 void
 OS2_initialize_channels (void)
index 97174f91c1019798b0bb7e0282060749a45fca68..a74d90d05091ebea5f2d32dbe739a4f49934e9e0 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2msg.c,v 1.2 1994/12/02 20:42:46 cph Exp $
+$Id: os2msg.c,v 1.3 1994/12/19 22:31:31 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -41,12 +41,12 @@ static void OS2_initialize_message_lengths (void);
 static void write_subqueue (msg_t *);
 static msg_t * read_subqueue (qid_t);
 static int subqueue_emptyp (qid_t);
-static int read_tqueue (tqueue_t *, int);
+static msg_t * read_tqueue (tqueue_t *, int);
 static void write_tqueue (tqueue_t *, msg_t *);
-static int read_std_tqueue (tqueue_t *, int);
+static msg_t * read_std_tqueue (tqueue_t *, int);
 static void write_std_tqueue (tqueue_t *, msg_t *);
 static tqueue_t * make_scm_tqueue (void);
-static int read_scm_tqueue (tqueue_t *, int);
+static msg_t * read_scm_tqueue (tqueue_t *, int);
 static void write_scm_tqueue (tqueue_t *, msg_t *);
 static void process_interrupt_messages (void);
 \f
@@ -101,7 +101,7 @@ OS2_initialize_message_queues (void)
   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 ());
+  qid_lock = (OS2_create_mutex_semaphore (0, 0));
   OS2_scheme_tqueue = (make_scm_tqueue ());
   OS2_make_qid_pair ((&OS2_interrupt_qid_local), (&OS2_interrupt_qid));
   OS2_open_qid (OS2_interrupt_qid_local, OS2_scheme_tqueue);
@@ -184,6 +184,17 @@ OS2_close_qid (qid_t qid)
   OS2_release_mutex_semaphore (qid_lock);
 }
 
+void
+OS2_close_qid_pair (qid_t qid)
+{
+  if (QID_ALLOCATEDP (qid))
+    {
+      if (((QID_TWIN (qid)) != QID_NONE) && (QID_ALLOCATEDP (QID_TWIN (qid))))
+       OS2_close_qid (QID_TWIN (qid));
+      OS2_close_qid (qid);
+    }
+}
+
 void
 OS2_set_qid_receive_filter (qid_t qid, qid_receive_filter_t filter)
 {
@@ -222,8 +233,6 @@ OS2_set_message_type_length (msg_type_t type, msg_length_t length)
 {
   (MESSAGE_LENGTH (type)) = length;
 }
-\f
-/* Message Transmission and Reception */
 
 msg_t *
 OS2_create_message (msg_type_t type)
@@ -239,7 +248,7 @@ OS2_create_message (msg_type_t type)
       OS2_logic_error ("Unable to allocate memory for error message.");
     else
       OS2_error_system_call (ERROR_NOT_ENOUGH_MEMORY, syscall_malloc);
-  (_MSG_TYPE (message)) = ((unsigned char) type);
+  (MSG_TYPE (message)) = type;
   return (message);
 }
 
@@ -248,6 +257,8 @@ OS2_destroy_message (msg_t * message)
 {
   OS_free ((void *) message);
 }
+\f
+/* Message Transmission and Reception */
 
 void
 OS2_send_message (qid_t qid, msg_t * message)
@@ -261,18 +272,19 @@ OS2_send_message (qid_t qid, msg_t * message)
 }
 
 msg_t *
-OS2_receive_message (qid_t qid, int blockp)
+OS2_receive_message (qid_t qid, int blockp, int interruptp)
 {
   tqueue_t * tqueue = (QID_TQUEUE (qid));
   msg_t * message;
   while (1)
     {
-      while (read_tqueue (tqueue, 0))
+      while ((read_tqueue (tqueue, 0)) != 0)
        ;
       if ((TQUEUE_TYPE (tqueue)) == tqt_scm)
        {
          process_interrupt_messages ();
-         deliver_pending_interrupts ();
+         if (interruptp)
+           deliver_pending_interrupts ();
        }
       message = (read_subqueue (qid));
       if ((!blockp) || (message != 0))
@@ -282,10 +294,51 @@ OS2_receive_message (qid_t qid, int blockp)
   return (message);
 }
 
+msg_avail_t
+OS2_message_availablep (qid_t qid, int blockp)
+{
+  tqueue_t * tqueue = (QID_TQUEUE (qid));
+  while (1)
+    {
+      while ((read_tqueue (tqueue, 0)) != 0)
+       ;
+      if ((TQUEUE_TYPE (tqueue)) == tqt_scm)
+       {
+         process_interrupt_messages ();
+         if (pending_interrupts_p ())
+           return (mat_interrupt);
+       }
+      if (!subqueue_emptyp (qid))
+       return (mat_available);
+      if (!blockp)
+       return (mat_not_available);
+      (void) read_tqueue (tqueue, 1);
+    }
+}
+
+int
+OS2_tqueue_select (tqueue_t * tqueue, int blockp)
+{
+  while (1)
+    {
+      msg_t * message = (read_tqueue (tqueue, blockp));
+      if ((TQUEUE_TYPE (tqueue)) == tqt_scm)
+       {
+         process_interrupt_messages ();
+         if (pending_interrupts_p ())
+           return (-2);
+       }
+      if (message != 0)
+       return (MSG_SENDER (message));
+      if (!blockp)
+       return (-1);
+    }
+}
+
 msg_t *
 OS2_wait_for_message (qid_t qid, msg_type_t reply_type)
 {
-  msg_t * reply = (OS2_receive_message (qid, 1));
+  msg_t * reply = (OS2_receive_message (qid, 1, 0));
   if (OS2_error_message_p (reply))
     OS2_handle_error_message (reply);
   if ((MSG_TYPE (reply)) != reply_type)
@@ -346,7 +399,7 @@ subqueue_emptyp (qid_t qid)
   return ((QID_SUBQUEUE_HEAD (qid)) == 0);
 }
 
-static int
+static msg_t *
 read_tqueue (tqueue_t * tqueue, int blockp)
 {
   switch (TQUEUE_TYPE (tqueue))
@@ -392,7 +445,7 @@ OS2_make_std_tqueue (void)
   tqueue_t * tqueue = (OS_malloc (sizeof (std_tqueue_t)));
   (TQUEUE_TYPE (tqueue)) = tqt_std;
   (STD_TQUEUE_QUEUE (tqueue)) = (OS2_create_queue (QUE_FIFO));
-  (STD_TQUEUE_EVENT (tqueue)) = (OS2_create_event_semaphore ());
+  (STD_TQUEUE_EVENT (tqueue)) = (OS2_create_event_semaphore (0, 0));
   return (tqueue);
 }
 
@@ -404,7 +457,7 @@ OS2_close_std_tqueue (tqueue_t * tqueue)
   OS_free (tqueue);
 }
 
-static int
+static msg_t *
 read_std_tqueue (tqueue_t * tqueue, int blockp)
 {
   ULONG type;
@@ -425,7 +478,7 @@ read_std_tqueue (tqueue_t * tqueue, int blockp)
   if ((type != 0) || (length != (MSG_LENGTH (message))))
     OS2_logic_error (s);
   write_subqueue (message);
-  return (1);
+  return (message);
 }
 
 static void
@@ -446,7 +499,9 @@ make_scm_tqueue (void)
   return (tqueue);
 }
 
-static int
+char OS2_scheme_tqueue_avail_map [QID_MAX + 1];
+
+static msg_t *
 read_scm_tqueue (tqueue_t * tqueue, int blockp)
 {
   /* The handling of the interrupt bit is a little tricky.  We clear
@@ -463,15 +518,19 @@ read_scm_tqueue (tqueue_t * tqueue, int blockp)
      Second, if we arrive at this read-dispatch loop by some means
      other than the attention-interrupt mechanism, this will clear the
      bit and thus avoid ever invoking the mechanism.  */
-  int result = 0;
+  msg_t * result = 0;
   (void) test_and_clear_attention_interrupt ();
   do
-    if (read_std_tqueue (tqueue, blockp))
-      {
-       result = 1;
-       /* At most one message needs to be read in blocking mode.  */
-       blockp = 0;
-      }
+    {
+      msg_t * message = (read_std_tqueue (tqueue, blockp));
+      if (message != 0)
+       {
+         (OS2_scheme_tqueue_avail_map [MSG_SENDER (message)]) = 1;
+         result = message;
+         /* At most one message needs to be read in blocking mode.  */
+         blockp = 0;
+       }
+    }
   while (test_and_clear_attention_interrupt ());
   return (result);
 }
@@ -487,7 +546,7 @@ void
 OS2_handle_attention_interrupt (void)
 {
   tqueue_t * tqueue = (QID_TQUEUE (OS2_interrupt_qid_local));
-  while (read_tqueue (tqueue, 0))
+  while ((read_tqueue (tqueue, 0)) != 0)
     ;
   process_interrupt_messages ();
 }
index c6dbf4636d137b23dbc14a211559ce291d3dc19e..7026d3f885d3583377a02a2c52d1b9b502d6a099 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2msg.h,v 1.2 1994/12/02 20:42:38 cph Exp $
+$Id: os2msg.h,v 1.3 1994/12/19 22:31:34 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -47,15 +47,14 @@ typedef enum
      generated asynchronously whenever the readahead is available.  */
   mt_readahead,
 
-  /* This is sent by the receiver or a readahead message.  It is used
+  /* This is sent by the receiver of 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
+     by the console readahead thread, and causes a Scheme character
      interrupt to be signalled in the interrupt-code register.  */
   mt_console_interrupt,
 
@@ -72,40 +71,45 @@ typedef enum
      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 command the PM thread to perform specific
+     actions.  A command that does not have a specific reply type will
+     receive a generic reply when the PM code is configured to do
+     handshaking; normally such a command has no reply.  */
+  mt_window_open_request,      /* open a window */
+  mt_window_open_reply,
+  mt_window_close,             /* close a window */
+  mt_window_show,              /* show/hide a window */
+  mt_window_write,             /* write chars in a window */
+  mt_window_move_cursor,       /* move a window's text cursor */
+  mt_window_shape_cursor,      /* set the text cursor shape of a window */
+  mt_window_show_cursor,       /* show/hide a window's text cursor */
+  mt_window_clear,             /* clear a window rectangle */
+  mt_window_scroll,            /* scroll a window rectangle */
+  mt_window_invalidate,                /* invalidate a window rectangle */
+  mt_window_set_font_request,  /* change the text font in a window */
+  mt_window_set_font_reply,
+  mt_window_set_grid,          /* set a window's resizing grid */
+  mt_window_activate,          /* activate a window (get the focus) */
+  mt_window_pos_request,       /* request position of window */
+  mt_window_pos_reply,
+  mt_window_set_pos,           /* set position of window */
+  mt_window_size_request,      /* request size of window */
+  mt_window_size_reply,
+  mt_window_set_size,          /* set size of window */
+  mt_window_focusp_request,    /* request focus state of window */
+  mt_window_focusp_reply,
+  mt_window_set_state,         /* raise/lower/hide/min/max/restore window */
+  mt_window_set_colors,                /* set fg/bg colors of window */
 
   /* 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_close_event,              /* window close (user command) */
+  mt_focus_event,              /* window focus change */
+  mt_key_event,                        /* key press */
+  mt_paint_event,              /* window needs painting */
   mt_resize_event,             /* window resized */
+  mt_visibility_event,         /* window visibility change */
 
   /* This requests the thread on the other end of the connection to
      kill itself.  At present this request is not used.  */
@@ -123,12 +127,12 @@ typedef unsigned short msg_length_t;
 #define MSG_LENGTH_MAX USHRT_MAX
 
 /* Fields of message header:
-   type: small integer classifying the type of message
+   type: msg_type_t identifying the type of message
    sender: qid identifying the message sender (used for replies)
    */
 
 #define DECLARE_MSG_HEADER_FIELDS                                      \
-  unsigned char type;                                                  \
+  msg_type_t type;                                                     \
   qid_t sender
 
 typedef struct
@@ -137,8 +141,7 @@ typedef struct
 } msg_t;
 
 #define _MSG(m) ((msg_t *) (m))
-#define _MSG_TYPE(m) ((_MSG (m)) -> type)
-#define MSG_TYPE(m) ((msg_type_t) (_MSG_TYPE (m)))
+#define MSG_TYPE(m) ((_MSG (m)) -> type)
 #define MSG_SENDER(m) ((_MSG (m)) -> sender)
 
 typedef enum
@@ -156,20 +159,26 @@ typedef struct
 
 typedef msg_t * (* qid_receive_filter_t) (msg_t *);
 
+typedef enum { mat_not_available, mat_available, mat_interrupt } msg_avail_t;
+
 extern tqueue_t * OS2_scheme_tqueue;
 extern qid_t OS2_interrupt_qid;
+extern char OS2_scheme_tqueue_avail_map [QID_MAX + 1];
 
 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_close_qid_pair (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_receive_message (qid_t, int, int);
+extern msg_avail_t OS2_message_availablep (qid_t, int);
+extern int OS2_tqueue_select (tqueue_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);
index b27696bc9d5b22115bba1b7deb039360dd13887c..c44fb40125cfb22f01d985c4b406e35ead8c2aeb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2pm.c,v 1.1 1994/12/02 20:44:26 cph Exp $
+$Id: os2pm.c,v 1.2 1994/12/19 22:31:36 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -41,42 +41,42 @@ typedef struct
   HWND frame;                  /* frame window handle */
   HWND client;                 /* client window handle */
   HPS hps;                     /* presentation space for client window */
-  unsigned short char_width;   /* char width (max increment) */
-  unsigned short char_ascender;        /* char ascender (max height above base) */
-  unsigned short char_descender; /* char descender (max height below base) */
-  unsigned short width;                /* width in characters */
-  unsigned short height;       /* height in characters */
-  char * charmap;              /* character array */
+  unsigned short grid_x;       /* x dimension of resizing grid */
+  unsigned short grid_y;       /* y dimension of resizing grid */
   unsigned short cursor_x;     /* x coordinate of the cursor */
   unsigned short cursor_y;     /* y coordinate of the cursor */
+  unsigned short cursor_width; /* width of the cursor */
+  unsigned short cursor_height;        /* height of the cursor */
+  unsigned short cursor_style; /* style of the cursor */
+  qid_t qid;                   /* qid to send commands to */
   qid_t event_qid;             /* qid to send input events to */
-  twid_t twid;                 /* twid for this twindow */
+  wid_t wid;                   /* wid for this window */
+  COLOR foreground_color;
+  COLOR background_color;
   unsigned int cursor_shownp : 1; /* nonzero if cursor is visible */
   unsigned int minimizingp : 1; /* nonzero if window being minimized */
   unsigned int minimizedp : 1; /* nonzero if window is minimized */
-} twindow_t;
-#define TWINDOW_FRAME(twindow) ((twindow) -> frame)
-#define TWINDOW_CLIENT(twindow) ((twindow) -> client)
-#define TWINDOW_HPS(twindow) ((twindow) -> hps)
-#define TWINDOW_CHAR_WIDTH(twindow) ((twindow) -> char_width)
-#define TWINDOW_CHAR_ASCENDER(twindow) ((twindow) -> char_ascender)
-#define TWINDOW_CHAR_DESCENDER(twindow) ((twindow) -> char_descender)
-#define TWINDOW_WIDTH(twindow) ((twindow) -> width)
-#define TWINDOW_HEIGHT(twindow) ((twindow) -> height)
-#define TWINDOW_CHARMAP(twindow) ((twindow) -> charmap)
-#define TWINDOW_CURSOR_X(twindow) ((twindow) -> cursor_x)
-#define TWINDOW_CURSOR_Y(twindow) ((twindow) -> cursor_y)
-#define TWINDOW_CURSOR_SHOWNP(twindow) ((twindow) -> cursor_shownp)
-#define TWINDOW_EVENT_QID(twindow) ((twindow) -> event_qid)
-#define TWINDOW_TWID(twindow) ((twindow) -> twid)
-#define TWINDOW_MINIMIZINGP(twindow) ((twindow) -> minimizingp)
-#define TWINDOW_MINIMIZEDP(twindow) ((twindow) -> minimizedp)
-
-#define TWINDOW_CHAR_HEIGHT(twindow)                                   \
-  ((TWINDOW_CHAR_ASCENDER (twindow)) + (TWINDOW_CHAR_DESCENDER (twindow)))
-
-#define TWINDOW_CHAR_LOC(twindow, x, y)                                        \
-  (& ((TWINDOW_CHARMAP (twindow)) [((y) * (TWINDOW_WIDTH (twindow))) + (x)]))
+  unsigned int permanentp : 1; /* nonzero means don't close on reload */
+} window_t;
+#define WINDOW_FRAME(window) ((window) -> frame)
+#define WINDOW_CLIENT(window) ((window) -> client)
+#define WINDOW_HPS(window) ((window) -> hps)
+#define WINDOW_GRID_X(window) ((window) -> grid_x)
+#define WINDOW_GRID_Y(window) ((window) -> grid_y)
+#define WINDOW_CURSOR_X(window) ((window) -> cursor_x)
+#define WINDOW_CURSOR_Y(window) ((window) -> cursor_y)
+#define WINDOW_CURSOR_WIDTH(window) ((window) -> cursor_width)
+#define WINDOW_CURSOR_HEIGHT(window) ((window) -> cursor_height)
+#define WINDOW_CURSOR_STYLE(window) ((window) -> cursor_style)
+#define WINDOW_QID(window) ((window) -> qid)
+#define WINDOW_EVENT_QID(window) ((window) -> event_qid)
+#define WINDOW_WID(window) ((window) -> wid)
+#define WINDOW_FOREGROUND_COLOR(window) ((window) -> foreground_color)
+#define WINDOW_BACKGROUND_COLOR(window) ((window) -> background_color)
+#define WINDOW_CURSOR_SHOWNP(window) ((window) -> cursor_shownp)
+#define WINDOW_MINIMIZINGP(window) ((window) -> minimizingp)
+#define WINDOW_MINIMIZEDP(window) ((window) -> minimizedp)
+#define WINDOW_PERMANENTP(window) ((window) -> permanentp)
 
 typedef struct
 {
@@ -85,135 +85,339 @@ typedef struct
 } pm_tqueue_t;
 #define PM_TQUEUE_HWND(q) (((pm_tqueue_t *) (q)) -> hwnd)
 \f
-static void simple_transaction (qid_t, msg_t *);
-static void simple_reply (qid_t);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  qid_t qid;
+  qid_t event_qid;
+  const char * title;
+} sm_open_request_t;
+#define SM_OPEN_REQUEST_QID(m) (((sm_open_request_t *) (m)) -> qid)
+#define SM_OPEN_REQUEST_EVENT_QID(m) (((sm_open_request_t *) (m)) -> event_qid)
+#define SM_OPEN_REQUEST_TITLE(m) (((sm_open_request_t *) (m)) -> title)
 
-static void pm_thread_procedure (void *);
-static tqueue_t * make_pm_tqueue (HWND);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  wid_t wid;
+} sm_open_reply_t;
+#define SM_OPEN_REPLY_WID(m) (((sm_open_reply_t *) (m)) -> wid)
 
-static unsigned short cx2x (twindow_t *, unsigned short);
-static unsigned short cy2y (twindow_t *, unsigned short, int);
-static unsigned short x2cx (twindow_t *, unsigned short, int);
-static unsigned short y2cy (twindow_t *, unsigned short, int);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+} sm_close_t;
+#define SM_CLOSE_WINDOW(m) (((sm_close_t *) (m)) -> window)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  char showp;
+} sm_show_t;
+#define SM_SHOW_WINDOW(m) (((sm_show_t *) (m)) -> window)
+#define SM_SHOW_SHOWP(m) (((sm_show_t *) (m)) -> showp)
 
-static void initialize_twid_table (void);
-static twid_t allocate_twid (twindow_t *);
-static void deallocate_twid (twid_t);
-static twindow_t * twid_to_twindow (twid_t);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short x;
+  unsigned short y;
+  unsigned short size;
+  const char * data;
+} sm_write_t;
+#define SM_WRITE_WINDOW(m) (((sm_write_t *) (m)) -> window)
+#define SM_WRITE_X(m) (((sm_write_t *) (m)) -> x)
+#define SM_WRITE_Y(m) (((sm_write_t *) (m)) -> y)
+#define SM_WRITE_SIZE(m) (((sm_write_t *) (m)) -> size)
+#define SM_WRITE_DATA(m) (((sm_write_t *) (m)) -> data)
 
-static MRESULT EXPENTRY object_window_procedure (HWND, ULONG, MPARAM, MPARAM);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short x;
+  unsigned short y;
+} sm_move_cursor_t;
+#define SM_MOVE_CURSOR_WINDOW(m) (((sm_move_cursor_t *) (m)) -> window)
+#define SM_MOVE_CURSOR_X(m) (((sm_move_cursor_t *) (m)) -> x)
+#define SM_MOVE_CURSOR_Y(m) (((sm_move_cursor_t *) (m)) -> y)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short width;
+  unsigned short height;
+  unsigned short style;
+} sm_shape_cursor_t;
+#define SM_SHAPE_CURSOR_WINDOW(m) (((sm_shape_cursor_t *) (m)) -> window)
+#define SM_SHAPE_CURSOR_WIDTH(m) (((sm_shape_cursor_t *) (m)) -> width)
+#define SM_SHAPE_CURSOR_HEIGHT(m) (((sm_shape_cursor_t *) (m)) -> height)
+#define SM_SHAPE_CURSOR_STYLE(m) (((sm_shape_cursor_t *) (m)) -> style)
 
-static msg_t * make_twindow_open_request (qid_t, const char *);
-static void handle_twindow_open_request (msg_t *);
-static msg_t * make_twindow_open_reply (twid_t);
-
-static msg_t * make_twindow_close_request (twid_t);
-static void handle_twindow_close_request (msg_t *);
-
-static msg_t * make_twindow_write_request
-  (twid_t, unsigned short, unsigned short, const char *, unsigned short);
-static void handle_twindow_write_request (msg_t *);
-
-static msg_t * make_twindow_move_cursor_request
-  (twid_t, unsigned short, unsigned short);
-static void handle_twindow_move_cursor_request (msg_t *);
-
-static void handle_twindow_clear_request (msg_t *);
-static msg_t * make_twindow_clear_request (twid_t);
-
-static msg_t * make_twindow_clear_eol_request
-  (twid_t, unsigned short, unsigned short);
-static void handle_twindow_clear_eol_request (msg_t *);
-
-static msg_t * make_twindow_scroll_request
-  (twid_t, unsigned short, unsigned short, unsigned short, unsigned short,
-   short, short);
-static void handle_twindow_scroll_request (msg_t *);
-
-static twindow_t * twindow_open (qid_t, const char *);
-static twindow_t * make_twindow (qid_t);
-static void twindow_close (twindow_t *);
-static msg_t * make_close_event (twid_t);
-static void twindow_write
-  (twindow_t *, unsigned short, unsigned short, const char *, unsigned short);
-static void twindow_clear (twindow_t *);
-static void twindow_clear_eol (twindow_t *, unsigned short, unsigned short);
-static void invalidate_partial_line
-  (twindow_t *, unsigned short, unsigned short, unsigned short);
-static void twindow_scroll
-  (twindow_t *, unsigned short, unsigned short, unsigned short, unsigned short,
-   short, short);
-static void twindow_move_cursor (twindow_t *, unsigned short, unsigned short);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  char showp;
+} sm_show_cursor_t;
+#define SM_SHOW_CURSOR_WINDOW(m) (((sm_show_cursor_t *) (m)) -> window)
+#define SM_SHOW_CURSOR_SHOWP(m) (((sm_show_cursor_t *) (m)) -> showp)
 
-static MRESULT EXPENTRY frame_window_procedure (HWND, ULONG, MPARAM, MPARAM);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short xl;
+  unsigned short xh;
+  unsigned short yl;
+  unsigned short yh;
+} sm_clear_t;
+#define SM_CLEAR_WINDOW(m) (((sm_clear_t *) (m)) -> window)
+#define SM_CLEAR_XL(m) (((sm_clear_t *) (m)) -> xl)
+#define SM_CLEAR_XH(m) (((sm_clear_t *) (m)) -> xh)
+#define SM_CLEAR_YL(m) (((sm_clear_t *) (m)) -> yl)
+#define SM_CLEAR_YH(m) (((sm_clear_t *) (m)) -> yh)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short xl;
+  unsigned short xh;
+  unsigned short yl;
+  unsigned short yh;
+  short x_delta;
+  short y_delta;
+} sm_scroll_t;
+#define SM_SCROLL_WINDOW(m) (((sm_scroll_t *) (m)) -> window)
+#define SM_SCROLL_XL(m) (((sm_scroll_t *) (m)) -> xl)
+#define SM_SCROLL_XH(m) (((sm_scroll_t *) (m)) -> xh)
+#define SM_SCROLL_YL(m) (((sm_scroll_t *) (m)) -> yl)
+#define SM_SCROLL_YH(m) (((sm_scroll_t *) (m)) -> yh)
+#define SM_SCROLL_X_DELTA(m) (((sm_scroll_t *) (m)) -> x_delta)
+#define SM_SCROLL_Y_DELTA(m) (((sm_scroll_t *) (m)) -> y_delta)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short xl;
+  unsigned short xh;
+  unsigned short yl;
+  unsigned short yh;
+} sm_invalidate_t;
+#define SM_INVALIDATE_WINDOW(m) (((sm_invalidate_t *) (m)) -> window)
+#define SM_INVALIDATE_XL(m) (((sm_invalidate_t *) (m)) -> xl)
+#define SM_INVALIDATE_XH(m) (((sm_invalidate_t *) (m)) -> xh)
+#define SM_INVALIDATE_YL(m) (((sm_invalidate_t *) (m)) -> yl)
+#define SM_INVALIDATE_YH(m) (((sm_invalidate_t *) (m)) -> yh)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short id;
+  const char * spec;
+} sm_set_font_request_t;
+#define SM_SET_FONT_REQUEST_WINDOW(m)                                  \
+  (((sm_set_font_request_t *) (m)) -> window)
+#define SM_SET_FONT_REQUEST_ID(m) (((sm_set_font_request_t *) (m)) -> id)
+#define SM_SET_FONT_REQUEST_SPEC(m) (((sm_set_font_request_t *) (m)) -> spec)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  font_metrics_t * metrics;
+} sm_set_font_reply_t;
+#define SM_SET_FONT_REPLY_WINDOW(m) (((sm_set_font_reply_t *) (m)) -> window)
+#define SM_SET_FONT_REPLY_METRICS(m) (((sm_set_font_reply_t *) (m)) -> metrics)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short x;
+  unsigned short y;
+} sm_set_grid_t;
+#define SM_SET_GRID_WINDOW(m) (((sm_set_grid_t *) (m)) -> window)
+#define SM_SET_GRID_X(m) (((sm_set_grid_t *) (m)) -> x)
+#define SM_SET_GRID_Y(m) (((sm_set_grid_t *) (m)) -> y)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+} sm_activate_t;
+#define SM_ACTIVATE_WINDOW(m) (((sm_activate_t *) (m)) -> window)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+} sm_pos_request_t;
+#define SM_POS_REQUEST_WINDOW(m) (((sm_pos_request_t *) (m)) -> window)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  unsigned short x;
+  unsigned short y;
+} sm_pos_reply_t;
+#define SM_POS_REPLY_X(m) (((sm_pos_reply_t *) (m)) -> x)
+#define SM_POS_REPLY_Y(m) (((sm_pos_reply_t *) (m)) -> y)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short x;
+  unsigned short y;
+} sm_set_pos_t;
+#define SM_SET_POS_WINDOW(m) (((sm_set_pos_t *) (m)) -> window)
+#define SM_SET_POS_X(m) (((sm_set_pos_t *) (m)) -> x)
+#define SM_SET_POS_Y(m) (((sm_set_pos_t *) (m)) -> y)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+} sm_size_request_t;
+#define SM_SIZE_REQUEST_WINDOW(m) (((sm_size_request_t *) (m)) -> window)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  unsigned short width;
+  unsigned short height;
+} sm_size_reply_t;
+#define SM_SIZE_REPLY_WIDTH(m) (((sm_size_reply_t *) (m)) -> width)
+#define SM_SIZE_REPLY_HEIGHT(m) (((sm_size_reply_t *) (m)) -> height)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  unsigned short width;
+  unsigned short height;
+} sm_set_size_t;
+#define SM_SET_SIZE_WINDOW(m) (((sm_set_size_t *) (m)) -> window)
+#define SM_SET_SIZE_WIDTH(m) (((sm_set_size_t *) (m)) -> width)
+#define SM_SET_SIZE_HEIGHT(m) (((sm_set_size_t *) (m)) -> height)
+
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+} sm_focusp_request_t;
+#define SM_FOCUSP_REQUEST_WINDOW(m) (((sm_focusp_request_t *) (m)) -> window)
 
-static MRESULT EXPENTRY twindow_procedure (HWND, ULONG, MPARAM, MPARAM);
-static twindow_t * hwnd_to_twindow (HWND);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  char focusp;
+} sm_focusp_reply_t;
+#define SM_FOCUSP_REPLY_FOCUSP(m) (((sm_focusp_reply_t *) (m)) -> focusp)
 
-static void twindow_initialize (twindow_t *);
-static void initialize_default_font (twindow_t *, PSZ, LONG, LONG);
-static void initialize_attributes (twindow_t *);
-static void set_twindow_char_dimensions (twindow_t *);
-static void initialize_charmap (twindow_t *);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  window_state_t state;
+} sm_set_state_t;
+#define SM_SET_STATE_WINDOW(m) (((sm_set_state_t *) (m)) -> window)
+#define SM_SET_STATE_STATE(m) (((sm_set_state_t *) (m)) -> state)
 
-static int set_font_1 (HPS, PSZ, LONG, LONG);
-static int use_font (HPS, PFONTMETRICS, LONG);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  window_t * window;
+  COLOR foreground;
+  COLOR background;
+} sm_set_colors_t;
+#define SM_SET_COLORS_WINDOW(m) (((sm_set_colors_t *) (m)) -> window)
+#define SM_SET_COLORS_FOREGROUND(m) (((sm_set_colors_t *) (m)) -> foreground)
+#define SM_SET_COLORS_BACKGROUND(m) (((sm_set_colors_t *) (m)) -> background)
+\f
+static void simple_transaction (qid_t, msg_t *);
+static void simple_reply (qid_t);
 
-static void twindow_paint (twindow_t *);
-static void draw_partial_line
-  (twindow_t *, unsigned short, unsigned short, unsigned short);
-static void activate_cursor (twindow_t *);
-static void deactivate_cursor (twindow_t *);
-static void show_cursor (twindow_t *);
-static void hide_cursor (twindow_t *);
-static int twindow_focusp (twindow_t *);
+static void pm_thread_procedure (void *);
+static tqueue_t * make_pm_tqueue (HWND);
 
-static void twindow_resize (twindow_t *, unsigned short, unsigned short);
-static msg_t * make_resize_event (twid_t, unsigned short, unsigned short);
+static void initialize_wid_table (void);
+static wid_t allocate_wid (window_t *);
+static void deallocate_wid (wid_t);
+static window_t * wid_to_window (wid_t);
+static void close_all_windows (void);
 
-static int twindow_process_keychar
-  (twindow_t *, unsigned short, unsigned char, unsigned char, unsigned short,
+static MRESULT EXPENTRY object_window_procedure (HWND, ULONG, MPARAM, MPARAM);
+static MRESULT EXPENTRY frame_window_procedure (HWND, ULONG, MPARAM, MPARAM);
+static MRESULT EXPENTRY window_procedure (HWND, ULONG, MPARAM, MPARAM);
+
+static wid_t open_window (qid_t, qid_t, const char *);
+static window_t * hwnd_to_window (HWND);
+static void close_window (window_t *);
+static void show_window (window_t *, int);
+static void move_cursor (window_t *, unsigned short, unsigned short);
+static void shape_cursor
+  (window_t *, unsigned short, unsigned short, unsigned short);
+static void show_cursor (window_t *, int);
+static void recreate_cursor (window_t *);
+static void activate_cursor (window_t *);
+static void deactivate_cursor (window_t *);
+static void clear_rectangle (window_t *, PRECTL);
+static font_metrics_t * set_font (window_t *, unsigned short, const char *);
+static void get_window_pos (window_t *, unsigned short *, unsigned short *);
+static void set_window_pos (window_t *, unsigned short, unsigned short);
+static void get_window_size (window_t *, unsigned short *, unsigned short *);
+static void set_window_size (window_t *, unsigned short, unsigned short);
+static int window_focusp (window_t *);
+static void set_window_state (window_t *, window_state_t);
+static void set_window_colors (window_t *, COLOR, COLOR);
+
+static msg_t * make_button_event
+  (wid_t, unsigned char, unsigned char, unsigned short, unsigned short,
    unsigned short);
-static void send_key_event
-  (twindow_t *, unsigned short, unsigned short, unsigned short);
+static msg_t * make_close_event (wid_t);
+static msg_t * make_focus_event (wid_t, int);
 static msg_t * make_key_event
-  (twid_t, unsigned short, unsigned short, unsigned short);
+  (wid_t, unsigned short, unsigned short, unsigned short);
+static msg_t * make_paint_event
+  (wid_t, unsigned short, unsigned short, unsigned short, unsigned short);
+static msg_t * make_resize_event (wid_t, unsigned short, unsigned short);
+static msg_t * make_visibility_event (wid_t, int);
 \f
 #define ID_RESOURCES 1
 #define ID_FRAME 1
 
 #define UWM_ENCAPSULATION WM_USER
 
-#define QWP_TWINDOW QWL_USER
+#define QWP_WINDOW QWL_USER
 
 /* These should have been defined by PM header file.  */
 #define MRVOID MRFROMP (0)
 #define MRTRUE MRFROMLONG (TRUE)
 #define MRFALSE MRFROMLONG (FALSE)
 
-static qid_t pm_qid_local;     /* PM thread side */
-static qid_t pm_qid_remote;    /* other thread side */
+static qid_t pm_init_qid;
 static TID pm_tid;
 static HAB pm_hab;
 static HMQ pm_hmq;
 static HWND pm_object_window;
+static tqueue_t * pm_tqueue;
 static PFNWP original_frame_window_procedure;
 
 static const char object_class [] = "mit-scheme.object";
-static const char twindow_class [] = "mit-scheme.twindow";
-
-#define SEND_EVENT(twindow, message)                                   \
-{                                                                      \
-  if ((TWINDOW_EVENT_QID (twindow)) != QID_NONE)                       \
-    OS2_send_message ((TWINDOW_EVENT_QID (twindow)), (message));       \
-}
+static const char window_class [] = "mit-scheme.window";
 
-#define FASTFILL(p, n, c)                                              \
+#define SEND_EVENT(window, message)                                    \
 {                                                                      \
-  char * FASTFILL_scan = (p);                                          \
-  char * FASTFILL_end = (FASTFILL_scan + (n));                         \
-  while (FASTFILL_scan < FASTFILL_end)                                 \
-    (*FASTFILL_scan++) = (c);                                          \
+  if ((WINDOW_EVENT_QID (window)) != QID_NONE)                         \
+    OS2_send_message ((WINDOW_EVENT_QID (window)), (message));         \
 }
 
 #define window_error(name) OS2_logic_error (#name)
@@ -221,43 +425,77 @@ static const char twindow_class [] = "mit-scheme.twindow";
 void
 OS2_initialize_pm_thread (void)
 {
-  SET_MSG_TYPE_LENGTH (mt_twindow_open_request, sm_twindow_open_request_t);
-  SET_MSG_TYPE_LENGTH (mt_twindow_open_reply, sm_twindow_open_reply_t);
-  SET_MSG_TYPE_LENGTH (mt_twindow_close_request, sm_twindow_close_request_t);
-  SET_MSG_TYPE_LENGTH (mt_twindow_write_request, sm_twindow_write_request_t);
-  SET_MSG_TYPE_LENGTH (mt_twindow_move_cursor_request,
-                      sm_twindow_move_cursor_request_t);
-  SET_MSG_TYPE_LENGTH (mt_twindow_clear_request, sm_twindow_clear_request_t);
-  SET_MSG_TYPE_LENGTH (mt_twindow_clear_eol_request,
-                      sm_twindow_clear_eol_request_t);
-  SET_MSG_TYPE_LENGTH (mt_twindow_scroll_request, sm_twindow_scroll_request_t);
-  SET_MSG_TYPE_LENGTH (mt_key_event, sm_key_event_t);
+  SET_MSG_TYPE_LENGTH (mt_window_open_request, sm_open_request_t);
+  SET_MSG_TYPE_LENGTH (mt_window_open_reply, sm_open_reply_t);
+  SET_MSG_TYPE_LENGTH (mt_window_close, sm_close_t);
+  SET_MSG_TYPE_LENGTH (mt_window_show, sm_show_t);
+  SET_MSG_TYPE_LENGTH (mt_window_write, sm_write_t);
+  SET_MSG_TYPE_LENGTH (mt_window_move_cursor, sm_move_cursor_t);
+  SET_MSG_TYPE_LENGTH (mt_window_shape_cursor, sm_shape_cursor_t);
+  SET_MSG_TYPE_LENGTH (mt_window_show_cursor, sm_show_cursor_t);
+  SET_MSG_TYPE_LENGTH (mt_window_clear, sm_clear_t);
+  SET_MSG_TYPE_LENGTH (mt_window_scroll, sm_scroll_t);
+  SET_MSG_TYPE_LENGTH (mt_window_invalidate, sm_invalidate_t);
+  SET_MSG_TYPE_LENGTH (mt_window_set_font_request, sm_set_font_request_t);
+  SET_MSG_TYPE_LENGTH (mt_window_set_font_reply, sm_set_font_reply_t);
+  SET_MSG_TYPE_LENGTH (mt_window_set_grid, sm_set_grid_t);
+  SET_MSG_TYPE_LENGTH (mt_window_activate, sm_activate_t);
+  SET_MSG_TYPE_LENGTH (mt_window_pos_request, sm_pos_request_t);
+  SET_MSG_TYPE_LENGTH (mt_window_pos_reply, sm_pos_reply_t);
+  SET_MSG_TYPE_LENGTH (mt_window_set_pos, sm_set_pos_t);
+  SET_MSG_TYPE_LENGTH (mt_window_size_request, sm_size_request_t);
+  SET_MSG_TYPE_LENGTH (mt_window_size_reply, sm_size_reply_t);
+  SET_MSG_TYPE_LENGTH (mt_window_set_size, sm_set_size_t);
+  SET_MSG_TYPE_LENGTH (mt_window_focusp_request, sm_focusp_request_t);
+  SET_MSG_TYPE_LENGTH (mt_window_focusp_reply, sm_focusp_reply_t);
+  SET_MSG_TYPE_LENGTH (mt_window_set_state, sm_set_state_t);
+  SET_MSG_TYPE_LENGTH (mt_window_set_colors, sm_set_colors_t);
   SET_MSG_TYPE_LENGTH (mt_button_event, sm_button_event_t);
   SET_MSG_TYPE_LENGTH (mt_close_event, sm_close_event_t);
-  SET_MSG_TYPE_LENGTH (mt_visibility_event, sm_visibility_event_t);
+  SET_MSG_TYPE_LENGTH (mt_focus_event, sm_focus_event_t);
+  SET_MSG_TYPE_LENGTH (mt_key_event, sm_key_event_t);
+  SET_MSG_TYPE_LENGTH (mt_paint_event, sm_paint_event_t);
   SET_MSG_TYPE_LENGTH (mt_resize_event, sm_resize_event_t);
-  initialize_twid_table ();
+  SET_MSG_TYPE_LENGTH (mt_visibility_event, sm_visibility_event_t);
+  initialize_wid_table ();
   original_frame_window_procedure = 0;
-  OS2_make_qid_pair ((&pm_qid_local), (&pm_qid_remote));
-  OS2_open_qid (pm_qid_remote, OS2_scheme_tqueue);
-  pm_tid = (OS2_beginthread (pm_thread_procedure, 0, 0x4000));
-  /* Wait for init message from PM thread.  This message tells us that
-     the other end of the connection is established and that it is
-     safe to send messages on the connection.  */
-  OS2_destroy_message (OS2_wait_for_message (pm_qid_remote, mt_init));
+  {
+    qid_t qid;
+    OS2_make_qid_pair ((&pm_init_qid), (&qid));
+    OS2_open_qid (qid, OS2_scheme_tqueue);
+    pm_tid = (OS2_beginthread (pm_thread_procedure, 0, 0x4000));
+    /* Wait for init message from PM thread.  This message tells us
+       that the other end of the connection is established and that it
+       is safe to send messages on the connection.  */
+    OS2_destroy_message (OS2_wait_for_message (qid, mt_init));
+    OS2_close_qid (qid);
+  }
+  add_reload_cleanup (close_all_windows);
 }
 
+/* Define this to cause a calling thread to wait for the PM thread to
+   finish requests that have trivial replies.  Otherwise, the calling
+   thread waits only when the request has a non-trivial reply.
+   Usually there is no good reason to wait for trivial replies.  */
+/* #define WAIT_FOR_ACTIONS */
+
 static void
 simple_transaction (qid_t qid, msg_t * message)
 {
+#ifdef WAIT_FOR_ACTIONS
   OS2_destroy_message
     (OS2_message_transaction (qid, message, mt_generic_reply));
+#else
+  OS2_send_message (qid, message);
+#endif
 }
 
 static void
 simple_reply (qid_t qid)
 {
+#ifdef WAIT_FOR_ACTIONS
   OS2_send_message (qid, (OS2_create_message (mt_generic_reply)));
+#endif
 }
 \f
 static void
@@ -265,12 +503,12 @@ pm_thread_procedure (void * arg)
 {
   QMSG qmsg;
 
-  if ((OS2_thread_initialize (pm_qid_local)) != 0)
+  if ((OS2_thread_initialize (QID_NONE)) != 0)
     OS2_logic_error ("Error signalled within PM thread.");
   pm_hab = (WinInitialize (0));
   if (pm_hab == NULLHANDLE)
     window_error (WinInitialize);
-  pm_hmq = (WinCreateMsgQueue (pm_hab, 0));
+  pm_hmq = (WinCreateMsgQueue (pm_hab, 1000));
   if (pm_hmq == NULLHANDLE)
     window_error (WinCreateMsgQueue);
   if (!WinRegisterClass (pm_hab,
@@ -280,8 +518,8 @@ pm_thread_procedure (void * arg)
                         0))
     window_error (WinRegisterClass);
   if (!WinRegisterClass (pm_hab,
-                        ((PSZ) twindow_class),
-                        twindow_procedure,
+                        ((PSZ) window_class),
+                        window_procedure,
                         0,     /* class style */
                         (sizeof (void *))))
     window_error (WinRegisterClass);
@@ -299,8 +537,8 @@ pm_thread_procedure (void * arg)
                        ));
   if (pm_object_window == NULLHANDLE)
     window_error (WinCreateWindow);
-  OS2_open_qid (pm_qid_local, (make_pm_tqueue (pm_object_window)));
-  OS2_send_message (pm_qid_local, (OS2_create_message (mt_init)));
+  pm_tqueue = (make_pm_tqueue (pm_object_window));
+  OS2_send_message (pm_init_qid, (OS2_create_message (mt_init)));
   while (WinGetMsg (pm_hab, (&qmsg), 0, 0, 0))
     WinDispatchMsg (pm_hab, (&qmsg));
   if (!WinDestroyWindow (pm_object_window))
@@ -308,7 +546,7 @@ pm_thread_procedure (void * arg)
   WinDestroyMsgQueue (pm_hmq);
   WinTerminate (pm_hab);
 }
-\f
+
 static tqueue_t *
 make_pm_tqueue (HWND hwnd)
 {
@@ -318,7 +556,7 @@ make_pm_tqueue (HWND hwnd)
   return (tqueue);
 }
 
-int
+msg_t *
 OS2_read_pm_tqueue (tqueue_t * tqueue, int blockp)
 {
   OS2_logic_error ("Read from PM tqueue.");
@@ -334,116 +572,110 @@ OS2_write_pm_tqueue (tqueue_t * tqueue, msg_t * message)
                   MPVOID))
     window_error (WinPostMsg);
 }
-
-static unsigned short
-cx2x (twindow_t * twindow, unsigned short x)
-{
-  return (x * (TWINDOW_CHAR_WIDTH (twindow)));
-}
-
-static unsigned short
-cy2y (twindow_t * twindow, unsigned short y, int lowerp)
-{
-  /* lowerp => result is bottommost pel of cell.  Otherwise result is
-     bottommost pel of cell above.  */
-  unsigned short height = (TWINDOW_HEIGHT (twindow));
-  unsigned short limit = (lowerp ? (height - 1) : height);
-  return (((y <= limit) ? (limit - y) : 0) * (TWINDOW_CHAR_HEIGHT (twindow)));
-}
-
-static unsigned short
-x2cx (twindow_t * twindow, unsigned short x, int lowerp)
-{
-  /* lowerp => `x' is inclusive lower bound, and result is cell it
-     falls in.  Otherwise, `x' is exclusive upper bound, and result is
-     cell to its right, unless it falls on leftmost edge of cell.  If
-     the argument is inclusive-lower, then the result is also;
-     likewise for exclusive-upper.  */
-  unsigned short cwidth = (TWINDOW_CHAR_WIDTH (twindow));
-  unsigned short cx = (x / cwidth);
-  return ((lowerp || ((x % cwidth) == 0)) ? cx : (cx + 1));
-}
-
-static unsigned short
-y2cy (twindow_t * twindow, unsigned short y, int lowerp)
-{
-  /* lowerp => `y' is inclusive lower bound, and result is cell below
-     the one it falls in.  Otherwise, `y' is exclusive upper bound,
-     and result is cell it falls in, unless it falls on bottommost
-     edge of cell, when result is cell below.  If the argument is
-     inclusive-lower, then the result is exclusive-upper, and
-     vice-versa.  */
-  unsigned short cheight = (TWINDOW_CHAR_HEIGHT (twindow));
-  short height = (TWINDOW_HEIGHT (twindow));
-  short cy = ((height - 1) - ((short) (y / cheight)));
-  if (lowerp || ((y % cheight) == 0))
-    cy += 1;
-  return ((cy < 0) ? 0 : cy);
-}
 \f
-static unsigned int twid_table_length;
-static twindow_t ** twid_table;
+static unsigned int wid_table_length;
+static window_t ** wid_table;
 
 static void
-initialize_twid_table (void)
+initialize_wid_table (void)
 {
-  twid_table_length = 16;
-  twid_table = (OS_malloc ((sizeof (twindow_t *)) * twid_table_length));
+  wid_table_length = 16;
+  wid_table = (OS_malloc ((sizeof (window_t *)) * wid_table_length));
   {
-    twindow_t ** scan = twid_table;
-    twindow_t ** end = (scan + twid_table_length);
+    window_t ** scan = wid_table;
+    window_t ** end = (scan + wid_table_length);
     while (scan < end)
       (*scan++) = 0;
   }
 }
 
-static twid_t
-allocate_twid (twindow_t * twindow)
+static wid_t
+allocate_wid (window_t * window)
 {
-  twid_t twid = 0;
+  wid_t wid = 0;
   while (1)
     {
-      if (twid == twid_table_length)
+      if (wid == wid_table_length)
        {
-         twid_table_length *= 2;
-         twid_table
-           = (OS_realloc (twid_table,
-                          ((sizeof (twindow_t *)) * twid_table_length)));
+         wid_table_length *= 2;
+         wid_table
+           = (OS_realloc (wid_table,
+                          ((sizeof (window_t *)) * wid_table_length)));
          {
-           twindow_t ** scan = (twid_table + twid + 1);
-           twindow_t ** end = (twid_table + twid_table_length);
+           window_t ** scan = (wid_table + wid + 1);
+           window_t ** end = (wid_table + wid_table_length);
            while (scan < end)
              (*scan++) = 0;
          }
          break;
        }
-      if ((twid_table [twid]) == 0)
+      if ((wid_table [wid]) == 0)
        break;
-      twid += 1;
+      wid += 1;
     }
-  (twid_table [twid]) = twindow;
-  (TWINDOW_TWID (twindow)) = twid;
-  return (twid);
+  (wid_table [wid]) = window;
+  (WINDOW_WID (window)) = wid;
+  return (wid);
 }
 
 static void
-deallocate_twid (twid_t twid)
+deallocate_wid (wid_t wid)
 {
-  (twid_table [twid]) = 0;
+  (wid_table [wid]) = 0;
 }
 
-static twindow_t *
-twid_to_twindow (twid_t twid)
+static window_t *
+wid_to_window (wid_t wid)
 {
-  if ((twid_table [twid]) == 0)
+  if ((wid_table [wid]) == 0)
     OS2_logic_error ("Invalid terminal window ID.");
-  return (twid_table [twid]);
+  return (wid_table [wid]);
+}
+
+int
+OS2_wid_validp (wid_t wid)
+{
+  return ((wid < wid_table_length) && ((wid_table [wid]) != 0));
+}
+
+static void
+close_all_windows (void)
+{
+  window_t ** scan = wid_table;
+  window_t ** end = (scan + wid_table_length);
+  while (scan < end)
+    {
+      window_t * window = (*scan++);
+      if ((window != 0) && (!WINDOW_PERMANENTP (window)))
+       close_window (window);
+    }
 }
 \f
 /* Implementation of the object window.  The object window handles
    encapsulated messages sent from the Scheme thread.  This defines
    the protocol used to communicate with the Scheme thread.  */
 
+static void handle_window_open_request (msg_t *);
+static void handle_window_close_request (msg_t *);
+static void handle_window_show_request (msg_t *);
+static void handle_window_write_request (msg_t *);
+static void handle_window_move_cursor_request (msg_t *);
+static void handle_window_shape_cursor_request (msg_t *);
+static void handle_window_show_cursor_request (msg_t *);
+static void handle_window_clear_request (msg_t *);
+static void handle_window_scroll_request (msg_t *);
+static void handle_window_invalidate_request (msg_t *);
+static void handle_window_set_font_request (msg_t *);
+static void handle_window_set_grid_request (msg_t *);
+static void handle_window_activate_request (msg_t *);
+static void handle_window_pos_request (msg_t *);
+static void handle_window_set_pos_request (msg_t *);
+static void handle_window_size_request (msg_t *);
+static void handle_window_set_size_request (msg_t *);
+static void handle_window_focusp_request (msg_t *);
+static void handle_window_set_state_request (msg_t *);
+static void handle_window_set_colors_request (msg_t *);
+
 static MRESULT EXPENTRY
 object_window_procedure (HWND window, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
@@ -452,26 +684,65 @@ object_window_procedure (HWND window, ULONG msg, MPARAM mp1, MPARAM mp2)
       msg_t * message = (PVOIDFROMMP (mp1));
       switch (MSG_TYPE (message))
        {
-       case mt_twindow_open_request:
-         handle_twindow_open_request (message);
+       case mt_window_open_request:
+         handle_window_open_request (message);
+         break;
+       case mt_window_close:
+         handle_window_close_request (message);
+         break;
+       case mt_window_show:
+         handle_window_show_request (message);
+         break;
+       case mt_window_write:
+         handle_window_write_request (message);
+         break;
+       case mt_window_move_cursor:
+         handle_window_move_cursor_request (message);
+         break;
+       case mt_window_shape_cursor:
+         handle_window_shape_cursor_request (message);
+         break;
+       case mt_window_show_cursor:
+         handle_window_show_cursor_request (message);
+         break;
+       case mt_window_clear:
+         handle_window_clear_request (message);
+         break;
+       case mt_window_scroll:
+         handle_window_scroll_request (message);
+         break;
+       case mt_window_invalidate:
+         handle_window_invalidate_request (message);
+         break;
+       case mt_window_set_font_request:
+         handle_window_set_font_request (message);
+         break;
+       case mt_window_set_grid:
+         handle_window_set_grid_request (message);
+         break;
+       case mt_window_activate:
+         handle_window_activate_request (message);
          break;
-       case mt_twindow_close_request:
-         handle_twindow_close_request (message);
+       case mt_window_pos_request:
+         handle_window_pos_request (message);
          break;
-       case mt_twindow_write_request:
-         handle_twindow_write_request (message);
+       case mt_window_set_pos:
+         handle_window_set_pos_request (message);
          break;
-       case mt_twindow_move_cursor_request:
-         handle_twindow_move_cursor_request (message);
+       case mt_window_size_request:
+         handle_window_size_request (message);
          break;
-       case mt_twindow_clear_request:
-         handle_twindow_clear_request (message);
+       case mt_window_set_size:
+         handle_window_set_size_request (message);
          break;
-       case mt_twindow_clear_eol_request:
-         handle_twindow_clear_eol_request (message);
+       case mt_window_focusp_request:
+         handle_window_focusp_request (message);
          break;
-       case mt_twindow_scroll_request:
-         handle_twindow_scroll_request (message);
+       case mt_window_set_state:
+         handle_window_set_state_request (message);
+         break;
+       case mt_window_set_colors:
+         handle_window_set_colors_request (message);
          break;
        default:
          OS2_logic_error ("Unknown message type sent to PM thread.");
@@ -480,255 +751,572 @@ object_window_procedure (HWND window, ULONG msg, MPARAM mp1, MPARAM mp2)
     }
   return (MRVOID);
 }
+\f
+qid_t
+OS2_create_pm_qid (tqueue_t * tqueue)
+{
+  qid_t pm_side;
+  qid_t client_side;
+  OS2_make_qid_pair ((&pm_side), (&client_side));
+  OS2_open_qid (pm_side, pm_tqueue);
+  OS2_open_qid (client_side, tqueue);
+  return (client_side);
+}
+
+wid_t
+OS2_window_open (qid_t qid, qid_t event_qid, const char * title)
+{
+  msg_t * message = (OS2_create_message (mt_window_open_request));
+  wid_t wid;
+  (SM_OPEN_REQUEST_QID (message)) = qid;
+  (SM_OPEN_REQUEST_EVENT_QID (message)) = event_qid;
+  (SM_OPEN_REQUEST_TITLE (message)) = title;
+  message = (OS2_message_transaction (qid, message, mt_window_open_reply));
+  wid = (SM_OPEN_REPLY_WID (message));
+  OS2_destroy_message (message);
+  return (wid);
+}
 
-twid_t
-OS2_twindow_open (qid_t event_qid, const char * title)
+static void
+handle_window_open_request (msg_t * message)
 {
-  msg_t * reply
-    = (OS2_message_transaction (pm_qid_remote,
-                               (make_twindow_open_request (event_qid, title)),
-                               mt_twindow_open_reply));
-  twid_t twid = (SM_TWINDOW_OPEN_REPLY_TWID (reply));
-  OS2_destroy_message (reply);
-  return (twid);
+  qid_t sender = (MSG_SENDER (message));
+  qid_t qid = (SM_OPEN_REQUEST_QID (message));
+  qid_t event_qid = (SM_OPEN_REQUEST_EVENT_QID (message));
+  const char * title = (SM_OPEN_REQUEST_TITLE (message));
+  OS2_destroy_message (message);
+  message = (OS2_create_message (mt_window_open_reply));
+  (SM_OPEN_REPLY_WID (message)) = (open_window (qid, event_qid, title));
+  OS2_send_message (sender, message);
 }
 
-static msg_t *
-make_twindow_open_request (qid_t event_qid, const char * title)
+void
+OS2_window_permanent (wid_t wid)
 {
-  msg_t * message = (OS2_create_message (mt_twindow_open_request));
-  (SM_TWINDOW_OPEN_REQUEST_EVENT_QID (message)) = event_qid;
-  (SM_TWINDOW_OPEN_REQUEST_TITLE (message)) = title;
-  return (message);
+  (WINDOW_PERMANENTP (wid_to_window (wid))) = 1;
+}
+
+void
+OS2_window_close (wid_t wid)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_close));
+  (SM_CLOSE_WINDOW (message)) = window;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
 static void
-handle_twindow_open_request (msg_t * message)
+handle_window_close_request (msg_t * message)
 {
   qid_t sender = (MSG_SENDER (message));
-  qid_t event_qid = (SM_TWINDOW_OPEN_REQUEST_EVENT_QID (message));
-  const char * title = (SM_TWINDOW_OPEN_REQUEST_TITLE (message));
+  window_t * window = (SM_CLOSE_WINDOW (message));
   OS2_destroy_message (message);
-  OS2_send_message
-    (sender,
-     (make_twindow_open_reply
-      (allocate_twid (twindow_open (event_qid, title)))));
+  close_window (window);
+  simple_reply (sender);
 }
 
-static msg_t *
-make_twindow_open_reply (twid_t twid)
+void
+OS2_window_show (wid_t wid, int showp)
 {
-  msg_t * message = (OS2_create_message (mt_twindow_open_reply));
-  (SM_TWINDOW_OPEN_REPLY_TWID (message)) = twid;
-  return (message);
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_show));
+  (SM_SHOW_WINDOW (message)) = window;
+  (SM_SHOW_SHOWP (message)) = showp;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
-\f
+
+static void
+handle_window_show_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SHOW_WINDOW (message));
+  int showp = (SM_SHOW_SHOWP (message));
+  OS2_destroy_message (message);
+  show_window (window, showp);
+  simple_reply (sender);
+}
+
 void
-OS2_twindow_close (twid_t twid)
+OS2_window_write (wid_t wid, unsigned short x, unsigned short y,
+                 const char * data, unsigned short size)
 {
-  simple_transaction (pm_qid_remote, (make_twindow_close_request (twid)));
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_write));
+  char * copy = (OS_malloc (size));
+  FASTCOPY (data, copy, size);
+  (SM_WRITE_WINDOW (message)) = window;
+  (SM_WRITE_X (message)) = x;
+  (SM_WRITE_Y (message)) = y;
+  (SM_WRITE_DATA (message)) = copy;
+  (SM_WRITE_SIZE (message)) = size;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
-static msg_t *
-make_twindow_close_request (twid_t twid)
+static void
+handle_window_write_request (msg_t * message)
 {
-  msg_t * message = (OS2_create_message (mt_twindow_close_request));
-  (SM_TWINDOW_CLOSE_REQUEST_TWID (message)) = twid;
-  return (message);
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_WRITE_WINDOW (message));
+  const char * data = (SM_WRITE_DATA (message));
+  unsigned short size = (SM_WRITE_SIZE (message));
+  POINTL ptl;
+  (ptl . x) = (SM_WRITE_X (message));
+  (ptl . y) = (SM_WRITE_Y (message));
+  OS2_destroy_message (message);
+  deactivate_cursor (window);
+  if (size <= 512)
+    GpiCharStringAt ((WINDOW_HPS (window)), (& ptl), size, ((char *) data));
+  else
+    {
+      const char * scan = data;
+      GpiMove ((WINDOW_HPS (window)), (& ptl));
+      while (size > 0)
+       {
+         unsigned short n = ((size > 512) ? 512 : size);
+         GpiCharString ((WINDOW_HPS (window)), n, ((char *) scan));
+         size -= n;
+         scan += n;
+       }
+    }
+  activate_cursor (window);
+  OS_free ((char *) data);
+  simple_reply (sender);
+}
+
+void
+OS2_window_move_cursor (wid_t wid, unsigned short x, unsigned short y)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_move_cursor));
+  (SM_MOVE_CURSOR_WINDOW (message)) = window;
+  (SM_MOVE_CURSOR_X (message)) = x;
+  (SM_MOVE_CURSOR_Y (message)) = y;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
 static void
-handle_twindow_close_request (msg_t * message)
+handle_window_move_cursor_request (msg_t * message)
 {
-  qid_t qid = (MSG_SENDER (message));
-  twid_t twid = (SM_TWINDOW_CLOSE_REQUEST_TWID (message));
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_MOVE_CURSOR_WINDOW (message));
+  (WINDOW_CURSOR_X (window)) = (SM_MOVE_CURSOR_X (message));
+  (WINDOW_CURSOR_Y (window)) = (SM_MOVE_CURSOR_Y (message));
   OS2_destroy_message (message);
-  twindow_close (twid_to_twindow (twid));
-  simple_reply (qid);
+  move_cursor (window, (WINDOW_CURSOR_X (window)), (WINDOW_CURSOR_Y (window)));
+  simple_reply (sender);
 }
 
 void
-OS2_twindow_write (twid_t twid, unsigned short x, unsigned short y,
-                  const char * data, unsigned short size)
+OS2_window_shape_cursor (wid_t wid,
+                        unsigned short width, unsigned short height,
+                        unsigned short style)
 {
-  simple_transaction (pm_qid_remote,
-                     (make_twindow_write_request (twid, x, y, data, size)));
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_shape_cursor));
+  (SM_SHAPE_CURSOR_WINDOW (message)) = window;
+  (SM_SHAPE_CURSOR_WIDTH (message)) = width;
+  (SM_SHAPE_CURSOR_HEIGHT (message)) = height;
+  (SM_SHAPE_CURSOR_STYLE (message)) = style;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
-static msg_t *
-make_twindow_write_request (twid_t twid, unsigned short x, unsigned short y,
-                           const char * data, unsigned short size)
-{
-  msg_t * message = (OS2_create_message (mt_twindow_write_request));
-  (SM_TWINDOW_WRITE_REQUEST_TWID (message)) = twid;
-  (SM_TWINDOW_WRITE_REQUEST_X (message)) = x;
-  (SM_TWINDOW_WRITE_REQUEST_Y (message)) = y;
-  (SM_TWINDOW_WRITE_REQUEST_DATA (message)) = data;
-  (SM_TWINDOW_WRITE_REQUEST_SIZE (message)) = size;
-  return (message);
+static void
+handle_window_shape_cursor_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SHAPE_CURSOR_WINDOW (message));
+  unsigned short width = (SM_SHAPE_CURSOR_WIDTH (message));
+  unsigned short height = (SM_SHAPE_CURSOR_HEIGHT (message));
+  unsigned short style = (SM_SHAPE_CURSOR_STYLE (message));
+  OS2_destroy_message (message);
+  shape_cursor (window, width, height, style);
+  simple_reply (sender);
+}
+
+void
+OS2_window_show_cursor (wid_t wid, int showp)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_show_cursor));
+  (SM_SHOW_CURSOR_WINDOW (message)) = window;
+  (SM_SHOW_CURSOR_SHOWP (message)) = showp;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
 static void
-handle_twindow_write_request (msg_t * message)
-{
-  qid_t qid = (MSG_SENDER (message));
-  twid_t twid = (SM_TWINDOW_WRITE_REQUEST_TWID (message));
-  unsigned short x = (SM_TWINDOW_WRITE_REQUEST_X (message));
-  unsigned short y = (SM_TWINDOW_WRITE_REQUEST_Y (message));
-  const char * data = (SM_TWINDOW_WRITE_REQUEST_DATA (message));
-  unsigned short size = (SM_TWINDOW_WRITE_REQUEST_SIZE (message));
+handle_window_show_cursor_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SHOW_CURSOR_WINDOW (message));
+  int showp = ((SM_SHOW_CURSOR_SHOWP (message)) ? 1 : 0);
   OS2_destroy_message (message);
-  twindow_write ((twid_to_twindow (twid)), x, y, data, size);
-  simple_reply (qid);
+  show_cursor (window, showp);
+  simple_reply (sender);
 }
-\f
+
 void
-OS2_twindow_move_cursor (twid_t twid, unsigned short x, unsigned short y)
+OS2_window_clear (wid_t wid,
+                 unsigned short xl, unsigned short xh,
+                 unsigned short yl, unsigned short yh)
 {
-  simple_transaction (pm_qid_remote,
-                     (make_twindow_move_cursor_request (twid, x, y)));
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_clear));
+  (SM_CLEAR_WINDOW (message)) = window;
+  (SM_CLEAR_XL (message)) = xl;
+  (SM_CLEAR_XH (message)) = xh;
+  (SM_CLEAR_YL (message)) = yl;
+  (SM_CLEAR_YH (message)) = yh;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
-static msg_t *
-make_twindow_move_cursor_request (twid_t twid, unsigned short x,
-                                 unsigned short y)
+static void
+handle_window_clear_request (msg_t * message)
 {
-  msg_t * message = (OS2_create_message (mt_twindow_move_cursor_request));
-  (SM_TWINDOW_MOVE_CURSOR_REQUEST_TWID (message)) = twid;
-  (SM_TWINDOW_MOVE_CURSOR_REQUEST_X (message)) = x;
-  (SM_TWINDOW_MOVE_CURSOR_REQUEST_Y (message)) = y;
-  return (message);
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_CLEAR_WINDOW (message));
+  RECTL rectl;
+  (rectl . xLeft)   = (SM_CLEAR_XL (message));
+  (rectl . xRight)  = (SM_CLEAR_XH (message));
+  (rectl . yBottom) = (SM_CLEAR_YL (message));
+  (rectl . yTop)    = (SM_CLEAR_YH (message));
+  OS2_destroy_message (message);
+  clear_rectangle (window, (& rectl));
+  simple_reply (sender);
+}
+
+void
+OS2_window_scroll (wid_t wid,
+                  unsigned short xl, unsigned short xh,
+                  unsigned short yl, unsigned short yh,
+                  short x_delta, short y_delta)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_scroll));
+  (SM_SCROLL_WINDOW (message)) = window;
+  (SM_SCROLL_XL (message)) = xl;
+  (SM_SCROLL_XH (message)) = xh;
+  (SM_SCROLL_YL (message)) = yl;
+  (SM_SCROLL_YH (message)) = yh;
+  (SM_SCROLL_X_DELTA (message)) = x_delta;
+  (SM_SCROLL_Y_DELTA (message)) = y_delta;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
 static void
-handle_twindow_move_cursor_request (msg_t * message)
+handle_window_scroll_request (msg_t * message)
 {
-  qid_t qid = (MSG_SENDER (message));
-  twid_t twid = (SM_TWINDOW_MOVE_CURSOR_REQUEST_TWID (message));
-  unsigned short x = (SM_TWINDOW_MOVE_CURSOR_REQUEST_X (message));
-  unsigned short y = (SM_TWINDOW_MOVE_CURSOR_REQUEST_Y (message));
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SCROLL_WINDOW (message));
+  short x_delta = (SM_SCROLL_X_DELTA (message));
+  short y_delta = (SM_SCROLL_Y_DELTA (message));
+  RECTL rectl;
+  (rectl . xLeft)   = (SM_SCROLL_XL (message));
+  (rectl . xRight)  = (SM_SCROLL_XH (message));
+  (rectl . yBottom) = (SM_SCROLL_YL (message));
+  (rectl . yTop)    = (SM_SCROLL_YH (message));
   OS2_destroy_message (message);
-  twindow_move_cursor ((twid_to_twindow (twid)), x, y);
-  simple_reply (qid);
+  if ((WinScrollWindow ((WINDOW_CLIENT (window)),
+                       x_delta, y_delta, (& rectl), 0, NULLHANDLE, 0, 0))
+      == RGN_ERROR)
+    window_error (WinScrollWindow);
+  simple_reply (sender);
 }
-\f
+
 void
-OS2_twindow_clear (twid_t twid)
+OS2_window_invalidate (wid_t wid,
+                      unsigned short xl, unsigned short xh,
+                      unsigned short yl, unsigned short yh)
 {
-  simple_transaction (pm_qid_remote, (make_twindow_clear_request (twid)));
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_invalidate));
+  (SM_INVALIDATE_WINDOW (message)) = window;
+  (SM_INVALIDATE_XL (message)) = xl;
+  (SM_INVALIDATE_XH (message)) = xh;
+  (SM_INVALIDATE_YL (message)) = yl;
+  (SM_INVALIDATE_YH (message)) = yh;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
 static void
-handle_twindow_clear_request (msg_t * message)
+handle_window_invalidate_request (msg_t * message)
 {
-  qid_t qid = (MSG_SENDER (message));
-  twid_t twid = (SM_TWINDOW_CLEAR_REQUEST_TWID (message));
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_INVALIDATE_WINDOW (message));
+  RECTL rectl;
+  (rectl . xLeft)   = (SM_INVALIDATE_XL (message));
+  (rectl . xRight)  = (SM_INVALIDATE_XH (message));
+  (rectl . yBottom) = (SM_INVALIDATE_YL (message));
+  (rectl . yTop)    = (SM_INVALIDATE_YH (message));
   OS2_destroy_message (message);
-  twindow_clear (twid_to_twindow (twid));
-  simple_reply (qid);
+  if (!WinInvalidateRect ((WINDOW_CLIENT (window)), (& rectl), FALSE))
+    window_error (WinInvalidateRect);
+  simple_reply (sender);
+}
+
+font_metrics_t *
+OS2_window_set_font (wid_t wid, unsigned short id, const char * name)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_set_font_request));
+  font_metrics_t * metrics;
+  (SM_SET_FONT_REQUEST_WINDOW (message)) = window;
+  (SM_SET_FONT_REQUEST_ID (message)) = id;
+  (SM_SET_FONT_REQUEST_SPEC (message)) = name;
+  message
+    = (OS2_message_transaction
+       ((WINDOW_QID (window)), message, mt_window_set_font_reply));
+  metrics = (SM_SET_FONT_REPLY_METRICS (message));
+  OS2_destroy_message (message);
+  return (metrics);
 }
 
-static msg_t *
-make_twindow_clear_request (twid_t twid)
+static void
+handle_window_set_font_request (msg_t * message)
 {
-  msg_t * message = (OS2_create_message (mt_twindow_clear_request));
-  (SM_TWINDOW_CLEAR_REQUEST_TWID (message)) = twid;
-  return (message);
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SET_FONT_REQUEST_WINDOW (message));
+  unsigned short id = (SM_SET_FONT_REQUEST_ID (message));
+  const char * spec = (SM_SET_FONT_REQUEST_SPEC (message));
+  OS2_destroy_message (message);
+  message = (OS2_create_message (mt_window_set_font_reply));
+  (SM_SET_FONT_REPLY_METRICS (message)) = (set_font (window, id, spec));
+  OS2_send_message (sender, message);
 }
 
 void
-OS2_twindow_clear_eol (twid_t twid, unsigned short x, unsigned short y)
+OS2_window_set_grid (wid_t wid, unsigned short x, unsigned short y)
 {
-  simple_transaction (pm_qid_remote,
-                     (make_twindow_clear_eol_request (twid, x, y)));
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_set_grid));
+  (SM_SET_GRID_WINDOW (message)) = window;
+  (SM_SET_GRID_X (message)) = x;
+  (SM_SET_GRID_Y (message)) = y;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
 static void
-handle_twindow_clear_eol_request (msg_t * message)
+handle_window_set_grid_request (msg_t * message)
 {
-  qid_t qid = (MSG_SENDER (message));
-  twid_t twid = (SM_TWINDOW_CLEAR_EOL_REQUEST_TWID (message));
-  unsigned short x = (SM_TWINDOW_CLEAR_EOL_REQUEST_X (message));
-  unsigned short y = (SM_TWINDOW_CLEAR_EOL_REQUEST_Y (message));
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SET_GRID_WINDOW (message));
+  (WINDOW_GRID_X (window)) = (SM_SET_GRID_X (message));
+  (WINDOW_GRID_Y (window)) = (SM_SET_GRID_Y (message));
   OS2_destroy_message (message);
-  twindow_clear_eol ((twid_to_twindow (twid)), x, y);
-  simple_reply (qid);
+  simple_reply (sender);
 }
 
-static msg_t *
-make_twindow_clear_eol_request (twid_t twid, unsigned short x,
-                               unsigned short y)
+void
+OS2_window_activate (wid_t wid)
 {
-  msg_t * message = (OS2_create_message (mt_twindow_clear_eol_request));
-  (SM_TWINDOW_CLEAR_EOL_REQUEST_TWID (message)) = twid;
-  (SM_TWINDOW_CLEAR_EOL_REQUEST_X (message)) = x;
-  (SM_TWINDOW_CLEAR_EOL_REQUEST_Y (message)) = y;
-  return (message);
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_activate));
+  (SM_ACTIVATE_WINDOW (message)) = window;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
-\f
+
+static void
+handle_window_activate_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_ACTIVATE_WINDOW (message));
+  OS2_destroy_message (message);
+  if (!WinSetActiveWindow (HWND_DESKTOP, (WINDOW_FRAME (window))))
+    window_error (WinSetActiveWindow);
+  simple_reply (sender);
+}
+
 void
-OS2_twindow_scroll (twid_t twid,
-                   unsigned short x_start, unsigned short x_end,
-                   unsigned short y_start, unsigned short y_end,
-                   short x_delta, short y_delta)
+OS2_window_pos (wid_t wid, unsigned short * x, unsigned short * y)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_pos_request));
+  (SM_POS_REQUEST_WINDOW (message)) = window;
+  message
+    = (OS2_message_transaction ((WINDOW_QID (window)),
+                               message,
+                               mt_window_pos_reply));
+  (* x) = (SM_POS_REPLY_X (message));
+  (* y) = (SM_POS_REPLY_Y (message));
+  OS2_destroy_message (message);
+}
+
+static void
+handle_window_pos_request (msg_t * message)
 {
-  simple_transaction
-    (pm_qid_remote,
-     (make_twindow_scroll_request
-      (twid, x_start, x_end, y_start, y_end, x_delta, y_delta)));
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_POS_REQUEST_WINDOW (message));
+  OS2_destroy_message (message);
+  message = (OS2_create_message (mt_window_pos_reply));
+  get_window_pos (window,
+                 (& (SM_POS_REPLY_X (message))),
+                 (& (SM_POS_REPLY_Y (message))));
+  OS2_send_message (sender, message);
 }
 
-static msg_t *
-make_twindow_scroll_request (twid_t twid,
-                            unsigned short x_start, unsigned short x_end,
-                            unsigned short y_start, unsigned short y_end,
-                            short x_delta, short y_delta)
-{
-  msg_t * message = (OS2_create_message (mt_twindow_scroll_request));
-  (SM_TWINDOW_SCROLL_REQUEST_TWID (message)) = twid;
-  (SM_TWINDOW_SCROLL_REQUEST_X_START (message)) = x_start;
-  (SM_TWINDOW_SCROLL_REQUEST_X_END (message)) = x_end;
-  (SM_TWINDOW_SCROLL_REQUEST_Y_START (message)) = y_start;
-  (SM_TWINDOW_SCROLL_REQUEST_Y_END (message)) = y_end;
-  (SM_TWINDOW_SCROLL_REQUEST_X_DELTA (message)) = x_delta;
-  (SM_TWINDOW_SCROLL_REQUEST_Y_DELTA (message)) = y_delta;
-  return (message);
+void
+OS2_window_set_pos (wid_t wid, unsigned short x, unsigned short y)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_set_pos));
+  (SM_SET_POS_WINDOW (message)) = window;
+  (SM_SET_POS_X (message)) = x;
+  (SM_SET_POS_Y (message)) = y;
+  simple_transaction ((WINDOW_QID (window)), message);
 }
 
 static void
-handle_twindow_scroll_request (msg_t * message)
-{
-  qid_t qid = (MSG_SENDER (message));
-  twid_t twid = (SM_TWINDOW_SCROLL_REQUEST_TWID (message));
-  unsigned short x_start = (SM_TWINDOW_SCROLL_REQUEST_X_START (message));
-  unsigned short x_end = (SM_TWINDOW_SCROLL_REQUEST_X_END (message));
-  unsigned short y_start = (SM_TWINDOW_SCROLL_REQUEST_Y_START (message));
-  unsigned short y_end = (SM_TWINDOW_SCROLL_REQUEST_Y_END (message));
-  short x_delta = (SM_TWINDOW_SCROLL_REQUEST_X_DELTA (message));
-  short y_delta = (SM_TWINDOW_SCROLL_REQUEST_Y_DELTA (message));
+handle_window_set_pos_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SET_POS_WINDOW (message));
+  unsigned short x = (SM_SET_POS_X (message));
+  unsigned short y = (SM_SET_POS_Y (message));
   OS2_destroy_message (message);
-  twindow_scroll
-    ((twid_to_twindow (twid)),
-     x_start, x_end, y_start, y_end, x_delta, y_delta);
-  simple_reply (qid);
+  set_window_pos (window, x, y);
+  simple_reply (sender);
 }
-\f
-static twindow_t *
-twindow_open (qid_t event_qid, const char * title)
+
+void
+OS2_window_size (wid_t wid, unsigned short * width, unsigned short * height)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_size_request));
+  (SM_SIZE_REQUEST_WINDOW (message)) = window;
+  message
+    = (OS2_message_transaction ((WINDOW_QID (window)),
+                               message,
+                               mt_window_size_reply));
+  (* width) = (SM_SIZE_REPLY_WIDTH (message));
+  (* height) = (SM_SIZE_REPLY_HEIGHT (message));
+  OS2_destroy_message (message);
+}
+
+static void
+handle_window_size_request (msg_t * message)
 {
-  twindow_t * twindow = (make_twindow (event_qid));
-  FRAMECDATA frame_data;
-  HWND frame_window;
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SIZE_REQUEST_WINDOW (message));
+  OS2_destroy_message (message);
+  message = (OS2_create_message (mt_window_size_reply));
+  get_window_size (window,
+                  (& (SM_SIZE_REPLY_WIDTH (message))),
+                  (& (SM_SIZE_REPLY_HEIGHT (message))));
+  OS2_send_message (sender, message);
+}
 
-  (frame_data . cb) = (sizeof (frame_data));
-  (frame_data . flCreateFlags)
-     = (FCF_TITLEBAR | FCF_SYSMENU | FCF_SHELLPOSITION | FCF_SIZEBORDER
-       | FCF_MINMAX | FCF_TASKLIST);
-  (frame_data . hmodResources) = NULLHANDLE;
-  (frame_data . idResources) = ID_RESOURCES;
-  frame_window
-    = (WinCreateWindow (HWND_DESKTOP,
-                       WC_FRAME,
+void
+OS2_window_set_size (wid_t wid, unsigned short width, unsigned short height)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_set_size));
+  (SM_SET_SIZE_WINDOW (message)) = window;
+  (SM_SET_SIZE_WIDTH (message)) = width;
+  (SM_SET_SIZE_HEIGHT (message)) = height;
+  simple_transaction ((WINDOW_QID (window)), message);
+}
+
+static void
+handle_window_set_size_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SET_SIZE_WINDOW (message));
+  unsigned short width = (SM_SET_SIZE_WIDTH (message));
+  unsigned short height = (SM_SET_SIZE_HEIGHT (message));
+  OS2_destroy_message (message);
+  set_window_size (window, width, height);
+  simple_reply (sender);
+}
+
+int
+OS2_window_focusp (wid_t wid)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_focusp_request));
+  (SM_FOCUSP_REQUEST_WINDOW (message)) = window;
+  message
+    = (OS2_message_transaction ((WINDOW_QID (window)),
+                               message,
+                               mt_window_focusp_reply));
+  {
+    int result = (SM_FOCUSP_REPLY_FOCUSP (message));
+    OS2_destroy_message (message);
+    return (result);
+  }
+}
+
+static void
+handle_window_focusp_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_FOCUSP_REQUEST_WINDOW (message));
+  OS2_destroy_message (message);
+  message = (OS2_create_message (mt_window_focusp_reply));
+  (SM_FOCUSP_REPLY_FOCUSP (message)) = (window_focusp (window));
+  OS2_send_message (sender, message);
+}
+
+void
+OS2_window_set_state (wid_t wid, window_state_t state)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_set_state));
+  (SM_SET_STATE_WINDOW (message)) = window;
+  (SM_SET_STATE_STATE (message)) = state;
+  simple_transaction ((WINDOW_QID (window)), message);
+}
+
+static void
+handle_window_set_state_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SET_STATE_WINDOW (message));
+  window_state_t state = (SM_SET_STATE_STATE (message));
+  OS2_destroy_message (message);
+  set_window_state (window, state);
+  simple_reply (sender);
+}
+
+void
+OS2_window_set_colors (wid_t wid, COLOR foreground, COLOR background)
+{
+  window_t * window = (wid_to_window (wid));
+  msg_t * message = (OS2_create_message (mt_window_set_colors));
+  (SM_SET_COLORS_WINDOW (message)) = window;
+  (SM_SET_COLORS_FOREGROUND (message)) = foreground;
+  (SM_SET_COLORS_BACKGROUND (message)) = background;
+  simple_transaction ((WINDOW_QID (window)), message);
+}
+
+static void
+handle_window_set_colors_request (msg_t * message)
+{
+  qid_t sender = (MSG_SENDER (message));
+  window_t * window = (SM_SET_COLORS_WINDOW (message));
+  COLOR foreground = (SM_SET_COLORS_FOREGROUND (message));
+  COLOR background = (SM_SET_COLORS_BACKGROUND (message));
+  OS2_destroy_message (message);
+  set_window_colors (window, foreground, background);
+  simple_reply (sender);
+}
+\f
+static window_t * make_window (qid_t, qid_t);
+
+static wid_t
+open_window (qid_t qid, qid_t event_qid, const char * title)
+{
+  window_t * window = (make_window (qid, event_qid));
+  FRAMECDATA frame_data;
+  HWND frame_window;
+
+  (frame_data . cb) = (sizeof (frame_data));
+  (frame_data . flCreateFlags)
+     = (FCF_TITLEBAR | FCF_SYSMENU | FCF_SHELLPOSITION | FCF_SIZEBORDER
+       | FCF_MINMAX | FCF_TASKLIST);
+  (frame_data . hmodResources) = NULLHANDLE;
+  (frame_data . idResources) = ID_RESOURCES;
+  frame_window
+    = (WinCreateWindow (HWND_DESKTOP,
+                       WC_FRAME,
                        ((PSZ) title), /* title string */
                        0,      /* window style */
                        0, 0, 0, 0, /* size and position */
@@ -739,7 +1327,7 @@ twindow_open (qid_t event_qid, const char * title)
                        0));
   if (frame_window == NULLHANDLE)
     window_error (WinCreateWindow);
-  (TWINDOW_FRAME (twindow)) = frame_window;
+  (WINDOW_FRAME (window)) = frame_window;
   {
     PFNWP procedure
       = (WinSubclassWindow (frame_window, frame_window_procedure));
@@ -751,156 +1339,383 @@ twindow_open (qid_t event_qid, const char * title)
       OS2_logic_error ("WinSubclassWindow returned two different answers.");
   }
   if ((WinCreateWindow (frame_window,
-                       ((PSZ) twindow_class),
+                       ((PSZ) window_class),
                        0,      /* window text (class-specific) */
                        0,      /* window style */
                        0, 0, 0, 0, /* size and position */
                        frame_window, /* owner window */
                        HWND_BOTTOM,
                        FID_CLIENT, /* window ID */
-                       twindow,
+                       window,
                        0))
       == NULLHANDLE)
     window_error (WinCreateWindow);
-  if (!WinShowWindow ((TWINDOW_FRAME (twindow)), TRUE))
-    window_error (WinShowWindow);
-  if (!WinShowWindow ((TWINDOW_CLIENT (twindow)), TRUE))
+  return (allocate_wid (window));
+}
+
+static window_t *
+make_window (qid_t qid, qid_t event_qid)
+{
+  window_t * window = (OS_malloc (sizeof (window_t)));
+  (WINDOW_FRAME (window)) = NULLHANDLE;
+  (WINDOW_CLIENT (window)) = NULLHANDLE;
+  (WINDOW_HPS (window)) = NULLHANDLE;
+  (WINDOW_CURSOR_X (window)) = 0;
+  (WINDOW_CURSOR_Y (window)) = 0;
+  (WINDOW_CURSOR_WIDTH (window)) = 0;
+  (WINDOW_CURSOR_HEIGHT (window)) = 0;
+  (WINDOW_CURSOR_STYLE (window)) = (CURSOR_SOLID | CURSOR_FLASH);
+  (WINDOW_CURSOR_SHOWNP (window)) = 0;
+  (WINDOW_QID (window)) = qid;
+  (WINDOW_EVENT_QID (window)) = event_qid;
+  (WINDOW_MINIMIZINGP (window)) = 0;
+  (WINDOW_MINIMIZEDP (window)) = 0;
+  (WINDOW_PERMANENTP (window)) = 0;
+  return (window);
+}
+
+static void
+close_window (window_t * window)
+{
+  if (!WinDestroyWindow (WINDOW_FRAME (window)))
+    window_error (WinDestroyWindow);
+  deallocate_wid (WINDOW_WID (window));
+  OS_free (window);
+}
+
+static void
+show_window (window_t * window, int showp)
+{
+  if (!WinShowWindow ((WINDOW_FRAME (window)), showp))
     window_error (WinShowWindow);
-  return (twindow);
 }
 
-static twindow_t *
-make_twindow (qid_t event_qid)
+static void
+move_cursor (window_t * window, unsigned short x, unsigned short y)
 {
-  twindow_t * twindow = (OS_malloc (sizeof (twindow_t)));
-  (TWINDOW_FRAME (twindow)) = NULLHANDLE;
-  (TWINDOW_CLIENT (twindow)) = NULLHANDLE;
-  (TWINDOW_CHARMAP (twindow)) = 0;
-  (TWINDOW_CURSOR_X (twindow)) = 0;
-  (TWINDOW_CURSOR_Y (twindow)) = 0;
-  (TWINDOW_CURSOR_SHOWNP (twindow)) = 1;
-  (TWINDOW_EVENT_QID (twindow)) = event_qid;
-  (TWINDOW_MINIMIZINGP (twindow)) = 0;
-  (TWINDOW_MINIMIZEDP (twindow)) = 0;
-  return (twindow);
+  if (window_focusp (window))
+    if (!WinCreateCursor ((WINDOW_CLIENT (window)),
+                         x, y, 0, 0, CURSOR_SETPOS, 0))
+      window_error (WinCreateCursor);
 }
-\f
+
 static void
-twindow_close (twindow_t * twindow)
+shape_cursor (window_t * window, unsigned short width, unsigned short height,
+             unsigned short style)
 {
-  OS_free (TWINDOW_CHARMAP (twindow));
-  if (!GpiDestroyPS (TWINDOW_HPS (twindow)))
-    window_error (GpiDestroyPS);
-  if (!WinDestroyWindow (TWINDOW_FRAME (twindow)))
-    window_error (WinDestroyWindow);
-  deallocate_twid (TWINDOW_TWID (twindow));
+  (WINDOW_CURSOR_WIDTH (window)) = width;
+  (WINDOW_CURSOR_HEIGHT (window)) = height;
+  (WINDOW_CURSOR_STYLE (window)) = style;
+  recreate_cursor (window);
 }
 
-static msg_t *
-make_close_event (twid_t twid)
+static void
+show_cursor (window_t * window, int showp)
 {
-  msg_t * message = (OS2_create_message (mt_close_event));
-  (SM_CLOSE_EVENT_TWID (message)) = twid;
-  return (message);
+  if ((window_focusp (window))
+      && (showp != (WINDOW_CURSOR_SHOWNP (window))))
+    if (!WinShowCursor ((WINDOW_CLIENT (window)), showp))
+      window_error (WinShowCursor);
+  (WINDOW_CURSOR_SHOWNP (window)) = showp;
 }
 
 static void
-twindow_write (twindow_t * twindow, unsigned short x, unsigned short y,
-              const char * data, unsigned short size)
+recreate_cursor (window_t * window)
 {
-  unsigned short width = (TWINDOW_WIDTH (twindow));
-  unsigned short height = (TWINDOW_HEIGHT (twindow));
-  if ((y < (TWINDOW_HEIGHT (twindow))) && (x < width))
+  if (window_focusp (window))
     {
-      char * target = (TWINDOW_CHAR_LOC (twindow, x, y));
-      if (size > (width - x))
-       size = (width - x);
-      FASTCOPY (data, target, size);
-      invalidate_partial_line (twindow, x, y, size);
+      if (!WinCreateCursor ((WINDOW_CLIENT (window)),
+                           (WINDOW_CURSOR_X (window)),
+                           (WINDOW_CURSOR_Y (window)),
+                           (WINDOW_CURSOR_WIDTH (window)),
+                           (WINDOW_CURSOR_HEIGHT (window)),
+                           (WINDOW_CURSOR_STYLE (window)),
+                           0))
+       window_error (WinCreateCursor);
+      if (WINDOW_CURSOR_SHOWNP (window))
+       if (!WinShowCursor ((WINDOW_CLIENT (window)), TRUE))
+         window_error (WinShowCursor);
     }
 }
 
 static void
-twindow_clear (twindow_t * twindow)
+activate_cursor (window_t * window)
 {
-  FASTFILL ((TWINDOW_CHARMAP (twindow)),
-           ((TWINDOW_WIDTH (twindow)) * (TWINDOW_HEIGHT (twindow))),
-           ' ');
-  if (!WinInvalidateRect ((TWINDOW_CLIENT (twindow)), 0, FALSE))
-    window_error (WinInvalidateRect);
+  if ((WINDOW_CURSOR_SHOWNP (window)) && (window_focusp (window)))
+    if (!WinShowCursor ((WINDOW_CLIENT (window)), TRUE))
+      window_error (WinShowCursor);
+}
+
+static void
+deactivate_cursor (window_t * window)
+{
+  if ((WINDOW_CURSOR_SHOWNP (window)) && (window_focusp (window)))
+    if (!WinShowCursor ((WINDOW_CLIENT (window)), FALSE))
+      window_error (WinShowCursor);
 }
 
 static void
-twindow_clear_eol (twindow_t * twindow, unsigned short x, unsigned short y)
+clear_rectangle (window_t * window, PRECTL rectl)
+{
+  deactivate_cursor (window);
+  if (!WinFillRect ((WINDOW_HPS (window)),
+                   rectl,
+                   (WINDOW_BACKGROUND_COLOR (window))))
+    window_error (WinFillRect);
+  activate_cursor (window);
+}
+
+static int parse_font_spec (const char *, PSZ *, LONG *, USHORT *);
+static int set_font_1 (HPS, PSZ, LONG, USHORT, LONG);
+
+static font_metrics_t *
+set_font (window_t * window, unsigned short id, const char * spec)
 {
-  unsigned short width = (TWINDOW_WIDTH (twindow));
-  if ((y < (TWINDOW_HEIGHT (twindow))) && (x < width))
+  PSZ name = 0;
+  LONG size;
+  USHORT selection;
+  if (!parse_font_spec (spec, (& name), (& size), (& selection)))
+    return (0);
+  if (!set_font_1 ((WINDOW_HPS (window)), name, size, selection, id))
+    {
+      OS_free (name);
+      return (0);
+    }
+  {
+    font_metrics_t * metrics = (OS_malloc (sizeof (font_metrics_t)));
+    FONTMETRICS fm;
+    if (!GpiQueryFontMetrics
+       ((WINDOW_HPS (window)), (sizeof (fm)), (& fm)))
+      window_error (GpiQueryFontMetrics);
+    (FONT_METRICS_WIDTH (metrics)) = (fm . lMaxCharInc);
+    (FONT_METRICS_HEIGHT (metrics)) = (fm . lMaxBaselineExt);
+    (FONT_METRICS_DESCENDER (metrics)) = (fm . lMaxDescender);
+    return (metrics);
+  }
+}
+
+static int
+parse_font_spec (const char * spec,
+                PSZ * pname, LONG * psize, USHORT * pselection)
+{
+  const char * scan = spec;
+  unsigned int size = 0;
+  unsigned int selection = 0;
+  while (('0' <= (*scan)) && ((*scan) <= '9'))
+    size = ((size * 10) + ((*scan++) - '0'));
+  if (size == 0)
+    return (0);
+  while (1)
     {
-      unsigned short size = (width - x);
-      FASTFILL ((TWINDOW_CHAR_LOC (twindow, x, y)), size, ' ');
-      invalidate_partial_line (twindow, x, y, size);
+      if ((strncmp (scan, ".bold", 5)) == 0)
+       {
+         selection |= FATTR_SEL_BOLD;
+         scan += 5;
+       }
+      else if ((strncmp (scan, ".italic", 7)) == 0)
+       {
+         selection |= FATTR_SEL_ITALIC;
+         scan += 7;
+       }
+      else
+       break;
     }
+  if ((*scan++) != '.')
+    return (0);
+  (*pname) = (OS_malloc ((strlen (scan)) + 1));
+  strcpy ((*pname), scan);
+  (*psize) = (size * 10);
+  (*pselection) = selection;
+  return (1);
+}
+
+static int create_font (HPS, LONG, PFONTMETRICS, USHORT);
+
+static int
+set_font_1 (HPS hps, PSZ name, LONG size, USHORT selection, LONG id)
+{
+  LONG nfonts;
+  ULONG index;
+  PFONTMETRICS pfm;
+
+  nfonts = 0;
+  nfonts = (GpiQueryFonts (hps,
+                          (QF_PUBLIC | QF_PRIVATE),
+                          name,
+                          (& nfonts),
+                          (sizeof (FONTMETRICS)),
+                          0));
+  if (nfonts == GPI_ALTERROR)
+    window_error (GpiQueryFonts);
+  if (nfonts == 0)
+    return (0);
+  pfm = (OS_malloc (nfonts * (sizeof (FONTMETRICS))));
+  if ((GpiQueryFonts (hps,
+                     (QF_PUBLIC | QF_PRIVATE),
+                     name,
+                     (& nfonts),
+                     (sizeof (FONTMETRICS)),
+                     pfm))
+      == GPI_ALTERROR)
+    window_error (GpiQueryFonts);
+  for (index = 0; (index < nfonts); index += 1)
+    if (((((pfm [index]) . fsType) & FM_TYPE_FIXED) != 0)
+       && ((((pfm [index]) . fsDefn) & FM_DEFN_OUTLINE) == 0)
+       && (((pfm [index]) . sNominalPointSize) == size)
+       && (create_font (hps, id, (& (pfm [index])), selection)))
+      {
+       GpiSetCharSet (hps, id);
+       OS_free (pfm);
+       return (1);
+      }
+  OS_free (pfm);
+  return (0);
+}
+
+static int
+create_font (HPS hps, LONG font_id, PFONTMETRICS pfm, USHORT selection)
+{
+  FATTRS font_attrs;
+
+  (font_attrs . usRecordLength) = (sizeof (font_attrs));
+  (font_attrs . fsSelection) = selection;
+  (font_attrs . lMatch) = (pfm -> lMatch);
+  strcpy ((font_attrs . szFacename), (pfm -> szFacename));
+  (font_attrs . idRegistry) = 0;
+  (font_attrs . usCodePage) = (WinQueryCp (pm_hmq));
+  if ((font_attrs . usCodePage) == 0)
+    window_error (WinQueryCp);
+  (font_attrs . lMaxBaselineExt) = 0;
+  (font_attrs . lAveCharWidth) = 0;
+  (font_attrs . fsType) = 0;
+  (font_attrs . fsFontUse) = 0;
+  return ((GpiCreateLogFont (hps, 0, font_id, (& font_attrs))) == FONT_MATCH);
 }
 
 static void
-invalidate_partial_line (twindow_t * twindow, unsigned short x,
-                        unsigned short y, unsigned short size)
+get_window_pos (window_t * window, unsigned short * x, unsigned short * y)
 {
-  RECTL rectl;
-  (rectl . xLeft) = (cx2x (twindow, x));
-  (rectl . xRight) = (cx2x (twindow, (x + size)));
-  (rectl . yBottom) = (cy2y (twindow, y, 1));
-  (rectl . yTop) = (cy2y (twindow, y, 0));
-  if (!WinInvalidateRect ((TWINDOW_CLIENT (twindow)), (& rectl), FALSE))
-    window_error (WinInvalidateRect);
+  SWP swp;
+  if (!WinQueryWindowPos ((WINDOW_FRAME (window)), (& swp)))
+    window_error (WinQueryWindowPos);
+  (* x) = (swp . x);
+  (* y) = (swp . y);
 }
-\f
+
 static void
-twindow_scroll (twindow_t * twindow,
-               unsigned short x_start, unsigned short x_end,
-               unsigned short y_start, unsigned short y_end,
-               short x_delta, short y_delta)
+set_window_pos (window_t * window, unsigned short x, unsigned short y)
 {
-  RECTL rectl;
-  (rectl . xLeft) = (cx2x (twindow, x_start));
-  (rectl . xRight) = (cx2x (twindow, x_end));
-  (rectl . yBottom) = (cy2y (twindow, y_end, 1));
-  (rectl . yTop) = (cy2y (twindow, y_start, 0));
-  if ((WinScrollWindow ((TWINDOW_CLIENT (twindow)),
-                       (x_delta * (TWINDOW_CHAR_WIDTH (twindow))),
-                       (y_delta * (TWINDOW_CHAR_HEIGHT (twindow))),
-                       (& rectl),
-                       0,
-                       NULLHANDLE,
-                       0,
-                       0))
-      == RGN_ERROR)
-    window_error (WinScrollWindow);
+  if (!WinSetWindowPos ((WINDOW_FRAME (window)), NULLHANDLE, x, y,
+                       0, 0, SWP_MOVE))
+    window_error (WinSetWindowPos);
 }
 
 static void
-twindow_move_cursor (twindow_t * twindow, unsigned short x, unsigned short y)
+get_window_size (window_t * window,
+                unsigned short * width, unsigned short * height)
 {
-  if ((x < (TWINDOW_WIDTH (twindow))) && (y < (TWINDOW_HEIGHT (twindow))))
+  SWP swp;
+  if (!WinQueryWindowPos ((WINDOW_CLIENT (window)), (& swp)))
+    window_error (WinQueryWindowPos);
+  (* width) = (swp . cx);
+  (* height) = (swp . cy);
+}
+
+static void
+set_window_size (window_t * window,
+                unsigned short width, unsigned short height)
+{
+  SWP swp;
+  POINTL ptl;
+  RECTL rcl;
+  if (!WinQueryWindowPos ((WINDOW_CLIENT (window)), (& swp)))
+    window_error (WinQueryWindowPos);
+  (ptl . x) = (swp . x);
+  (ptl . y) = (swp . y);
+  if (!WinMapWindowPoints ((WINDOW_FRAME (window)), HWND_DESKTOP, (& ptl), 1))
+    window_error (WinMapWindowPoints);
+  (rcl . xLeft) = (ptl . x);
+  (rcl . xRight) = ((ptl . x) + width);
+  (rcl . yBottom) = (ptl . y);
+  (rcl . yTop) = ((ptl . y) + height);
+  if (!WinCalcFrameRect ((WINDOW_FRAME (window)), (& rcl), FALSE))
+    window_error (WinCalcFrameRect);
+  deactivate_cursor (window);
+  if (!WinSetWindowPos ((WINDOW_FRAME (window)),
+                       NULLHANDLE, 0, 0,
+                       ((rcl . xRight) - (rcl . xLeft)),
+                       ((rcl . yTop) - (rcl . yBottom)),
+                       SWP_SIZE))
+    window_error (WinSetWindowPos);
+  activate_cursor (window);
+}
+
+static int
+window_focusp (window_t * window)
+{
+  return ((WINDOW_CLIENT (window)) == (WinQueryFocus (HWND_DESKTOP)));
+}
+
+static void
+set_window_state (window_t * window, window_state_t state)
+{
+  ULONG op = 0;
+  HWND behind = NULLHANDLE;
+  switch (state)
     {
-      (TWINDOW_CURSOR_X (twindow)) = x;
-      (TWINDOW_CURSOR_Y (twindow)) = y;
-      if (twindow_focusp (twindow))
-       if (!WinCreateCursor ((TWINDOW_CLIENT (twindow)),
-                             (cx2x (twindow, x)),
-                             (cy2y (twindow, y, 1)),
-                             0,
-                             0,
-                             CURSOR_SETPOS,
-                             0))
-         window_error (WinCreateCursor);
+    case state_top:
+      op = SWP_ZORDER;
+      behind = HWND_TOP;
+      break;
+    case state_bottom:
+      op = SWP_ZORDER;
+      behind = HWND_BOTTOM;
+      break;
+    case state_show:
+      op = SWP_SHOW;
+      break;
+    case state_hide:
+      op = SWP_HIDE;
+      break;
+    case state_activate:
+      op = SWP_ACTIVATE;
+      break;
+    case state_deactivate:
+      op = SWP_DEACTIVATE;
+      break;
+    case state_minimize:
+      op = SWP_MINIMIZE;
+      break;
+    case state_maximize:
+      op = SWP_MAXIMIZE;
+      break;
+    case state_restore:
+      op = SWP_RESTORE;
+      break;
     }
+  if (!WinSetWindowPos ((WINDOW_FRAME (window)), behind, 0, 0, 0, 0, op))
+    window_error (WinSetWindowPos);
+}
+
+static void
+set_window_colors (window_t * window, COLOR foreground, COLOR background)
+{
+  if (!GpiSetColor ((WINDOW_HPS (window)), foreground))
+    window_error (GpiSetColor);
+  if (!GpiSetMix ((WINDOW_HPS (window)), FM_OVERPAINT))
+    window_error (GpiSetMix);
+  if (!GpiSetBackColor ((WINDOW_HPS (window)), background))
+    window_error (GpiSetBackColor);
+  if (!GpiSetBackMix ((WINDOW_HPS (window)), BM_OVERPAINT))
+    window_error (GpiSetBackMix);
+  (WINDOW_FOREGROUND_COLOR (window)) = foreground;
+  (WINDOW_BACKGROUND_COLOR (window)) = background;
 }
 \f
 static MRESULT EXPENTRY
 frame_window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-  twindow_t * twindow = (hwnd_to_twindow (WinWindowFromID (hwnd, FID_CLIENT)));
+  window_t * window = (hwnd_to_window (WinWindowFromID (hwnd, FID_CLIENT)));
   switch (msg)
     {
     case WM_QUERYTRACKINFO:
@@ -916,10 +1731,10 @@ frame_window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
                    || (((pti -> fs) & TF_SETPOINTERPOS) != 0)))
              {
                (pti -> fs) |= TF_GRID;
-               (pti -> cxGrid) = (TWINDOW_CHAR_WIDTH (twindow));
-               (pti -> cyGrid) = (TWINDOW_CHAR_HEIGHT (twindow));
-               (pti -> cxKeyboard) = (TWINDOW_CHAR_WIDTH (twindow));
-               (pti -> cyKeyboard) = (TWINDOW_CHAR_HEIGHT (twindow));
+               (pti -> cxGrid) = (WINDOW_GRID_X (window));
+               (pti -> cyGrid) = (WINDOW_GRID_Y (window));
+               (pti -> cxKeyboard) = (WINDOW_GRID_X (window));
+               (pti -> cyKeyboard) = (WINDOW_GRID_Y (window));
              }
          }
        return (mr);
@@ -930,433 +1745,355 @@ frame_window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
         minimization has completed.  */
       {
        PSWP pswp = (PVOIDFROMMP (mp1));
-       if ((!TWINDOW_MINIMIZEDP (twindow))
+       if ((!WINDOW_MINIMIZEDP (window))
            && (((pswp -> fl) & SWP_MINIMIZE) != 0))
          {
-           (TWINDOW_MINIMIZINGP (twindow)) = 1;
-           (TWINDOW_MINIMIZEDP (twindow)) = 1;
+           (WINDOW_MINIMIZINGP (window)) = 1;
+           (WINDOW_MINIMIZEDP (window)) = 1;
          }
-       else if ((TWINDOW_MINIMIZEDP (twindow))
+       else if ((WINDOW_MINIMIZEDP (window))
                 && (((pswp -> fl) & (SWP_RESTORE | SWP_MAXIMIZE)) != 0))
-         (TWINDOW_MINIMIZEDP (twindow)) = 0;
+         (WINDOW_MINIMIZEDP (window)) = 0;
       }
       break;
     }
   return ((* original_frame_window_procedure) (hwnd, msg, mp1, mp2));
 }
 \f
+static int process_button (HWND, MPARAM, MPARAM, unsigned char, unsigned char);
+static int process_keychar
+  (window_t *, unsigned short, unsigned char, unsigned char, unsigned short,
+   unsigned short);
+
 static MRESULT EXPENTRY
-twindow_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
   switch (msg)
     {
     case WM_CREATE:
       {
-       twindow_t * twindow = (PVOIDFROMMP (mp1));
-       (TWINDOW_CLIENT (twindow)) = hwnd;
-       if (!WinSetWindowPtr (hwnd, QWP_TWINDOW, twindow))
+       window_t * window = (PVOIDFROMMP (mp1));
+       SIZEL sizel;
+       (WINDOW_CLIENT (window)) = hwnd;
+       if (!WinSetWindowPtr (hwnd, QWP_WINDOW, window))
          window_error (WinSetWindowPtr);
-       twindow_initialize (twindow);
+       (sizel . cx) = 0;
+       (sizel . cy) = 0;
+       (WINDOW_HPS (window))
+         = (GpiCreatePS (pm_hab,
+                         (WinOpenWindowDC (WINDOW_CLIENT (window))),
+                         (& sizel),
+                         (PU_PELS | GPIF_DEFAULT | GPIT_MICRO
+                          | GPIA_ASSOC)));
+       if ((WINDOW_HPS (window)) == 0)
+         window_error (GpiCreatePS);
+       if (!GpiSetBackMix ((WINDOW_HPS (window)), BM_OVERPAINT))
+         window_error (GpiSetBackMix);
+       /* Put color table in RGB mode so we can specify colors
+          directly in RGB values rather than as indices.  */
+       if (!GpiCreateLogColorTable ((WINDOW_HPS (window)), LCOL_PURECOLOR,
+                                    LCOLF_RGB, 0, 0, 0))
+         window_error (GpiCreateLogColorTable);
+       (WINDOW_FOREGROUND_COLOR (window))
+         = (GpiQueryColor (WINDOW_HPS (window)));
+       (WINDOW_BACKGROUND_COLOR (window))
+         = (GpiQueryBackColor (WINDOW_HPS (window)));
        return (MRFALSE);
       }
     case WM_PAINT:
       {
-       twindow_t * twindow = (hwnd_to_twindow (hwnd));
-       if (((WinQueryWindowULong ((TWINDOW_FRAME (twindow)), QWL_STYLE))
+       window_t * window = (hwnd_to_window (hwnd));
+       if (((WinQueryWindowULong ((WINDOW_FRAME (window)), QWL_STYLE))
             & WS_MINIMIZED)
            != 0)
          break;
-       twindow_paint (twindow);
+       {
+         RECTL rectl;
+         if ((WinBeginPaint ((WINDOW_CLIENT (window)),
+                             (WINDOW_HPS (window)),
+                             (& rectl)))
+             == NULLHANDLE)
+           window_error (WinBeginPaint);
+         clear_rectangle (window, (& rectl));
+         if (!WinEndPaint (WINDOW_HPS (window)))
+           window_error (WinEndPaint);
+         SEND_EVENT (window,
+                     (make_paint_event ((WINDOW_WID (window)),
+                                        (rectl . xLeft),
+                                        (rectl . xRight),
+                                        (rectl . yBottom),
+                                        (rectl . yTop))));
+       }
        return (MRVOID);
       }
     case WM_SETFOCUS:
       {
-       twindow_t * twindow = (hwnd_to_twindow (hwnd));
+       window_t * window = (hwnd_to_window (hwnd));
        if (SHORT1FROMMP (mp2))
-         activate_cursor (twindow);
+         recreate_cursor (window);
        else
-         deactivate_cursor (twindow);
+         {
+           if (!WinDestroyCursor (WINDOW_CLIENT (window)))
+             window_error (WinDestroyCursor);
+         }
+       SEND_EVENT (window,
+                   (make_focus_event ((WINDOW_WID (window)),
+                                      (SHORT1FROMMP (mp2)))));
        return (MRVOID);
       }
     case WM_CHAR:
       return
-       ((twindow_process_keychar ((hwnd_to_twindow (hwnd)),
-                                  (SHORT1FROMMP (mp1)),
-                                  (CHAR3FROMMP (mp1)),
-                                  (CHAR4FROMMP (mp1)),
-                                  (SHORT1FROMMP (mp2)),
-                                  (SHORT2FROMMP (mp2))))
+       ((process_keychar ((hwnd_to_window (hwnd)),
+                          (SHORT1FROMMP (mp1)),
+                          (CHAR3FROMMP (mp1)),
+                          (CHAR4FROMMP (mp1)),
+                          (SHORT1FROMMP (mp2)),
+                          (SHORT2FROMMP (mp2))))
         ? MRTRUE
         : MRFALSE);
+
+    case WM_TRANSLATEACCEL:
+      {
+       PQMSG qmsg = (PVOIDFROMMP (mp1));
+       USHORT flags = (SHORT1FROMMP (qmsg -> mp1));
+       USHORT char_code = (SHORT1FROMMP (qmsg -> mp2));
+       USHORT virtual_key = (SHORT2FROMMP (qmsg -> mp2));
+       /* Disable specific default accelerator keys.  */
+       if ((flags & KC_VIRTUALKEY) != 0)
+         switch (virtual_key)
+           {
+           case VK_ALT:
+           case VK_ALTGRAF:
+             /* Disable "Alt" keys, which normally pop up the system
+                menu.  These keys are used often in Edwin and the
+                default behavior is unacceptable.  */
+             return (MRFALSE);
+           case VK_SPACE:
+           case VK_ESC:
+           case VK_TAB:
+             /* Disable "Alt-SPC", "Alt-ESC", and "Alt-TAB", which
+                have standard key bindings in Edwin.  */
+             if ((flags & KC_ALT) != 0)
+               return (MRFALSE);
+           }
+       else if ((flags & KC_CHAR) != 0)
+         switch (char_code)
+           {
+           case ' ':
+           case '\033':
+           case '\t':
+             /* Disable "Alt-SPC", "Alt-ESC", and "Alt-TAB", if for
+                some reason they are reported as ASCII characters
+                rather than as virtual keys.  */
+             if ((flags & KC_ALT) != 0)
+               return (MRFALSE);
+           }
+       break;
+      }
     case WM_CLOSE:
       {
-       twindow_t * twindow = (hwnd_to_twindow (hwnd));
-       SEND_EVENT (twindow, (make_close_event (TWINDOW_TWID (twindow))));
+       window_t * window = (hwnd_to_window (hwnd));
+       SEND_EVENT (window, (make_close_event (WINDOW_WID (window))));
        return (MRVOID);
       }
+    case WM_DESTROY:
+      if (!GpiDestroyPS (WINDOW_HPS (hwnd_to_window (hwnd))))
+       window_error (GpiDestroyPS);
+      return (MRVOID);
     case WM_SIZE:
       {
-       twindow_t * twindow = (hwnd_to_twindow (hwnd));
+       window_t * window = (hwnd_to_window (hwnd));
        /* If this message is part of a minimization, ignore it.  */
-       if (TWINDOW_MINIMIZINGP (twindow))
+       if (WINDOW_MINIMIZINGP (window))
          {
-           (TWINDOW_MINIMIZINGP (twindow)) = 0;
-           (TWINDOW_MINIMIZEDP (twindow)) = 1;
+           (WINDOW_MINIMIZINGP (window)) = 0;
+           (WINDOW_MINIMIZEDP (window)) = 1;
            break;
          }
-       twindow_resize (twindow, (SHORT1FROMMP (mp2)), (SHORT2FROMMP (mp2)));
+       SEND_EVENT (window,
+                   (make_resize_event ((WINDOW_WID (window)),
+                                       (SHORT1FROMMP (mp2)),
+                                       (SHORT2FROMMP (mp2)))));
        return (MRVOID);
       }
     case WM_SHOW:
-    case WM_BUTTON1CLICK:
+      {
+       window_t * window = (hwnd_to_window (hwnd));
+       SEND_EVENT (window,
+                   (make_visibility_event ((WINDOW_WID (window)),
+                                           (SHORT1FROMMP (mp1)))));
+       return (MRVOID);
+      }
     case WM_BUTTON1DOWN:
+      if (process_button (hwnd, mp1, mp2, 0, BUTTON_EVENT_DOWN))
+       return (MRTRUE);
+      break;
     case WM_BUTTON1UP:
+      if (process_button (hwnd, mp1, mp2, 0, BUTTON_EVENT_UP))
+       return (MRTRUE);
+      break;
+    case WM_BUTTON1CLICK:
+      if (process_button (hwnd, mp1, mp2, 0, BUTTON_EVENT_CLICK))
+       return (MRTRUE);
+      break;
     case WM_BUTTON1DBLCLK:
-    case WM_BUTTON2CLICK:
+      if (process_button (hwnd, mp1, mp2, 0, BUTTON_EVENT_DBLCLK))
+       return (MRTRUE);
+      break;
     case WM_BUTTON2DOWN:
+      if (process_button (hwnd, mp1, mp2, 1, BUTTON_EVENT_DOWN))
+       return (MRTRUE);
+      break;
     case WM_BUTTON2UP:
+      if (process_button (hwnd, mp1, mp2, 1, BUTTON_EVENT_UP))
+       return (MRTRUE);
+      break;
+    case WM_BUTTON2CLICK:
+      if (process_button (hwnd, mp1, mp2, 1, BUTTON_EVENT_CLICK))
+       return (MRTRUE);
+      break;
     case WM_BUTTON2DBLCLK:
-    case WM_BUTTON3CLICK:
+      if (process_button (hwnd, mp1, mp2, 1, BUTTON_EVENT_DBLCLK))
+       return (MRTRUE);
+      break;
     case WM_BUTTON3DOWN:
+      if (process_button (hwnd, mp1, mp2, 2, BUTTON_EVENT_DOWN))
+       return (MRTRUE);
+      break;
     case WM_BUTTON3UP:
+      if (process_button (hwnd, mp1, mp2, 2, BUTTON_EVENT_UP))
+       return (MRTRUE);
+      break;
+    case WM_BUTTON3CLICK:
+      if (process_button (hwnd, mp1, mp2, 2, BUTTON_EVENT_CLICK))
+       return (MRTRUE);
+      break;
     case WM_BUTTON3DBLCLK:
-    case WM_MOUSEMOVE:
+      if (process_button (hwnd, mp1, mp2, 2, BUTTON_EVENT_DBLCLK))
+       return (MRTRUE);
+      break;
     default:
       break;
     }
   return (WinDefWindowProc (hwnd, msg, mp1, mp2));
 }
 
-static twindow_t *
-hwnd_to_twindow (HWND hwnd)
+static window_t *
+hwnd_to_window (HWND hwnd)
 {
-  twindow_t * twindow = (WinQueryWindowPtr (hwnd, QWP_TWINDOW));
-  if (twindow == 0)
+  window_t * window = (WinQueryWindowPtr (hwnd, QWP_WINDOW));
+  if (window == 0)
     window_error (WinQueryWindowPtr);
-  return (twindow);
-}
-\f
-static void
-twindow_initialize (twindow_t * twindow)
-{
-  SIZEL sizel;
-  (sizel . cx) = 0;
-  (sizel . cy) = 0;
-  (TWINDOW_HPS (twindow))
-    = (GpiCreatePS (pm_hab,
-                   (WinOpenWindowDC (TWINDOW_CLIENT (twindow))),
-                   (& sizel),
-                   (PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)));
-  if ((TWINDOW_HPS (twindow)) == 0)
-    window_error (GpiCreatePS);
-  initialize_default_font (twindow, "System VIO", 40, 1);
-  initialize_attributes (twindow);
-  set_twindow_char_dimensions (twindow);
-  initialize_charmap (twindow);
-}
-
-static void
-initialize_default_font (twindow_t * twindow, PSZ font_name, LONG font_size,
-                        LONG font_id)
-{
-  HPS hps = (TWINDOW_HPS (twindow));
-  if ((!set_font_1 (hps, font_name, font_size, font_id))
-      && (!set_font_1 (hps, "Courier", 100, font_id)))
-    OS2_logic_error ("Unable to initialize default font.");
-  {
-    FONTMETRICS fm;
-    if (!GpiQueryFontMetrics (hps, (sizeof (fm)), (& fm)))
-      window_error (GpiQueryFontMetrics);
-    (TWINDOW_CHAR_WIDTH (twindow)) = (fm . lMaxCharInc);
-    (TWINDOW_CHAR_ASCENDER (twindow)) = (fm . lMaxBaselineExt);
-    (TWINDOW_CHAR_DESCENDER (twindow)) = (fm . lMaxDescender);
-  }
-}
-
-static void
-initialize_attributes (twindow_t * twindow)
-{
-  CHARBUNDLE attrs;
-#if 0
-  LONG default_mask
-    = (GpiQueryAttrs ((TWINDOW_HPS (twindow)),
-                     PRIM_CHAR,
-                     (CBB_COLOR | CBB_BACK_COLOR | CBB_MIX_MODE
-                      | CBB_BACK_MIX_MODE | CBB_BOX | CBB_SET | CBB_MODE
-                      | CBB_ANGLE | CBB_SHEAR | CBB_DIRECTION
-                      | CBB_TEXT_ALIGN | CBB_EXTRA | CBB_BREAK_EXTRA),
-                     (& attrs)));
-  if (default_mask == GPI_ALTERROR)
-    window_error (GpiQueryAttrs);
-#endif
-#if 0
-  (attrs . lColor) = CLR_NEUTRAL;
-  (attrs . lBackColor) = CLR_BACKGROUND;
-  (attrs . usMixMode) = FM_OVERPAINT;
-  (attrs . usBackMixMode) = BM_LEAVEALONE;
-  if (!GpiSetAttrs ((TWINDOW_HPS (twindow)),
-                   PRIM_CHAR,
-                   (CBB_COLOR | CBB_BACK_COLOR | CBB_MIX_MODE
-                    | CBB_BACK_MIX_MODE),
-                   0,
-                   (& attrs)))
-    window_error (GpiSetAttrs);
-#endif
-}
-
-static void
-set_twindow_char_dimensions (twindow_t * twindow)
-{
-  SWP swp;
-  if (!WinQueryWindowPos ((TWINDOW_CLIENT (twindow)), (& swp)))
-    window_error (WinQueryWindowPos);
-  (TWINDOW_WIDTH (twindow)) = ((swp . cx) / (TWINDOW_CHAR_WIDTH (twindow)));
-  (TWINDOW_HEIGHT (twindow)) = ((swp . cy) / (TWINDOW_CHAR_HEIGHT (twindow)));
-}
-
-static void
-initialize_charmap (twindow_t * twindow)
-{
-  unsigned short n = ((TWINDOW_WIDTH (twindow)) * (TWINDOW_HEIGHT (twindow)));
-  if ((TWINDOW_CHARMAP (twindow)) != 0)
-    OS_free (TWINDOW_CHARMAP (twindow));
-  if (n == 0)
-    (TWINDOW_CHARMAP (twindow)) = 0;
-  else
-    {
-      (TWINDOW_CHARMAP (twindow)) = (OS_malloc (n));
-      FASTFILL ((TWINDOW_CHARMAP (twindow)), n, ' ');
-    }
+  return (window);
 }
 \f
 static int
-set_font_1 (HPS hps, PSZ font_name, LONG font_size, LONG font_id)
+process_keychar (window_t * window, unsigned short flags,
+                unsigned char repeat, unsigned char scan_code,
+                unsigned short char_code, unsigned short virtual_key)
 {
-  LONG nfonts;
-  ULONG index;
-  PFONTMETRICS pfm;
-
-  nfonts = 0;
-  nfonts = (GpiQueryFonts (hps,
-                          (QF_PUBLIC | QF_PRIVATE),
-                          font_name,
-                          (& nfonts),
-                          (sizeof (FONTMETRICS)),
-                          0));
-  if (nfonts == GPI_ALTERROR)
-    window_error (GpiQueryFonts);
-  if (nfonts == 0)
+  unsigned short code;
+  /* Ignore compound keys for now.  */
+  if ((flags & (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP | KC_KEYUP)) != 0)
     return (0);
-  pfm = (OS_malloc (nfonts * (sizeof (FONTMETRICS))));
-  if ((GpiQueryFonts (hps,
-                     (QF_PUBLIC | QF_PRIVATE),
-                     font_name,
-                     (& nfonts),
-                     (sizeof (FONTMETRICS)),
-                     pfm))
-      == GPI_ALTERROR)
-    window_error (GpiQueryFonts);
-  for (index = 0; (index < nfonts); index += 1)
-    if (((((pfm [index]) . fsType) & FM_TYPE_FIXED) != 0)
-       && ((((pfm [index]) . fsDefn) & FM_DEFN_OUTLINE) == 0)
-       && (((pfm [index]) . sNominalPointSize) == font_size)
-       && (use_font (hps, (& (pfm [index])), font_id)))
-      {
-       OS_free (pfm);
-       return (1);
-      }
-  OS_free (pfm);
-  return (0);
+  else if ((flags & KC_VIRTUALKEY) != 0)
+    code = virtual_key;
+  else if ((flags & (KC_CHAR | KC_CTRL | KC_ALT)) != 0)
+    code = char_code;
+  else
+    return (0);
+  SEND_EVENT
+    (window,
+     (make_key_event ((WINDOW_WID (window)), code, flags, repeat)));
 }
 
 static int
-use_font (HPS hps, PFONTMETRICS pfm, LONG font_id)
-{
-  FATTRS font_attrs;
-
-  (font_attrs . usRecordLength) = (sizeof (font_attrs));
-  (font_attrs . fsSelection) = 0;
-  (font_attrs . lMatch) = (pfm -> lMatch);
-  strcpy ((font_attrs . szFacename), (pfm -> szFacename));
-  (font_attrs . idRegistry) = 0;
-  (font_attrs . usCodePage) = (WinQueryCp (pm_hmq));
-  if ((font_attrs . usCodePage) == 0)
-    window_error (WinQueryCp);
-  (font_attrs . lMaxBaselineExt) = 0;
-  (font_attrs . lAveCharWidth) = 0;
-  (font_attrs . fsType) = 0;
-  (font_attrs . fsFontUse) = 0;
-  if ((GpiCreateLogFont (hps, 0, font_id, (& font_attrs))) != FONT_MATCH)
-    return (0);
-  GpiSetCharSet (hps, font_id);
+process_button (HWND hwnd, MPARAM mp1, MPARAM mp2,
+               unsigned char number, unsigned char type)
+{
+  window_t * window = (hwnd_to_window (hwnd));
+  SEND_EVENT (window,
+             (make_button_event ((WINDOW_WID (window)),
+                                 number,
+                                 type,
+                                 (SHORT1FROMMP (mp1)),
+                                 (SHORT2FROMMP (mp1)),
+                                 ((SHORT2FROMMP (mp2))
+                                  & (KC_SHIFT | KC_CTRL | KC_ALT)))));
   return (1);
 }
 \f
-static void
-twindow_paint (twindow_t * twindow)
-{
-  RECTL rectl;
-  HPS hps =
-    (WinBeginPaint ((TWINDOW_CLIENT (twindow)),
-                   (TWINDOW_HPS (twindow)),
-                   (& rectl)));
-  if (hps == NULLHANDLE)
-    window_error (WinBeginPaint);
-  if (!WinFillRect ((TWINDOW_HPS (twindow)), (& rectl), CLR_BACKGROUND))
-    window_error (WinFillRect);
-  {
-    unsigned short xl = (x2cx (twindow, (rectl . xLeft), 1));
-    unsigned short xh = (x2cx (twindow, (rectl . xRight), 0));
-    unsigned short yl = (y2cy (twindow, (rectl . yTop), 0));
-    unsigned short yh = (y2cy (twindow, (rectl . yBottom), 1));
-    unsigned short size = (xh - xl);
-    while (yl < yh)
-      draw_partial_line (twindow, xl, (yl++), size);
-  }
-  if (!WinEndPaint (hps))
-    window_error (WinEndPaint);
-}
-
-static void
-draw_partial_line (twindow_t * twindow, unsigned short x, unsigned short y,
-                  unsigned short size)
-{
-  HPS hps = (TWINDOW_HPS (twindow));
-  char * target = (TWINDOW_CHAR_LOC (twindow, x, y));
-  POINTL ptl;
-  (ptl . x) = (cx2x (twindow, x));
-  (ptl . y) = ((cy2y (twindow, y, 1)) + (TWINDOW_CHAR_DESCENDER (twindow)));
-  if (size <= 512)
-    GpiCharStringAt (hps, (& ptl), size, target);
-  else
-    {
-      GpiMove (hps, (& ptl));
-      while (size > 0)
-       {
-         unsigned short n = ((size > 512) ? 512 : size);
-         GpiCharString (hps, n, target);
-         size -= n;
-         target += n;
-       }
-    }
-}
-\f
-static void
-activate_cursor (twindow_t * twindow)
-{
-  if (!WinCreateCursor ((TWINDOW_CLIENT (twindow)),
-                       (cx2x (twindow, (TWINDOW_CURSOR_X (twindow)))),
-                       (cy2y (twindow, (TWINDOW_CURSOR_Y (twindow)), 1)),
-                       (TWINDOW_CHAR_WIDTH (twindow)),
-                       (TWINDOW_CHAR_HEIGHT (twindow)),
-                       (CURSOR_SOLID | CURSOR_FLASH),
-                       0))
-    window_error (WinCreateCursor);
-  if (TWINDOW_CURSOR_SHOWNP (twindow))
-    if (!WinShowCursor ((TWINDOW_CLIENT (twindow)), TRUE))
-      window_error (WinShowCursor);
-}
-
-static void
-deactivate_cursor (twindow_t * twindow)
-{
-  if (!WinDestroyCursor (TWINDOW_CLIENT (twindow)))
-    window_error (WinDestroyCursor);
+static msg_t *
+make_button_event (wid_t wid, unsigned char number, unsigned char type,
+                  unsigned short x, unsigned short y, unsigned short flags)
+{
+  msg_t * message = (OS2_create_message (mt_button_event));
+  (SM_BUTTON_EVENT_WID (message)) = wid;
+  (SM_BUTTON_EVENT_TYPE (message)) = (number | (type << 4));
+  (SM_BUTTON_EVENT_X (message)) = x;
+  (SM_BUTTON_EVENT_Y (message)) = y;
+  (SM_BUTTON_EVENT_FLAGS (message)) = flags;
+  return (message);
 }
 
-static void
-show_cursor (twindow_t * twindow)
+static msg_t *
+make_close_event (wid_t wid)
 {
-  if (!TWINDOW_CURSOR_SHOWNP (twindow))
-    {
-      if (twindow_focusp (twindow))
-       if (!WinShowCursor ((TWINDOW_CLIENT (twindow)), TRUE))
-         window_error (WinShowCursor);
-      (TWINDOW_CURSOR_SHOWNP (twindow)) = 1;
-    }
+  msg_t * message = (OS2_create_message (mt_close_event));
+  (SM_CLOSE_EVENT_WID (message)) = wid;
+  return (message);
 }
 
-static void
-hide_cursor (twindow_t * twindow)
+static msg_t *
+make_focus_event (wid_t wid, int gainedp)
 {
-  if (TWINDOW_CURSOR_SHOWNP (twindow))
-    {
-      if (twindow_focusp (twindow))
-       if (!WinShowCursor ((TWINDOW_CLIENT (twindow)), FALSE))
-         window_error (WinShowCursor);
-      (TWINDOW_CURSOR_SHOWNP (twindow)) = 0;
-    }
+  msg_t * message = (OS2_create_message (mt_focus_event));
+  (SM_FOCUS_EVENT_WID (message)) = wid;
+  (SM_FOCUS_EVENT_GAINEDP (message)) = gainedp;
+  return (message);
 }
 
-static int
-twindow_focusp (twindow_t * twindow)
+static msg_t *
+make_key_event (wid_t wid, unsigned short code,
+               unsigned short flags, unsigned short repeat)
 {
-  return ((TWINDOW_CLIENT (twindow)) == (WinQueryFocus (HWND_DESKTOP)));
+  msg_t * message = (OS2_create_message (mt_key_event));
+  (SM_KEY_EVENT_WID (message)) = wid;
+  (SM_KEY_EVENT_CODE (message)) = code;
+  (SM_KEY_EVENT_FLAGS (message)) = flags;
+  (SM_KEY_EVENT_REPEAT (message)) = repeat;
+  return (message);
 }
 
-static void
-twindow_resize (twindow_t * twindow, unsigned short width,
-               unsigned short height)
-{
-  unsigned short cx = (width / (TWINDOW_CHAR_WIDTH (twindow)));
-  unsigned short cy = (height / (TWINDOW_CHAR_HEIGHT (twindow)));
-  if ((cx == (TWINDOW_WIDTH (twindow))) && (cy == (TWINDOW_HEIGHT (twindow))))
-    return;
-  (TWINDOW_WIDTH (twindow)) = cx;
-  (TWINDOW_HEIGHT (twindow)) = cy;
-  initialize_charmap (twindow);
-  SEND_EVENT (twindow, (make_resize_event ((TWINDOW_TWID (twindow)), cx, cy)));
+static msg_t *
+make_paint_event (wid_t wid,
+                 unsigned short xl, unsigned short xh,
+                 unsigned short yl, unsigned short yh)
+{
+  msg_t * message = (OS2_create_message (mt_paint_event));
+  (SM_PAINT_EVENT_WID (message)) = wid;
+  (SM_PAINT_EVENT_XL (message)) = xl;
+  (SM_PAINT_EVENT_XH (message)) = xh;
+  (SM_PAINT_EVENT_YL (message)) = yl;
+  (SM_PAINT_EVENT_YH (message)) = yh;
+  return (message);
 }
 
 static msg_t *
-make_resize_event (twid_t twid, unsigned short width, unsigned short height)
+make_resize_event (wid_t wid, unsigned short width, unsigned short height)
 {
   msg_t * message = (OS2_create_message (mt_resize_event));
-  (SM_RESIZE_EVENT_TWID (message)) = twid;
+  (SM_RESIZE_EVENT_WID (message)) = wid;
   (SM_RESIZE_EVENT_WIDTH (message)) = width;
   (SM_RESIZE_EVENT_HEIGHT (message)) = height;
   return (message);
 }
-\f
-static int
-twindow_process_keychar (twindow_t * twindow, unsigned short flags,
-                        unsigned char repeat, unsigned char scan_code,
-                        unsigned short char_code, unsigned short virtual_key)
-{
-  /* Ignore compound keys for now.  */
-  if ((flags & (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP | KC_KEYUP)) != 0)
-    return (0);
-  else if ((flags & KC_VIRTUALKEY) != 0)
-    {
-      send_key_event (twindow, virtual_key, flags, repeat);
-      return (1);
-    }
-  else if ((flags & (KC_CHAR | KC_CTRL | KC_ALT)) != 0)
-    {
-      send_key_event (twindow, char_code, flags, repeat);
-      return (1);
-    }
-  else
-    return (0);
-}
-
-static void
-send_key_event (twindow_t * twindow, unsigned short code,
-               unsigned short flags, unsigned short repeat)
-{
-  SEND_EVENT
-    (twindow,
-     (make_key_event ((TWINDOW_TWID (twindow)), code, flags, repeat)));
-}
 
 static msg_t *
-make_key_event (twid_t twid, unsigned short code,
-               unsigned short flags, unsigned short repeat)
+make_visibility_event (wid_t wid, int shownp)
 {
-  msg_t * message = (OS2_create_message (mt_key_event));
-  (SM_KEY_EVENT_TWID (message)) = twid;
-  (SM_KEY_EVENT_CODE (message)) = code;
-  (SM_KEY_EVENT_FLAGS (message)) = flags;
-  (SM_KEY_EVENT_REPEAT (message)) = repeat;
+  msg_t * message = (OS2_create_message (mt_visibility_event));
+  (SM_VISIBILITY_EVENT_WID (message)) = wid;
+  (SM_VISIBILITY_EVENT_SHOWNP (message)) = shownp;
   return (message);
 }
index c50bacf18601d051f8d1dae2e46059c315fa8a0c..c614d9933596ff25e0815ade5dfbd7d9d1e1fcc9 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2pm.h,v 1.1 1994/12/02 20:44:35 cph Exp $
+$Id: os2pm.h,v 1.2 1994/12/19 22:31:40 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -35,130 +35,66 @@ MIT in each case. */
 #ifndef SCM_OS2PM_H
 #define SCM_OS2PM_H
 \f
-typedef unsigned short twid_t;
+typedef unsigned short wid_t;
 
 typedef struct
 {
-  DECLARE_MSG_HEADER_FIELDS;
-  qid_t event_qid;
-  const char * title;
-} sm_twindow_open_request_t;
-#define SM_TWINDOW_OPEN_REQUEST_EVENT_QID(m)                           \
-  (((sm_twindow_open_request_t *) (m)) -> event_qid)
-#define SM_TWINDOW_OPEN_REQUEST_TITLE(m)                               \
-  (((sm_twindow_open_request_t *) (m)) -> title)
-
-typedef struct
-{
-  DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-} sm_twindow_open_reply_t;
-#define SM_TWINDOW_OPEN_REPLY_TWID(m)                                  \
-  (((sm_twindow_open_reply_t *) (m)) -> twid)
-
-typedef struct
-{
-  DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-} sm_twindow_close_request_t;
-#define SM_TWINDOW_CLOSE_REQUEST_TWID(m)                               \
-  (((sm_twindow_close_request_t *) (m)) -> twid)
+  unsigned short width;
+  unsigned short height;
+  unsigned short descender;
+} font_metrics_t;
+#define FONT_METRICS_WIDTH(m) ((m) -> width)
+#define FONT_METRICS_HEIGHT(m) ((m) -> height)
+#define FONT_METRICS_DESCENDER(m) ((m) -> descender)
 
 typedef struct
 {
   DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
+  wid_t wid;
+  unsigned char btype;
   unsigned short x;
   unsigned short y;
-  unsigned short size;
-  const char * data;
-} sm_twindow_write_request_t;
-#define SM_TWINDOW_WRITE_REQUEST_TWID(m)                               \
-  (((sm_twindow_write_request_t *) (m)) -> twid)
-#define SM_TWINDOW_WRITE_REQUEST_X(m)                                  \
-  (((sm_twindow_write_request_t *) (m)) -> x)
-#define SM_TWINDOW_WRITE_REQUEST_Y(m)                                  \
-  (((sm_twindow_write_request_t *) (m)) -> y)
-#define SM_TWINDOW_WRITE_REQUEST_SIZE(m)                               \
-  (((sm_twindow_write_request_t *) (m)) -> size)
-#define SM_TWINDOW_WRITE_REQUEST_DATA(m)                               \
-  (((sm_twindow_write_request_t *) (m)) -> data)
+  unsigned short flags;
+} sm_button_event_t;
+#define SM_BUTTON_EVENT_WID(m) (((sm_button_event_t *) (m)) -> wid)
+#define SM_BUTTON_EVENT_TYPE(m) (((sm_button_event_t *) (m)) -> btype)
+#define SM_BUTTON_EVENT_X(m) (((sm_button_event_t *) (m)) -> x)
+#define SM_BUTTON_EVENT_Y(m) (((sm_button_event_t *) (m)) -> y)
+#define SM_BUTTON_EVENT_FLAGS(m) (((sm_button_event_t *) (m)) -> flags)
 
-typedef struct
-{
-  DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-  unsigned short x;
-  unsigned short y;
-} sm_twindow_move_cursor_request_t;
-#define SM_TWINDOW_MOVE_CURSOR_REQUEST_TWID(m)                         \
-  (((sm_twindow_move_cursor_request_t *) (m)) -> twid)
-#define SM_TWINDOW_MOVE_CURSOR_REQUEST_X(m)                            \
-  (((sm_twindow_move_cursor_request_t *) (m)) -> x)
-#define SM_TWINDOW_MOVE_CURSOR_REQUEST_Y(m)                            \
-  (((sm_twindow_move_cursor_request_t *) (m)) -> y)
+#define BUTTON_EVENT_DOWN 0
+#define BUTTON_EVENT_UP 1
+#define BUTTON_EVENT_CLICK 2
+#define BUTTON_EVENT_DBLCLK 3
+
+#define BUTTON_TYPE_NUMBER(type) ((type) & 0xf)
+#define BUTTON_TYPE_EVENT(type) (((type) >> 4) & 0xf)
 
 typedef struct
 {
   DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-} sm_twindow_clear_request_t;
-#define SM_TWINDOW_CLEAR_REQUEST_TWID(m)                               \
-  (((sm_twindow_clear_request_t *) (m)) -> twid)
-#define SM_TWINDOW_CLEAR_REQUEST_X(m)                                  \
-  (((sm_twindow_clear_request_t *) (m)) -> x)
-#define SM_TWINDOW_CLEAR_REQUEST_Y(m)                                  \
-  (((sm_twindow_clear_request_t *) (m)) -> y)
-\f
-typedef struct
-{
-  DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-  unsigned short x;
-  unsigned short y;
-} sm_twindow_clear_eol_request_t;
-#define SM_TWINDOW_CLEAR_EOL_REQUEST_TWID(m)                           \
-  (((sm_twindow_clear_eol_request_t *) (m)) -> twid)
-#define SM_TWINDOW_CLEAR_EOL_REQUEST_X(m)                              \
-  (((sm_twindow_clear_eol_request_t *) (m)) -> x)
-#define SM_TWINDOW_CLEAR_EOL_REQUEST_Y(m)                              \
-  (((sm_twindow_clear_eol_request_t *) (m)) -> y)
+  wid_t wid;
+} sm_close_event_t;
+#define SM_CLOSE_EVENT_WID(m) (((sm_close_event_t *) (m)) -> wid)
 
 typedef struct
 {
   DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-  unsigned short x_start;
-  unsigned short x_end;
-  unsigned short y_start;
-  unsigned short y_end;
-  short x_delta;
-  short y_delta;
-} sm_twindow_scroll_request_t;
-#define SM_TWINDOW_SCROLL_REQUEST_TWID(m)                              \
-  (((sm_twindow_scroll_request_t *) (m)) -> twid)
-#define SM_TWINDOW_SCROLL_REQUEST_X_START(m)                           \
-  (((sm_twindow_scroll_request_t *) (m)) -> x_start)
-#define SM_TWINDOW_SCROLL_REQUEST_X_END(m)                             \
-  (((sm_twindow_scroll_request_t *) (m)) -> x_end)
-#define SM_TWINDOW_SCROLL_REQUEST_Y_START(m)                           \
-  (((sm_twindow_scroll_request_t *) (m)) -> y_start)
-#define SM_TWINDOW_SCROLL_REQUEST_Y_END(m)                             \
-  (((sm_twindow_scroll_request_t *) (m)) -> y_end)
-#define SM_TWINDOW_SCROLL_REQUEST_X_DELTA(m)                           \
-  (((sm_twindow_scroll_request_t *) (m)) -> x_delta)
-#define SM_TWINDOW_SCROLL_REQUEST_Y_DELTA(m)                           \
-  (((sm_twindow_scroll_request_t *) (m)) -> y_delta)
+  wid_t wid;
+  char gainedp;
+} sm_focus_event_t;
+#define SM_FOCUS_EVENT_WID(m) (((sm_focus_event_t *) (m)) -> wid)
+#define SM_FOCUS_EVENT_GAINEDP(m) (((sm_focus_event_t *) (m)) -> gainedp)
 
 typedef struct
 {
   DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
+  wid_t wid;
   unsigned short code;
   unsigned short flags;
   unsigned short repeat;
 } sm_key_event_t;
-#define SM_KEY_EVENT_TWID(m) (((sm_key_event_t *) (m)) -> twid)
+#define SM_KEY_EVENT_WID(m) (((sm_key_event_t *) (m)) -> wid)
 #define SM_KEY_EVENT_CODE(m) (((sm_key_event_t *) (m)) -> code)
 #define SM_KEY_EVENT_FLAGS(m) (((sm_key_event_t *) (m)) -> flags)
 #define SM_KEY_EVENT_REPEAT(m) (((sm_key_event_t *) (m)) -> repeat)
@@ -166,54 +102,85 @@ typedef struct
 typedef struct
 {
   DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-  
-} sm_button_event_t;
-#define SM_BUTTON_EVENT_TWID(m) (((sm_button_event_t *) (m)) -> twid)
-
-typedef struct
-{
-  DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-} sm_close_event_t;
-#define SM_CLOSE_EVENT_TWID(m) (((sm_close_event_t *) (m)) -> twid)
-\f
-typedef struct
-{
-  DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
-  unsigned char state;
-} sm_visibility_event_t;
-#define SM_VISIBILITY_EVENT_TWID(m) (((sm_visibility_event_t *) (m)) -> twid)
-#define SM_VISIBILITY_EVENT_STATE(m) (((sm_visibility_event_t *) (m)) -> state)
-
-#define VISIBILITY_OBSCURED 0
-#define VISIBILITY_PARTIALLY_OBSCURED 1
-#define VISIBILITY_UNOBSCURED 2
+  wid_t wid;
+  unsigned short xl;
+  unsigned short xh;
+  unsigned short yl;
+  unsigned short yh;
+} sm_paint_event_t;
+#define SM_PAINT_EVENT_WID(m) (((sm_paint_event_t *) (m)) -> wid)
+#define SM_PAINT_EVENT_XL(m) (((sm_paint_event_t *) (m)) -> xl)
+#define SM_PAINT_EVENT_XH(m) (((sm_paint_event_t *) (m)) -> xh)
+#define SM_PAINT_EVENT_YL(m) (((sm_paint_event_t *) (m)) -> yl)
+#define SM_PAINT_EVENT_YH(m) (((sm_paint_event_t *) (m)) -> yh)
 
 typedef struct
 {
   DECLARE_MSG_HEADER_FIELDS;
-  twid_t twid;
+  wid_t wid;
   unsigned short width;
   unsigned short height;
 } sm_resize_event_t;
-#define SM_RESIZE_EVENT_TWID(m) (((sm_resize_event_t *) (m)) -> twid)
+#define SM_RESIZE_EVENT_WID(m) (((sm_resize_event_t *) (m)) -> wid)
 #define SM_RESIZE_EVENT_WIDTH(m) (((sm_resize_event_t *) (m)) -> width)
 #define SM_RESIZE_EVENT_HEIGHT(m) (((sm_resize_event_t *) (m)) -> height)
 
-extern int OS2_read_pm_tqueue (tqueue_t *, int);
+typedef struct
+{
+  DECLARE_MSG_HEADER_FIELDS;
+  wid_t wid;
+  char shownp;
+} sm_visibility_event_t;
+#define SM_VISIBILITY_EVENT_WID(m) (((sm_visibility_event_t *) (m)) -> wid)
+#define SM_VISIBILITY_EVENT_SHOWNP(m)                                  \
+  (((sm_visibility_event_t *) (m)) -> shownp)
+\f
+typedef enum
+{
+  state_top,
+  state_bottom,
+  state_show,
+  state_hide,
+  state_activate,
+  state_deactivate,
+  state_minimize,
+  state_maximize,
+  state_restore,
+  state_supremum
+} window_state_t;
+
+extern msg_t * OS2_read_pm_tqueue (tqueue_t *, int);
 extern void OS2_write_pm_tqueue (tqueue_t *, msg_t *);
 
-extern twid_t OS2_twindow_open (qid_t, const char *);
-extern void OS2_twindow_close (twid_t);
-extern void OS2_twindow_write
-  (twid_t, unsigned short, unsigned short, const char *, unsigned short);
-extern void OS2_twindow_move_cursor (twid_t, unsigned short, unsigned short);
-extern void OS2_twindow_clear (twid_t);
-extern void OS2_twindow_clear_eol (twid_t, unsigned short, unsigned short);
-extern void OS2_twindow_scroll
-  (twid_t, unsigned short, unsigned short, unsigned short, unsigned short,
+extern int OS2_wid_validp (wid_t);
+extern qid_t OS2_create_pm_qid (tqueue_t *);
+extern wid_t OS2_window_open (qid_t, qid_t, const char *);
+extern void OS2_window_permanent (wid_t);
+extern void OS2_window_close (wid_t);
+extern void OS2_window_show (wid_t, int);
+extern void OS2_window_write
+  (wid_t, unsigned short, unsigned short, const char *, unsigned short);
+extern void OS2_window_move_cursor (wid_t, unsigned short, unsigned short);
+extern void OS2_window_shape_cursor
+  (wid_t, unsigned short, unsigned short, unsigned short);
+extern void OS2_window_show_cursor (wid_t, int);
+extern void OS2_window_clear
+  (wid_t, unsigned short, unsigned short, unsigned short, unsigned short);
+extern void OS2_window_scroll
+  (wid_t, unsigned short, unsigned short, unsigned short, unsigned short,
    short, short);
+extern void OS2_window_invalidate
+  (wid_t, unsigned short, unsigned short, unsigned short, unsigned short);
+extern font_metrics_t * OS2_window_set_font
+  (wid_t, unsigned short, const char *);
+extern void OS2_window_set_grid (wid_t, unsigned short, unsigned short);
+extern void OS2_window_activate (wid_t);
+extern void OS2_window_pos (wid_t, unsigned short *, unsigned short *);
+extern void OS2_window_set_pos (wid_t, unsigned short, unsigned short);
+extern void OS2_window_size (wid_t, unsigned short *, unsigned short *);
+extern void OS2_window_set_size (wid_t, unsigned short, unsigned short);
+extern int OS2_window_focusp (wid_t);
+extern void OS2_window_set_state (wid_t, window_state_t);
+extern void OS2_window_set_colors (wid_t, COLOR, COLOR);
 
 #endif /* SCM_OS2PM_H */
index 592e512e7fea7e9e25a3ddf713f220a093975ed6..6bfe5b762072949e43721dd6300733e7fdc951a6 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2pmcon.c,v 1.1 1994/12/02 20:44:41 cph Exp $
+$Id: os2pmcon.c,v 1.2 1994/12/19 22:31:42 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -35,49 +35,162 @@ MIT in each case. */
 #define INCL_WIN
 #include "os2.h"
 
+/* #define CONSOLE_WRAP */
+
+static void grab_console_lock (void);
+static void release_console_lock (void);
 static void process_events (int);
-static int  translate_key_event (msg_t *);
+static void console_resize (unsigned short, unsigned short);
+static void console_paint
+  (unsigned short, unsigned short, unsigned short, unsigned short);
+static void console_clear
+  (unsigned short, unsigned short, unsigned short, unsigned short);
+static void console_clear_all (void);
+static int translate_key_event (msg_t *);
 static const char * find_nonprint (const char *, const char *);
 static void do_carriage_return (void);
 static void do_linefeed (void);
+static unsigned short find_invalid_line (unsigned short, unsigned short);
 static void do_formfeed (void);
 static void do_backspace (void);
 static void do_alert (void);
 \f
+static HMTX console_lock;
+static unsigned short console_pel_width;
+static unsigned short console_pel_height;
 static unsigned short console_width;
 static unsigned short console_height;
+static char * console_chars;
+static font_metrics_t * metrics;
 static unsigned short point_x;
 static unsigned short point_y;
-static tqueue_t * console_tqueue;
-static qid_t console_qid;
-static qid_t remote_qid;
-static twid_t console_twid;
+static int console_visiblep;
 static int console_closedp;
 static unsigned short readahead_repeat;
 static char readahead_char;
 static msg_list_t * pending_events_head;
 static msg_list_t * pending_events_tail;
+static tqueue_t * console_tqueue;
+static qid_t console_event_qid;
+static qid_t console_pm_qid;
+static wid_t console_wid;
+
+#define CHAR_WIDTH (FONT_METRICS_WIDTH (metrics))
+#define CHAR_HEIGHT (FONT_METRICS_HEIGHT (metrics))
+#define CHAR_DESCENDER (FONT_METRICS_DESCENDER (metrics))
+#define CHAR_LOC(x, y) (& (console_chars [((y) * console_width) + (x)]))
+
+#define FASTFILL(p, n, c)                                              \
+{                                                                      \
+  char * FASTFILL_scan = (p);                                          \
+  char * FASTFILL_end = (FASTFILL_scan + (n));                         \
+  while (FASTFILL_scan < FASTFILL_end)                                 \
+    (*FASTFILL_scan++) = (c);                                          \
+}
 
 void
 OS2_initialize_pm_console (void)
 {
+  console_lock = (OS2_create_mutex_semaphore (0, 0));
+  console_pel_width = 0;
+  console_pel_height = 0;
+  console_width = 0;
+  console_height = 0;
+  console_chars = 0;
   point_x = 0;
   point_y = 0;
+  console_visiblep = 0;
   console_closedp = 0;
   readahead_repeat = 0;
   pending_events_head = 0;
   console_tqueue = (OS2_make_std_tqueue ());
-  OS2_make_qid_pair ((&console_qid), (&remote_qid));
-  OS2_open_qid (console_qid, console_tqueue);
-  console_twid = (OS2_twindow_open (remote_qid, "Scheme"));
+  {
+    qid_t remote;
+    OS2_make_qid_pair ((&console_event_qid), (&remote));
+    OS2_open_qid (console_event_qid, console_tqueue);
+    console_pm_qid = (OS2_create_pm_qid (console_tqueue));
+    console_wid = (OS2_window_open (console_pm_qid, remote, "Scheme"));
+  }
+  OS2_window_permanent (console_wid);
+  metrics = OS2_window_set_font (console_wid, 1, "4.System VIO");
+  if (metrics == 0)
+    OS2_logic_error ("Unable to find 4 point System VIO font.");
+  OS2_window_set_grid (console_wid, CHAR_WIDTH, CHAR_HEIGHT);
+  OS2_window_show (console_wid, 1);
+  OS2_window_shape_cursor
+    (console_wid, CHAR_WIDTH, CHAR_HEIGHT, (CURSOR_SOLID | CURSOR_FLASH));
+  OS2_window_show_cursor (console_wid, 1);
 }
 
+wid_t
+OS2_console_wid (void)
+{
+  return (console_wid);
+}
+\f
+static void
+grab_console_lock (void)
+{
+  OS2_request_mutex_semaphore (console_lock);
+}
+
+static void
+release_console_lock (void)
+{
+  OS2_release_mutex_semaphore (console_lock);
+}
+
+static unsigned short
+cx2x (unsigned short x)
+{
+  return (x * CHAR_WIDTH);
+}
+
+static unsigned short
+cy2y (unsigned short y, int lowerp)
+{
+  /* lowerp => result is bottommost pel of cell.  Otherwise result is
+     bottommost pel of cell above.  */
+  unsigned short limit = (lowerp ? (console_height - 1) : console_height);
+  return ((y < limit) ? ((limit - y) * CHAR_HEIGHT) : 0);
+}
+
+static unsigned short
+x2cx (unsigned short x, int lowerp)
+{
+  /* lowerp => `x' is inclusive lower bound, and result is cell it
+     falls in.  Otherwise, `x' is exclusive upper bound, and result is
+     cell to its right, unless it falls on leftmost edge of cell.  If
+     the argument is inclusive-lower, then the result is also;
+     likewise for exclusive-upper.  */
+  unsigned short cx = (x / CHAR_WIDTH);
+  if (! (lowerp || ((x % CHAR_WIDTH) == 0)))
+    cx += 1;
+  return ((cx > console_width) ? console_width : cx);
+}
+
+static unsigned short
+y2cy (unsigned short y, int lowerp)
+{
+  /* lowerp => `y' is inclusive lower bound, and result is cell below
+     the one it falls in.  Otherwise, `y' is exclusive upper bound,
+     and result is cell it falls in, unless it falls on bottommost
+     edge of cell, when result is cell below.  If the argument is
+     inclusive-lower, then the result is exclusive-upper, and
+     vice-versa.  */
+  short cy = (((short) (console_height - 1)) - ((short) (y / CHAR_HEIGHT)));
+  if (lowerp || ((y % CHAR_HEIGHT) == 0))
+    cy += 1;
+  return ((cy < 0) ? 0 : cy);
+}
+\f
 static void
 process_events (int blockp)
 {
   while (1)
     {
-      msg_t * message = (OS2_receive_message (console_qid, blockp));
+      msg_t * message
+       = (OS2_receive_message (console_event_qid, blockp, 0));
       if (message == 0)
        break;
       switch (MSG_TYPE (message))
@@ -98,21 +211,120 @@ process_events (int blockp)
            break;
          }
        case mt_resize_event:
-         console_width = (SM_RESIZE_EVENT_WIDTH (message));
-         console_height = (SM_RESIZE_EVENT_HEIGHT (message));
+         {
+           unsigned short new_pel_width = (SM_RESIZE_EVENT_WIDTH (message));
+           unsigned short new_pel_height = (SM_RESIZE_EVENT_HEIGHT (message));
+           OS2_destroy_message (message);
+           grab_console_lock ();
+           console_resize (new_pel_width, new_pel_height);
+           release_console_lock ();
+           break;
+         }
+       case mt_paint_event:
+         {
+           unsigned short xl = (SM_PAINT_EVENT_XL (message));
+           unsigned short xh = (SM_PAINT_EVENT_XH (message));
+           unsigned short yl = (SM_PAINT_EVENT_YL (message));
+           unsigned short yh = (SM_PAINT_EVENT_YH (message));
+           OS2_destroy_message (message);
+           grab_console_lock ();
+           console_paint (xl, xh, yl, yh);
+           release_console_lock ();
+           break;
+         }
+       case mt_visibility_event:
+         if ((!console_visiblep) && (SM_VISIBILITY_EVENT_SHOWNP (message)))
+           {
+             grab_console_lock ();
+             OS2_window_invalidate (console_wid,
+                                    0, console_pel_width,
+                                    0, console_pel_height);
+             release_console_lock ();
+           }
+         console_visiblep = (SM_VISIBILITY_EVENT_SHOWNP (message));
          OS2_destroy_message (message);
          break;
        case mt_button_event:
-       case mt_visibility_event:
+         if ((BUTTON_TYPE_EVENT (SM_BUTTON_EVENT_TYPE (message)))
+              == BUTTON_EVENT_DOWN)
+           OS2_window_activate (SM_BUTTON_EVENT_WID (message));
          OS2_destroy_message (message);
          break;
        default:
-         OS2_logic_error ("Unknown message type received by PM console.");
+         OS2_destroy_message (message);
          break;
        }
     }
 }
 \f
+static void
+console_resize (unsigned short new_pel_width, unsigned short new_pel_height)
+{
+  unsigned short new_width = (new_pel_width / CHAR_WIDTH);
+  unsigned short new_height = (new_pel_height / CHAR_HEIGHT);
+  char * new_chars = (OS_malloc (new_width * new_height));
+  FASTFILL (new_chars, (new_width * new_height), ' ');
+  if (console_chars != 0)
+    {
+      unsigned short xlim
+       = ((new_width < console_width) ? new_width : console_width);
+      unsigned short ylim
+       = ((new_height < console_height) ? new_height : console_height);
+      char * from = console_chars;
+      char * to = new_chars;
+      unsigned short y = 0;
+      while (y < ylim)
+       {
+         FASTCOPY (from, to, xlim);
+         from += console_width;
+         to += new_width;
+         y += 1;
+       }
+      OS_free (console_chars);
+    }
+  console_pel_width = new_pel_width;
+  console_pel_height = new_pel_height;
+  console_width = new_width;
+  console_height = new_height;
+  console_chars = new_chars;
+}
+
+static void
+console_paint (unsigned short xl, unsigned short xh,
+              unsigned short yl, unsigned short yh)
+{
+  unsigned short cxl = (x2cx (xl, 1));
+  unsigned short cxh = (x2cx (xh, 0));
+  unsigned short cyl = (y2cy (yh, 0));
+  unsigned short cyh = (y2cy (yl, 1));
+  if ((cxl < cxh) && (cyl < cyh))
+    {
+      unsigned short size = (cxh - cxl);
+      unsigned short x = (cx2x (cxl));
+      while (cyl < cyh)
+       {
+         OS2_window_write (console_wid, x, ((cy2y (cyl, 1)) + CHAR_DESCENDER),
+                           (CHAR_LOC (cxl, cyl)), size);
+         cyl += 1;
+       }
+    }
+}
+
+static void
+console_clear (unsigned short xl, unsigned short xh,
+                   unsigned short yl, unsigned short yh)
+{
+  OS2_window_clear (console_wid,
+                   (cx2x (xl)), (cx2x (xh)),
+                   (cy2y (yh, 0)), (cy2y (yl, 0)));
+}
+
+static void
+console_clear_all (void)
+{
+  OS2_window_clear (console_wid, 0, console_pel_width, 0, console_pel_height);
+}
+\f
 int
 OS2_pm_console_getch (void)
 {
@@ -142,12 +354,11 @@ OS2_pm_console_getch (void)
              }
            case mt_close_event:
              {
-               twid_t twid = (SM_CLOSE_EVENT_TWID (message));
+               wid_t wid = (SM_CLOSE_EVENT_WID (message));
                OS2_destroy_message (message);
-               OS2_twindow_close (twid);
+               OS2_window_close (wid);
              }
-             OS2_close_qid (remote_qid);
-             OS2_close_qid (console_qid);
+             OS2_close_qid (console_event_qid);
              OS2_close_std_tqueue (console_tqueue);
              console_closedp = 1;
              goto do_read;
@@ -207,17 +418,23 @@ void
 OS2_pm_console_write (const char * data, size_t size)
 {
   const char * end = (data + size);
+  const char * nonprint;
+  grab_console_lock ();
   while (data < end)
     {
-      process_events (0);
-      {
-       const char * nonprint = (find_nonprint (data, end));
-       if (data < nonprint)
+      nonprint = (find_nonprint (data, end));
+      if (data < nonprint)
+       while (1)
          {
            unsigned short size = (nonprint - data);
            if (size > (console_width - point_x))
              size = (console_width - point_x);
-           OS2_twindow_write (console_twid, point_x, point_y, data, size);
+           FASTCOPY (data, (CHAR_LOC (point_x, point_y)), size);
+           OS2_window_write (console_wid,
+                             (cx2x (point_x)),
+                             ((cy2y (point_y, 1)) + CHAR_DESCENDER),
+                             data,
+                             size);
            data += size;
            point_x += size;
            if (point_x == console_width)
@@ -225,30 +442,31 @@ OS2_pm_console_write (const char * data, size_t size)
                do_carriage_return ();
                do_linefeed ();
              }
-           if (data == end)
+           if (data == nonprint)
              break;
          }
-      }
-      switch (*data++)
-       {
-       case '\r':
-         do_carriage_return ();
-         break;
-       case '\012':
-         do_linefeed ();
-         break;
-       case '\f':
-         do_formfeed ();
-         break;
-       case '\b':
-         do_backspace ();
-         break;
-       case '\a':
-         do_alert ();
-         break;
-       }
+      if (data < end)
+       switch (*data++)
+         {
+         case '\r':
+           do_carriage_return ();
+           break;
+         case '\012':
+           do_linefeed ();
+           break;
+         case '\f':
+           do_formfeed ();
+           break;
+         case '\b':
+           do_backspace ();
+           break;
+         case '\a':
+           do_alert ();
+           break;
+         }
     }
-  OS2_twindow_move_cursor (console_twid, point_x, point_y);
+  OS2_window_move_cursor (console_wid, (cx2x (point_x)), (cy2y (point_y, 1)));
+  release_console_lock ();
 }
 
 static const char *
@@ -270,13 +488,30 @@ static void
 do_linefeed (void)
 {
   if (point_y < (console_height - 1))
-    point_y += 1;
+    {
+      point_y += 1;
+      FASTFILL ((CHAR_LOC (0, point_y)), console_width, ' ');
+      console_clear (0, console_width, point_y, (point_y + 1));
+    }
   else
     {
+#ifdef CONSOLE_WRAP
+      point_y = 0;
+      FASTFILL ((CHAR_LOC (0, 0)), console_width, ' ');
+      console_clear (0, console_width, 0, 1);
+#else /* not CONSOLE_WRAP */
       point_y = (console_height - 1);
-      OS2_twindow_scroll (console_twid, 0, console_width, 0, point_y, 0, 1);
+      FASTCOPY ((CHAR_LOC (0, 1)),
+               (CHAR_LOC (0, 0)),
+               (point_y * console_width));
+      FASTFILL ((CHAR_LOC (0, point_y)), console_width, ' ');
+      OS2_window_scroll (console_wid,
+                        0, console_pel_width,
+                        0, (point_y * CHAR_HEIGHT),
+                        0, CHAR_HEIGHT);
+      OS2_window_clear (console_wid, 0, console_pel_width, 0, CHAR_HEIGHT);
+#endif /* not CONSOLE_WRAP */
     }
-  OS2_twindow_clear_eol (console_twid, 0, point_y);
 }
 
 static void
@@ -284,7 +519,8 @@ do_formfeed (void)
 {
   point_x = 0;
   point_y = 0;
-  OS2_twindow_clear (console_twid);
+  FASTFILL ((CHAR_LOC (0, 0)), (console_width * console_height), ' ');
+  console_clear_all ();
 }
 
 static void
index efa8e738fb17010ab495e857df1cefac354457f2..d18b7d231b4b65219e1f929e9e53d91932499578 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: os2top.c,v 1.3 1994/12/02 20:40:20 cph Exp $
+$Id: os2top.c,v 1.4 1994/12/19 22:31:44 cph Exp $
 
 Copyright (c) 1994 Massachusetts Institute of Technology
 
@@ -41,17 +41,21 @@ extern void OS2_initialize_channel_thread_messages (void);
 extern void OS2_initialize_console (void);
 extern void OS2_initialize_directory_reader (void);
 extern void OS2_initialize_environment (void);
+extern void OS2_initialize_exception_handling (void);
 extern void OS2_initialize_keyboard_interrupts (void);
 extern void OS2_initialize_message_queues (void);
 extern void OS2_initialize_pm_thread (void);
 extern void OS2_initialize_scheme_thread (void);
 extern void OS2_initialize_tty (void);
+extern void OS2_initialize_window_primitives (void);
 
 extern const char * OS_Name;
 extern const char * OS_Variant;
 
 static const char * OS2_version_string (void);
 static void initialize_locks (void);
+static HAB scheme_hab;
+static HMQ scheme_hmq;
 \f
 int
 OS_under_emacs_p (void)
@@ -63,6 +67,15 @@ void
 OS_initialize (void)
 {
   initialize_locks ();
+  /* Create a PM message queue.  This allows us to use message boxes
+     to report fatal errors.  */
+  scheme_hab = (WinInitialize (0));
+  if (scheme_hab == NULLHANDLE)
+    OS2_logic_error ("Unable to initialize anchor block.");
+  scheme_hmq = (WinCreateMsgQueue (scheme_hab, 0));
+  if (scheme_hmq == NULLHANDLE)
+    OS2_logic_error ("Unable to create PM message queue.");
+  OS2_initialize_exception_handling ();
   OS2_initialize_message_queues ();
   OS2_initialize_scheme_thread ();
   OS2_initialize_pm_thread ();
@@ -73,6 +86,7 @@ OS_initialize (void)
   OS2_initialize_environment ();
   OS2_initialize_directory_reader ();
   OS2_initialize_tty ();
+  OS2_initialize_window_primitives ();
   OS_Name = "OS/2";
   {
     const char * version = (OS2_version_string ());
@@ -175,12 +189,6 @@ OS_restartable_exit (void)
 {
 }
 
-long
-OS_set_trap_state (long arg)
-{
-  return (arg);
-}
-
 #ifdef __IBMC__
 void
 bcopy (const char * from, char * to, unsigned int n)
@@ -194,7 +202,7 @@ static HMTX interrupt_registers_lock;
 static void
 initialize_locks (void)
 {
-  interrupt_registers_lock = (OS2_create_mutex_semaphore ());
+  interrupt_registers_lock = (OS2_create_mutex_semaphore (0, 0));
 }
 
 void
@@ -824,6 +832,621 @@ OS_error_code_to_syserr (int code)
     }
 }
 \f
+/* Machine-generated procedure, do not edit: */
+static APIRET
+syserr_to_error_code (enum syserr_names syserr)
+{
+  switch (syserr)
+    {
+    case syserr_invalid_function:      return (ERROR_INVALID_FUNCTION);
+    case syserr_file_not_found:        return (ERROR_FILE_NOT_FOUND);
+    case syserr_path_not_found:        return (ERROR_PATH_NOT_FOUND);
+    case syserr_too_many_open_files:   return (ERROR_TOO_MANY_OPEN_FILES);
+    case syserr_access_denied: return (ERROR_ACCESS_DENIED);
+    case syserr_invalid_handle:        return (ERROR_INVALID_HANDLE);
+    case syserr_arena_trashed: return (ERROR_ARENA_TRASHED);
+    case syserr_not_enough_memory:     return (ERROR_NOT_ENOUGH_MEMORY);
+    case syserr_invalid_block: return (ERROR_INVALID_BLOCK);
+    case syserr_bad_environment:       return (ERROR_BAD_ENVIRONMENT);
+    case syserr_bad_format:    return (ERROR_BAD_FORMAT);
+    case syserr_invalid_access:        return (ERROR_INVALID_ACCESS);
+    case syserr_invalid_data:  return (ERROR_INVALID_DATA);
+    case syserr_invalid_drive: return (ERROR_INVALID_DRIVE);
+    case syserr_current_directory:     return (ERROR_CURRENT_DIRECTORY);
+    case syserr_not_same_device:       return (ERROR_NOT_SAME_DEVICE);
+    case syserr_no_more_files: return (ERROR_NO_MORE_FILES);
+    case syserr_write_protect: return (ERROR_WRITE_PROTECT);
+    case syserr_bad_unit:      return (ERROR_BAD_UNIT);
+    case syserr_not_ready:     return (ERROR_NOT_READY);
+    case syserr_bad_command:   return (ERROR_BAD_COMMAND);
+    case syserr_crc:   return (ERROR_CRC);
+    case syserr_bad_length:    return (ERROR_BAD_LENGTH);
+    case syserr_seek:  return (ERROR_SEEK);
+    case syserr_not_dos_disk:  return (ERROR_NOT_DOS_DISK);
+    case syserr_sector_not_found:      return (ERROR_SECTOR_NOT_FOUND);
+    case syserr_out_of_paper:  return (ERROR_OUT_OF_PAPER);
+    case syserr_write_fault:   return (ERROR_WRITE_FAULT);
+    case syserr_read_fault:    return (ERROR_READ_FAULT);
+    case syserr_gen_failure:   return (ERROR_GEN_FAILURE);
+    case syserr_sharing_violation:     return (ERROR_SHARING_VIOLATION);
+    case syserr_lock_violation:        return (ERROR_LOCK_VIOLATION);
+    case syserr_wrong_disk:    return (ERROR_WRONG_DISK);
+    case syserr_fcb_unavailable:       return (ERROR_FCB_UNAVAILABLE);
+    case syserr_sharing_buffer_exceeded:       return (ERROR_SHARING_BUFFER_EXCEEDED);
+    case syserr_code_page_mismatched:  return (ERROR_CODE_PAGE_MISMATCHED);
+    case syserr_handle_eof:    return (ERROR_HANDLE_EOF);
+    case syserr_handle_disk_full:      return (ERROR_HANDLE_DISK_FULL);
+    case syserr_not_supported: return (ERROR_NOT_SUPPORTED);
+    case syserr_rem_not_list:  return (ERROR_REM_NOT_LIST);
+    case syserr_dup_name:      return (ERROR_DUP_NAME);
+    case syserr_bad_netpath:   return (ERROR_BAD_NETPATH);
+    case syserr_network_busy:  return (ERROR_NETWORK_BUSY);
+    case syserr_dev_not_exist: return (ERROR_DEV_NOT_EXIST);
+    case syserr_too_many_cmds: return (ERROR_TOO_MANY_CMDS);
+    case syserr_adap_hdw_err:  return (ERROR_ADAP_HDW_ERR);
+    case syserr_bad_net_resp:  return (ERROR_BAD_NET_RESP);
+    case syserr_unexp_net_err: return (ERROR_UNEXP_NET_ERR);
+    case syserr_bad_rem_adap:  return (ERROR_BAD_REM_ADAP);
+    case syserr_printq_full:   return (ERROR_PRINTQ_FULL);
+    case syserr_no_spool_space:        return (ERROR_NO_SPOOL_SPACE);
+    case syserr_print_cancelled:       return (ERROR_PRINT_CANCELLED);
+    case syserr_netname_deleted:       return (ERROR_NETNAME_DELETED);
+    case syserr_network_access_denied: return (ERROR_NETWORK_ACCESS_DENIED);
+    case syserr_bad_dev_type:  return (ERROR_BAD_DEV_TYPE);
+    case syserr_bad_net_name:  return (ERROR_BAD_NET_NAME);
+    case syserr_too_many_names:        return (ERROR_TOO_MANY_NAMES);
+    case syserr_too_many_sess: return (ERROR_TOO_MANY_SESS);
+    case syserr_sharing_paused:        return (ERROR_SHARING_PAUSED);
+    case syserr_req_not_accep: return (ERROR_REQ_NOT_ACCEP);
+    case syserr_redir_paused:  return (ERROR_REDIR_PAUSED);
+    case syserr_sbcs_att_write_prot:   return (ERROR_SBCS_ATT_WRITE_PROT);
+    case syserr_sbcs_general_failure:  return (ERROR_SBCS_GENERAL_FAILURE);
+    case syserr_xga_out_memory:        return (ERROR_XGA_OUT_MEMORY);
+    case syserr_file_exists:   return (ERROR_FILE_EXISTS);
+    case syserr_dup_fcb:       return (ERROR_DUP_FCB);
+    case syserr_cannot_make:   return (ERROR_CANNOT_MAKE);
+    case syserr_fail_i24:      return (ERROR_FAIL_I24);
+    case syserr_out_of_structures:     return (ERROR_OUT_OF_STRUCTURES);
+    case syserr_already_assigned:      return (ERROR_ALREADY_ASSIGNED);
+    case syserr_invalid_password:      return (ERROR_INVALID_PASSWORD);
+    case syserr_invalid_parameter:     return (ERROR_INVALID_PARAMETER);
+    case syserr_net_write_fault:       return (ERROR_NET_WRITE_FAULT);
+    case syserr_no_proc_slots: return (ERROR_NO_PROC_SLOTS);
+    case syserr_not_frozen:    return (ERROR_NOT_FROZEN);
+    case syserr_tstovfl:       return (ERR_TSTOVFL);
+    case syserr_tstdup:        return (ERR_TSTDUP);
+    case syserr_no_items:      return (ERROR_NO_ITEMS);
+    case syserr_interrupt:     return (ERROR_INTERRUPT);
+    case syserr_device_in_use: return (ERROR_DEVICE_IN_USE);
+    case syserr_too_many_semaphores:   return (ERROR_TOO_MANY_SEMAPHORES);
+    case syserr_excl_sem_already_owned:        return (ERROR_EXCL_SEM_ALREADY_OWNED);
+    case syserr_sem_is_set:    return (ERROR_SEM_IS_SET);
+    case syserr_too_many_sem_requests: return (ERROR_TOO_MANY_SEM_REQUESTS);
+    case syserr_invalid_at_interrupt_time:     return (ERROR_INVALID_AT_INTERRUPT_TIME);
+    case syserr_sem_owner_died:        return (ERROR_SEM_OWNER_DIED);
+    case syserr_sem_user_limit:        return (ERROR_SEM_USER_LIMIT);
+    case syserr_disk_change:   return (ERROR_DISK_CHANGE);
+    case syserr_drive_locked:  return (ERROR_DRIVE_LOCKED);
+    case syserr_broken_pipe:   return (ERROR_BROKEN_PIPE);
+    case syserr_open_failed:   return (ERROR_OPEN_FAILED);
+    case syserr_buffer_overflow:       return (ERROR_BUFFER_OVERFLOW);
+    case syserr_disk_full:     return (ERROR_DISK_FULL);
+    case syserr_no_more_search_handles:        return (ERROR_NO_MORE_SEARCH_HANDLES);
+    case syserr_invalid_target_handle: return (ERROR_INVALID_TARGET_HANDLE);
+    case syserr_protection_violation:  return (ERROR_PROTECTION_VIOLATION);
+    case syserr_viokbd_request:        return (ERROR_VIOKBD_REQUEST);
+    case syserr_invalid_category:      return (ERROR_INVALID_CATEGORY);
+    case syserr_invalid_verify_switch: return (ERROR_INVALID_VERIFY_SWITCH);
+    case syserr_bad_driver_level:      return (ERROR_BAD_DRIVER_LEVEL);
+    case syserr_call_not_implemented:  return (ERROR_CALL_NOT_IMPLEMENTED);
+    case syserr_sem_timeout:   return (ERROR_SEM_TIMEOUT);
+    case syserr_insufficient_buffer:   return (ERROR_INSUFFICIENT_BUFFER);
+    case syserr_invalid_name:  return (ERROR_INVALID_NAME);
+    case syserr_invalid_level: return (ERROR_INVALID_LEVEL);
+    case syserr_no_volume_label:       return (ERROR_NO_VOLUME_LABEL);
+    case syserr_mod_not_found: return (ERROR_MOD_NOT_FOUND);
+    case syserr_proc_not_found:        return (ERROR_PROC_NOT_FOUND);
+    case syserr_wait_no_children:      return (ERROR_WAIT_NO_CHILDREN);
+    case syserr_child_not_complete:    return (ERROR_CHILD_NOT_COMPLETE);
+    case syserr_direct_access_handle:  return (ERROR_DIRECT_ACCESS_HANDLE);
+    case syserr_negative_seek: return (ERROR_NEGATIVE_SEEK);
+    case syserr_seek_on_device:        return (ERROR_SEEK_ON_DEVICE);
+    case syserr_is_join_target:        return (ERROR_IS_JOIN_TARGET);
+    case syserr_is_joined:     return (ERROR_IS_JOINED);
+    case syserr_is_substed:    return (ERROR_IS_SUBSTED);
+    case syserr_not_joined:    return (ERROR_NOT_JOINED);
+    case syserr_not_substed:   return (ERROR_NOT_SUBSTED);
+    case syserr_join_to_join:  return (ERROR_JOIN_TO_JOIN);
+    case syserr_subst_to_subst:        return (ERROR_SUBST_TO_SUBST);
+    case syserr_join_to_subst: return (ERROR_JOIN_TO_SUBST);
+    case syserr_subst_to_join: return (ERROR_SUBST_TO_JOIN);
+    case syserr_busy_drive:    return (ERROR_BUSY_DRIVE);
+    case syserr_same_drive:    return (ERROR_SAME_DRIVE);
+    case syserr_dir_not_root:  return (ERROR_DIR_NOT_ROOT);
+    case syserr_dir_not_empty: return (ERROR_DIR_NOT_EMPTY);
+    case syserr_is_subst_path: return (ERROR_IS_SUBST_PATH);
+    case syserr_is_join_path:  return (ERROR_IS_JOIN_PATH);
+    case syserr_path_busy:     return (ERROR_PATH_BUSY);
+    case syserr_is_subst_target:       return (ERROR_IS_SUBST_TARGET);
+    case syserr_system_trace:  return (ERROR_SYSTEM_TRACE);
+    case syserr_invalid_event_count:   return (ERROR_INVALID_EVENT_COUNT);
+    case syserr_too_many_muxwaiters:   return (ERROR_TOO_MANY_MUXWAITERS);
+    case syserr_invalid_list_format:   return (ERROR_INVALID_LIST_FORMAT);
+    case syserr_label_too_long:        return (ERROR_LABEL_TOO_LONG);
+    case syserr_too_many_tcbs: return (ERROR_TOO_MANY_TCBS);
+    case syserr_signal_refused:        return (ERROR_SIGNAL_REFUSED);
+    case syserr_discarded:     return (ERROR_DISCARDED);
+    case syserr_not_locked:    return (ERROR_NOT_LOCKED);
+    case syserr_bad_threadid_addr:     return (ERROR_BAD_THREADID_ADDR);
+    case syserr_bad_arguments: return (ERROR_BAD_ARGUMENTS);
+    case syserr_bad_pathname:  return (ERROR_BAD_PATHNAME);
+    case syserr_signal_pending:        return (ERROR_SIGNAL_PENDING);
+    case syserr_uncertain_media:       return (ERROR_UNCERTAIN_MEDIA);
+    case syserr_max_thrds_reached:     return (ERROR_MAX_THRDS_REACHED);
+    case syserr_monitors_not_supported:        return (ERROR_MONITORS_NOT_SUPPORTED);
+    case syserr_unc_driver_not_installed:      return (ERROR_UNC_DRIVER_NOT_INSTALLED);
+    case syserr_lock_failed:   return (ERROR_LOCK_FAILED);
+    case syserr_swapio_failed: return (ERROR_SWAPIO_FAILED);
+    case syserr_swapin_failed: return (ERROR_SWAPIN_FAILED);
+    case syserr_busy:  return (ERROR_BUSY);
+    case syserr_cancel_violation:      return (ERROR_CANCEL_VIOLATION);
+    case syserr_atomic_lock_not_supported:     return (ERROR_ATOMIC_LOCK_NOT_SUPPORTED);
+    case syserr_read_locks_not_supported:      return (ERROR_READ_LOCKS_NOT_SUPPORTED);
+    case syserr_invalid_segment_number:        return (ERROR_INVALID_SEGMENT_NUMBER);
+    case syserr_invalid_callgate:      return (ERROR_INVALID_CALLGATE);
+    case syserr_invalid_ordinal:       return (ERROR_INVALID_ORDINAL);
+    case syserr_already_exists:        return (ERROR_ALREADY_EXISTS);
+    case syserr_no_child_process:      return (ERROR_NO_CHILD_PROCESS);
+    case syserr_child_alive_nowait:    return (ERROR_CHILD_ALIVE_NOWAIT);
+    case syserr_invalid_flag_number:   return (ERROR_INVALID_FLAG_NUMBER);
+    case syserr_sem_not_found: return (ERROR_SEM_NOT_FOUND);
+    case syserr_invalid_starting_codeseg:      return (ERROR_INVALID_STARTING_CODESEG);
+    case syserr_invalid_stackseg:      return (ERROR_INVALID_STACKSEG);
+    case syserr_invalid_moduletype:    return (ERROR_INVALID_MODULETYPE);
+    case syserr_invalid_exe_signature: return (ERROR_INVALID_EXE_SIGNATURE);
+    case syserr_exe_marked_invalid:    return (ERROR_EXE_MARKED_INVALID);
+    case syserr_bad_exe_format:        return (ERROR_BAD_EXE_FORMAT);
+    case syserr_iterated_data_exceeds_64k:     return (ERROR_ITERATED_DATA_EXCEEDS_64k);
+    case syserr_invalid_minallocsize:  return (ERROR_INVALID_MINALLOCSIZE);
+    case syserr_dynlink_from_invalid_ring:     return (ERROR_DYNLINK_FROM_INVALID_RING);
+    case syserr_iopl_not_enabled:      return (ERROR_IOPL_NOT_ENABLED);
+    case syserr_invalid_segdpl:        return (ERROR_INVALID_SEGDPL);
+    case syserr_autodataseg_exceeds_64k:       return (ERROR_AUTODATASEG_EXCEEDS_64k);
+    case syserr_ring2seg_must_be_movable:      return (ERROR_RING2SEG_MUST_BE_MOVABLE);
+    case syserr_reloc_chain_xeeds_seglim:      return (ERROR_RELOC_CHAIN_XEEDS_SEGLIM);
+    case syserr_infloop_in_reloc_chain:        return (ERROR_INFLOOP_IN_RELOC_CHAIN);
+    case syserr_envvar_not_found:      return (ERROR_ENVVAR_NOT_FOUND);
+    case syserr_not_current_ctry:      return (ERROR_NOT_CURRENT_CTRY);
+    case syserr_no_signal_sent:        return (ERROR_NO_SIGNAL_SENT);
+    case syserr_filename_exced_range:  return (ERROR_FILENAME_EXCED_RANGE);
+    case syserr_ring2_stack_in_use:    return (ERROR_RING2_STACK_IN_USE);
+    case syserr_meta_expansion_too_long:       return (ERROR_META_EXPANSION_TOO_LONG);
+    case syserr_invalid_signal_number: return (ERROR_INVALID_SIGNAL_NUMBER);
+    case syserr_thread_1_inactive:     return (ERROR_THREAD_1_INACTIVE);
+    case syserr_info_not_avail:        return (ERROR_INFO_NOT_AVAIL);
+    case syserr_locked:        return (ERROR_LOCKED);
+    case syserr_bad_dynalink:  return (ERROR_BAD_DYNALINK);
+    case syserr_too_many_modules:      return (ERROR_TOO_MANY_MODULES);
+    case syserr_nesting_not_allowed:   return (ERROR_NESTING_NOT_ALLOWED);
+    case syserr_cannot_shrink: return (ERROR_CANNOT_SHRINK);
+    case syserr_zombie_process:        return (ERROR_ZOMBIE_PROCESS);
+    case syserr_stack_in_high_memory:  return (ERROR_STACK_IN_HIGH_MEMORY);
+    case syserr_invalid_exitroutine_ring:      return (ERROR_INVALID_EXITROUTINE_RING);
+    case syserr_getbuf_failed: return (ERROR_GETBUF_FAILED);
+    case syserr_flushbuf_failed:       return (ERROR_FLUSHBUF_FAILED);
+    case syserr_transfer_too_long:     return (ERROR_TRANSFER_TOO_LONG);
+    case syserr_forcenoswap_failed:    return (ERROR_FORCENOSWAP_FAILED);
+    case syserr_smg_no_target_window:  return (ERROR_SMG_NO_TARGET_WINDOW);
+    case syserr_no_children:   return (ERROR_NO_CHILDREN);
+    case syserr_invalid_screen_group:  return (ERROR_INVALID_SCREEN_GROUP);
+    case syserr_bad_pipe:      return (ERROR_BAD_PIPE);
+    case syserr_pipe_busy:     return (ERROR_PIPE_BUSY);
+    case syserr_no_data:       return (ERROR_NO_DATA);
+    case syserr_pipe_not_connected:    return (ERROR_PIPE_NOT_CONNECTED);
+    case syserr_more_data:     return (ERROR_MORE_DATA);
+    case syserr_vc_disconnected:       return (ERROR_VC_DISCONNECTED);
+    case syserr_circularity_requested: return (ERROR_CIRCULARITY_REQUESTED);
+    case syserr_directory_in_cds:      return (ERROR_DIRECTORY_IN_CDS);
+    case syserr_invalid_fsd_name:      return (ERROR_INVALID_FSD_NAME);
+    case syserr_invalid_path:  return (ERROR_INVALID_PATH);
+    case syserr_invalid_ea_name:       return (ERROR_INVALID_EA_NAME);
+    case syserr_ea_list_inconsistent:  return (ERROR_EA_LIST_INCONSISTENT);
+    case syserr_ea_list_too_long:      return (ERROR_EA_LIST_TOO_LONG);
+    case syserr_no_meta_match: return (ERROR_NO_META_MATCH);
+    case syserr_findnotify_timeout:    return (ERROR_FINDNOTIFY_TIMEOUT);
+    case syserr_no_more_items: return (ERROR_NO_MORE_ITEMS);
+    case syserr_search_struc_reused:   return (ERROR_SEARCH_STRUC_REUSED);
+    case syserr_char_not_found:        return (ERROR_CHAR_NOT_FOUND);
+    case syserr_too_much_stack:        return (ERROR_TOO_MUCH_STACK);
+    case syserr_invalid_attr:  return (ERROR_INVALID_ATTR);
+    case syserr_invalid_starting_ring: return (ERROR_INVALID_STARTING_RING);
+    case syserr_invalid_dll_init_ring: return (ERROR_INVALID_DLL_INIT_RING);
+    case syserr_cannot_copy:   return (ERROR_CANNOT_COPY);
+    case syserr_directory:     return (ERROR_DIRECTORY);
+    case syserr_oplocked_file: return (ERROR_OPLOCKED_FILE);
+    case syserr_oplock_thread_exists:  return (ERROR_OPLOCK_THREAD_EXISTS);
+    case syserr_volume_changed:        return (ERROR_VOLUME_CHANGED);
+    case syserr_findnotify_handle_in_use:      return (ERROR_FINDNOTIFY_HANDLE_IN_USE);
+    case syserr_findnotify_handle_closed:      return (ERROR_FINDNOTIFY_HANDLE_CLOSED);
+    case syserr_notify_object_removed: return (ERROR_NOTIFY_OBJECT_REMOVED);
+    case syserr_already_shutdown:      return (ERROR_ALREADY_SHUTDOWN);
+    case syserr_eas_didnt_fit: return (ERROR_EAS_DIDNT_FIT);
+    case syserr_ea_file_corrupt:       return (ERROR_EA_FILE_CORRUPT);
+    case syserr_ea_table_full: return (ERROR_EA_TABLE_FULL);
+    case syserr_invalid_ea_handle:     return (ERROR_INVALID_EA_HANDLE);
+    case syserr_no_cluster:    return (ERROR_NO_CLUSTER);
+    case syserr_create_ea_file:        return (ERROR_CREATE_EA_FILE);
+    case syserr_cannot_open_ea_file:   return (ERROR_CANNOT_OPEN_EA_FILE);
+    case syserr_eas_not_supported:     return (ERROR_EAS_NOT_SUPPORTED);
+    case syserr_need_eas_found:        return (ERROR_NEED_EAS_FOUND);
+    case syserr_duplicate_handle:      return (ERROR_DUPLICATE_HANDLE);
+    case syserr_duplicate_name:        return (ERROR_DUPLICATE_NAME);
+    case syserr_empty_muxwait: return (ERROR_EMPTY_MUXWAIT);
+    case syserr_mutex_owned:   return (ERROR_MUTEX_OWNED);
+    case syserr_not_owner:     return (ERROR_NOT_OWNER);
+    case syserr_param_too_small:       return (ERROR_PARAM_TOO_SMALL);
+    case syserr_too_many_handles:      return (ERROR_TOO_MANY_HANDLES);
+    case syserr_too_many_opens:        return (ERROR_TOO_MANY_OPENS);
+    case syserr_wrong_type:    return (ERROR_WRONG_TYPE);
+    case syserr_unused_code:   return (ERROR_UNUSED_CODE);
+    case syserr_thread_not_terminated: return (ERROR_THREAD_NOT_TERMINATED);
+    case syserr_init_routine_failed:   return (ERROR_INIT_ROUTINE_FAILED);
+    case syserr_module_in_use: return (ERROR_MODULE_IN_USE);
+    case syserr_not_enough_watchpoints:        return (ERROR_NOT_ENOUGH_WATCHPOINTS);
+    case syserr_too_many_posts:        return (ERROR_TOO_MANY_POSTS);
+    case syserr_already_posted:        return (ERROR_ALREADY_POSTED);
+    case syserr_already_reset: return (ERROR_ALREADY_RESET);
+    case syserr_sem_busy:      return (ERROR_SEM_BUSY);
+    case syserr_invalid_procid:        return (ERROR_INVALID_PROCID);
+    case syserr_invalid_pdelta:        return (ERROR_INVALID_PDELTA);
+    case syserr_not_descendant:        return (ERROR_NOT_DESCENDANT);
+    case syserr_not_session_manager:   return (ERROR_NOT_SESSION_MANAGER);
+    case syserr_invalid_pclass:        return (ERROR_INVALID_PCLASS);
+    case syserr_invalid_scope: return (ERROR_INVALID_SCOPE);
+    case syserr_invalid_threadid:      return (ERROR_INVALID_THREADID);
+    case syserr_dossub_shrink: return (ERROR_DOSSUB_SHRINK);
+    case syserr_dossub_nomem:  return (ERROR_DOSSUB_NOMEM);
+    case syserr_dossub_overlap:        return (ERROR_DOSSUB_OVERLAP);
+    case syserr_dossub_badsize:        return (ERROR_DOSSUB_BADSIZE);
+    case syserr_dossub_badflag:        return (ERROR_DOSSUB_BADFLAG);
+    case syserr_dossub_badselector:    return (ERROR_DOSSUB_BADSELECTOR);
+    case syserr_mr_msg_too_long:       return (ERROR_MR_MSG_TOO_LONG);
+    case syserr_mr_mid_not_found:      return (ERROR_MR_MID_NOT_FOUND);
+    case syserr_mr_un_acc_msgf:        return (ERROR_MR_UN_ACC_MSGF);
+    case syserr_mr_inv_msgf_format:    return (ERROR_MR_INV_MSGF_FORMAT);
+    case syserr_mr_inv_ivcount:        return (ERROR_MR_INV_IVCOUNT);
+    case syserr_mr_un_perform: return (ERROR_MR_UN_PERFORM);
+    case syserr_ts_wakeup:     return (ERROR_TS_WAKEUP);
+    case syserr_ts_semhandle:  return (ERROR_TS_SEMHANDLE);
+    case syserr_ts_notimer:    return (ERROR_TS_NOTIMER);
+    case syserr_ts_handle:     return (ERROR_TS_HANDLE);
+    case syserr_ts_datetime:   return (ERROR_TS_DATETIME);
+    case syserr_sys_internal:  return (ERROR_SYS_INTERNAL);
+    case syserr_que_current_name:      return (ERROR_QUE_CURRENT_NAME);
+    case syserr_que_proc_not_owned:    return (ERROR_QUE_PROC_NOT_OWNED);
+    case syserr_que_proc_owned:        return (ERROR_QUE_PROC_OWNED);
+    case syserr_que_duplicate: return (ERROR_QUE_DUPLICATE);
+    case syserr_que_element_not_exist: return (ERROR_QUE_ELEMENT_NOT_EXIST);
+    case syserr_que_no_memory: return (ERROR_QUE_NO_MEMORY);
+    case syserr_que_invalid_name:      return (ERROR_QUE_INVALID_NAME);
+    case syserr_que_invalid_priority:  return (ERROR_QUE_INVALID_PRIORITY);
+    case syserr_que_invalid_handle:    return (ERROR_QUE_INVALID_HANDLE);
+    case syserr_que_link_not_found:    return (ERROR_QUE_LINK_NOT_FOUND);
+    case syserr_que_memory_error:      return (ERROR_QUE_MEMORY_ERROR);
+    case syserr_que_prev_at_end:       return (ERROR_QUE_PREV_AT_END);
+    case syserr_que_proc_no_access:    return (ERROR_QUE_PROC_NO_ACCESS);
+    case syserr_que_empty:     return (ERROR_QUE_EMPTY);
+    case syserr_que_name_not_exist:    return (ERROR_QUE_NAME_NOT_EXIST);
+    case syserr_que_not_initialized:   return (ERROR_QUE_NOT_INITIALIZED);
+    case syserr_que_unable_to_access:  return (ERROR_QUE_UNABLE_TO_ACCESS);
+    case syserr_que_unable_to_add:     return (ERROR_QUE_UNABLE_TO_ADD);
+    case syserr_que_unable_to_init:    return (ERROR_QUE_UNABLE_TO_INIT);
+    case syserr_vio_invalid_mask:      return (ERROR_VIO_INVALID_MASK);
+    case syserr_vio_ptr:       return (ERROR_VIO_PTR);
+    case syserr_vio_aptr:      return (ERROR_VIO_APTR);
+    case syserr_vio_rptr:      return (ERROR_VIO_RPTR);
+    case syserr_vio_cptr:      return (ERROR_VIO_CPTR);
+    case syserr_vio_lptr:      return (ERROR_VIO_LPTR);
+    case syserr_vio_mode:      return (ERROR_VIO_MODE);
+    case syserr_vio_width:     return (ERROR_VIO_WIDTH);
+    case syserr_vio_attr:      return (ERROR_VIO_ATTR);
+    case syserr_vio_row:       return (ERROR_VIO_ROW);
+    case syserr_vio_col:       return (ERROR_VIO_COL);
+    case syserr_vio_toprow:    return (ERROR_VIO_TOPROW);
+    case syserr_vio_botrow:    return (ERROR_VIO_BOTROW);
+    case syserr_vio_rightcol:  return (ERROR_VIO_RIGHTCOL);
+    case syserr_vio_leftcol:   return (ERROR_VIO_LEFTCOL);
+    case syserr_scs_call:      return (ERROR_SCS_CALL);
+    case syserr_scs_value:     return (ERROR_SCS_VALUE);
+    case syserr_vio_wait_flag: return (ERROR_VIO_WAIT_FLAG);
+    case syserr_vio_unlock:    return (ERROR_VIO_UNLOCK);
+    case syserr_sgs_not_session_mgr:   return (ERROR_SGS_NOT_SESSION_MGR);
+    case syserr_smg_invalid_session_id:        return (ERROR_SMG_INVALID_SESSION_ID);
+    case syserr_smg_no_sessions:       return (ERROR_SMG_NO_SESSIONS);
+    case syserr_smg_session_not_found: return (ERROR_SMG_SESSION_NOT_FOUND);
+    case syserr_smg_set_title: return (ERROR_SMG_SET_TITLE);
+    case syserr_kbd_parameter: return (ERROR_KBD_PARAMETER);
+    case syserr_kbd_no_device: return (ERROR_KBD_NO_DEVICE);
+    case syserr_kbd_invalid_iowait:    return (ERROR_KBD_INVALID_IOWAIT);
+    case syserr_kbd_invalid_length:    return (ERROR_KBD_INVALID_LENGTH);
+    case syserr_kbd_invalid_echo_mask: return (ERROR_KBD_INVALID_ECHO_MASK);
+    case syserr_kbd_invalid_input_mask:        return (ERROR_KBD_INVALID_INPUT_MASK);
+    case syserr_mon_invalid_parms:     return (ERROR_MON_INVALID_PARMS);
+    case syserr_mon_invalid_devname:   return (ERROR_MON_INVALID_DEVNAME);
+    case syserr_mon_invalid_handle:    return (ERROR_MON_INVALID_HANDLE);
+    case syserr_mon_buffer_too_small:  return (ERROR_MON_BUFFER_TOO_SMALL);
+    case syserr_mon_buffer_empty:      return (ERROR_MON_BUFFER_EMPTY);
+    case syserr_mon_data_too_large:    return (ERROR_MON_DATA_TOO_LARGE);
+    case syserr_mouse_no_device:       return (ERROR_MOUSE_NO_DEVICE);
+    case syserr_mouse_inv_handle:      return (ERROR_MOUSE_INV_HANDLE);
+    case syserr_mouse_inv_parms:       return (ERROR_MOUSE_INV_PARMS);
+    case syserr_mouse_cant_reset:      return (ERROR_MOUSE_CANT_RESET);
+    case syserr_mouse_display_parms:   return (ERROR_MOUSE_DISPLAY_PARMS);
+    case syserr_mouse_inv_module:      return (ERROR_MOUSE_INV_MODULE);
+    case syserr_mouse_inv_entry_pt:    return (ERROR_MOUSE_INV_ENTRY_PT);
+    case syserr_mouse_inv_mask:        return (ERROR_MOUSE_INV_MASK);
+    case syserr_mouse_no_data: return (NO_ERROR_MOUSE_NO_DATA);
+    case syserr_mouse_ptr_drawn:       return (NO_ERROR_MOUSE_PTR_DRAWN);
+    case syserr_invalid_frequency:     return (ERROR_INVALID_FREQUENCY);
+    case syserr_nls_no_country_file:   return (ERROR_NLS_NO_COUNTRY_FILE);
+    case syserr_nls_open_failed:       return (ERROR_NLS_OPEN_FAILED);
+    case syserr_no_country_or_codepage:        return (ERROR_NO_COUNTRY_OR_CODEPAGE);
+    case syserr_nls_table_truncated:   return (ERROR_NLS_TABLE_TRUNCATED);
+    case syserr_nls_bad_type:  return (ERROR_NLS_BAD_TYPE);
+    case syserr_nls_type_not_found:    return (ERROR_NLS_TYPE_NOT_FOUND);
+    case syserr_vio_smg_only:  return (ERROR_VIO_SMG_ONLY);
+    case syserr_vio_invalid_asciiz:    return (ERROR_VIO_INVALID_ASCIIZ);
+    case syserr_vio_deregister:        return (ERROR_VIO_DEREGISTER);
+    case syserr_vio_no_popup:  return (ERROR_VIO_NO_POPUP);
+    case syserr_vio_existing_popup:    return (ERROR_VIO_EXISTING_POPUP);
+    case syserr_kbd_smg_only:  return (ERROR_KBD_SMG_ONLY);
+    case syserr_kbd_invalid_asciiz:    return (ERROR_KBD_INVALID_ASCIIZ);
+    case syserr_kbd_invalid_mask:      return (ERROR_KBD_INVALID_MASK);
+    case syserr_kbd_register:  return (ERROR_KBD_REGISTER);
+    case syserr_kbd_deregister:        return (ERROR_KBD_DEREGISTER);
+    case syserr_mouse_smg_only:        return (ERROR_MOUSE_SMG_ONLY);
+    case syserr_mouse_invalid_asciiz:  return (ERROR_MOUSE_INVALID_ASCIIZ);
+    case syserr_mouse_invalid_mask:    return (ERROR_MOUSE_INVALID_MASK);
+    case syserr_mouse_register:        return (ERROR_MOUSE_REGISTER);
+    case syserr_mouse_deregister:      return (ERROR_MOUSE_DEREGISTER);
+    case syserr_smg_bad_action:        return (ERROR_SMG_BAD_ACTION);
+    case syserr_smg_invalid_call:      return (ERROR_SMG_INVALID_CALL);
+    case syserr_scs_sg_notfound:       return (ERROR_SCS_SG_NOTFOUND);
+    case syserr_scs_not_shell: return (ERROR_SCS_NOT_SHELL);
+    case syserr_vio_invalid_parms:     return (ERROR_VIO_INVALID_PARMS);
+    case syserr_vio_function_owned:    return (ERROR_VIO_FUNCTION_OWNED);
+    case syserr_vio_return:    return (ERROR_VIO_RETURN);
+    case syserr_scs_invalid_function:  return (ERROR_SCS_INVALID_FUNCTION);
+    case syserr_scs_not_session_mgr:   return (ERROR_SCS_NOT_SESSION_MGR);
+    case syserr_vio_register:  return (ERROR_VIO_REGISTER);
+    case syserr_vio_no_mode_thread:    return (ERROR_VIO_NO_MODE_THREAD);
+    case syserr_vio_no_save_restore_thd:       return (ERROR_VIO_NO_SAVE_RESTORE_THD);
+    case syserr_vio_in_bg:     return (ERROR_VIO_IN_BG);
+    case syserr_vio_illegal_during_popup:      return (ERROR_VIO_ILLEGAL_DURING_POPUP);
+    case syserr_smg_not_baseshell:     return (ERROR_SMG_NOT_BASESHELL);
+    case syserr_smg_bad_statusreq:     return (ERROR_SMG_BAD_STATUSREQ);
+    case syserr_que_invalid_wait:      return (ERROR_QUE_INVALID_WAIT);
+    case syserr_vio_lock:      return (ERROR_VIO_LOCK);
+    case syserr_mouse_invalid_iowait:  return (ERROR_MOUSE_INVALID_IOWAIT);
+    case syserr_vio_invalid_handle:    return (ERROR_VIO_INVALID_HANDLE);
+    case syserr_vio_illegal_during_lock:       return (ERROR_VIO_ILLEGAL_DURING_LOCK);
+    case syserr_vio_invalid_length:    return (ERROR_VIO_INVALID_LENGTH);
+    case syserr_kbd_invalid_handle:    return (ERROR_KBD_INVALID_HANDLE);
+    case syserr_kbd_no_more_handle:    return (ERROR_KBD_NO_MORE_HANDLE);
+    case syserr_kbd_cannot_create_kcb: return (ERROR_KBD_CANNOT_CREATE_KCB);
+    case syserr_kbd_codepage_load_incompl:     return (ERROR_KBD_CODEPAGE_LOAD_INCOMPL);
+    case syserr_kbd_invalid_codepage_id:       return (ERROR_KBD_INVALID_CODEPAGE_ID);
+    case syserr_kbd_no_codepage_support:       return (ERROR_KBD_NO_CODEPAGE_SUPPORT);
+    case syserr_kbd_focus_required:    return (ERROR_KBD_FOCUS_REQUIRED);
+    case syserr_kbd_focus_already_active:      return (ERROR_KBD_FOCUS_ALREADY_ACTIVE);
+    case syserr_kbd_keyboard_busy:     return (ERROR_KBD_KEYBOARD_BUSY);
+    case syserr_kbd_invalid_codepage:  return (ERROR_KBD_INVALID_CODEPAGE);
+    case syserr_kbd_unable_to_focus:   return (ERROR_KBD_UNABLE_TO_FOCUS);
+    case syserr_smg_session_non_select:        return (ERROR_SMG_SESSION_NON_SELECT);
+    case syserr_smg_session_not_foregrnd:      return (ERROR_SMG_SESSION_NOT_FOREGRND);
+    case syserr_smg_session_not_parent:        return (ERROR_SMG_SESSION_NOT_PARENT);
+    case syserr_smg_invalid_start_mode:        return (ERROR_SMG_INVALID_START_MODE);
+    case syserr_smg_invalid_related_opt:       return (ERROR_SMG_INVALID_RELATED_OPT);
+    case syserr_smg_invalid_bond_option:       return (ERROR_SMG_INVALID_BOND_OPTION);
+    case syserr_smg_invalid_select_opt:        return (ERROR_SMG_INVALID_SELECT_OPT);
+    case syserr_smg_start_in_background:       return (ERROR_SMG_START_IN_BACKGROUND);
+    case syserr_smg_invalid_stop_option:       return (ERROR_SMG_INVALID_STOP_OPTION);
+    case syserr_smg_bad_reserve:       return (ERROR_SMG_BAD_RESERVE);
+    case syserr_smg_process_not_parent:        return (ERROR_SMG_PROCESS_NOT_PARENT);
+    case syserr_smg_invalid_data_length:       return (ERROR_SMG_INVALID_DATA_LENGTH);
+    case syserr_smg_not_bound: return (ERROR_SMG_NOT_BOUND);
+    case syserr_smg_retry_sub_alloc:   return (ERROR_SMG_RETRY_SUB_ALLOC);
+    case syserr_kbd_detached:  return (ERROR_KBD_DETACHED);
+    case syserr_vio_detached:  return (ERROR_VIO_DETACHED);
+    case syserr_mou_detached:  return (ERROR_MOU_DETACHED);
+    case syserr_vio_font:      return (ERROR_VIO_FONT);
+    case syserr_vio_user_font: return (ERROR_VIO_USER_FONT);
+    case syserr_vio_bad_cp:    return (ERROR_VIO_BAD_CP);
+    case syserr_vio_no_cp:     return (ERROR_VIO_NO_CP);
+    case syserr_vio_na_cp:     return (ERROR_VIO_NA_CP);
+    case syserr_invalid_code_page:     return (ERROR_INVALID_CODE_PAGE);
+    case syserr_cplist_too_small:      return (ERROR_CPLIST_TOO_SMALL);
+    case syserr_cp_not_moved:  return (ERROR_CP_NOT_MOVED);
+    case syserr_mode_switch_init:      return (ERROR_MODE_SWITCH_INIT);
+    case syserr_code_page_not_found:   return (ERROR_CODE_PAGE_NOT_FOUND);
+    case syserr_unexpected_slot_returned:      return (ERROR_UNEXPECTED_SLOT_RETURNED);
+    case syserr_smg_invalid_trace_option:      return (ERROR_SMG_INVALID_TRACE_OPTION);
+    case syserr_vio_internal_resource: return (ERROR_VIO_INTERNAL_RESOURCE);
+    case syserr_vio_shell_init:        return (ERROR_VIO_SHELL_INIT);
+    case syserr_smg_no_hard_errors:    return (ERROR_SMG_NO_HARD_ERRORS);
+    case syserr_cp_switch_incomplete:  return (ERROR_CP_SWITCH_INCOMPLETE);
+    case syserr_vio_transparent_popup: return (ERROR_VIO_TRANSPARENT_POPUP);
+    case syserr_critsec_overflow:      return (ERROR_CRITSEC_OVERFLOW);
+    case syserr_critsec_underflow:     return (ERROR_CRITSEC_UNDERFLOW);
+    case syserr_vio_bad_reserve:       return (ERROR_VIO_BAD_RESERVE);
+    case syserr_invalid_address:       return (ERROR_INVALID_ADDRESS);
+    case syserr_zero_selectors_requested:      return (ERROR_ZERO_SELECTORS_REQUESTED);
+    case syserr_not_enough_selectors_ava:      return (ERROR_NOT_ENOUGH_SELECTORS_AVA);
+    case syserr_invalid_selector:      return (ERROR_INVALID_SELECTOR);
+    case syserr_smg_invalid_program_type:      return (ERROR_SMG_INVALID_PROGRAM_TYPE);
+    case syserr_smg_invalid_pgm_control:       return (ERROR_SMG_INVALID_PGM_CONTROL);
+    case syserr_smg_invalid_inherit_opt:       return (ERROR_SMG_INVALID_INHERIT_OPT);
+    case syserr_vio_extended_sg:       return (ERROR_VIO_EXTENDED_SG);
+    case syserr_vio_not_pres_mgr_sg:   return (ERROR_VIO_NOT_PRES_MGR_SG);
+    case syserr_vio_shield_owned:      return (ERROR_VIO_SHIELD_OWNED);
+    case syserr_vio_no_more_handles:   return (ERROR_VIO_NO_MORE_HANDLES);
+    case syserr_vio_see_error_log:     return (ERROR_VIO_SEE_ERROR_LOG);
+    case syserr_vio_associated_dc:     return (ERROR_VIO_ASSOCIATED_DC);
+    case syserr_kbd_no_console:        return (ERROR_KBD_NO_CONSOLE);
+    case syserr_mouse_no_console:      return (ERROR_MOUSE_NO_CONSOLE);
+    case syserr_mouse_invalid_handle:  return (ERROR_MOUSE_INVALID_HANDLE);
+    case syserr_smg_invalid_debug_parms:       return (ERROR_SMG_INVALID_DEBUG_PARMS);
+    case syserr_kbd_extended_sg:       return (ERROR_KBD_EXTENDED_SG);
+    case syserr_mou_extended_sg:       return (ERROR_MOU_EXTENDED_SG);
+    case syserr_smg_invalid_icon_file: return (ERROR_SMG_INVALID_ICON_FILE);
+    case syserr_trc_pid_non_existent:  return (ERROR_TRC_PID_NON_EXISTENT);
+    case syserr_trc_count_active:      return (ERROR_TRC_COUNT_ACTIVE);
+    case syserr_trc_suspended_by_count:        return (ERROR_TRC_SUSPENDED_BY_COUNT);
+    case syserr_trc_count_inactive:    return (ERROR_TRC_COUNT_INACTIVE);
+    case syserr_trc_count_reached:     return (ERROR_TRC_COUNT_REACHED);
+    case syserr_no_mc_trace:   return (ERROR_NO_MC_TRACE);
+    case syserr_mc_trace:      return (ERROR_MC_TRACE);
+    case syserr_trc_count_zero:        return (ERROR_TRC_COUNT_ZERO);
+    case syserr_smg_too_many_dds:      return (ERROR_SMG_TOO_MANY_DDS);
+    case syserr_smg_invalid_notification:      return (ERROR_SMG_INVALID_NOTIFICATION);
+    case syserr_lf_invalid_function:   return (ERROR_LF_INVALID_FUNCTION);
+    case syserr_lf_not_avail:  return (ERROR_LF_NOT_AVAIL);
+    case syserr_lf_suspended:  return (ERROR_LF_SUSPENDED);
+    case syserr_lf_buf_too_small:      return (ERROR_LF_BUF_TOO_SMALL);
+    case syserr_lf_buffer_full:        return (ERROR_LF_BUFFER_FULL);
+    case syserr_lf_invalid_record:     return (ERROR_LF_INVALID_RECORD);
+    case syserr_lf_invalid_service:    return (ERROR_LF_INVALID_SERVICE);
+    case syserr_lf_general_failure:    return (ERROR_LF_GENERAL_FAILURE);
+    case syserr_lf_invalid_id: return (ERROR_LF_INVALID_ID);
+    case syserr_lf_invalid_handle:     return (ERROR_LF_INVALID_HANDLE);
+    case syserr_lf_no_id_avail:        return (ERROR_LF_NO_ID_AVAIL);
+    case syserr_lf_template_area_full: return (ERROR_LF_TEMPLATE_AREA_FULL);
+    case syserr_lf_id_in_use:  return (ERROR_LF_ID_IN_USE);
+    case syserr_mou_not_initialized:   return (ERROR_MOU_NOT_INITIALIZED);
+    case syserr_mouinitreal_done:      return (ERROR_MOUINITREAL_DONE);
+    case syserr_dossub_corrupted:      return (ERROR_DOSSUB_CORRUPTED);
+    case syserr_mouse_caller_not_subsys:       return (ERROR_MOUSE_CALLER_NOT_SUBSYS);
+    case syserr_arithmetic_overflow:   return (ERROR_ARITHMETIC_OVERFLOW);
+    case syserr_tmr_no_device: return (ERROR_TMR_NO_DEVICE);
+    case syserr_tmr_invalid_time:      return (ERROR_TMR_INVALID_TIME);
+    case syserr_pvw_invalid_entity:    return (ERROR_PVW_INVALID_ENTITY);
+    case syserr_pvw_invalid_entity_type:       return (ERROR_PVW_INVALID_ENTITY_TYPE);
+    case syserr_pvw_invalid_spec:      return (ERROR_PVW_INVALID_SPEC);
+    case syserr_pvw_invalid_range_type:        return (ERROR_PVW_INVALID_RANGE_TYPE);
+    case syserr_pvw_invalid_counter_blk:       return (ERROR_PVW_INVALID_COUNTER_BLK);
+    case syserr_pvw_invalid_text_blk:  return (ERROR_PVW_INVALID_TEXT_BLK);
+    case syserr_prf_not_initialized:   return (ERROR_PRF_NOT_INITIALIZED);
+    case syserr_prf_already_initialized:       return (ERROR_PRF_ALREADY_INITIALIZED);
+    case syserr_prf_not_started:       return (ERROR_PRF_NOT_STARTED);
+    case syserr_prf_already_started:   return (ERROR_PRF_ALREADY_STARTED);
+    case syserr_prf_timer_out_of_range:        return (ERROR_PRF_TIMER_OUT_OF_RANGE);
+    case syserr_prf_timer_reset:       return (ERROR_PRF_TIMER_RESET);
+    case syserr_vdd_lock_useage_denied:        return (ERROR_VDD_LOCK_USEAGE_DENIED);
+    case syserr_timeout:       return (ERROR_TIMEOUT);
+    case syserr_vdm_down:      return (ERROR_VDM_DOWN);
+    case syserr_vdm_limit:     return (ERROR_VDM_LIMIT);
+    case syserr_vdd_not_found: return (ERROR_VDD_NOT_FOUND);
+    case syserr_invalid_caller:        return (ERROR_INVALID_CALLER);
+    case syserr_pid_mismatch:  return (ERROR_PID_MISMATCH);
+    case syserr_invalid_vdd_handle:    return (ERROR_INVALID_VDD_HANDLE);
+    case syserr_vlpt_no_spooler:       return (ERROR_VLPT_NO_SPOOLER);
+    case syserr_vcom_device_busy:      return (ERROR_VCOM_DEVICE_BUSY);
+    case syserr_vlpt_device_busy:      return (ERROR_VLPT_DEVICE_BUSY);
+    case syserr_nesting_too_deep:      return (ERROR_NESTING_TOO_DEEP);
+    case syserr_vdd_missing:   return (ERROR_VDD_MISSING);
+    case syserr_bidi_invalid_length:   return (ERROR_BIDI_INVALID_LENGTH);
+    case syserr_bidi_invalid_increment:        return (ERROR_BIDI_INVALID_INCREMENT);
+    case syserr_bidi_invalid_combination:      return (ERROR_BIDI_INVALID_COMBINATION);
+    case syserr_bidi_invalid_reserved: return (ERROR_BIDI_INVALID_RESERVED);
+    case syserr_bidi_invalid_effect:   return (ERROR_BIDI_INVALID_EFFECT);
+    case syserr_bidi_invalid_csdrec:   return (ERROR_BIDI_INVALID_CSDREC);
+    case syserr_bidi_invalid_csdstate: return (ERROR_BIDI_INVALID_CSDSTATE);
+    case syserr_bidi_invalid_level:    return (ERROR_BIDI_INVALID_LEVEL);
+    case syserr_bidi_invalid_type_support:     return (ERROR_BIDI_INVALID_TYPE_SUPPORT);
+    case syserr_bidi_invalid_orientation:      return (ERROR_BIDI_INVALID_ORIENTATION);
+    case syserr_bidi_invalid_num_shape:        return (ERROR_BIDI_INVALID_NUM_SHAPE);
+    case syserr_bidi_invalid_csd:      return (ERROR_BIDI_INVALID_CSD);
+    case syserr_bidi_no_support:       return (ERROR_BIDI_NO_SUPPORT);
+    case syserr_bidi_rw_incomplete:    return (NO_ERROR_BIDI_RW_INCOMPLETE);
+    case syserr_imp_invalid_parm:      return (ERROR_IMP_INVALID_PARM);
+    case syserr_imp_invalid_length:    return (ERROR_IMP_INVALID_LENGTH);
+    case syserr_hpfs_disk_error_warn:  return (MSG_HPFS_DISK_ERROR_WARN);
+    case syserr_mon_bad_buffer:        return (ERROR_MON_BAD_BUFFER);
+    case syserr_module_corrupted:      return (ERROR_MODULE_CORRUPTED);
+    case syserr_sm_outof_swapfile:     return (ERROR_SM_OUTOF_SWAPFILE);
+    case syserr_lf_timeout:    return (ERROR_LF_TIMEOUT);
+    case syserr_lf_suspend_success:    return (ERROR_LF_SUSPEND_SUCCESS);
+    case syserr_lf_resume_success:     return (ERROR_LF_RESUME_SUCCESS);
+    case syserr_lf_redirect_success:   return (ERROR_LF_REDIRECT_SUCCESS);
+    case syserr_lf_redirect_failure:   return (ERROR_LF_REDIRECT_FAILURE);
+    case syserr_swapper_not_active:    return (ERROR_SWAPPER_NOT_ACTIVE);
+    case syserr_invalid_swapid:        return (ERROR_INVALID_SWAPID);
+    case syserr_ioerr_swap_file:       return (ERROR_IOERR_SWAP_FILE);
+    case syserr_swap_table_full:       return (ERROR_SWAP_TABLE_FULL);
+    case syserr_swap_file_full:        return (ERROR_SWAP_FILE_FULL);
+    case syserr_cant_init_swapper:     return (ERROR_CANT_INIT_SWAPPER);
+    case syserr_swapper_already_init:  return (ERROR_SWAPPER_ALREADY_INIT);
+    case syserr_pmm_insufficient_memory:       return (ERROR_PMM_INSUFFICIENT_MEMORY);
+    case syserr_pmm_invalid_flags:     return (ERROR_PMM_INVALID_FLAGS);
+    case syserr_pmm_invalid_address:   return (ERROR_PMM_INVALID_ADDRESS);
+    case syserr_pmm_lock_failed:       return (ERROR_PMM_LOCK_FAILED);
+    case syserr_pmm_unlock_failed:     return (ERROR_PMM_UNLOCK_FAILED);
+    case syserr_pmm_move_incomplete:   return (ERROR_PMM_MOVE_INCOMPLETE);
+    case syserr_ucom_drive_renamed:    return (ERROR_UCOM_DRIVE_RENAMED);
+    case syserr_ucom_filename_truncated:       return (ERROR_UCOM_FILENAME_TRUNCATED);
+    case syserr_ucom_buffer_length:    return (ERROR_UCOM_BUFFER_LENGTH);
+    case syserr_mon_chain_handle:      return (ERROR_MON_CHAIN_HANDLE);
+    case syserr_mon_not_registered:    return (ERROR_MON_NOT_REGISTERED);
+    case syserr_smg_already_top:       return (ERROR_SMG_ALREADY_TOP);
+    case syserr_pmm_arena_modified:    return (ERROR_PMM_ARENA_MODIFIED);
+    case syserr_smg_printer_open:      return (ERROR_SMG_PRINTER_OPEN);
+    case syserr_pmm_set_flags_failed:  return (ERROR_PMM_SET_FLAGS_FAILED);
+    case syserr_invalid_dos_dd:        return (ERROR_INVALID_DOS_DD);
+    case syserr_blocked:       return (ERROR_BLOCKED);
+    case syserr_noblock:       return (ERROR_NOBLOCK);
+    case syserr_instance_shared:       return (ERROR_INSTANCE_SHARED);
+    case syserr_no_object:     return (ERROR_NO_OBJECT);
+    case syserr_partial_attach:        return (ERROR_PARTIAL_ATTACH);
+    case syserr_incache:       return (ERROR_INCACHE);
+    case syserr_swap_io_problems:      return (ERROR_SWAP_IO_PROBLEMS);
+    case syserr_crosses_object_boundary:       return (ERROR_CROSSES_OBJECT_BOUNDARY);
+    case syserr_longlock:      return (ERROR_LONGLOCK);
+    case syserr_shortlock:     return (ERROR_SHORTLOCK);
+    case syserr_uvirtlock:     return (ERROR_UVIRTLOCK);
+    case syserr_aliaslock:     return (ERROR_ALIASLOCK);
+    case syserr_alias: return (ERROR_ALIAS);
+    case syserr_no_more_handles:       return (ERROR_NO_MORE_HANDLES);
+    case syserr_scan_terminated:       return (ERROR_SCAN_TERMINATED);
+    case syserr_terminator_not_found:  return (ERROR_TERMINATOR_NOT_FOUND);
+    case syserr_not_direct_child:      return (ERROR_NOT_DIRECT_CHILD);
+    case syserr_delay_free:    return (ERROR_DELAY_FREE);
+    case syserr_guardpage:     return (ERROR_GUARDPAGE);
+    case syserr_swaperror:     return (ERROR_SWAPERROR);
+    case syserr_ldrerror:      return (ERROR_LDRERROR);
+    case syserr_nomemory:      return (ERROR_NOMEMORY);
+    case syserr_noaccess:      return (ERROR_NOACCESS);
+    case syserr_no_dll_term:   return (ERROR_NO_DLL_TERM);
+    case syserr_cpsio_code_page_invalid:       return (ERROR_CPSIO_CODE_PAGE_INVALID);
+    case syserr_cpsio_no_spooler:      return (ERROR_CPSIO_NO_SPOOLER);
+    case syserr_cpsio_font_id_invalid: return (ERROR_CPSIO_FONT_ID_INVALID);
+    case syserr_cpsio_internal_error:  return (ERROR_CPSIO_INTERNAL_ERROR);
+    case syserr_cpsio_invalid_ptr_name:        return (ERROR_CPSIO_INVALID_PTR_NAME);
+    case syserr_cpsio_not_active:      return (ERROR_CPSIO_NOT_ACTIVE);
+    case syserr_cpsio_pid_full:        return (ERROR_CPSIO_PID_FULL);
+    case syserr_cpsio_pid_not_found:   return (ERROR_CPSIO_PID_NOT_FOUND);
+    case syserr_cpsio_read_ctl_seq:    return (ERROR_CPSIO_READ_CTL_SEQ);
+    case syserr_cpsio_read_fnt_def:    return (ERROR_CPSIO_READ_FNT_DEF);
+    case syserr_cpsio_write_error:     return (ERROR_CPSIO_WRITE_ERROR);
+    case syserr_cpsio_write_full_error:        return (ERROR_CPSIO_WRITE_FULL_ERROR);
+    case syserr_cpsio_write_handle_bad:        return (ERROR_CPSIO_WRITE_HANDLE_BAD);
+    case syserr_cpsio_swit_load:       return (ERROR_CPSIO_SWIT_LOAD);
+    case syserr_cpsio_inv_command:     return (ERROR_CPSIO_INV_COMMAND);
+    case syserr_cpsio_no_font_swit:    return (ERROR_CPSIO_NO_FONT_SWIT);
+    case syserr_entry_is_callgate:     return (ERROR_ENTRY_IS_CALLGATE);
+    default:   return (NO_ERROR);
+    }
+}
+\f
 #ifdef __GCC2__
 /* Grumble... stupid linking bug.  */
 #define dos_error_message(rc) 0
@@ -870,9 +1493,12 @@ const char *
 OS_error_code_to_message (unsigned int syserr)
 {
   static const char * last_message = 0;
+  APIRET code = (syserr_to_error_code ((enum syserr_names) syserr));
+  if (code == NO_ERROR)
+    return (0);
   if (last_message != 0)
     free ((void *) last_message);
-  last_message = (dos_error_message (syserr));
+  last_message = (dos_error_message (code));
   return (last_message);
 }
 \f
@@ -904,6 +1530,8 @@ static char * syscall_names_table [] =
   "dos-query-current-dir",
   "dos-query-current-disk",
   "dos-query-file-info",
+  "dos-query-fs-attach",
+  "dos-query-fs-info",
   "dos-query-h-type",
   "dos-query-n-p-h-state",
   "dos-query-path-info",
@@ -1019,7 +1647,6 @@ static char * syserr_names_table [] =
   "NET-WRITE-FAULT",
   "NO-PROC-SLOTS",
   "NOT-FROZEN",
-  "SYS-COMP-NOT-LOADED",
   "TSTOVFL",
   "TSTDUP",
   "NO-ITEMS",
index fd5cfc040d50298a8abfb806796aaad6d8e6f964..2de71a89f781a50424cefc1799088faac16fea31 100644 (file)
@@ -1,6 +1,6 @@
 ### -*- Fundamental -*-
 ###
-###    $Id: makefile,v 1.2 1994/12/02 20:44:01 cph Exp $
+###    $Id: makefile,v 1.3 1994/12/19 22:32:49 cph Exp $
 ###
 ###    Copyright (c) 1994 Massachusetts Institute of Technology
 ###
@@ -233,7 +233,9 @@ prosfs.c \
 prosio.c \
 prosterm.c \
 prostty.c \
-pros2fs.c
+pros2fs.c \
+pros2io.c \
+pros2pm.c
 # prosproc.c
 # prospty.c
 
@@ -244,7 +246,9 @@ prosfs.$(OBJ) \
 prosio.$(OBJ) \
 prosterm.$(OBJ) \
 prostty.$(OBJ) \
-pros2fs.$(OBJ)
+pros2fs.$(OBJ) \
+pros2io.$(OBJ) \
+pros2pm.$(OBJ)
 #prosproc.$(OBJ)
 #prospty.$(OBJ)
 
@@ -265,7 +269,8 @@ os2pmcon.c \
 os2term.c \
 os2thrd.c \
 os2top.c \
-os2tty.c
+os2tty.c \
+os2xcpt.c
 
 OS2_OBJECTS = \
 os2.$(OBJ) \
@@ -284,7 +289,8 @@ os2pmcon.$(OBJ) \
 os2term.$(OBJ) \
 os2thrd.$(OBJ) \
 os2top.$(OBJ) \
-os2tty.$(OBJ)
+os2tty.$(OBJ) \
+os2xcpt.$(OBJ)
 
 HEAD_FILES = scheme.tch prims.h zones.h locks.h bignum.h \
        $(GC_HEAD_FILES) trap.h lookup.h history.h cmpint.h
@@ -429,12 +435,17 @@ prosterm.$(OBJ) : osterm.h osio.h
 prostty.$(OBJ) : ostty.h osctty.h osfile.h osio.h
 prmcon.$(OBJ) : scheme.tch prims.h prmcon.h
 
-$(OS2_OBJECTS) : dstack.h osscheme.h outf.h os.h ansidecl.h oscond.h \
-       posixtyp.h syscall.h osio.h os2.h os2api.h os2cthrd.h os2ctty.h \
-       os2io.h os2msg.h os2pm.h os2thrd.h
+$(OS2_OBJECTS) pros2fs.$(OBJ) pros2io.$(OBJ) pros2pm.$(OBJ) : \
+       dstack.h osscheme.h outf.h os.h ansidecl.h oscond.h posixtyp.h \
+       syscall.h osio.h os2.h os2api.h os2cthrd.h os2ctty.h os2io.h \
+       os2msg.h os2pm.h os2thrd.h
 os2ctty.$(OBJ) : osctty.h ossig.h
-os2env.$(OBJ) : osenv.h scheme.tch
+os2env.$(OBJ) : scheme.tch osenv.h
 os2file.$(OBJ) : osfile.h
 os2fs.$(OBJ) : osfs.h
 os2top.$(OBJ) : ostop.h option.h
 os2tty.$(OBJ) : ostty.h
+os2xcpt.$(OBJ) : scheme.tch $(GC_HEAD_FILES)
+pros2fs.$(OBJ) : scheme.tch prims.h osfs.h
+pros2io.$(OBJ) : scheme.tch prims.h
+pros2pm.$(OBJ) : scheme.tch prims.h