From e518f96cbcaad800b43924092b5deb79e3ed3813 Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Fri, 3 Nov 1995 01:30:21 +0000 Subject: [PATCH] * Reorganize the PM interface to encapsulate PM event messages and send them to the window's event qid in their original format. This simplifies the process of adding new event types, and allows the window's owner to decide what is relevant information. * Add some new interface calls to support mouse tracking and pop-up menus. * Implement a mechanism to mark characters with the mouse in the console window, and a Copy command to copy them to the clipboard. --- v7/src/microcode/os2msg.h | 11 +- v7/src/microcode/os2pm.c | 2110 +++++++++++++++++----------------- v7/src/microcode/os2pm.h | 123 +- v7/src/microcode/os2pm.scm | 116 +- v7/src/microcode/os2pmcon.c | 740 +++++++++--- v7/src/microcode/os2pmcon.rc | 8 +- v7/src/microcode/pros2pm.c | 459 +++++--- 7 files changed, 2036 insertions(+), 1531 deletions(-) diff --git a/v7/src/microcode/os2msg.h b/v7/src/microcode/os2msg.h index a6dbebba2..402c16b65 100644 --- a/v7/src/microcode/os2msg.h +++ b/v7/src/microcode/os2msg.h @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2msg.h,v 1.12 1995/10/30 08:01:05 cph Exp $ +$Id: os2msg.h,v 1.13 1995/11/03 01:29:04 cph Exp $ Copyright (c) 1994-95 Massachusetts Institute of Technology @@ -97,15 +97,8 @@ typedef enum /* These are messages that are automatically generated by the PM thread when the corresponding events occur. */ - mt_button_event, /* mouse button press */ - mt_close_event, /* window close (user command) */ - mt_focus_event, /* window focus change */ - mt_key_event, /* key press */ + mt_pm_event, /* undecoded PM input event */ mt_paint_event, /* window needs painting */ - mt_resize_event, /* window resized */ - mt_visibility_event, /* window visibility change */ - mt_command_event, /* WM_COMMAND message */ - mt_help_event, /* WM_HELP message */ /* This requests the thread on the other end of the connection to kill itself. At present this request is not used. */ diff --git a/v7/src/microcode/os2pm.c b/v7/src/microcode/os2pm.c index 37f3e2538..dda12b4c2 100644 --- a/v7/src/microcode/os2pm.c +++ b/v7/src/microcode/os2pm.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2pm.c,v 1.20 1995/10/30 08:02:37 cph Exp $ +$Id: os2pm.c,v 1.21 1995/11/03 01:29:14 cph Exp $ Copyright (c) 1994-95 Massachusetts Institute of Technology @@ -81,6 +81,7 @@ typedef struct _window_t unsigned int minimizingp : 1; /* nonzero if window being minimized */ unsigned int minimizedp : 1; /* nonzero if window is minimized */ unsigned int permanentp : 1; /* nonzero means don't close on reload */ + unsigned int mousetrackp : 1; /* nonzero means generate WM_MOUSEMOVE msgs */ } window_t; #define WINDOW_FRAME(window) ((window) -> frame) #define WINDOW_CLIENT(window) ((window) -> client) @@ -100,6 +101,7 @@ typedef struct _window_t #define WINDOW_MINIMIZINGP(window) ((window) -> minimizingp) #define WINDOW_MINIMIZEDP(window) ((window) -> minimizedp) #define WINDOW_PERMANENTP(window) ((window) -> permanentp) +#define WINDOW_MOUSETRACKP(window) ((window) -> mousetrackp) typedef struct _bitmap_t { @@ -130,7 +132,7 @@ typedef struct structure definitions for most of the procedures. */ #include "os2pm-id.h" -static void get_window_pos (window_t *, short *, short *); +static void window_pos (window_t *, short *, short *); static void handle_window_pos_request (msg_t *); typedef struct @@ -149,7 +151,7 @@ typedef struct #define SM_POS_REPLY_X(m) (((sm_pos_reply_t *) (m)) -> x) #define SM_POS_REPLY_Y(m) (((sm_pos_reply_t *) (m)) -> y) -static void get_window_size (window_t *, unsigned short *, unsigned short *); +static void window_size (window_t *, unsigned short *, unsigned short *); static void handle_window_size_request (msg_t *); typedef struct @@ -168,7 +170,7 @@ typedef struct #define SM_SIZE_REPLY_WIDTH(m) (((sm_size_reply_t *) (m)) -> width) #define SM_SIZE_REPLY_HEIGHT(m) (((sm_size_reply_t *) (m)) -> height) -static void get_window_frame_size +static void window_frame_size (window_t *, unsigned short *, unsigned short *); static void handle_window_frame_size_request (msg_t *); @@ -213,6 +215,8 @@ typedef struct #define SM_PS_SET_BITMAP_REPLY_BITMAP(m) \ (((sm_ps_set_bitmap_reply_t *) (m)) -> bitmap) +static void close_all_windows (void); + static void sync_transaction (qid_t, msg_t *); static void sync_reply (qid_t); @@ -223,43 +227,48 @@ static void initialize_id_table (id_table_t *); static unsigned int allocate_id (id_table_t *, void *); static void deallocate_id (id_table_t *, unsigned int); static void * id_to_pointer (id_table_t *, unsigned int); - +static int id_validp (id_table_t *, unsigned int); static ps_t * psid_to_ps (psid_t); static window_t * wid_to_window (wid_t); static bitmap_t * bid_to_bitmap (bid_t); -static void close_all_windows (void); 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 window_t * hwnd_to_window (HWND); +static msg_t * make_pm_event (wid_t, ULONG, MPARAM, MPARAM); +static msg_t * make_paint_event + (wid_t, unsigned short, unsigned short, unsigned short, unsigned short); + +static void recreate_cursor (window_t *); +static void activate_cursor (window_t *); +static void deactivate_cursor (window_t *); + +static window_t * make_window (qid_t, qid_t); + +static void win_create_cursor (HWND, LONG, LONG, LONG, LONG, ULONG, PRECTL); +static void win_destroy_cursor (HWND); +static void win_show_cursor (HWND, BOOL); static void recreate_cursor (window_t *); static void activate_cursor (window_t *); static void deactivate_cursor (window_t *); +static void maybe_activate_cursor (ps_t *); +static void maybe_deactivate_cursor (ps_t *); static HDC get_ps_device (HPS); static LONG get_device_capability (HDC, LONG); static ps_t * create_ps (pst_t, HDC, qid_t); static void destroy_ps (ps_t *); -static void maybe_activate_cursor (ps_t *); -static void maybe_deactivate_cursor (ps_t *); static int ps_set_font (ps_t *, unsigned short, const char *); - -static msg_t * make_button_event - (wid_t, unsigned char, unsigned char, 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 - (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); -static msg_t * make_command_event (wid_t, USHORT, USHORT, USHORT); -static msg_t * make_help_event (wid_t, USHORT, USHORT, USHORT); +static int parse_font_spec (const char *, PSZ *, LONG *, USHORT *); +static const char * unparse_font_spec (PSZ, LONG, USHORT); +static int ps_set_font_1 (ps_t * ps, PSZ, LONG, USHORT, LONG); +static PLONG ps_make_char_increments (LONG); +static int create_font (HPS, LONG, PFONTMETRICS, USHORT); +static void copy_fontmetrics_to_fattrs (FONTMETRICS *, FATTRS *); +static void ps_set_font_size (ps_t *, LONG); #define ID_FRAME 1 @@ -282,6 +291,7 @@ static HMQ pm_hmq; static HWND pm_object_window; static tqueue_t * pm_tqueue; static PFNWP original_frame_window_procedure; +static window_t * capture_window; static const char object_class [] = "mit-scheme.object"; static const char window_class [] = "mit-scheme.window"; @@ -292,6 +302,13 @@ static const char window_class [] = "mit-scheme.window"; OS2_send_message ((WINDOW_EVENT_QID (window)), (message)); \ } +#define SEND_PM_EVENT(hwnd, msg, mp1, mp2) \ +{ \ + window_t * window = (hwnd_to_window (hwnd)); \ + SEND_EVENT (window, \ + (make_pm_event ((WINDOW_ID (window)), msg, mp1, mp2))); \ +} + #define window_error(name) window_error_1 (#name, 1) #define window_warning(name) window_error_1 (#name, 0) @@ -332,20 +349,14 @@ OS2_initialize_pm_thread (void) SET_MSG_TYPE_LENGTH (mt_ps_set_bitmap_request, sm_ps_set_bitmap_request_t); SET_MSG_TYPE_LENGTH (mt_ps_set_bitmap_reply, sm_ps_set_bitmap_reply_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_focus_event, sm_focus_event_t); - SET_MSG_TYPE_LENGTH (mt_key_event, sm_key_event_t); + SET_MSG_TYPE_LENGTH (mt_pm_event, sm_pm_event_t); SET_MSG_TYPE_LENGTH (mt_paint_event, sm_paint_event_t); - SET_MSG_TYPE_LENGTH (mt_resize_event, sm_resize_event_t); - SET_MSG_TYPE_LENGTH (mt_visibility_event, sm_visibility_event_t); - SET_MSG_TYPE_LENGTH (mt_command_event, sm_command_event_t); - SET_MSG_TYPE_LENGTH (mt_help_event, sm_help_event_t); initialize_id_table (& psid_table); initialize_id_table (& wid_table); initialize_id_table (& bid_table); original_frame_window_procedure = 0; + capture_window = 0; { qid_t qid; OS2_make_qid_pair ((&pm_init_qid), (&qid)); @@ -359,6 +370,19 @@ OS2_initialize_pm_thread (void) } add_reload_cleanup (close_all_windows); } + +static void +close_all_windows (void) +{ + window_t ** scan = ((window_t **) (ID_TABLE_POINTERS (& wid_table))); + window_t ** end = (scan + (ID_TABLE_LENGTH (& wid_table))); + while (scan < end) + { + window_t * window = (*scan++); + if ((window != 0) && (!WINDOW_PERMANENTP (window))) + window_close (window); + } +} /* Define this to cause a calling thread to wait for the PM thread to finish requests that have trivial replies. Otherwise, the calling @@ -501,6 +525,12 @@ OS2_write_pm_tqueue (tqueue_t * tqueue, msg_t * message) window_warning (WinPostMsg); } +/* Object IDs + + These tables maintain data structures in the PM thread, and + associate those structures with ID numbers that are given out to + other threads (and to Scheme programs). */ + static void initialize_id_table (id_table_t * table) { @@ -564,61 +594,24 @@ id_validp (id_table_t * table, unsigned int id) && (id < (ID_TABLE_LENGTH (table))) && (((ID_TABLE_POINTERS (table)) [id]) != 0)); } - + static ps_t * psid_to_ps (psid_t psid) { return (id_to_pointer ((& psid_table), psid)); } -int -OS2_psid_validp (psid_t psid) -{ - return (id_validp ((& psid_table), psid)); -} - static window_t * wid_to_window (wid_t wid) { return (id_to_pointer ((& wid_table), wid)); } -int -OS2_wid_validp (wid_t wid) -{ - return (id_validp ((& wid_table), wid)); -} - static bitmap_t * bid_to_bitmap (bid_t bid) { return (id_to_pointer ((& bid_table), bid)); } - -int -OS2_bid_validp (bid_t bid) -{ - return (id_validp ((& bid_table), bid)); -} - -psid_t -OS2_window_client_ps (wid_t wid) -{ - return (PS_ID (WINDOW_CLIENT_PS (wid_to_window (wid)))); -} - -static void -close_all_windows (void) -{ - window_t ** scan = ((window_t **) (ID_TABLE_POINTERS (& wid_table))); - window_t ** end = (scan + (ID_TABLE_LENGTH (& wid_table))); - while (scan < end) - { - window_t * window = (*scan++); - if ((window != 0) && (!WINDOW_PERMANENTP (window))) - close_window (window); - } -} /* Implementation of the object window. The object window handles encapsulated messages sent from the Scheme thread. This defines @@ -657,150 +650,465 @@ object_window_procedure (HWND window, ULONG msg, MPARAM mp1, MPARAM mp2) return (MRVOID); } -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); -} - -void -OS2_window_permanent (wid_t wid) -{ - (WINDOW_PERMANENTP (wid_to_window (wid))) = 1; -} - -HWND -OS2_window_frame_handle (wid_t wid) -{ - /* This is needed by the OS2_menu_create, to supply an owner for the - top-level menu bar. */ - return (WINDOW_FRAME (wid_to_window (wid))); -} +/* Implementation of the Frame Window */ -int -OS2_memory_ps_p (psid_t psid) -{ - return ((PS_VISUAL_TYPE (psid_to_ps (psid))) == pst_memory); -} - -bid_t -OS2_ps_get_bitmap (psid_t psid) +static MRESULT EXPENTRY +frame_window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - bitmap_t * bitmap = (PS_VISUAL (psid_to_ps (psid))); - return ((bitmap == 0) ? BID_NONE : (BITMAP_ID (bitmap))); + window_t * window = (hwnd_to_window (WinWindowFromID (hwnd, FID_CLIENT))); + switch (msg) + { + case WM_QUERYTRACKINFO: + /* Set the tracking grid for the resize operation. */ + { + MRESULT mr + = ((* original_frame_window_procedure) (hwnd, msg, mp1, mp2)); + if (mr == MRTRUE) + { + PTRACKINFO pti = (PVOIDFROMMP (mp2)); + if ((((pti -> fs) & TF_MOVE) != TF_MOVE) + && ((((pti -> fs) & TF_MOVE) != 0) + || (((pti -> fs) & TF_SETPOINTERPOS) != 0))) + { + (pti -> fs) |= TF_GRID; + (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); + } + case WM_MINMAXFRAME: + /* If minimizing, mark the window to indicate this. The client + will shortly receive a WM_SIZE which indicates that the + minimization has completed. */ + { + PSWP pswp = (PVOIDFROMMP (mp1)); + if ((!WINDOW_MINIMIZEDP (window)) + && (((pswp -> fl) & SWP_MINIMIZE) != 0)) + { + (WINDOW_MINIMIZINGP (window)) = 1; + (WINDOW_MINIMIZEDP (window)) = 1; + } + else if ((WINDOW_MINIMIZEDP (window)) + && (((pswp -> fl) & (SWP_RESTORE | SWP_MAXIMIZE)) != 0)) + (WINDOW_MINIMIZEDP (window)) = 0; + } + break; + } + return ((* original_frame_window_procedure) (hwnd, msg, mp1, mp2)); } -/* This macro supplies a NO-OP procedure needed by the - machine-generated code for OS2_pm_synchronize. */ -#define pm_synchronize(qid) - -/* This machine-generated file contains most of the external procedure - definitions, and their associated handler procedures. */ -#include "os2pm-rp.h" - -void -OS2_window_pos (wid_t wid, short * x, 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 * request) -{ - qid_t sender = (MSG_SENDER (request)); - msg_t * reply = (OS2_create_message (mt_window_pos_reply)); - get_window_pos ((SM_POS_REQUEST_WINDOW (request)), - (& (SM_POS_REPLY_X (reply))), - (& (SM_POS_REPLY_Y (reply)))); - OS2_destroy_message (request); - OS2_send_message (sender, reply); -} - -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 * request) -{ - qid_t sender = (MSG_SENDER (request)); - msg_t * reply = (OS2_create_message (mt_window_size_reply)); - get_window_size ((SM_SIZE_REQUEST_WINDOW (request)), - (& (SM_SIZE_REPLY_WIDTH (reply))), - (& (SM_SIZE_REPLY_HEIGHT (reply)))); - OS2_destroy_message (request); - OS2_send_message (sender, reply); -} - -void -OS2_window_frame_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_frame_size_request)); - (SM_FRAME_SIZE_REQUEST_WINDOW (message)) = window; - message - = (OS2_message_transaction ((WINDOW_QID (window)), - message, - mt_window_frame_size_reply)); - (* width) = (SM_FRAME_SIZE_REPLY_WIDTH (message)); - (* height) = (SM_FRAME_SIZE_REPLY_HEIGHT (message)); - OS2_destroy_message (message); -} - -static void -handle_window_frame_size_request (msg_t * request) -{ - qid_t sender = (MSG_SENDER (request)); - msg_t * reply = (OS2_create_message (mt_window_frame_size_reply)); - get_window_frame_size ((SM_FRAME_SIZE_REQUEST_WINDOW (request)), - (& (SM_FRAME_SIZE_REPLY_WIDTH (reply))), - (& (SM_FRAME_SIZE_REPLY_HEIGHT (reply)))); - OS2_destroy_message (request); - OS2_send_message (sender, reply); -} +/* Implementation of the Client Window */ -bid_t -OS2_ps_set_bitmap (psid_t psid, bid_t bid) +static MRESULT EXPENTRY +window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) { - ps_t * ps = (psid_to_ps (psid)); - bitmap_t * bitmap = ((bid == BID_NONE) ? 0 : (bid_to_bitmap (bid))); - msg_t * message = (OS2_create_message (mt_ps_set_bitmap_request)); - (SM_PS_SET_BITMAP_REQUEST_PS (message)) = ps; - (SM_PS_SET_BITMAP_REQUEST_BITMAP (message)) = bitmap; - message - = (OS2_message_transaction ((PS_QID (ps)), - message, - mt_ps_set_bitmap_reply)); - bitmap = (SM_PS_SET_BITMAP_REPLY_BITMAP (message)); - OS2_destroy_message (message); - return ((bitmap == 0) ? BID_NONE : (BITMAP_ID (bitmap))); -} + switch (msg) + { + case WM_CREATE: + { + window_t * window = (PVOIDFROMMP (mp1)); + if (!WinSetWindowPtr (hwnd, QWP_WINDOW, window)) + window_error (WinSetWindowPtr); + (WINDOW_CLIENT (window)) = hwnd; + (WINDOW_CLIENT_PS (window)) + = (create_ps (pst_window, + (WinOpenWindowDC (hwnd)), + (WINDOW_QID (window)))); + (PS_VISUAL (WINDOW_CLIENT_PS (window))) = window; + return (MRFALSE); + } + case WM_PAINT: + { + window_t * window = (hwnd_to_window (hwnd)); + if (((WinQueryWindowULong ((WINDOW_FRAME (window)), QWL_STYLE)) + & WS_MINIMIZED) + != 0) + break; + { + HPS hps = (PS_HANDLE (WINDOW_CLIENT_PS (window))); + RECTL rectl; + if ((WinBeginPaint ((WINDOW_CLIENT (window)), hps, (& rectl))) + == NULLHANDLE) + window_error (WinBeginPaint); + if (!WinEndPaint (hps)) + window_error (WinEndPaint); + SEND_EVENT (window, + (make_paint_event ((WINDOW_ID (window)), + (rectl . xLeft), + (rectl . xRight), + (rectl . yBottom), + (rectl . yTop)))); + } + return (MRVOID); + } + case WM_SETFOCUS: + { + window_t * window = (hwnd_to_window (hwnd)); + if (SHORT1FROMMP (mp2)) + recreate_cursor (window); + else + { + win_destroy_cursor (WINDOW_CLIENT (window)); + (WINDOW_CURSOR_CREATEDP (window)) = 0; + } + } + SEND_PM_EVENT (hwnd, msg, mp1, mp2); + return (MRVOID); + 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_DESTROY: + { + window_t * window = (hwnd_to_window (hwnd)); + destroy_ps (WINDOW_CLIENT_PS (window)); + (WINDOW_CLIENT_PS (window)) = 0; + return (MRVOID); + } + case WM_SIZE: + { + window_t * window = (hwnd_to_window (hwnd)); + /* If this message is part of a minimization, ignore it. */ + if (WINDOW_MINIMIZINGP (window)) + { + (WINDOW_MINIMIZINGP (window)) = 0; + (WINDOW_MINIMIZEDP (window)) = 1; + break; + } + if (WINDOW_CURSOR_CREATEDP (window)) + { + win_destroy_cursor (WINDOW_CLIENT (window)); + (WINDOW_CURSOR_CREATEDP (window)) = 0; + (WINDOW_CURSOR_X (window)) = 0; + (WINDOW_CURSOR_Y (window)) = 0; + recreate_cursor (window); + } + } + SEND_PM_EVENT (hwnd, msg, mp1, mp2); + return (MRVOID); + case WM_CLOSE: + case WM_COMMAND: + case WM_CONTROL: + case WM_HELP: + case WM_SHOW: + SEND_PM_EVENT (hwnd, msg, mp1, mp2); + return (MRVOID); + case WM_CHAR: + case WM_BUTTON1DOWN: + case WM_BUTTON1UP: + case WM_BUTTON1CLICK: + case WM_BUTTON1DBLCLK: + case WM_BUTTON2DOWN: + case WM_BUTTON2UP: + case WM_BUTTON2CLICK: + case WM_BUTTON2DBLCLK: + case WM_BUTTON3DOWN: + case WM_BUTTON3UP: + case WM_BUTTON3CLICK: + case WM_BUTTON3DBLCLK: + SEND_PM_EVENT (hwnd, msg, mp1, mp2); + return (MRTRUE); + case WM_MOUSEMOVE: + if (WINDOW_MOUSETRACKP (hwnd_to_window (hwnd))) + { + SEND_PM_EVENT (hwnd, msg, mp1, mp2); + return (MRTRUE); + } + break; + default: + break; + } + return (WinDefWindowProc (hwnd, msg, mp1, mp2)); +} + +static window_t * +hwnd_to_window (HWND hwnd) +{ + window_t * window = (WinQueryWindowPtr (hwnd, QWP_WINDOW)); + if (window == 0) + window_error (WinQueryWindowPtr); + return (window); +} + +static msg_t * +make_pm_event (wid_t wid, ULONG msg, MPARAM mp1, MPARAM mp2) +{ + msg_t * message = (OS2_create_message (mt_pm_event)); + (SM_PM_EVENT_WID (message)) = wid; + (SM_PM_EVENT_MSG (message)) = msg; + (SM_PM_EVENT_MP1 (message)) = mp1; + (SM_PM_EVENT_MP2 (message)) = mp2; + return (message); +} + +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); +} + +int +OS2_translate_wm_char (MPARAM mp1, MPARAM mp2, + unsigned short * code, + unsigned short * flags, + unsigned char * repeat) +{ + (*flags) = (SHORT1FROMMP (mp1)); + (*repeat) = (CHAR3FROMMP (mp1)); + /* Ignore compound keys for now. */ + if (((*flags) & (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP | KC_KEYUP)) + != 0) + return (0); + if (((*flags) & KC_VIRTUALKEY) != 0) + { + (*code) = (SHORT2FROMMP (mp2)); + return (1); + } + if (((*flags) & (KC_CHAR | KC_CTRL | KC_ALT)) != 0) + { + (*code) = (SHORT1FROMMP (mp2)); + return (1); + } + return (0); +} + +/* Direct Operations + + These are exported operations that can be implemented directly in + the calling thread. Other operations that require communication + with the PM thread appear on following pages. */ + +int +OS2_psid_validp (psid_t psid) +{ + return (id_validp ((& psid_table), psid)); +} + +int +OS2_wid_validp (wid_t wid) +{ + return (id_validp ((& wid_table), wid)); +} + +int +OS2_bid_validp (bid_t bid) +{ + return (id_validp ((& bid_table), bid)); +} + +psid_t +OS2_window_client_ps (wid_t wid) +{ + return (PS_ID (WINDOW_CLIENT_PS (wid_to_window (wid)))); +} + +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); +} + +void +OS2_window_permanent (wid_t wid) +{ + (WINDOW_PERMANENTP (wid_to_window (wid))) = 1; +} + +void +OS2_window_mousetrack (wid_t wid, int trackp) +{ + (WINDOW_MOUSETRACKP (wid_to_window (wid))) = trackp; +} + +HWND +OS2_window_frame_handle (wid_t wid) +{ + return (WINDOW_FRAME (wid_to_window (wid))); +} + +HWND +OS2_window_client_handle (wid_t wid) +{ + return (WINDOW_CLIENT (wid_to_window (wid))); +} + +int +OS2_memory_ps_p (psid_t psid) +{ + return ((PS_VISUAL_TYPE (psid_to_ps (psid))) == pst_memory); +} + +bid_t +OS2_ps_get_bitmap (psid_t psid) +{ + bitmap_t * bitmap = (PS_VISUAL (psid_to_ps (psid))); + return ((bitmap == 0) ? BID_NONE : (BITMAP_ID (bitmap))); +} + +/* Relayed Operations + + This page implements exported operations that require communication + with the PM thread. The PM-thread-side of these operations appear + on the following pages; this page implements only the mechanism to + communicate the operation to the PM thread. The bulk of these + communication procedures is machine-generated. */ + +/* This macro supplies a NO-OP procedure needed by the + machine-generated code for OS2_pm_synchronize. */ +#define pm_synchronize(qid) + +/* This machine-generated file contains most of the external procedure + definitions, and their associated handler procedures. */ +#include "os2pm-rp.h" + +void +OS2_window_pos (wid_t wid, short * x, 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 * request) +{ + qid_t sender = (MSG_SENDER (request)); + msg_t * reply = (OS2_create_message (mt_window_pos_reply)); + window_pos ((SM_POS_REQUEST_WINDOW (request)), + (& (SM_POS_REPLY_X (reply))), + (& (SM_POS_REPLY_Y (reply)))); + OS2_destroy_message (request); + OS2_send_message (sender, reply); +} + +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 * request) +{ + qid_t sender = (MSG_SENDER (request)); + msg_t * reply = (OS2_create_message (mt_window_size_reply)); + window_size ((SM_SIZE_REQUEST_WINDOW (request)), + (& (SM_SIZE_REPLY_WIDTH (reply))), + (& (SM_SIZE_REPLY_HEIGHT (reply)))); + OS2_destroy_message (request); + OS2_send_message (sender, reply); +} + +void +OS2_window_frame_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_frame_size_request)); + (SM_FRAME_SIZE_REQUEST_WINDOW (message)) = window; + message + = (OS2_message_transaction ((WINDOW_QID (window)), + message, + mt_window_frame_size_reply)); + (* width) = (SM_FRAME_SIZE_REPLY_WIDTH (message)); + (* height) = (SM_FRAME_SIZE_REPLY_HEIGHT (message)); + OS2_destroy_message (message); +} + +static void +handle_window_frame_size_request (msg_t * request) +{ + qid_t sender = (MSG_SENDER (request)); + msg_t * reply = (OS2_create_message (mt_window_frame_size_reply)); + window_frame_size ((SM_FRAME_SIZE_REQUEST_WINDOW (request)), + (& (SM_FRAME_SIZE_REPLY_WIDTH (reply))), + (& (SM_FRAME_SIZE_REPLY_HEIGHT (reply)))); + OS2_destroy_message (request); + OS2_send_message (sender, reply); +} + +bid_t +OS2_ps_set_bitmap (psid_t psid, bid_t bid) +{ + ps_t * ps = (psid_to_ps (psid)); + bitmap_t * bitmap = ((bid == BID_NONE) ? 0 : (bid_to_bitmap (bid))); + msg_t * message = (OS2_create_message (mt_ps_set_bitmap_request)); + (SM_PS_SET_BITMAP_REQUEST_PS (message)) = ps; + (SM_PS_SET_BITMAP_REQUEST_BITMAP (message)) = bitmap; + message + = (OS2_message_transaction ((PS_QID (ps)), + message, + mt_ps_set_bitmap_reply)); + bitmap = (SM_PS_SET_BITMAP_REPLY_BITMAP (message)); + OS2_destroy_message (message); + return ((bitmap == 0) ? BID_NONE : (BITMAP_ID (bitmap))); +} static void handle_ps_set_bitmap_request (msg_t * request) @@ -823,10 +1131,17 @@ OS2_ps_set_font (psid_t psid, unsigned short id, const char * name) return (metrics); } -static window_t * make_window (qid_t, qid_t); +/* PM-thread Operation Implementations + + All of the procedures from this point on are implementations of + exported operations. These implementations are the code that is + run in the PM thread to implement the operations that are invoked + in other threads. */ + +/* Windows */ static wid_t -open_window (qid_t qid, qid_t event_qid, ULONG flags, HMODULE module, ULONG id, +window_open (qid_t qid, qid_t event_qid, ULONG flags, HMODULE module, ULONG id, ULONG style, const char * title) { window_t * window = (make_window (qid, event_qid)); @@ -894,109 +1209,30 @@ make_window (qid_t qid, qid_t event_qid) (WINDOW_EVENT_QID (window)) = event_qid; (WINDOW_ID (window)) = (allocate_id ((& wid_table), window)); (WINDOW_CURSOR_CREATEDP (window)) = 0; - (WINDOW_CURSOR_ENABLEDP (window)) = 0; - (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_warning (WinDestroyWindow); - deallocate_id ((& wid_table), (WINDOW_ID (window))); - OS_free (window); -} - -static void -show_window (window_t * window, int showp) -{ - if (!WinShowWindow ((WINDOW_FRAME (window)), showp)) - window_warning (WinShowWindow); -} - -static void -win_create_cursor (HWND client, LONG x, LONG y, LONG cx, LONG cy, ULONG fs, - PRECTL clip_rectl) -{ - if (!WinCreateCursor (client, x, y, cx, cy, fs, clip_rectl)) - window_warning (WinCreateCursor); -} - -static void -win_destroy_cursor (HWND client) -{ - if (!WinDestroyCursor (client)) - window_warning (WinDestroyCursor); -} - -static void -win_show_cursor (HWND client, BOOL showp) -{ - if (!WinShowCursor (client, showp)) - window_warning (WinShowCursor); -} - -static void -move_cursor (window_t * window, short x, short y) -{ - (WINDOW_CURSOR_X (window)) = x; - (WINDOW_CURSOR_Y (window)) = y; - if (WINDOW_CURSOR_CREATEDP (window)) - win_create_cursor ((WINDOW_CLIENT (window)), x, y, 0, 0, CURSOR_SETPOS, 0); -} - -static void -shape_cursor (window_t * window, unsigned short width, unsigned short height, - unsigned short style) -{ - (WINDOW_CURSOR_WIDTH (window)) = width; - (WINDOW_CURSOR_HEIGHT (window)) = height; - (WINDOW_CURSOR_STYLE (window)) = style; - if (WINDOW_CURSOR_CREATEDP (window)) - recreate_cursor (window); -} - -static void -enable_cursor (window_t * window, int showp) -{ - if ((WINDOW_CURSOR_CREATEDP (window)) - && ((showp != 0) != (WINDOW_CURSOR_ENABLEDP (window)))) - win_show_cursor ((WINDOW_CLIENT (window)), showp); - (WINDOW_CURSOR_ENABLEDP (window)) = (showp != 0); -} - -static void -recreate_cursor (window_t * window) -{ - win_create_cursor ((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_CURSOR_CREATEDP (window)) = 1; - if (WINDOW_CURSOR_ENABLEDP (window)) - win_show_cursor ((WINDOW_CLIENT (window)), TRUE); + (WINDOW_CURSOR_ENABLEDP (window)) = 0; + (WINDOW_MINIMIZINGP (window)) = 0; + (WINDOW_MINIMIZEDP (window)) = 0; + (WINDOW_PERMANENTP (window)) = 0; + (WINDOW_MOUSETRACKP (window)) = 0; + return (window); } static void -activate_cursor (window_t * window) +window_close (window_t * window) { - if ((WINDOW_CURSOR_CREATEDP (window)) && (WINDOW_CURSOR_ENABLEDP (window))) - win_show_cursor ((WINDOW_CLIENT (window)), TRUE); + if (!WinDestroyWindow (WINDOW_FRAME (window))) + window_warning (WinDestroyWindow); + deallocate_id ((& wid_table), (WINDOW_ID (window))); + OS_free (window); } static void -deactivate_cursor (window_t * window) +window_show (window_t * window, int showp) { - if ((WINDOW_CURSOR_CREATEDP (window)) && (WINDOW_CURSOR_ENABLEDP (window))) - win_show_cursor ((WINDOW_CLIENT (window)), FALSE); + if (!WinShowWindow ((WINDOW_FRAME (window)), showp)) + window_warning (WinShowWindow); } - + static void window_scroll (window_t * window, short xl, short xh, short yl, short yh, short x_delta, short y_delta) @@ -1041,7 +1277,7 @@ window_activate (window_t * window) } static void -get_window_pos (window_t * window, short * x, short * y) +window_pos (window_t * window, short * x, short * y) { SWP swp; if (!WinQueryWindowPos ((WINDOW_FRAME (window)), (& swp))) @@ -1051,7 +1287,7 @@ get_window_pos (window_t * window, short * x, short * y) } static void -set_window_pos (window_t * window, short x, short y) +window_set_pos (window_t * window, short x, short y) { if (!WinSetWindowPos ((WINDOW_FRAME (window)), NULLHANDLE, x, y, 0, 0, SWP_MOVE)) @@ -1059,8 +1295,8 @@ set_window_pos (window_t * window, short x, short y) } static void -get_window_size (window_t * window, - unsigned short * width, unsigned short * height) +window_size (window_t * window, + unsigned short * width, unsigned short * height) { SWP swp; if (!WinQueryWindowPos ((WINDOW_CLIENT (window)), (& swp))) @@ -1070,8 +1306,8 @@ get_window_size (window_t * window, } static void -get_window_frame_size (window_t * window, - unsigned short * width, unsigned short * height) +window_frame_size (window_t * window, + unsigned short * width, unsigned short * height) { SWP swp; if (!WinQueryWindowPos ((WINDOW_FRAME (window)), (& swp))) @@ -1081,7 +1317,7 @@ get_window_frame_size (window_t * window, } static void -set_window_size (window_t * window, +window_set_size (window_t * window, unsigned short width, unsigned short height) { SWP swp; @@ -1114,7 +1350,7 @@ window_focusp (window_t * window) } static void -set_window_state (window_t * window, window_state_t state) +window_set_state (window_t * window, window_state_t state) { ULONG op = 0; HWND behind = NULLHANDLE; @@ -1155,20 +1391,148 @@ set_window_state (window_t * window, window_state_t state) } static void -set_window_title (window_t * window, const char * title) +window_set_title (window_t * window, const char * title) { if (!WinSetWindowText ((WINDOW_FRAME (window)), ((PSZ) title))) window_warning (WinSetWindowText); } static void -update_frame_window (window_t * window, USHORT flags) +window_update_frame (window_t * window, USHORT flags) { (void) WinSendMsg ((WINDOW_FRAME (window)), WM_UPDATEFRAME, (MPFROMSHORT (flags)), 0); } + +static HWND +window_handle_from_id (qid_t qid, HWND window, ULONG id) +{ + return (WinWindowFromID (window, id)); +} + +static BOOL +window_set_capture (window_t * window, int capturep) +{ + if (capturep) + { + if (capture_window == 0) + { + BOOL rc = (WinSetCapture (HWND_DESKTOP, (WINDOW_CLIENT (window)))); + if (rc) + capture_window = window; + return (rc); + } + else + return (capture_window == window); + } + else + { + capture_window = 0; + return (WinSetCapture (HWND_DESKTOP, NULLHANDLE)); + } +} + +/* Text Cursors */ + +static void +window_move_cursor (window_t * window, short x, short y) +{ + (WINDOW_CURSOR_X (window)) = x; + (WINDOW_CURSOR_Y (window)) = y; + if (WINDOW_CURSOR_CREATEDP (window)) + win_create_cursor ((WINDOW_CLIENT (window)), x, y, 0, 0, CURSOR_SETPOS, 0); +} + +static void +window_shape_cursor (window_t * window, unsigned short width, + unsigned short height, unsigned short style) +{ + (WINDOW_CURSOR_WIDTH (window)) = width; + (WINDOW_CURSOR_HEIGHT (window)) = height; + (WINDOW_CURSOR_STYLE (window)) = style; + if (WINDOW_CURSOR_CREATEDP (window)) + recreate_cursor (window); +} + +static void +window_show_cursor (window_t * window, int showp) +{ + if ((WINDOW_CURSOR_CREATEDP (window)) + && ((showp != 0) != (WINDOW_CURSOR_ENABLEDP (window)))) + win_show_cursor ((WINDOW_CLIENT (window)), showp); + (WINDOW_CURSOR_ENABLEDP (window)) = (showp != 0); +} + +/* Helper Procedures */ + +static void +win_create_cursor (HWND client, LONG x, LONG y, LONG cx, LONG cy, ULONG fs, + PRECTL clip_rectl) +{ + if (!WinCreateCursor (client, x, y, cx, cy, fs, clip_rectl)) + window_warning (WinCreateCursor); +} + +static void +win_destroy_cursor (HWND client) +{ + if (!WinDestroyCursor (client)) + window_warning (WinDestroyCursor); +} + +static void +win_show_cursor (HWND client, BOOL showp) +{ + if (!WinShowCursor (client, showp)) + window_warning (WinShowCursor); +} + +static void +recreate_cursor (window_t * window) +{ + win_create_cursor ((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_CURSOR_CREATEDP (window)) = 1; + if (WINDOW_CURSOR_ENABLEDP (window)) + win_show_cursor ((WINDOW_CLIENT (window)), TRUE); +} + +static void +activate_cursor (window_t * window) +{ + if ((WINDOW_CURSOR_CREATEDP (window)) && (WINDOW_CURSOR_ENABLEDP (window))) + win_show_cursor ((WINDOW_CLIENT (window)), TRUE); +} + +static void +deactivate_cursor (window_t * window) +{ + if ((WINDOW_CURSOR_CREATEDP (window)) && (WINDOW_CURSOR_ENABLEDP (window))) + win_show_cursor ((WINDOW_CLIENT (window)), FALSE); +} + +static void +maybe_activate_cursor (ps_t * ps) +{ + if ((PS_VISUAL_TYPE (ps)) == pst_window) + activate_cursor (PS_VISUAL (ps)); +} + +static void +maybe_deactivate_cursor (ps_t * ps) +{ + if ((PS_VISUAL_TYPE (ps)) == pst_window) + deactivate_cursor (PS_VISUAL (ps)); +} +/* Presentation Spaces */ + static ps_t * create_memory_ps (qid_t qid) { @@ -1236,61 +1600,6 @@ ps_set_bitmap (ps_t * ps, bitmap_t * bitmap) return (previous_bitmap); } -static HDC -get_ps_device (HPS hps) -{ - HDC hdc = (GpiQueryDevice (hps)); - if (hdc == HDC_ERROR) - window_error (GpiQueryDevice); - return (hdc); -} - -static LONG -get_device_capability (HDC hdc, LONG index) -{ - LONG result; - if (!DevQueryCaps (hdc, index, 1, (& result))) - window_error (DevQueryCaps); - return (result); -} - -static ps_t * -create_ps (pst_t type, HDC hdc, qid_t qid) -{ - ps_t * ps = (OS_malloc (sizeof (ps_t))); - SIZEL sizel; - HPS hps; - (sizel . cx) = 0; - (sizel . cy) = 0; - hps = (GpiCreatePS (pm_hab, hdc, (& sizel), - (PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC))); - if (hps == 0) - window_error (GpiCreatePS); - /* Put color table in RGB mode so we can specify colors - directly in RGB values rather than as indices. */ - if (!GpiCreateLogColorTable (hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, 0)) - window_warning (GpiCreateLogColorTable); - (PS_HANDLE (ps)) = hps; - (PS_ID (ps)) = (allocate_id ((& psid_table), ps)); - (PS_QID (ps)) = qid; - (PS_VISUAL_TYPE (ps)) = type; - (PS_VISUAL (ps)) = 0; - (PS_CHAR_INCREMENTS (ps)) = 0; - ps_set_colors (ps, RGB_BLACK, RGB_WHITE); - return (ps); -} - -static void -destroy_ps (ps_t * ps) -{ - if ((PS_CHAR_INCREMENTS (ps)) != 0) - OS_free (PS_CHAR_INCREMENTS (ps)); - if (!GpiDestroyPS (PS_HANDLE (ps))) - window_warning (GpiDestroyPS); - deallocate_id ((& psid_table), (PS_ID (ps))); - OS_free (ps); -} - static void ps_bitblt (ps_t * target, ps_t * source, LONG npoints, PPOINTL points, LONG rop, ULONG options) @@ -1355,20 +1664,6 @@ ps_text_width (ps_t * ps, const char * data, unsigned short size) return (size * ((PS_CHAR_INCREMENTS (ps)) [0])); } -static void -maybe_activate_cursor (ps_t * ps) -{ - if ((PS_VISUAL_TYPE (ps)) == pst_window) - activate_cursor (PS_VISUAL (ps)); -} - -static void -maybe_deactivate_cursor (ps_t * ps) -{ - if ((PS_VISUAL_TYPE (ps)) == pst_window) - deactivate_cursor (PS_VISUAL (ps)); -} - static void ps_clear (ps_t * ps, short xl, short xh, short yl, short yh) { @@ -1383,6 +1678,18 @@ ps_clear (ps_t * ps, short xl, short xh, short yl, short yh) maybe_activate_cursor (ps); } +static COLOR +ps_get_foreground_color (ps_t * ps) +{ + return (PS_FOREGROUND_COLOR (ps)); +} + +static COLOR +ps_get_background_color (ps_t * ps) +{ + return (PS_BACKGROUND_COLOR (ps)); +} + static void ps_set_colors (ps_t * ps, COLOR foreground, COLOR background) { @@ -1519,15 +1826,74 @@ ps_get_bitmap_bits (ps_t * ps, unsigned long start, unsigned long length, return (r); } -static unsigned long -ps_set_bitmap_bits (ps_t * ps, unsigned long start, unsigned long length, - PBYTE data, PBITMAPINFO2 info) +static unsigned long +ps_set_bitmap_bits (ps_t * ps, unsigned long start, unsigned long length, + PBYTE data, PBITMAPINFO2 info) +{ + LONG r = (GpiSetBitmapBits ((PS_HANDLE (ps)), start, length, data, info)); + if (r < 0) + window_error (GpiSetBitmapBits); + return (r); +} + +/* Helper Procedures */ + +static HDC +get_ps_device (HPS hps) +{ + HDC hdc = (GpiQueryDevice (hps)); + if (hdc == HDC_ERROR) + window_error (GpiQueryDevice); + return (hdc); +} + +static LONG +get_device_capability (HDC hdc, LONG index) +{ + LONG result; + if (!DevQueryCaps (hdc, index, 1, (& result))) + window_error (DevQueryCaps); + return (result); +} + +static ps_t * +create_ps (pst_t type, HDC hdc, qid_t qid) +{ + ps_t * ps = (OS_malloc (sizeof (ps_t))); + SIZEL sizel; + HPS hps; + (sizel . cx) = 0; + (sizel . cy) = 0; + hps = (GpiCreatePS (pm_hab, hdc, (& sizel), + (PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC))); + if (hps == 0) + window_error (GpiCreatePS); + /* Put color table in RGB mode so we can specify colors + directly in RGB values rather than as indices. */ + if (!GpiCreateLogColorTable (hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, 0)) + window_warning (GpiCreateLogColorTable); + (PS_HANDLE (ps)) = hps; + (PS_ID (ps)) = (allocate_id ((& psid_table), ps)); + (PS_QID (ps)) = qid; + (PS_VISUAL_TYPE (ps)) = type; + (PS_VISUAL (ps)) = 0; + (PS_CHAR_INCREMENTS (ps)) = 0; + ps_set_colors (ps, RGB_BLACK, RGB_WHITE); + return (ps); +} + +static void +destroy_ps (ps_t * ps) { - LONG r = (GpiSetBitmapBits ((PS_HANDLE (ps)), start, length, data, info)); - if (r < 0) - window_error (GpiSetBitmapBits); - return (r); + if ((PS_CHAR_INCREMENTS (ps)) != 0) + OS_free (PS_CHAR_INCREMENTS (ps)); + if (!GpiDestroyPS (PS_HANDLE (ps))) + window_warning (GpiDestroyPS); + deallocate_id ((& psid_table), (PS_ID (ps))); + OS_free (ps); } + +/* Clipboard */ static void clipboard_write_text (qid_t qid, const char * text) @@ -1573,31 +1939,29 @@ clipboard_read_text (qid_t qid) return (result); } +/* Menus */ + static HWND menu_create (qid_t qid, HWND owner, USHORT style, USHORT id) { - HWND menu - = (WinCreateWindow (owner, /* parent window */ - WC_MENU, /* class name */ - "", /* window text */ - style, /* window style */ - 0, 0, 0, 0, /* size and position */ - owner, /* owner window */ - HWND_TOP, /* sibling window */ - id, /* ID */ - 0, /* control data */ - 0 /* presentation parameters */ - )); - if (menu == NULLHANDLE) - window_error (WinCreateWindow); - return (menu); -} - -static void + return + (WinCreateWindow (owner, /* parent window */ + WC_MENU, /* class name */ + "", /* window text */ + style, /* window style */ + 0, 0, 0, 0, /* size and position */ + owner, /* owner window */ + HWND_TOP, /* sibling window */ + id, /* ID */ + 0, /* control data */ + 0 /* presentation parameters */ + )); +} + +static BOOL menu_destroy (qid_t qid, HWND menu) { - if (!WinDestroyWindow (menu)) - window_error (WinDestroyWindow); + return (WinDestroyWindow (menu)); } static USHORT @@ -1671,21 +2035,19 @@ menu_set_item_attributes (qid_t qid, HWND menu, USHORT id, USHORT submenup, } static HWND -window_handle_from_id (qid_t qid, HWND window, ULONG id) +window_load_menu (window_t * window, HMODULE module, ULONG id) { - return (WinWindowFromID (window, id)); + return (WinLoadMenu ((WINDOW_FRAME (window)), module, id)); } -static HWND -window_load_menu (window_t * window, HMODULE module, ULONG id) +static BOOL +window_popup_menu (qid_t qid, HWND parent, HWND owner, HWND menu, + LONG x, LONG y, LONG id, ULONG options) { - return (WinLoadMenu ((WINDOW_FRAME (window)), module, id)); + return (WinPopupMenu (parent, owner, menu, x, y, id, options)); } -static int parse_font_spec (const char *, PSZ *, LONG *, USHORT *); -static const char * unparse_font_spec (PSZ, LONG, USHORT); -static int ps_set_font_1 (ps_t * ps, PSZ, LONG, USHORT, LONG); -static PLONG ps_make_char_increments (LONG); +/* Fonts */ static font_metrics_t * ps_get_font_metrics (ps_t * ps) @@ -1700,245 +2062,10 @@ ps_get_font_metrics (ps_t * ps) return (metrics); } -static font_metrics_t * -ps_set_font_internal (ps_t * ps, unsigned short id, const char * spec) -{ - return ((ps_set_font (ps, id, spec)) ? (ps_get_font_metrics (ps)) : 0); -} - -static int -ps_set_font (ps_t * ps, unsigned short id, const char * spec) -{ - PSZ name = 0; - LONG size; - USHORT selection; - if (!parse_font_spec (spec, (& name), (& size), (& selection))) - return (0); - if (!ps_set_font_1 (ps, name, size, selection, id)) - { - OS_free (name); - return (0); - } - { - FONTMETRICS fm; - if (!GpiQueryFontMetrics ((PS_HANDLE (ps)), (sizeof (fm)), (& fm))) - window_error (GpiQueryFontMetrics); - if ((PS_CHAR_INCREMENTS (ps)) != 0) - OS_free (PS_CHAR_INCREMENTS (ps)); - (PS_CHAR_INCREMENTS (ps)) - = ((((fm . fsDefn) & FM_DEFN_OUTLINE) != 0) - ? (ps_make_char_increments (fm . lMaxCharInc)) - : 0); - } - return (1); -} - -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) - { - 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 if ((strncmp (scan, ".outline", 8)) == 0) - { - selection |= FATTR_SEL_OUTLINE; - scan += 8; - } - else if ((strncmp (scan, ".strikeout", 10)) == 0) - { - selection |= FATTR_SEL_STRIKEOUT; - scan += 10; - } - else if ((strncmp (scan, ".underscore", 11)) == 0) - { - selection |= FATTR_SEL_UNDERSCORE; - scan += 11; - } - else - break; - } - if ((*scan++) != '.') - return (0); - (*pname) = (OS_malloc ((strlen (scan)) + 1)); - strcpy ((*pname), scan); - (*psize) = (size * 10); - (*pselection) = selection; - return (1); -} - -static const char * -unparse_font_spec (PSZ name, LONG size, USHORT selection) -{ - char size_buffer [16]; - char selection_buffer [16]; - char * result; - - sprintf (size_buffer, "%d", (size / 10)); - strcpy (selection_buffer, ""); - if ((selection & FATTR_SEL_BOLD) != 0) - strcat (selection_buffer, ".bold"); - if ((selection & FATTR_SEL_ITALIC) != 0) - strcat (selection_buffer, ".italic"); - if ((selection & FATTR_SEL_OUTLINE) != 0) - strcat (selection_buffer, ".outline"); - if ((selection & FATTR_SEL_STRIKEOUT) != 0) - strcat (selection_buffer, ".strikeout"); - if ((selection & FATTR_SEL_UNDERSCORE) != 0) - strcat (selection_buffer, ".underscore"); - result - = (OS_malloc ((strlen (size_buffer)) - + (strlen (name)) - + (strlen (selection_buffer)) - + 2)); - strcpy (result, size_buffer); - strcat (result, selection_buffer); - strcat (result, "."); - strcat (result, name); - return (result); -} - -static int create_font (HPS, LONG, PFONTMETRICS, USHORT); -static void copy_fontmetrics_to_fattrs (FONTMETRICS *, FATTRS *); -static void ps_set_font_size (ps_t *, LONG); - -static int -ps_set_font_1 (ps_t * ps, PSZ name, LONG size, USHORT selection, LONG id) -{ - HPS hps = (PS_HANDLE (ps)); - 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); - { - int result = 0; - /* Choose an image font if one is available. */ - 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); - result = 1; - goto done; - } - /* Otherwise, look for an outline font. */ - for (index = 0; (index < nfonts); index += 1) - if (((((pfm [index]) . fsType) & FM_TYPE_FIXED) != 0) - && ((((pfm [index]) . fsDefn) & FM_DEFN_OUTLINE) != 0) - && (create_font (hps, id, (& (pfm [index])), selection))) - { - GpiSetCharSet (hps, id); - ps_set_font_size (ps, size); - result = 1; - goto done; - } - done: - OS_free (pfm); - return (result); - } -} - -static int -create_font (HPS hps, LONG font_id, PFONTMETRICS pfm, USHORT selection) -{ - FATTRS fa; - copy_fontmetrics_to_fattrs (pfm, (&fa)); - (fa . fsSelection) = selection; - return ((GpiCreateLogFont (hps, 0, font_id, (&fa))) == FONT_MATCH); -} - -static void -copy_fontmetrics_to_fattrs (FONTMETRICS * pfm, FATTRS * pfa) -{ - (pfa -> usRecordLength) = (sizeof (*pfa)); - (pfa -> fsSelection) = (pfm -> fsSelection); - (pfa -> lMatch) = (pfm -> lMatch); - strcpy ((pfa -> szFacename), (pfm -> szFacename)); - (pfa -> idRegistry) = (pfm -> idRegistry); - (pfa -> usCodePage) = (pfm -> usCodePage); - (pfa -> lMaxBaselineExt) = 0; - (pfa -> lAveCharWidth) = 0; - (pfa -> fsType) = 0; - (pfa -> fsFontUse) - = ((((pfm -> fsDefn) & FM_DEFN_OUTLINE) != 0) - ? (FATTR_FONTUSE_OUTLINE | FATTR_FONTUSE_TRANSFORMABLE) - : 0); -} - -static void -ps_set_font_size (ps_t * ps, LONG size) -{ - POINTL ptl [2]; - - ((ptl[0]) . x) = 0; - ((ptl[0]) . y) = 0; - { - LONG xres; - ps_query_caps (ps, CAPS_HORIZONTAL_FONT_RES, 1, (&xres)); - ((ptl[1]) . x) = ((((xres * size) << 4) + 360) / 720); - } - { - LONG yres; - ps_query_caps (ps, CAPS_VERTICAL_FONT_RES, 1, (&yres)); - ((ptl[1]) . y) = ((((yres * size) << 4) + 360) / 720); - } - if (!GpiConvert ((PS_HANDLE (ps)), CVTC_DEVICE, CVTC_WORLD, 2, ptl)) - window_error (GpiConvert); - { - SIZEF s; - (s . cx) = ((((ptl[1]) . x) - ((ptl[0]) . x)) << 12); - (s . cy) = ((((ptl[1]) . y) - ((ptl[0]) . y)) << 12); - if (!GpiSetCharBox ((PS_HANDLE (ps)), (&s))) - window_error (GpiSetCharBox); - } -} - -static PLONG -ps_make_char_increments (LONG increment) -{ - PLONG increments = (OS_malloc ((sizeof (LONG)) * 512)); - unsigned int index; - for (index = 0; (index < 512); index += 1) - (increments[index]) = increment; - return (increments); +static font_metrics_t * +ps_set_font_internal (ps_t * ps, unsigned short id, const char * spec) +{ + return ((ps_set_font (ps, id, spec)) ? (ps_get_font_metrics (ps)) : 0); } static const char * @@ -1974,458 +2101,287 @@ window_font_dialog (window_t * window, const char * title) (info . flStyle) = (fm . fsSelection); /* copy_fontmetrics_to_fattrs ((&fm), (& (info . fAttrs))); */ } - } - result = (WinFontDlg (HWND_DESKTOP, (WINDOW_CLIENT (window)), (&info))); - if ((result == NULLHANDLE) || ((info . lReturn) != DID_OK)) - return (0); - { - PSZ face_name; - const char * font_spec; - { - FACENAMEDESC desc; - ULONG face_name_length; - (desc . usSize) = (sizeof (desc)); - (desc . usWeightClass) = (info . usWeight); - (desc . usWidthClass) = (info . usWidth); - (desc . flOptions) = (info . flType); - face_name_length - = (GpiQueryFaceString (hps, (info . pszFamilyname), (&desc), 0, 0)); - if (face_name_length == GPI_ERROR) - return (0); - face_name = (OS_malloc (face_name_length)); - face_name_length - = (GpiQueryFaceString (hps, (info . pszFamilyname), (&desc), - face_name_length, face_name)); - if (face_name_length == GPI_ERROR) - { - OS_free (face_name); - return (0); - } - } - font_spec = (unparse_font_spec (face_name, - ((FIXEDINT (info . fxPointSize)) * 10), - (info . flStyle))); - OS_free (face_name); - return (font_spec); - } -} - -static MRESULT EXPENTRY -frame_window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) -{ - window_t * window = (hwnd_to_window (WinWindowFromID (hwnd, FID_CLIENT))); - switch (msg) - { - case WM_QUERYTRACKINFO: - /* Set the tracking grid for the resize operation. */ - { - MRESULT mr - = ((* original_frame_window_procedure) (hwnd, msg, mp1, mp2)); - if (mr == MRTRUE) - { - PTRACKINFO pti = (PVOIDFROMMP (mp2)); - if ((((pti -> fs) & TF_MOVE) != TF_MOVE) - && ((((pti -> fs) & TF_MOVE) != 0) - || (((pti -> fs) & TF_SETPOINTERPOS) != 0))) - { - (pti -> fs) |= TF_GRID; - (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); - } - case WM_MINMAXFRAME: - /* If minimizing, mark the window to indicate this. The client - will shortly receive a WM_SIZE which indicates that the - minimization has completed. */ - { - PSWP pswp = (PVOIDFROMMP (mp1)); - if ((!WINDOW_MINIMIZEDP (window)) - && (((pswp -> fl) & SWP_MINIMIZE) != 0)) - { - (WINDOW_MINIMIZINGP (window)) = 1; - (WINDOW_MINIMIZEDP (window)) = 1; - } - else if ((WINDOW_MINIMIZEDP (window)) - && (((pswp -> fl) & (SWP_RESTORE | SWP_MAXIMIZE)) != 0)) - (WINDOW_MINIMIZEDP (window)) = 0; - } - break; - } - return ((* original_frame_window_procedure) (hwnd, msg, mp1, mp2)); -} - -static int process_keychar - (window_t *, unsigned short, unsigned char, unsigned char, unsigned short, - unsigned short); -static int process_button (HWND, MPARAM, MPARAM, unsigned char, unsigned char); - -static MRESULT EXPENTRY -window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) -{ - switch (msg) - { - case WM_CREATE: - { - window_t * window = (PVOIDFROMMP (mp1)); - if (!WinSetWindowPtr (hwnd, QWP_WINDOW, window)) - window_error (WinSetWindowPtr); - (WINDOW_CLIENT (window)) = hwnd; - (WINDOW_CLIENT_PS (window)) - = (create_ps (pst_window, - (WinOpenWindowDC (hwnd)), - (WINDOW_QID (window)))); - (PS_VISUAL (WINDOW_CLIENT_PS (window))) = window; - return (MRFALSE); - } - case WM_PAINT: - { - window_t * window = (hwnd_to_window (hwnd)); - if (((WinQueryWindowULong ((WINDOW_FRAME (window)), QWL_STYLE)) - & WS_MINIMIZED) - != 0) - break; - { - HPS hps = (PS_HANDLE (WINDOW_CLIENT_PS (window))); - RECTL rectl; - if ((WinBeginPaint ((WINDOW_CLIENT (window)), hps, (& rectl))) - == NULLHANDLE) - window_error (WinBeginPaint); - if (!WinEndPaint (hps)) - window_error (WinEndPaint); - SEND_EVENT (window, - (make_paint_event ((WINDOW_ID (window)), - (rectl . xLeft), - (rectl . xRight), - (rectl . yBottom), - (rectl . yTop)))); - } - return (MRVOID); - } - case WM_SETFOCUS: - { - window_t * window = (hwnd_to_window (hwnd)); - if (SHORT1FROMMP (mp2)) - recreate_cursor (window); - else - { - win_destroy_cursor (WINDOW_CLIENT (window)); - (WINDOW_CURSOR_CREATEDP (window)) = 0; - } - SEND_EVENT (window, - (make_focus_event ((WINDOW_ID (window)), - (SHORT1FROMMP (mp2))))); - return (MRVOID); - } - case WM_CHAR: - return - ((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: - { - window_t * window = (hwnd_to_window (hwnd)); - SEND_EVENT (window, (make_close_event (WINDOW_ID (window)))); - return (MRVOID); - } - case WM_DESTROY: - { - window_t * window = (hwnd_to_window (hwnd)); - destroy_ps (WINDOW_CLIENT_PS (window)); - (WINDOW_CLIENT_PS (window)) = 0; - return (MRVOID); - } - case WM_SIZE: - { - window_t * window = (hwnd_to_window (hwnd)); - /* If this message is part of a minimization, ignore it. */ - if (WINDOW_MINIMIZINGP (window)) - { - (WINDOW_MINIMIZINGP (window)) = 0; - (WINDOW_MINIMIZEDP (window)) = 1; - break; - } - if (WINDOW_CURSOR_CREATEDP (window)) - { - win_destroy_cursor (WINDOW_CLIENT (window)); - (WINDOW_CURSOR_CREATEDP (window)) = 0; - (WINDOW_CURSOR_X (window)) = 0; - (WINDOW_CURSOR_Y (window)) = 0; - recreate_cursor (window); - } - SEND_EVENT (window, - (make_resize_event ((WINDOW_ID (window)), - (SHORT1FROMMP (mp2)), - (SHORT2FROMMP (mp2))))); - return (MRVOID); - } - case WM_SHOW: - { - window_t * window = (hwnd_to_window (hwnd)); - SEND_EVENT (window, - (make_visibility_event ((WINDOW_ID (window)), - (SHORT1FROMMP (mp1))))); - return (MRVOID); - } - case WM_COMMAND: - { - window_t * window = (hwnd_to_window (hwnd)); - SEND_EVENT (window, - (make_command_event ((WINDOW_ID (window)), - ((COMMANDMSG (&msg)) -> cmd), - ((COMMANDMSG (&msg)) -> source), - ((COMMANDMSG (&msg)) -> fMouse)))); - return (MRVOID); - } - case WM_HELP: - { - window_t * window = (hwnd_to_window (hwnd)); - SEND_EVENT (window, - (make_help_event ((WINDOW_ID (window)), - ((COMMANDMSG (&msg)) -> cmd), - ((COMMANDMSG (&msg)) -> source), - ((COMMANDMSG (&msg)) -> fMouse)))); - 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: - 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: - 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: - if (process_button (hwnd, mp1, mp2, 2, BUTTON_EVENT_DBLCLK)) - return (MRTRUE); - break; - default: - break; + } + result = (WinFontDlg (HWND_DESKTOP, (WINDOW_CLIENT (window)), (&info))); + if ((result == NULLHANDLE) || ((info . lReturn) != DID_OK)) + return (0); + { + PSZ face_name; + const char * font_spec; + { + FACENAMEDESC desc; + ULONG face_name_length; + (desc . usSize) = (sizeof (desc)); + (desc . usWeightClass) = (info . usWeight); + (desc . usWidthClass) = (info . usWidth); + (desc . flOptions) = (info . flType); + face_name_length + = (GpiQueryFaceString (hps, (info . pszFamilyname), (&desc), 0, 0)); + if (face_name_length == GPI_ERROR) + return (0); + face_name = (OS_malloc (face_name_length)); + face_name_length + = (GpiQueryFaceString (hps, (info . pszFamilyname), (&desc), + face_name_length, face_name)); + if (face_name_length == GPI_ERROR) + { + OS_free (face_name); + return (0); + } } - return (WinDefWindowProc (hwnd, msg, mp1, mp2)); + font_spec = (unparse_font_spec (face_name, + ((FIXEDINT (info . fxPointSize)) * 10), + (info . flStyle))); + OS_free (face_name); + return (font_spec); + } } -static window_t * -hwnd_to_window (HWND hwnd) +/* Helper Procedures */ + +static int +ps_set_font (ps_t * ps, unsigned short id, const char * spec) { - window_t * window = (WinQueryWindowPtr (hwnd, QWP_WINDOW)); - if (window == 0) - window_error (WinQueryWindowPtr); - return (window); + PSZ name = 0; + LONG size; + USHORT selection; + if (!parse_font_spec (spec, (& name), (& size), (& selection))) + return (0); + if (!ps_set_font_1 (ps, name, size, selection, id)) + { + OS_free (name); + return (0); + } + { + FONTMETRICS fm; + if (!GpiQueryFontMetrics ((PS_HANDLE (ps)), (sizeof (fm)), (& fm))) + window_error (GpiQueryFontMetrics); + if ((PS_CHAR_INCREMENTS (ps)) != 0) + OS_free (PS_CHAR_INCREMENTS (ps)); + (PS_CHAR_INCREMENTS (ps)) + = ((((fm . fsDefn) & FM_DEFN_OUTLINE) != 0) + ? (ps_make_char_increments (fm . lMaxCharInc)) + : 0); + } + return (1); } - + static int -process_keychar (window_t * window, unsigned short flags, - unsigned char repeat, unsigned char scan_code, - unsigned short char_code, unsigned short virtual_key) +ps_set_font_1 (ps_t * ps, PSZ name, LONG size, USHORT selection, LONG id) { - unsigned short code; - /* Ignore compound keys for now. */ - if ((flags & (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP | KC_KEYUP)) != 0) - 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 + HPS hps = (PS_HANDLE (ps)); + 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); - SEND_EVENT - (window, - (make_key_event ((WINDOW_ID (window)), code, flags, repeat))); + pfm = (OS_malloc (nfonts * (sizeof (FONTMETRICS)))); + if ((GpiQueryFonts (hps, + (QF_PUBLIC | QF_PRIVATE), + name, + (& nfonts), + (sizeof (FONTMETRICS)), + pfm)) + == GPI_ALTERROR) + window_error (GpiQueryFonts); + { + int result = 0; + /* Choose an image font if one is available. */ + 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); + result = 1; + goto done; + } + /* Otherwise, look for an outline font. */ + for (index = 0; (index < nfonts); index += 1) + if (((((pfm [index]) . fsType) & FM_TYPE_FIXED) != 0) + && ((((pfm [index]) . fsDefn) & FM_DEFN_OUTLINE) != 0) + && (create_font (hps, id, (& (pfm [index])), selection))) + { + GpiSetCharSet (hps, id); + ps_set_font_size (ps, size); + result = 1; + goto done; + } + done: + OS_free (pfm); + return (result); + } } static int -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_ID (window)), - number, - type, - (SHORT1FROMMP (mp1)), - (SHORT2FROMMP (mp1)), - ((SHORT2FROMMP (mp2)) - & (KC_SHIFT | KC_CTRL | KC_ALT))))); - return (1); -} - -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); +create_font (HPS hps, LONG font_id, PFONTMETRICS pfm, USHORT selection) +{ + FATTRS fa; + copy_fontmetrics_to_fattrs (pfm, (&fa)); + (fa . fsSelection) = selection; + return ((GpiCreateLogFont (hps, 0, font_id, (&fa))) == FONT_MATCH); } -static msg_t * -make_close_event (wid_t wid) +static void +copy_fontmetrics_to_fattrs (FONTMETRICS * pfm, FATTRS * pfa) { - msg_t * message = (OS2_create_message (mt_close_event)); - (SM_CLOSE_EVENT_WID (message)) = wid; - return (message); + (pfa -> usRecordLength) = (sizeof (*pfa)); + (pfa -> fsSelection) = (pfm -> fsSelection); + (pfa -> lMatch) = (pfm -> lMatch); + strcpy ((pfa -> szFacename), (pfm -> szFacename)); + (pfa -> idRegistry) = (pfm -> idRegistry); + (pfa -> usCodePage) = (pfm -> usCodePage); + (pfa -> lMaxBaselineExt) = 0; + (pfa -> lAveCharWidth) = 0; + (pfa -> fsType) = 0; + (pfa -> fsFontUse) + = ((((pfm -> fsDefn) & FM_DEFN_OUTLINE) != 0) + ? (FATTR_FONTUSE_OUTLINE | FATTR_FONTUSE_TRANSFORMABLE) + : 0); } -static msg_t * -make_focus_event (wid_t wid, int gainedp) +static void +ps_set_font_size (ps_t * ps, LONG size) { - msg_t * message = (OS2_create_message (mt_focus_event)); - (SM_FOCUS_EVENT_WID (message)) = wid; - (SM_FOCUS_EVENT_GAINEDP (message)) = gainedp; - return (message); -} + POINTL ptl [2]; -static msg_t * -make_key_event (wid_t wid, unsigned short code, - unsigned short flags, unsigned short repeat) -{ - 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); + ((ptl[0]) . x) = 0; + ((ptl[0]) . y) = 0; + { + LONG xres; + ps_query_caps (ps, CAPS_HORIZONTAL_FONT_RES, 1, (&xres)); + ((ptl[1]) . x) = ((((xres * size) << 4) + 360) / 720); + } + { + LONG yres; + ps_query_caps (ps, CAPS_VERTICAL_FONT_RES, 1, (&yres)); + ((ptl[1]) . y) = ((((yres * size) << 4) + 360) / 720); + } + if (!GpiConvert ((PS_HANDLE (ps)), CVTC_DEVICE, CVTC_WORLD, 2, ptl)) + window_error (GpiConvert); + { + SIZEF s; + (s . cx) = ((((ptl[1]) . x) - ((ptl[0]) . x)) << 12); + (s . cy) = ((((ptl[1]) . y) - ((ptl[0]) . y)) << 12); + if (!GpiSetCharBox ((PS_HANDLE (ps)), (&s))) + window_error (GpiSetCharBox); + } } -static msg_t * -make_paint_event (wid_t wid, - unsigned short xl, unsigned short xh, - unsigned short yl, unsigned short yh) +static PLONG +ps_make_char_increments (LONG increment) { - 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); + PLONG increments = (OS_malloc ((sizeof (LONG)) * 512)); + unsigned int index; + for (index = 0; (index < 512); index += 1) + (increments[index]) = increment; + return (increments); } -static msg_t * -make_resize_event (wid_t wid, unsigned short width, unsigned short height) +static struct font_selection { - msg_t * message = (OS2_create_message (mt_resize_event)); - (SM_RESIZE_EVENT_WID (message)) = wid; - (SM_RESIZE_EVENT_WIDTH (message)) = width; - (SM_RESIZE_EVENT_HEIGHT (message)) = height; - return (message); + const char * name; + unsigned int selector; +} font_selections [] = +{ + { ".bold", FATTR_SEL_BOLD }, + { ".italic", FATTR_SEL_ITALIC }, + { ".outline", FATTR_SEL_OUTLINE }, + { ".strikeout", FATTR_SEL_STRIKEOUT }, + { ".underscore", FATTR_SEL_UNDERSCORE }, + { 0, 0 } +}; + +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) + { + struct font_selection * selections = font_selections; + unsigned int name_length; + while (1) + { + if ((selections -> name) == 0) + goto no_more_selections; + name_length = (strlen (selections -> name)); + if ((strncmp (scan, (selections -> name), name_length)) == 0) + { + selection |= (selections -> selector); + scan += name_length; + break; + } + selections += 1; + } + } + no_more_selections: + if ((*scan++) != '.') + return (0); + (*pname) = (OS_malloc ((strlen (scan)) + 1)); + strcpy ((*pname), scan); + (*psize) = (size * 10); + (*pselection) = selection; + return (1); } -static msg_t * -make_visibility_event (wid_t wid, int shownp) +static const char * +unparse_font_spec (PSZ name, LONG size, USHORT selection) { - msg_t * message = (OS2_create_message (mt_visibility_event)); - (SM_VISIBILITY_EVENT_WID (message)) = wid; - (SM_VISIBILITY_EVENT_SHOWNP (message)) = shownp; - return (message); + char size_buffer [16]; + char selection_buffer [16]; + struct font_selection * selections = font_selections; + char * result; + + sprintf (size_buffer, "%d", (size / 10)); + strcpy (selection_buffer, ""); + while (1) + { + if ((selections -> name) == 0) + break; + if ((selection & (selections -> selector)) != 0) + strcat (selection_buffer, (selections -> name)); + selections += 1; + } + result + = (OS_malloc ((strlen (size_buffer)) + + (strlen (name)) + + (strlen (selection_buffer)) + + 2)); + strcpy (result, size_buffer); + strcat (result, selection_buffer); + strcat (result, "."); + strcat (result, name); + return (result); } + +/* Pointers */ -static msg_t * -make_command_event (wid_t wid, USHORT command, USHORT source, USHORT mousep) +static HPOINTER +query_system_pointer (qid_t qid, HWND desktop, LONG id, BOOL copyp) { - msg_t * message = (OS2_create_message (mt_command_event)); - (SM_COMMAND_EVENT_WID (message)) = wid; - (SM_COMMAND_EVENT_COMMAND (message)) = command; - (SM_COMMAND_EVENT_SOURCE (message)) = source; - (SM_COMMAND_EVENT_MOUSEP (message)) = mousep; - return (message); + return (WinQuerySysPointer (desktop, id, copyp)); } -static msg_t * -make_help_event (wid_t wid, USHORT command, USHORT source, USHORT mousep) +static BOOL +set_pointer (qid_t qid, HWND desktop, HPOINTER pointer) { - msg_t * message = (OS2_create_message (mt_help_event)); - (SM_HELP_EVENT_WID (message)) = wid; - (SM_HELP_EVENT_COMMAND (message)) = command; - (SM_HELP_EVENT_SOURCE (message)) = source; - (SM_HELP_EVENT_MOUSEP (message)) = mousep; - return (message); + return (WinSetPointer (desktop, pointer)); } diff --git a/v7/src/microcode/os2pm.h b/v7/src/microcode/os2pm.h index 5550e87c3..14770848a 100644 --- a/v7/src/microcode/os2pm.h +++ b/v7/src/microcode/os2pm.h @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2pm.h,v 1.11 1995/10/30 08:03:19 cph Exp $ +$Id: os2pm.h,v 1.12 1995/11/03 01:29:32 cph Exp $ Copyright (c) 1994-95 Massachusetts Institute of Technology @@ -58,53 +58,14 @@ typedef struct { DECLARE_MSG_HEADER_FIELDS; wid_t wid; - unsigned char btype; - unsigned short x; - unsigned short y; - 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) - -#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; - 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; - 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; - wid_t wid; - unsigned short code; - unsigned short flags; - unsigned short repeat; -} sm_key_event_t; -#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) + ULONG msg; + MPARAM mp1; + MPARAM mp2; +} sm_pm_event_t; +#define SM_PM_EVENT_WID(m) (((sm_pm_event_t *) (m)) -> wid) +#define SM_PM_EVENT_MSG(m) (((sm_pm_event_t *) (m)) -> msg) +#define SM_PM_EVENT_MP1(m) (((sm_pm_event_t *) (m)) -> mp1) +#define SM_PM_EVENT_MP2(m) (((sm_pm_event_t *) (m)) -> mp2) typedef struct { @@ -120,53 +81,6 @@ typedef struct #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; - wid_t wid; - unsigned short width; - unsigned short height; -} sm_resize_event_t; -#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) - -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) - -typedef struct -{ - DECLARE_MSG_HEADER_FIELDS; - wid_t wid; - unsigned short command; - unsigned short source; - unsigned short mousep; -} sm_command_event_t; -#define SM_COMMAND_EVENT_WID(m) (((sm_command_event_t *) (m)) -> wid) -#define SM_COMMAND_EVENT_COMMAND(m) (((sm_command_event_t *) (m)) -> command) -#define SM_COMMAND_EVENT_SOURCE(m) (((sm_command_event_t *) (m)) -> source) -#define SM_COMMAND_EVENT_MOUSEP(m) (((sm_command_event_t *) (m)) -> mousep) - -typedef struct -{ - DECLARE_MSG_HEADER_FIELDS; - wid_t wid; - unsigned short command; - unsigned short source; - unsigned short mousep; -} sm_help_event_t; -#define SM_HELP_EVENT_WID(m) (((sm_help_event_t *) (m)) -> wid) -#define SM_HELP_EVENT_COMMAND(m) (((sm_help_event_t *) (m)) -> command) -#define SM_HELP_EVENT_SOURCE(m) (((sm_help_event_t *) (m)) -> source) -#define SM_HELP_EVENT_MOUSEP(m) (((sm_help_event_t *) (m)) -> mousep) typedef enum { @@ -185,23 +99,28 @@ typedef enum extern msg_t * OS2_read_pm_tqueue (tqueue_t *, int); extern void OS2_write_pm_tqueue (tqueue_t *, msg_t *); -extern int OS2_psid_validp (psid_t); -extern int OS2_wid_validp (wid_t); -extern int OS2_bid_validp (bid_t); - /* This machine-generated file contains most of the procedure prototypes. */ #include "os2pm-ed.h" +extern int OS2_psid_validp (psid_t); +extern int OS2_wid_validp (wid_t); +extern int OS2_bid_validp (bid_t); extern psid_t OS2_window_client_ps (wid_t); extern qid_t OS2_create_pm_qid (tqueue_t *); extern void OS2_window_permanent (wid_t); -extern void OS2_window_pos (wid_t, short *, short *); -extern void OS2_window_size (wid_t, unsigned short *, unsigned short *); -extern void OS2_window_frame_size (wid_t, unsigned short *, unsigned short *); +extern void OS2_window_mousetrack (wid_t, int); extern HWND OS2_window_frame_handle (wid_t); +extern HWND OS2_window_client_handle (wid_t); extern int OS2_memory_ps_p (psid_t); extern bid_t OS2_ps_get_bitmap (psid_t); + +extern void OS2_window_pos (wid_t, short *, short *); +extern void OS2_window_size (wid_t, unsigned short *, unsigned short *); +extern void OS2_window_frame_size (wid_t, unsigned short *, unsigned short *); extern bid_t OS2_ps_set_bitmap (psid_t, bid_t); extern font_metrics_t * OS2_ps_set_font (psid_t, unsigned short, const char *); +extern int OS2_translate_wm_char + (MPARAM, MPARAM, unsigned short *, unsigned short *, unsigned char *); + #endif /* SCM_OS2PM_H */ diff --git a/v7/src/microcode/os2pm.scm b/v7/src/microcode/os2pm.scm index f980191b4..969a24036 100644 --- a/v7/src/microcode/os2pm.scm +++ b/v7/src/microcode/os2pm.scm @@ -1,6 +1,6 @@ #| -*-Scheme-*- -$Id: os2pm.scm,v 1.1 1995/10/30 07:57:55 cph Exp $ +$Id: os2pm.scm,v 1.2 1995/11/03 01:29:45 cph Exp $ Copyright (c) 1995 Massachusetts Institute of Technology @@ -766,7 +766,9 @@ MIT in each case. */ (value sync) (arguments qid)) -(define-pm-procedure (window_open open_window) +;;; Windows + +(define-pm-procedure window_open (value ("wid_t" wid)) (arguments qid (qid_t event_qid) @@ -776,19 +778,10 @@ MIT in each case. */ (ulong style) ((array (const char)) title))) -(define-pm-procedure (window_close close_window) +(define-pm-procedure window_close (arguments window)) -(define-pm-procedure (window_show show_window) - (arguments window (boolean showp))) - -(define-pm-procedure (window_move_cursor move_cursor) - (arguments window (short x) (short y))) - -(define-pm-procedure (window_shape_cursor shape_cursor) - (arguments window (ushort width) (ushort height) (ushort style))) - -(define-pm-procedure (window_show_cursor enable_cursor) +(define-pm-procedure window_show (arguments window (boolean showp))) (define-pm-procedure window_scroll @@ -809,30 +802,51 @@ MIT in each case. */ (define-pm-procedure window_activate (arguments window)) -;;; window_pos +;;; (define_pm_procedure window_pos ...) -(define-pm-procedure (window_set_pos set_window_pos) +(define-pm-procedure window_set_pos (arguments window (short x) (short y))) -;;; window_size -;;; window_frame_size +;;; (define_pm_procedure window_size ...) +;;; (define_pm_procedure window_frame_size ...) -(define-pm-procedure (window_set_size set_window_size) +(define-pm-procedure window_set_size (arguments window (ushort x) (ushort y))) (define-pm-procedure window_focusp (value (boolean focusp)) (arguments window)) -(define-pm-procedure (window_set_state set_window_state) +(define-pm-procedure window_set_state (arguments window (window_state_t state))) -(define-pm-procedure (window_set_title set_window_title) +(define-pm-procedure window_set_title (arguments window ((array (const char)) title))) -(define-pm-procedure (window_update_frame update_frame_window) +(define-pm-procedure window_update_frame (arguments window (ushort flags))) +(define-pm-procedure window_handle_from_id + (value ("HWND" child)) + (arguments qid ("HWND" parent) (ulong id))) + +(define-pm-procedure window_set_capture + (value ("BOOL" successp)) + (arguments window (int capturep))) + +;;; Text Cursors + +(define-pm-procedure window_move_cursor + (arguments window (short x) (short y))) + +(define-pm-procedure window_shape_cursor + (arguments window (ushort width) (ushort height) (ushort style))) + +(define-pm-procedure window_show_cursor + (arguments window (boolean showp))) + +;;; Presentation Spaces + (define-pm-procedure create_memory_ps (value ps) (arguments qid)) @@ -847,7 +861,7 @@ MIT in each case. */ (define-pm-procedure destroy_bitmap (arguments bitmap)) -;;; ps_set_bitmap +;;; (define_pm_procedure ps_set_bitmap ...) (define-pm-procedure ps_bitblt (arguments ((id ps) target) @@ -870,18 +884,16 @@ MIT in each case. */ ((array (const char)) data size) (ushort size))) -(define-pm-procedure ps_get_font_metrics - (value ((pointer font_metrics_t) metrics)) - (arguments ps)) - (define-pm-procedure ps_clear (arguments ps (short xl) (short xh) (short yl) (short yh))) -(define-pm-procedure ps_set_font_internal - (value ((pointer font_metrics_t) metrics)) - (arguments ps - (ushort id) - ((array (const char)) name))) +(define-pm-procedure ps_get_foreground_color + (value ("COLOR" color)) + (arguments ps)) + +(define-pm-procedure ps_get_background_color + (value ("COLOR" color)) + (arguments ps)) (define-pm-procedure ps_set_colors (arguments ps ("COLOR" foreground) ("COLOR" background))) @@ -943,6 +955,8 @@ MIT in each case. */ ((pointer "BYTE") data) ((pointer "BITMAPINFO2") info))) +;;; Clipboard + (define-pm-procedure clipboard_write_text (value sync) (arguments qid ((pointer (const char)) text))) @@ -951,11 +965,14 @@ MIT in each case. */ (value ((pointer (const char)) text)) (arguments qid)) +;;; Menus + (define-pm-procedure menu_create (value ("HWND" menu)) (arguments qid ("HWND" owner) (ushort style) (ushort id))) (define-pm-procedure menu_destroy + (value ("BOOL" successp)) (arguments qid ("HWND" menu))) (define-pm-procedure menu_insert_item @@ -1008,16 +1025,45 @@ MIT in each case. */ (ushort mask) (ushort attributes))) -(define-pm-procedure window_handle_from_id - (value ("HWND" child)) - (arguments qid ("HWND" parent) (ulong id))) - (define-pm-procedure window_load_menu (value ("HWND" menu)) (arguments window ("HMODULE" module) (ulong id))) +(define-pm-procedure window_popup_menu + (value ("BOOL" successp)) + (arguments qid + ("HWND" parent) + ("HWND" owner) + ("HWND" menu) + (long x) + (long y) + (long id) + (ulong options))) + +;;; Font + +(define-pm-procedure ps_get_font_metrics + (value ((pointer font_metrics_t) metrics)) + (arguments ps)) + +(define-pm-procedure ps_set_font_internal + (value ((pointer font_metrics_t) metrics)) + (arguments ps + (ushort id) + ((array (const char)) name))) + (define-pm-procedure window_font_dialog (value ((pointer (const char)) spec)) (arguments window ((pointer (const char)) title))) +;;; Pointers + +(define-pm-procedure query_system_pointer + (value ("HPOINTER" pointer)) + (arguments qid ("HWND" desktop) (long id) ("BOOL" copyp))) + +(define-pm-procedure set_pointer + (value ("BOOL" successp)) + (arguments qid ("HWND" desktop) ("HPOINTER" pointer))) + (write-all-files) \ No newline at end of file diff --git a/v7/src/microcode/os2pmcon.c b/v7/src/microcode/os2pmcon.c index e35e01a99..469bfa519 100644 --- a/v7/src/microcode/os2pmcon.c +++ b/v7/src/microcode/os2pmcon.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2pmcon.c,v 1.16 1995/10/30 08:07:22 cph Exp $ +$Id: os2pmcon.c,v 1.17 1995/11/03 01:29:57 cph Exp $ Copyright (c) 1994-95 Massachusetts Institute of Technology @@ -45,18 +45,31 @@ static void grab_console_lock (void); static void release_console_lock (void); static unsigned short cx2x (unsigned short); static unsigned short cy2y (unsigned short, int); -static unsigned short x2cx (unsigned short, int); -static unsigned short y2cy (unsigned short, int); +static unsigned short x2cx (short, int); +static unsigned short y2cy (short, int); static void process_events (int); static void enqueue_pending_event (msg_t *); +static void initialize_marked_region (short, short); +static void update_marked_region (short, short); +static void unmark_marked_region (void); +static void compute_marked_region + (short, short, short, short, + unsigned short *, unsigned short *, unsigned short *, unsigned short *); +static void highlight_marked_region + (unsigned short, unsigned short, unsigned short, unsigned short, char); +static void paint_marked_region_segment + (unsigned short, unsigned short, unsigned short, unsigned short); +static char * extract_marked_region (int); static void console_resize (unsigned short, unsigned short); static void console_paint (unsigned short, unsigned short, unsigned short, unsigned short); +static unsigned short compute_run_length (const char *, const char *); static void console_clear (unsigned short, unsigned short, unsigned short, unsigned short); static void console_clear_all (void); static int do_paste (void); -static int translate_key_event (msg_t *); +static int translate_key_event + (MPARAM, MPARAM, unsigned short *, unsigned char *); static const char * find_nonprint (const char *, const char *); static void do_carriage_return (void); static void do_linefeed (void); @@ -71,6 +84,8 @@ static unsigned short console_pel_height; static unsigned short console_width; static unsigned short console_height; static char * console_chars; +static char * console_highlights; +static unsigned short * console_line_lengths; static font_metrics_t * console_metrics; static unsigned short point_x; static unsigned short point_y; @@ -87,11 +102,20 @@ static qid_t console_event_qid; static qid_t console_pm_qid; static wid_t console_wid; static psid_t console_psid; +static int console_tracking_mouse_p; +static HWND console_tracking_mouse_pointer; +static int console_marked_region_active_p; +static short console_mark_x; +static short console_mark_y; +static short console_point_x; +static short console_point_y; #define CHAR_WIDTH (FONT_METRICS_WIDTH (console_metrics)) #define CHAR_HEIGHT (FONT_METRICS_HEIGHT (console_metrics)) #define CHAR_DESCENDER (FONT_METRICS_DESCENDER (console_metrics)) #define CHAR_LOC(x, y) (& (console_chars [((y) * console_width) + (x)])) +#define CHAR_HL(x, y) (& (console_highlights [((y) * console_width) + (x)])) +#define LINE_LEN_LOC(y) ((char *) (& (console_line_lengths [(y)]))) #define FASTFILL(p, n, c) \ { \ @@ -110,10 +134,16 @@ OS2_initialize_pm_console (void) console_width = 0; console_height = 0; console_chars = 0; + console_highlights = 0; + console_line_lengths = 0; point_x = 0; point_y = 0; console_visiblep = 0; console_closedp = 0; + console_tracking_mouse_p = 0; + console_tracking_mouse_pointer + = (WinQuerySysPointer (HWND_DESKTOP, SPTR_TEXT, FALSE)); + console_marked_region_active_p = 0; readahead_repeat = 0; readahead_insert = 0; pending_events_head = 0; @@ -215,21 +245,21 @@ cy2y (unsigned short y, int lowerp) } static unsigned short -x2cx (unsigned short x, int lowerp) +x2cx (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); + short cx = (x / CHAR_WIDTH); if (! (lowerp || ((x % CHAR_WIDTH) == 0))) cx += 1; - return ((cx > console_width) ? console_width : cx); + return ((cx < 0) ? 0 : (cx > console_width) ? console_width : cx); } static unsigned short -y2cy (unsigned short y, int lowerp) +y2cy (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, @@ -240,7 +270,7 @@ y2cy (unsigned short y, int lowerp) short cy = (((short) (console_height - 1)) - ((short) (y / CHAR_HEIGHT))); if (lowerp || ((y % CHAR_HEIGHT) == 0)) cy += 1; - return ((cy < 0) ? 0 : cy); + return ((cy < 0) ? 0 : (cy > console_height) ? console_height : cy); } static void @@ -254,22 +284,6 @@ process_events (int blockp) break; switch (MSG_TYPE (message)) { - case mt_key_event: - case mt_close_event: - enqueue_pending_event (message); - if (blockp) - return; - break; - case mt_resize_event: - { - 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)); @@ -278,65 +292,135 @@ process_events (int blockp) unsigned short yh = (SM_PAINT_EVENT_YH (message)); OS2_destroy_message (message); grab_console_lock (); - console_paint (xl, xh, yl, yh); + OS2_ps_clear (console_psid, xl, xh, yl, yh); + console_paint ((x2cx (xl, 1)), + (x2cx (xh, 0)), + (y2cy (yh, 0)), + (y2cy (yl, 1))); 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: - 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; - case mt_command_event: - switch (SM_COMMAND_EVENT_COMMAND (message)) - { - case IDM_CUT: - case IDM_COPY: - case IDM_PASTE: - enqueue_pending_event (message); - if (blockp) - return; - break; - case IDM_FONT: + case mt_pm_event: + { + ULONG msg = (SM_PM_EVENT_MSG (message)); + MPARAM mp1 = (SM_PM_EVENT_MP1 (message)); + MPARAM mp2 = (SM_PM_EVENT_MP2 (message)); + switch (msg) { - const char * font_spec - = (OS2_window_font_dialog (console_wid, - "Console Window Font")); - if (font_spec != 0) + case WM_CHAR: + case WM_CLOSE: + postpone_event: + enqueue_pending_event (message); + message = 0; + if (blockp) + return; + break; + case WM_SIZE: + { + unsigned short new_pel_width = (SHORT1FROMMP (mp2)); + unsigned short new_pel_height = (SHORT2FROMMP (mp2)); + grab_console_lock (); + console_resize (new_pel_width, new_pel_height); + release_console_lock (); + break; + } + case WM_SHOW: + if ((!console_visiblep) && (SHORT1FROMMP (mp1))) { - (void) OS2_ps_set_font (console_psid, 1, font_spec); - OS_free ((void *) font_spec); + grab_console_lock (); + OS2_window_invalidate (console_wid, + 0, console_pel_width, + 0, console_pel_height); + release_console_lock (); + } + console_visiblep = (SHORT1FROMMP (mp1)); + break; + case WM_BUTTON1DOWN: + grab_console_lock (); + if (!OS2_window_focusp (console_wid)) + OS2_window_activate (console_wid); + else if (OS2_window_set_capture (console_wid, 1)) + { + console_tracking_mouse_p = 1; + initialize_marked_region ((SHORT1FROMMP (mp1)), + (SHORT2FROMMP (mp1))); + OS2_window_mousetrack (console_wid, 1); + OS2_set_pointer (console_pm_qid, + HWND_DESKTOP, + console_tracking_mouse_pointer); + } + else + (void) WinAlarm (HWND_DESKTOP, WA_ERROR); + release_console_lock (); + break; + case WM_BUTTON1UP: + if (console_tracking_mouse_p) + { + grab_console_lock (); + update_marked_region ((SHORT1FROMMP (mp1)), + (SHORT2FROMMP (mp1))); + (void) OS2_window_set_capture (console_wid, 0); + OS2_window_mousetrack (console_wid, 0); + console_tracking_mouse_p = 0; + release_console_lock (); + } + break; + case WM_MOUSEMOVE: + if (console_tracking_mouse_p) + { + grab_console_lock (); + update_marked_region ((SHORT1FROMMP (mp1)), + (SHORT2FROMMP (mp1))); + OS2_set_pointer (console_pm_qid, + HWND_DESKTOP, + console_tracking_mouse_pointer); + release_console_lock (); + } + break; + case WM_BUTTON2DOWN: + case WM_BUTTON3DOWN: + grab_console_lock (); + if (!OS2_window_focusp (console_wid)) + OS2_window_activate (console_wid); + release_console_lock (); + break; + case WM_COMMAND: + switch (SHORT1FROMMP (mp1)) + { + case IDM_CUT: + case IDM_COPY: + case IDM_PASTE: + goto postpone_event; + case IDM_FONT: + grab_console_lock (); + { + const char * font_spec + = (OS2_window_font_dialog (console_wid, + "Console Window Font")); + if (font_spec != 0) + { + (void) OS2_ps_set_font (console_psid, 1, font_spec); + OS_free ((void *) font_spec); + } + } + release_console_lock (); + break; + case IDM_EXIT: + termination_normal (0); + break; + case IDM_ABOUT: + (void) WinMessageBox + (HWND_DESKTOP, NULLHANDLE, + "This is MIT Scheme Release " + RELEASE + ", brought to you by the MIT Scheme Team.\n", + "The Uncommon Lisp", 0, MB_OK); + break; } } - break; - case IDM_EXIT: - termination_normal (0); - break; - case IDM_ABOUT: - { - char buffer [256]; - sprintf (buffer, - "This is MIT Scheme Release %s, built on %s. " - "Brought to you by the MIT Scheme Team.\n", - RELEASE, __DATE__); - (void) WinMessageBox (HWND_DESKTOP, NULLHANDLE, buffer, "", 0, - MB_OK); - } - break; - } + if (message != 0) + OS2_destroy_message (message); + } break; default: OS2_destroy_message (message); @@ -359,36 +443,294 @@ enqueue_pending_event (msg_t * message) } static void +initialize_marked_region (short x, short y) +{ + unmark_marked_region (); + console_mark_x = x; + console_mark_y = y; + console_point_x = x; + console_point_y = y; + console_marked_region_active_p = 1; +} + +static void +update_marked_region (short x, short y) +{ + unsigned short cx11; + unsigned short cy11; + unsigned short cx21; + unsigned short cy21; + unsigned short cx12; + unsigned short cy12; + unsigned short cx22; + unsigned short cy22; + + unsigned short i11; + unsigned short i21; + unsigned short i12; + unsigned short i22; + + compute_marked_region (console_mark_x, console_mark_y, + console_point_x, console_point_y, + (&cx11), (&cy11), (&cx21), (&cy21)); + highlight_marked_region (cx11, cy11, cx21, cy21, '\0'); + + compute_marked_region (console_mark_x, console_mark_y, x, y, + (&cx12), (&cy12), (&cx22), (&cy22)); + highlight_marked_region (cx12, cy12, cx22, cy22, '\1'); + + i11 = ((cy11 * console_width) + cx11); + i21 = ((cy21 * console_width) + cx21); + i12 = ((cy12 * console_width) + cx12); + i22 = ((cy22 * console_width) + cx22); + + if (i11 < i12) + paint_marked_region_segment (cx11, cy11, cx12, cy12); + else if (i12 < i11) + paint_marked_region_segment (cx12, cy12, cx11, cy11); + if (i21 < i22) + paint_marked_region_segment (cx21, cy21, cx22, cy22); + else if (i22 < i21) + paint_marked_region_segment (cx22, cy22, cx21, cy21); + + console_point_x = x; + console_point_y = y; + console_marked_region_active_p = 1; +} + +static void +unmark_marked_region (void) +{ + if (console_marked_region_active_p) + { + unsigned short cx1; + unsigned short cy1; + unsigned short cx2; + unsigned short cy2; + compute_marked_region (console_mark_x, console_mark_y, + console_point_x, console_point_y, + (&cx1), (&cy1), (&cx2), (&cy2)); + highlight_marked_region (cx1, cy1, cx2, cy2, '\0'); + paint_marked_region_segment (cx1, cy1, cx2, cy2); + console_marked_region_active_p = 0; + } +} + +static char * +extract_marked_region (int cutp) +{ + if (console_marked_region_active_p) + { + unsigned short cx1; + unsigned short cy1; + unsigned short cx2; + unsigned short cy2; + unsigned short length; + unsigned short y; + char * result; + char * scan; + + compute_marked_region (console_mark_x, console_mark_y, + console_point_x, console_point_y, + (&cx1), (&cy1), (&cx2), (&cy2)); + length = 1; + for (y = cy1; (y <= cy2); y += 1) + { + unsigned short xl = ((y == cy1) ? cx1 : 0); + unsigned short xh = ((y == cy2) ? cx2 : console_width); + unsigned short lx = (console_line_lengths[y]); + if (y > cy1) + length += 2; + if (xl < lx) + length += (((xh < lx) ? xh : lx) - xl); + } + result = (OS_malloc (length)); + scan = result; + for (y = cy1; (y <= cy2); y += 1) + { + unsigned short xl = ((y == cy1) ? cx1 : 0); + unsigned short xh = ((y == cy2) ? cx2 : console_width); + unsigned short lx = (console_line_lengths[y]); + if (y > cy1) + { + (*scan++) = '\r'; + (*scan++) = '\n'; + } + if (xl < lx) + { + unsigned short ll = (((xh < lx) ? xh : lx) - xl); + FASTCOPY ((CHAR_LOC (xl, y)), scan, ll); + scan += ll; + } + } + (*scan) = '\0'; + if (cutp) + { + unsigned short x1 + = ((cx1 < (console_line_lengths[cy1])) + ? cx1 + : (console_line_lengths[cy1])); + { + unsigned short d + = ((cx2 < (console_line_lengths[cy2])) + ? ((console_line_lengths[cy2]) - cx2) + : 0); + FASTCOPY ((CHAR_LOC (cx2, cy2)), (CHAR_LOC (x1, cy1)), d); + FASTFILL ((CHAR_LOC ((x1 + d), cy1)), + (console_width - (x1 + d)), + ' '); + FASTCOPY ((CHAR_HL (cx2, cy2)), (CHAR_HL (x1, cy1)), d); + FASTFILL ((CHAR_HL ((x1 + d), cy1)), + (console_width - (x1 + d)), + '\0'); + (console_line_lengths[cy1]) = (x1 + d); + } + if (cy1 < cy2) + { + unsigned short d = (console_height - (cy2 + 1)); + FASTCOPY ((CHAR_LOC (0, (cy2 + 1))), + (CHAR_LOC (0, (cy1 + 1))), + (d * console_width)); + FASTCOPY ((CHAR_HL (0, (cy2 + 1))), + (CHAR_HL (0, (cy1 + 1))), + (d * console_width)); + FASTCOPY ((LINE_LEN_LOC (cy2 + 1)), + (LINE_LEN_LOC (cy1 + 1)), + (d * (sizeof (unsigned short)))); + } + if ((cy1 < point_y) || ((cy1 == point_y) && (x1 < point_x))) + { + if ((cy2 > point_y) || ((cy2 == point_y) && (cx2 >= point_x))) + { + point_x = x1; + point_y = cy1; + } + else if (cy2 < point_y) + point_y -= (cy2 - cy1); + else + point_x -= (cx2 - ((cy1 == cy2) ? x1 : 0)); + OS2_window_move_cursor (console_wid, + (cx2x (point_x)), + (cy2y (point_y, 1))); + } + console_paint (0, console_width, cy1, console_height); + } + return (result); + } + else + return (0); +} + +static void +compute_marked_region (short x1, short y1, short x2, short y2, + unsigned short * cx1, unsigned short * cy1, + unsigned short * cx2, unsigned short * cy2) +{ + /* (cx1,cy1) is inclusive, and (cx2,cy2) is exclusive. */ + unsigned short cx1a = (x2cx (x1, 1)); + unsigned short cy1a = (y2cy (y1, 0)); + unsigned short cx2a = (x2cx (x2, 1)); + unsigned short cy2a = (y2cy (y2, 0)); + if (((cy1a * console_width) + cx1a) < ((cy2a * console_width) + cx2a)) + { + (*cx1) = cx1a; + (*cy1) = cy1a; + (*cx2) = cx2a; + (*cy2) = cy2a; + } + else + { + (*cx1) = cx2a; + (*cy1) = cy2a; + (*cx2) = cx1a; + (*cy2) = cy1a; + } +} + +static void +highlight_marked_region (unsigned short cx1, unsigned short cy1, + unsigned short cx2, unsigned short cy2, + char hl) +{ + char * start = (CHAR_HL (cx1, cy1)); + FASTFILL (start, ((CHAR_HL (cx2, cy2)) - start), hl); +} + +static void +paint_marked_region_segment (unsigned short x1, unsigned short y1, + unsigned short x2, unsigned short y2) +{ + if (y1 == y2) + console_paint (x1, x2, y1, (y1 + 1)); + else + { + console_paint (x1, console_width, y1, (y1 + 1)); + if ((y1 + 1) < y2) + console_paint (0, console_width, (y1 + 1), y2); + console_paint (0, x2, y2, (y2 + 1)); + } +} + +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)); + char * new_chars; + char * new_highlights; + unsigned short * new_line_lengths; + + if ((console_chars != 0) + && (new_width == console_width) + && (new_height == console_height)) + return; + + new_chars = (OS_malloc (new_width * new_height)); + new_highlights = (OS_malloc (new_width * new_height)); + new_line_lengths = (OS_malloc ((sizeof (unsigned short)) * new_height)); + FASTFILL (new_chars, (new_width * new_height), ' '); + FASTFILL (new_highlights, (new_width * new_height), '\0'); + FASTFILL (((char *) new_line_lengths), + ((sizeof (unsigned short)) * new_height), + 0); + if (console_chars != 0) { unsigned short xlim = ((new_width < console_width) ? new_width : console_width); - unsigned short y + unsigned short oy = (((point_y + 1) > new_height) ? ((point_y + 1) - new_height) : 0); - unsigned short ylim - = (y + ((new_height < console_height) ? new_height : console_height)); - char * from = (CHAR_LOC (0, y)); - char * to = new_chars; - while (y < ylim) + unsigned short oylim + = (oy + ((new_height < console_height) ? new_height : console_height)); + char * cfrom = (CHAR_LOC (0, oy)); + char * cto = new_chars; + char * hfrom = (CHAR_HL (0, oy)); + char * hto = new_highlights; + unsigned short ny = 0; + while (oy < oylim) { - FASTCOPY (from, to, xlim); - from += console_width; - to += new_width; - y += 1; + FASTCOPY (cfrom, cto, xlim); + FASTCOPY (hfrom, hto, xlim); + (new_line_lengths[ny]) = (console_line_lengths[oy]); + cfrom += console_width; + cto += new_width; + hfrom += console_width; + hto += new_width; + oy += 1; + ny += 1; } OS_free (console_chars); + OS_free (console_highlights); + OS_free (console_line_lengths); } console_pel_width = new_pel_width; console_pel_height = new_pel_height; console_width = new_width; console_height = new_height; console_chars = new_chars; + console_highlights = new_highlights; + console_line_lengths = new_line_lengths; if (point_x >= new_width) point_x = (new_width - 1); if ((point_y + 1) >= new_height) @@ -400,28 +742,63 @@ console_resize (unsigned short new_pel_width, unsigned short new_pel_height) } static void -console_paint (unsigned short xl, unsigned short xh, - unsigned short yl, unsigned short yh) +console_paint (unsigned short cxl, unsigned short cxh, + unsigned short cyl, unsigned short cyh) { - unsigned short cxl = (x2cx (xl, 1)); - unsigned short cxh = (x2cx (xh, 0)); - unsigned short cyl = (y2cy (yh, 0)); - unsigned short cyh = (y2cy (yl, 1)); - OS2_ps_clear (console_psid, xl, xh, yl, yh); if ((cxl < cxh) && (cyl < cyh)) { + COLOR foreground = (OS2_ps_get_foreground_color (console_psid)); + COLOR background = (OS2_ps_get_background_color (console_psid)); unsigned short size = (cxh - cxl); - unsigned short x = (cx2x (cxl)); + char current_hl = '\0'; while (cyl < cyh) { - OS2_ps_draw_text (console_psid, - x, ((cy2y (cyl, 1)) + CHAR_DESCENDER), - (CHAR_LOC (cxl, cyl)), size); + unsigned short x = (cx2x (cxl)); + unsigned short y = ((cy2y (cyl, 1)) + CHAR_DESCENDER); + char * cstart = (CHAR_LOC (cxl, cyl)); + char * hstart = (CHAR_HL (cxl, cyl)); + char * hend = (hstart + size); + while (hstart < hend) + { + unsigned short run_length = (compute_run_length (hstart, hend)); + if (current_hl != (*hstart)) + { + if ((*hstart) == '\0') + OS2_ps_set_colors (console_psid, foreground, background); + else + OS2_ps_set_colors (console_psid, background, foreground); + current_hl = (*hstart); + } + OS2_ps_draw_text (console_psid, x, y, cstart, run_length); + x += (run_length * CHAR_WIDTH); + cstart += run_length; + hstart += run_length; + } cyl += 1; } + if (current_hl != '\0') + OS2_ps_set_colors (console_psid, foreground, background); } } +static unsigned short +compute_run_length (const char * start, const char * end) +{ + if (start < end) + { + const char * scan = start; + const char c = (*scan++); + while (scan < end) + if ((*scan) == c) + scan += 1; + else + break; + return (scan - start); + } + else + return (0); +} + static void console_clear (unsigned short xl, unsigned short xh, unsigned short yl, unsigned short yh) @@ -449,24 +826,47 @@ OS2_pm_console_getch (void) { msg_list_t * element = pending_events_head; msg_t * message = (element -> message); + ULONG msg = (SM_PM_EVENT_MSG (message)); + MPARAM mp1 = (SM_PM_EVENT_MP1 (message)); + MPARAM mp2 = (SM_PM_EVENT_MP2 (message)); pending_events_head = (element -> next); + OS2_destroy_message (message); OS_free (element); - switch (MSG_TYPE (message)) + switch (msg) { - case mt_key_event: + case WM_CHAR: { - int translation = (translate_key_event (message)); - unsigned short repeat = (SM_KEY_EVENT_REPEAT (message)); - OS2_destroy_message (message); - if ((translation >= 0) && (repeat > 0)) + unsigned short code; + unsigned char repeat; + if (translate_key_event (mp1, mp2, (&code), (&repeat))) { - readahead_char = translation; - readahead_repeat = repeat; - goto do_read; + /* The feature that causes Delete and Backspace to + delete the marked region is disabled because it + is too much trouble to make the typeahead + buffer conform to the displayed characters. */ +#if 0 + /* Delete and Backspace must discard the marked + region if there is one. */ + if ((code == '\177') && (repeat > 0)) + { + char * region = (extract_marked_region (1)); + if (region != 0) + { + OS_free (region); + repeat -= 1; + } + } +#endif + if (repeat > 0) + { + readahead_char = code; + readahead_repeat = repeat; + goto do_read; + } } - break; } - case mt_close_event: + break; + case WM_CLOSE: switch (WinMessageBox (HWND_DESKTOP, @@ -487,27 +887,42 @@ OS2_pm_console_getch (void) break; case MBID_NO: console_closedp = 1; - { - wid_t wid = (SM_CLOSE_EVENT_WID (message)); - OS2_destroy_message (message); - OS2_window_close (wid); - } + OS2_window_close (console_wid); OS2_close_qid (console_event_qid); OS2_close_std_tqueue (console_tqueue); goto do_read; } break; - case mt_command_event: - switch (SM_COMMAND_EVENT_COMMAND (message)) - { - case IDM_PASTE: - if (do_paste ()) - goto do_read; - break; - } - break; - default: - OS2_logic_error ("Unknown message type received by PM console."); + case WM_COMMAND: + { + ULONG msg = (SHORT1FROMMP (mp1)); + switch (msg) + { + case IDM_PASTE: + if (do_paste ()) + goto do_read; + break; +#if 0 + /* IDM_CUT is disabled because it is too much + trouble to make the typeahead buffer conform to + the displayed characters. */ + case IDM_CUT: +#endif + case IDM_COPY: + grab_console_lock (); + { + char * region = (extract_marked_region (msg == IDM_CUT)); + if (region != 0) + { + OS2_clipboard_write_text (console_pm_qid, region); + OS_free (region); + unmark_marked_region (); + } + } + release_console_lock (); + break; + } + } break; } } @@ -535,7 +950,7 @@ static int do_paste (void) { const char * text = (OS2_clipboard_read_text (console_pm_qid)); - if ((*text) != '\0') + if ((text != 0) && ((*text) != '\0')) { readahead_insert = text; readahead_insert_scan = text; @@ -549,42 +964,45 @@ do_paste (void) } static int -translate_key_event (msg_t * message) +translate_key_event (MPARAM mp1, MPARAM mp2, + unsigned short * code, unsigned char * repeat) { - unsigned short code = (SM_KEY_EVENT_CODE (message)); - unsigned short flags = (SM_KEY_EVENT_FLAGS (message)); + unsigned short flags; + if (!OS2_translate_wm_char (mp1, mp2, code, (&flags), repeat)) + return (0); if ((flags & KC_VIRTUALKEY) != 0) - switch (code) + switch (*code) { case VK_BACKSPACE: - code = '\177'; + case VK_DELETE: + (*code) = '\177'; break; case VK_TAB: - code = '\t'; + (*code) = '\t'; break; case VK_ESC: - code = '\033'; + (*code) = '\033'; break; case VK_SPACE: - code = ' '; + (*code) = ' '; break; case VK_NEWLINE: case VK_ENTER: - code = '\r'; + (*code) = '\r'; break; default: - return (-1); + return (0); } - if ((code >= 0200) || ((flags & KC_ALT) != 0)) - return (-1); + if (((*code) >= 0200) || ((flags & KC_ALT) != 0)) + return (0); if ((flags & KC_CTRL) != 0) - if (code >= 040) - code &= 037; + if ((*code) >= 040) + (*code) &= 037; else - return (-1); - if (code == 0) - return (-1); - return (code); + return (0); + if ((*code) == 0) + return (0); + return (1); } void @@ -595,6 +1013,7 @@ OS2_pm_console_write (const char * data, size_t size) if (console_closedp) return; grab_console_lock (); + unmark_marked_region (); while (data < end) { nonprint = (find_nonprint (data, end)); @@ -605,6 +1024,7 @@ OS2_pm_console_write (const char * data, size_t size) if (size > (console_width - point_x)) size = (console_width - point_x); FASTCOPY (data, (CHAR_LOC (point_x, point_y)), size); + FASTFILL ((CHAR_HL (point_x, point_y)), size, '\0'); OS2_ps_draw_text (console_psid, (cx2x (point_x)), ((cy2y (point_y, 1)) + CHAR_DESCENDER), @@ -612,6 +1032,7 @@ OS2_pm_console_write (const char * data, size_t size) size); data += size; point_x += size; + (console_line_lengths[point_y]) = point_x; if (point_x == console_width) { do_carriage_return (); @@ -663,30 +1084,32 @@ static void do_linefeed (void) { if (point_y < (console_height - 1)) - { - point_y += 1; - FASTFILL ((CHAR_LOC (0, point_y)), console_width, ' '); - console_clear (0, console_width, point_y, (point_y + 1)); - } + 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); FASTCOPY ((CHAR_LOC (0, 1)), (CHAR_LOC (0, 0)), (point_y * console_width)); - FASTFILL ((CHAR_LOC (0, point_y)), console_width, ' '); + FASTCOPY ((CHAR_HL (0, 1)), + (CHAR_HL (0, 0)), + (point_y * console_width)); + FASTCOPY ((LINE_LEN_LOC (1)), + (LINE_LEN_LOC (0)), + (point_y * (sizeof (unsigned short)))); OS2_window_scroll (console_wid, 0, console_pel_width, 0, (point_y * CHAR_HEIGHT), 0, CHAR_HEIGHT); - OS2_ps_clear (console_psid, 0, console_pel_width, 0, CHAR_HEIGHT); #endif /* not CONSOLE_WRAP */ } + FASTFILL ((CHAR_LOC (0, point_y)), console_width, ' '); + FASTFILL ((CHAR_HL (0, point_y)), console_width, '\0'); + (console_line_lengths[point_y]) = 0; + console_clear (0, console_width, point_y, (point_y + 1)); } static void @@ -694,7 +1117,11 @@ do_formfeed (void) { point_x = 0; point_y = 0; - FASTFILL ((CHAR_LOC (0, 0)), (console_width * console_height), ' '); + FASTFILL ((CHAR_LOC (0, 0)), (console_height * console_width), ' '); + FASTFILL ((CHAR_HL (0, 0)), (console_height * console_width), '\0'); + FASTFILL ((LINE_LEN_LOC (0)), + (console_height * (sizeof (unsigned short))), + 0); console_clear_all (); } @@ -704,11 +1131,12 @@ do_backspace (void) if (point_x > 0) { point_x -= 1; + (console_line_lengths[point_y]) = point_x; } } static void do_alert (void) { - DosBeep (880, 50); + WinAlarm (HWND_DESKTOP, WA_ERROR); } diff --git a/v7/src/microcode/os2pmcon.rc b/v7/src/microcode/os2pmcon.rc index 53978d80c..1da75c685 100644 --- a/v7/src/microcode/os2pmcon.rc +++ b/v7/src/microcode/os2pmcon.rc @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: os2pmcon.rc,v 1.1 1995/10/30 07:58:27 cph Exp $ +$Id: os2pmcon.rc,v 1.2 1995/11/03 01:30:07 cph Exp $ Copyright (c) 1995 Massachusetts Institute of Technology @@ -41,12 +41,12 @@ MENU ID_PMCON_RESOURCES { SUBMENU "~File", IDM_FILE { - MENUITEM "~Exit", IDM_EXIT + MENUITEM "E~xit", IDM_EXIT } SUBMENU "~Edit", IDM_EDIT { MENUITEM "Cu~t\tShift+Delete", IDM_CUT, 0, MIA_DISABLED - MENUITEM "~Copy\tCtrl+Insert", IDM_COPY, 0, MIA_DISABLED + MENUITEM "~Copy\tCtrl+Insert", IDM_COPY MENUITEM "~Paste\tShift+Insert", IDM_PASTE } SUBMENU "~Options", IDM_OPTIONS @@ -55,7 +55,7 @@ MENU ID_PMCON_RESOURCES } SUBMENU "~Help", IDM_HELP { - MENUITEM "~Product information...", IDM_ABOUT + MENUITEM "~About...", IDM_ABOUT } } diff --git a/v7/src/microcode/pros2pm.c b/v7/src/microcode/pros2pm.c index 9831db32a..fbf866fcd 100644 --- a/v7/src/microcode/pros2pm.c +++ b/v7/src/microcode/pros2pm.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: pros2pm.c,v 1.10 1995/10/30 08:04:30 cph Exp $ +$Id: pros2pm.c,v 1.11 1995/11/03 01:30:21 cph Exp $ Copyright (c) 1994-95 Massachusetts Institute of Technology @@ -55,7 +55,7 @@ qid_argument (unsigned int arg_number) static psid_t psid_argument (unsigned int arg_number) { - unsigned long result = (arg_nonnegative_integer (arg_number)); + unsigned long result = (arg_ulong_integer (arg_number)); if (!OS2_psid_validp (result)) error_bad_range_arg (arg_number); return (result); @@ -73,7 +73,7 @@ memory_psid_argument (unsigned int arg_number) static wid_t wid_argument (unsigned int arg_number) { - unsigned long result = (arg_nonnegative_integer (arg_number)); + unsigned long result = (arg_ulong_integer (arg_number)); if (!OS2_wid_validp (result)) error_bad_range_arg (arg_number); return (result); @@ -82,7 +82,7 @@ wid_argument (unsigned int arg_number) static bid_t bid_argument (unsigned int arg_number) { - unsigned long result = (arg_nonnegative_integer (arg_number)); + unsigned long result = (arg_ulong_integer (arg_number)); if (!OS2_bid_validp (result)) error_bad_range_arg (arg_number); return (result); @@ -119,10 +119,17 @@ OS2_initialize_window_primitives (void) pm_qid = (OS2_create_pm_qid (OS2_scheme_tqueue)); } +DEFINE_PRIMITIVE ("OS2WIN-ALARM", Prim_OS2_window_alarm, 1, 1, 0) +{ + PRIMITIVE_HEADER (1); + PRIMITIVE_RETURN + (BOOLEAN_TO_OBJECT (WinAlarm (HWND_DESKTOP, (arg_ulong_integer (1))))); +} + DEFINE_PRIMITIVE ("OS2WIN-BEEP", Prim_OS2_window_beep, 2, 2, 0) { PRIMITIVE_HEADER (2); - DosBeep ((arg_nonnegative_integer (1)), (arg_nonnegative_integer (2))); + DosBeep ((arg_ulong_integer (1)), (arg_ulong_integer (2))); PRIMITIVE_RETURN (UNSPECIFIC); } @@ -137,15 +144,15 @@ DEFINE_PRIMITIVE ("OS2WIN-OPEN", Prim_OS2_window_open, 2, 2, 0) { PRIMITIVE_HEADER (2); PRIMITIVE_RETURN - (long_to_integer (OS2_window_open (pm_qid, - (OS2_qid_twin (qid_argument (1))), - (FCF_TITLEBAR | FCF_SYSMENU - | FCF_SHELLPOSITION | FCF_SIZEBORDER - | FCF_MINMAX | FCF_TASKLIST), - NULLHANDLE, - 1, - 0, - (STRING_ARG (2))))); + (ulong_to_integer (OS2_window_open (pm_qid, + (OS2_qid_twin (qid_argument (1))), + (FCF_TITLEBAR | FCF_SYSMENU + | FCF_SHELLPOSITION | FCF_SIZEBORDER + | FCF_MINMAX | FCF_TASKLIST), + NULLHANDLE, + 1, + 0, + (STRING_ARG (2))))); } DEFINE_PRIMITIVE ("OS2WIN-CLOSE", Prim_OS2_window_close, 1, 1, 0) @@ -177,7 +184,7 @@ DEFINE_PRIMITIVE ("OS2WIN-SHAPE-CURSOR", Prim_OS2_window_shape_cursor, 4, 4, 0) OS2_window_shape_cursor ((wid_argument (1)), (DIMENSION_ARG (2)), (DIMENSION_ARG (3)), - (arg_nonnegative_integer (4))); + (USHORT_ARG (4))); PRIMITIVE_RETURN (UNSPECIFIC); } @@ -306,11 +313,25 @@ DEFINE_PRIMITIVE ("OS2WIN-SET-TITLE", Prim_OS2_window_set_title, 2, 2, 0) PRIMITIVE_RETURN (UNSPECIFIC); } +DEFINE_PRIMITIVE ("OS2WIN-TRACK-MOUSE", Prim_OS2_window_track_mouse, 2, 2, 0) +{ + PRIMITIVE_HEADER (2); + OS2_window_mousetrack ((wid_argument (1)), (BOOLEAN_ARG (2))); + PRIMITIVE_RETURN (UNSPECIFIC); +} + DEFINE_PRIMITIVE ("OS2WIN-FRAME-HANDLE", Prim_OS2_window_frame_handle, 1, 1, 0) { PRIMITIVE_HEADER (1); PRIMITIVE_RETURN - (long_to_integer (OS2_window_frame_handle (wid_argument (1)))); + (ulong_to_integer (OS2_window_frame_handle (wid_argument (1)))); +} + +DEFINE_PRIMITIVE ("OS2WIN-CLIENT-HANDLE", Prim_OS2_window_client_handle, 1, 1, 0) +{ + PRIMITIVE_HEADER (1); + PRIMITIVE_RETURN + (ulong_to_integer (OS2_window_client_handle (wid_argument (1)))); } DEFINE_PRIMITIVE ("OS2WIN-UPDATE-FRAME", Prim_OS2_window_update_frame, 2, 2, 0) @@ -319,17 +340,63 @@ DEFINE_PRIMITIVE ("OS2WIN-UPDATE-FRAME", Prim_OS2_window_update_frame, 2, 2, 0) OS2_window_update_frame ((wid_argument (1)), (USHORT_ARG (2))); PRIMITIVE_RETURN (UNSPECIFIC); } + +DEFINE_PRIMITIVE ("OS2-WINDOW-HANDLE-FROM-ID", Prim_OS2_window_handle_from_id, 2, 2, 0) +{ + PRIMITIVE_HEADER (2); + PRIMITIVE_RETURN + (ulong_to_integer (OS2_window_handle_from_id (pm_qid, + (arg_ulong_integer (1)), + (arg_ulong_integer (2))))); +} + +DEFINE_PRIMITIVE ("OS2-MAP-WINDOW-POINT", Prim_OS2_map_window_point, 3, 3, 0) +{ + PRIMITIVE_HEADER (3); + { + SCHEME_OBJECT scheme_point; + POINTL point; + BOOL rc; + + CHECK_ARG (3, PAIR_P); + scheme_point = (ARG_REF (3)); + if ((!INTEGER_P (PAIR_CAR (scheme_point))) + || (!INTEGER_P (PAIR_CDR (scheme_point)))) + error_wrong_type_arg (3); + if ((!integer_to_long_p (PAIR_CAR (scheme_point))) + || (!integer_to_long_p (PAIR_CDR (scheme_point)))) + error_bad_range_arg (3); + (point . x) = (integer_to_long (PAIR_CAR (scheme_point))); + (point . y) = (integer_to_long (PAIR_CDR (scheme_point))); + rc = (WinMapWindowPoints ((HWND_ARG (1)), (HWND_ARG (2)), (&point), 1)); + if (rc) + { + SET_PAIR_CAR (scheme_point, (long_to_integer (point . x))); + SET_PAIR_CDR (scheme_point, (long_to_integer (point . y))); + } + PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (rc)); + } +} + +DEFINE_PRIMITIVE ("OS2WIN-SET-CAPTURE", PRIM_OS2_WINDOW_SET_CAPTURE, 2, 2, 0) +{ + PRIMITIVE_HEADER (2); + PRIMITIVE_RETURN + (BOOLEAN_TO_OBJECT + (OS2_window_set_capture ((wid_argument (1)), (BOOLEAN_ARG (2))))); +} DEFINE_PRIMITIVE ("OS2WIN-PS", Prim_OS2_window_ps, 1, 1, 0) { PRIMITIVE_HEADER (1); - PRIMITIVE_RETURN (long_to_integer (OS2_window_client_ps (wid_argument (1)))); + PRIMITIVE_RETURN + (ulong_to_integer (OS2_window_client_ps (wid_argument (1)))); } DEFINE_PRIMITIVE ("OS2PS-CREATE-MEMORY-PS", Prim_OS2_create_memory_ps, 0, 0, 0) { PRIMITIVE_HEADER (0); - PRIMITIVE_RETURN (long_to_integer (OS2_create_memory_ps (pm_qid))); + PRIMITIVE_RETURN (ulong_to_integer (OS2_create_memory_ps (pm_qid))); } DEFINE_PRIMITIVE ("OS2PS-DESTROY-MEMORY-PS", Prim_OS2_destroy_memory_ps, 1, 1, 0) @@ -343,9 +410,9 @@ DEFINE_PRIMITIVE ("OS2PS-CREATE-BITMAP", Prim_OS2_create_bitmap, 3, 3, 0) { PRIMITIVE_HEADER (3); PRIMITIVE_RETURN - (long_to_integer (OS2_create_bitmap ((psid_argument (1)), - (USHORT_ARG (2)), - (USHORT_ARG (3))))); + (ulong_to_integer (OS2_create_bitmap ((psid_argument (1)), + (USHORT_ARG (2)), + (USHORT_ARG (3))))); } DEFINE_PRIMITIVE ("OS2PS-DESTROY-BITMAP", Prim_OS2_destroy_bitmap, 1, 1, 0) @@ -360,7 +427,7 @@ DEFINE_PRIMITIVE ("OS2PS-GET-BITMAP", Prim_OS2_ps_get_bitmap, 1, 1, 0) PRIMITIVE_HEADER (1); { bid_t bid = (OS2_ps_get_bitmap ((memory_psid_argument (1)))); - PRIMITIVE_RETURN ((bid == BID_NONE) ? SHARP_F : (long_to_integer (bid))); + PRIMITIVE_RETURN ((bid == BID_NONE) ? SHARP_F : (ulong_to_integer (bid))); } } @@ -372,7 +439,7 @@ DEFINE_PRIMITIVE ("OS2PS-SET-BITMAP", Prim_OS2_ps_set_bitmap, 2, 2, 0) = (OS2_ps_set_bitmap ((memory_psid_argument (1)), (((ARG_REF (2)) == SHARP_F) ? BID_NONE : (bid_argument (2))))); - PRIMITIVE_RETURN ((bid == BID_NONE) ? SHARP_F : (long_to_integer (bid))); + PRIMITIVE_RETURN ((bid == BID_NONE) ? SHARP_F : (ulong_to_integer (bid))); } } @@ -386,7 +453,7 @@ DEFINE_PRIMITIVE ("OS2PS-BITBLT", Prim_OS2_ps_bitblt, 6, 6, 0) unsigned long npoints; PPOINTL points = (coordinate_vector_point_args (3, 4, (& npoints))); LONG rop = (arg_index_integer (5, 0x100)); - ULONG options = (arg_nonnegative_integer (6)); + ULONG options = (arg_ulong_integer (6)); if (! ((npoints == 3) || (npoints == 4))) error_bad_range_arg (3); OS2_ps_bitblt (target, source, npoints, points, rop, options); @@ -401,8 +468,8 @@ DEFINE_PRIMITIVE ("OS2PS-WRITE", Prim_OS2_ps_write, 6, 6, 0) CHECK_ARG (4, STRING_P); { SCHEME_OBJECT string = (ARG_REF (4)); - unsigned long start = (arg_nonnegative_integer (5)); - unsigned long end = (arg_nonnegative_integer (6)); + unsigned long start = (arg_ulong_integer (5)); + unsigned long end = (arg_ulong_integer (6)); if (end > (STRING_LENGTH (string))) error_bad_range_arg (6); if (start > end) @@ -422,14 +489,14 @@ DEFINE_PRIMITIVE ("OS2PS-TEXT-WIDTH", Prim_OS2_ps_text_width, 4, 4, 0) CHECK_ARG (2, STRING_P); { SCHEME_OBJECT string = (ARG_REF (2)); - unsigned long start = (arg_nonnegative_integer (3)); - unsigned long end = (arg_nonnegative_integer (4)); + unsigned long start = (arg_ulong_integer (3)); + unsigned long end = (arg_ulong_integer (4)); if (end > (STRING_LENGTH (string))) error_bad_range_arg (4); if (start > end) error_bad_range_arg (3); PRIMITIVE_RETURN - (long_to_integer + (ulong_to_integer (OS2_ps_text_width ((psid_argument (1)), (STRING_LOC (string, start)), (end - start)))); @@ -444,9 +511,9 @@ convert_font_metrics (font_metrics_t * m) else { SCHEME_OBJECT v = (allocate_marked_vector (TC_VECTOR, 3, 1)); - VECTOR_SET (v, 0, (long_to_integer (FONT_METRICS_WIDTH (m)))); - VECTOR_SET (v, 1, (long_to_integer (FONT_METRICS_HEIGHT (m)))); - VECTOR_SET (v, 2, (long_to_integer (FONT_METRICS_DESCENDER (m)))); + VECTOR_SET (v, 0, (ulong_to_integer (FONT_METRICS_WIDTH (m)))); + VECTOR_SET (v, 1, (ulong_to_integer (FONT_METRICS_HEIGHT (m)))); + VECTOR_SET (v, 2, (ulong_to_integer (FONT_METRICS_DESCENDER (m)))); OS_free (m); return (v); } @@ -666,10 +733,10 @@ DEFINE_PRIMITIVE ("OS2PS-GET-BITMAP-BITS", Prim_OS2_ps_get_bitmap_bits, 5, 5, 0) { PRIMITIVE_HEADER (5); PRIMITIVE_RETURN - (long_to_integer + (ulong_to_integer (OS2_ps_get_bitmap_bits ((memory_psid_argument (1)), - (arg_nonnegative_integer (2)), - (arg_nonnegative_integer (3)), + (arg_ulong_integer (2)), + (arg_ulong_integer (3)), (STRING_ARG (4)), ((void *) (STRING_ARG (5)))))); } @@ -678,10 +745,10 @@ DEFINE_PRIMITIVE ("OS2PS-SET-BITMAP-BITS", Prim_OS2_ps_set_bitmap_bits, 5, 5, 0) { PRIMITIVE_HEADER (5); PRIMITIVE_RETURN - (long_to_integer + (ulong_to_integer (OS2_ps_set_bitmap_bits ((memory_psid_argument (1)), - (arg_nonnegative_integer (2)), - (arg_nonnegative_integer (3)), + (arg_ulong_integer (2)), + (arg_ulong_integer (3)), (STRING_ARG (4)), ((void *) (STRING_ARG (5)))))); } @@ -814,15 +881,6 @@ DEFINE_PRIMITIVE ("OS2MENU-SET-ITEM-ATTRIBUTES", Prim_OS2_menu_set_item_attribut PRIMITIVE_RETURN (UNSPECIFIC); } -DEFINE_PRIMITIVE ("OS2-WINDOW-HANDLE-FROM-ID", Prim_OS2_window_handle_from_id, 2, 2, 0) -{ - PRIMITIVE_HEADER (2); - PRIMITIVE_RETURN - (ulong_to_integer (OS2_window_handle_from_id (pm_qid, - (arg_ulong_integer (1)), - (arg_ulong_integer (2))))); -} - DEFINE_PRIMITIVE ("OS2WIN-LOAD-MENU", Prim_OS2_window_load_menu, 3, 3, 0) { PRIMITIVE_HEADER (3); @@ -832,6 +890,21 @@ DEFINE_PRIMITIVE ("OS2WIN-LOAD-MENU", Prim_OS2_window_load_menu, 3, 3, 0) (arg_ulong_integer (3))))); } +DEFINE_PRIMITIVE ("OS2WIN-POPUP-MENU", Prim_OS2_window_popup_menu, 7, 7, 0) +{ + PRIMITIVE_HEADER (7); + PRIMITIVE_RETURN + (BOOLEAN_TO_OBJECT + (OS2_window_popup_menu (pm_qid, + (HWND_ARG (1)), + (HWND_ARG (2)), + (HWND_ARG (3)), + (arg_integer (4)), + (arg_integer (5)), + (arg_integer (6)), + (arg_ulong_integer (7))))); +} + DEFINE_PRIMITIVE ("OS2WIN-FONT-DIALOG", Prim_OS2_window_font_dialog, 2, 2, 0) { const char * spec; @@ -849,6 +922,25 @@ DEFINE_PRIMITIVE ("OS2WIN-FONT-DIALOG", Prim_OS2_window_font_dialog, 2, 2, 0) PRIMITIVE_RETURN (result); } +DEFINE_PRIMITIVE ("OS2-QUERY-SYSTEM-POINTER", Prim_OS2_query_system_pointer, 3, 3, 0) +{ + PRIMITIVE_HEADER (3); + PRIMITIVE_RETURN + (ulong_to_integer (OS2_query_system_pointer (pm_qid, + (HWND_ARG (1)), + (arg_integer (2)), + (BOOLEAN_ARG (3))))); +} + +DEFINE_PRIMITIVE ("OS2-SET-POINTER", Prim_OS2_set_pointer, 2, 2, 0) +{ + PRIMITIVE_HEADER (2); + PRIMITIVE_RETURN + (BOOLEAN_TO_OBJECT (OS2_set_pointer (pm_qid, + (HWND_ARG (1)), + (arg_ulong_integer (2))))); +} + DEFINE_PRIMITIVE ("OS2WIN-OPEN-EVENT-QID", Prim_OS2_window_open_event_qid, 0, 0, 0) { qid_t local; @@ -875,119 +967,190 @@ DEFINE_PRIMITIVE ("OS2WIN-CLOSE-EVENT-QID", Prim_OS2_window_close_event_qid, 1, #define ET_VISIBILITY 6 #define ET_COMMAND 7 #define ET_HELP 8 +#define ET_MOUSEMOVE 9 -#define CVT_UNSIGNED(n, v) \ +#define CVT_USHORT(n, v) \ VECTOR_SET (result, n, (LONG_TO_UNSIGNED_FIXNUM (v))) +#define CVT_SHORT(n, v) \ + VECTOR_SET (result, n, (LONG_TO_FIXNUM (v))) #define CVT_BOOLEAN(n, v) \ VECTOR_SET (result, n, (BOOLEAN_TO_OBJECT (v))) +static SCHEME_OBJECT make_button_event + (wid_t, MPARAM, MPARAM, unsigned short, unsigned short); + DEFINE_PRIMITIVE ("OS2WIN-GET-EVENT", Prim_OS2_window_get_event, 2, 2, 0) { + qid_t qid; + int blockp; PRIMITIVE_HEADER (2); + + qid = (qid_argument (1)); + blockp = (BOOLEAN_ARG (2)); Primitive_GC_If_Needed (8); - { - msg_t * message - = (OS2_receive_message ((qid_argument (1)), (BOOLEAN_ARG (2)), 1)); - SCHEME_OBJECT result = SHARP_F; - if (message != 0) - { - switch (MSG_TYPE (message)) + while (1) + { + msg_t * message = (OS2_receive_message (qid, blockp, 1)); + SCHEME_OBJECT result = SHARP_F; + if (message == 0) + PRIMITIVE_RETURN (result); + switch (MSG_TYPE (message)) + { + case mt_pm_event: { - case mt_button_event: - { - unsigned short type = (SM_BUTTON_EVENT_TYPE (message)); - result = (allocate_marked_vector (TC_VECTOR, 7, 0)); - CVT_UNSIGNED (0, ET_BUTTON); - CVT_UNSIGNED (1, (SM_BUTTON_EVENT_WID (message))); - CVT_UNSIGNED (2, (BUTTON_TYPE_NUMBER (type))); - CVT_UNSIGNED (3, (BUTTON_TYPE_EVENT (type))); - CVT_UNSIGNED (4, (SM_BUTTON_EVENT_X (message))); - CVT_UNSIGNED (5, (SM_BUTTON_EVENT_Y (message))); - CVT_UNSIGNED (6, (SM_BUTTON_EVENT_FLAGS (message))); - break; - } - case mt_close_event: - { - result = (allocate_marked_vector (TC_VECTOR, 2, 0)); - CVT_UNSIGNED (0, ET_CLOSE); - CVT_UNSIGNED (1, (SM_CLOSE_EVENT_WID (message))); - break; - } - case mt_focus_event: - { - result = (allocate_marked_vector (TC_VECTOR, 3, 0)); - CVT_UNSIGNED (0, ET_FOCUS); - CVT_UNSIGNED (1, (SM_FOCUS_EVENT_WID (message))); - CVT_BOOLEAN (2, (SM_FOCUS_EVENT_GAINEDP (message))); - break; - } - case mt_key_event: - { - result = (allocate_marked_vector (TC_VECTOR, 5, 0)); - CVT_UNSIGNED (0, ET_KEY); - CVT_UNSIGNED (1, (SM_KEY_EVENT_WID (message))); - CVT_UNSIGNED (2, (SM_KEY_EVENT_CODE (message))); - CVT_UNSIGNED (3, (SM_KEY_EVENT_FLAGS (message))); - CVT_UNSIGNED (4, (SM_KEY_EVENT_REPEAT (message))); - break; - } - case mt_paint_event: - { - result = (allocate_marked_vector (TC_VECTOR, 6, 0)); - CVT_UNSIGNED (0, ET_PAINT); - CVT_UNSIGNED (1, (SM_PAINT_EVENT_WID (message))); - CVT_UNSIGNED (2, (SM_PAINT_EVENT_XL (message))); - CVT_UNSIGNED (3, (SM_PAINT_EVENT_XH (message))); - CVT_UNSIGNED (4, (SM_PAINT_EVENT_YL (message))); - CVT_UNSIGNED (5, (SM_PAINT_EVENT_YH (message))); - break; - } - case mt_resize_event: - { - result = (allocate_marked_vector (TC_VECTOR, 4, 0)); - CVT_UNSIGNED (0, ET_RESIZE); - CVT_UNSIGNED (1, (SM_RESIZE_EVENT_WID (message))); - CVT_UNSIGNED (2, (SM_RESIZE_EVENT_WIDTH (message))); - CVT_UNSIGNED (3, (SM_RESIZE_EVENT_HEIGHT (message))); - break; - } - case mt_visibility_event: - { - result = (allocate_marked_vector (TC_VECTOR, 3, 0)); - CVT_UNSIGNED (0, ET_VISIBILITY); - CVT_UNSIGNED (1, (SM_VISIBILITY_EVENT_WID (message))); - CVT_BOOLEAN (2, (SM_VISIBILITY_EVENT_SHOWNP (message))); - break; - } - case mt_command_event: - { - result = (allocate_marked_vector (TC_VECTOR, 5, 0)); - CVT_UNSIGNED (0, ET_COMMAND); - CVT_UNSIGNED (1, (SM_COMMAND_EVENT_WID (message))); - CVT_UNSIGNED (2, (SM_COMMAND_EVENT_COMMAND (message))); - CVT_UNSIGNED (3, (SM_COMMAND_EVENT_SOURCE (message))); - CVT_BOOLEAN (4, (SM_COMMAND_EVENT_MOUSEP (message))); - break; - } - case mt_help_event: - { - result = (allocate_marked_vector (TC_VECTOR, 5, 0)); - CVT_UNSIGNED (0, ET_HELP); - CVT_UNSIGNED (1, (SM_HELP_EVENT_WID (message))); - CVT_UNSIGNED (2, (SM_HELP_EVENT_COMMAND (message))); - CVT_UNSIGNED (3, (SM_HELP_EVENT_SOURCE (message))); - CVT_BOOLEAN (4, (SM_HELP_EVENT_MOUSEP (message))); - break; - } - default: + wid_t wid = (SM_PM_EVENT_WID (message)); + ULONG msg = (SM_PM_EVENT_MSG (message)); + MPARAM mp1 = (SM_PM_EVENT_MP1 (message)); + MPARAM mp2 = (SM_PM_EVENT_MP2 (message)); OS2_destroy_message (message); - OS2_error_anonymous (); + switch (msg) + { + case WM_SETFOCUS: + { + result = (allocate_marked_vector (TC_VECTOR, 3, 0)); + CVT_USHORT (0, ET_FOCUS); + CVT_USHORT (1, wid); + CVT_BOOLEAN (2, (SHORT1FROMMP (mp2))); + break; + } + case WM_SIZE: + { + result = (allocate_marked_vector (TC_VECTOR, 4, 0)); + CVT_USHORT (0, ET_RESIZE); + CVT_USHORT (1, wid); + CVT_USHORT (2, (SHORT1FROMMP (mp2))); + CVT_USHORT (3, (SHORT2FROMMP (mp2))); + break; + } + case WM_CLOSE: + { + result = (allocate_marked_vector (TC_VECTOR, 2, 0)); + CVT_USHORT (0, ET_CLOSE); + CVT_USHORT (1, wid); + break; + } + case WM_COMMAND: + case WM_HELP: + { + result = (allocate_marked_vector (TC_VECTOR, 5, 0)); + CVT_USHORT (0, + ((msg == WM_HELP) ? ET_HELP : ET_COMMAND)); + CVT_USHORT (1, wid); + CVT_USHORT (2, (SHORT1FROMMP (mp1))); + CVT_USHORT (3, (SHORT1FROMMP (mp2))); + CVT_BOOLEAN (4, (SHORT2FROMMP (mp2))); + break; + } + case WM_SHOW: + { + result = (allocate_marked_vector (TC_VECTOR, 3, 0)); + CVT_USHORT (0, ET_VISIBILITY); + CVT_USHORT (1, wid); + CVT_BOOLEAN (2, (SHORT1FROMMP (mp1))); + break; + } + case WM_CHAR: + { + unsigned short code; + unsigned short flags; + unsigned char repeat; + if (OS2_translate_wm_char (mp1, mp2, + (&code), (&flags), (&repeat))) + { + result = (allocate_marked_vector (TC_VECTOR, 5, 0)); + CVT_USHORT (0, ET_KEY); + CVT_USHORT (1, wid); + CVT_USHORT (2, code); + CVT_USHORT (3, flags); + CVT_USHORT (4, repeat); + } + break; + } + case WM_BUTTON1DOWN: + result = (make_button_event (wid, mp1, mp2, 0, 0)); + break; + case WM_BUTTON1UP: + result = (make_button_event (wid, mp1, mp2, 0, 1)); + break; + case WM_BUTTON1CLICK: + result = (make_button_event (wid, mp1, mp2, 0, 2)); + break; + case WM_BUTTON1DBLCLK: + result = (make_button_event (wid, mp1, mp2, 0, 3)); + break; + case WM_BUTTON2DOWN: + result = (make_button_event (wid, mp1, mp2, 1, 0)); + break; + case WM_BUTTON2UP: + result = (make_button_event (wid, mp1, mp2, 1, 1)); + break; + case WM_BUTTON2CLICK: + result = (make_button_event (wid, mp1, mp2, 1, 2)); + break; + case WM_BUTTON2DBLCLK: + result = (make_button_event (wid, mp1, mp2, 1, 3)); + break; + case WM_BUTTON3DOWN: + result = (make_button_event (wid, mp1, mp2, 2, 0)); + break; + case WM_BUTTON3UP: + result = (make_button_event (wid, mp1, mp2, 2, 1)); + break; + case WM_BUTTON3CLICK: + result = (make_button_event (wid, mp1, mp2, 2, 2)); + break; + case WM_BUTTON3DBLCLK: + result = (make_button_event (wid, mp1, mp2, 2, 3)); + break; + case WM_MOUSEMOVE: + result = (allocate_marked_vector (TC_VECTOR, 6, 0)); + CVT_USHORT (0, ET_MOUSEMOVE); + CVT_USHORT (1, wid); + CVT_SHORT (2, (SHORT1FROMMP (mp1))); + CVT_SHORT (3, (SHORT2FROMMP (mp1))); + CVT_USHORT (4, (SHORT1FROMMP (mp2))); + CVT_USHORT (5, (SHORT2FROMMP (mp2))); + break; + default: + break; + } break; } - OS2_destroy_message (message); - } - PRIMITIVE_RETURN (result); - } + case mt_paint_event: + { + result = (allocate_marked_vector (TC_VECTOR, 6, 0)); + CVT_USHORT (0, ET_PAINT); + CVT_USHORT (1, (SM_PAINT_EVENT_WID (message))); + CVT_USHORT (2, (SM_PAINT_EVENT_XL (message))); + CVT_USHORT (3, (SM_PAINT_EVENT_XH (message))); + CVT_USHORT (4, (SM_PAINT_EVENT_YL (message))); + CVT_USHORT (5, (SM_PAINT_EVENT_YH (message))); + OS2_destroy_message (message); + break; + } + default: + OS2_destroy_message (message); + OS2_error_anonymous (); + break; + } + if (result != SHARP_F) + PRIMITIVE_RETURN (result); + } +} + +static SCHEME_OBJECT +make_button_event (wid_t wid, MPARAM mp1, MPARAM mp2, + unsigned short number, unsigned short type) +{ + SCHEME_OBJECT result = (allocate_marked_vector (TC_VECTOR, 7, 0)); + CVT_USHORT (0, ET_BUTTON); + CVT_USHORT (1, wid); + CVT_USHORT (2, number); + CVT_USHORT (3, type); + CVT_SHORT (4, (SHORT1FROMMP (mp1))); + CVT_SHORT (5, (SHORT2FROMMP (mp1))); + CVT_USHORT (6, ((SHORT2FROMMP (mp2)) & (KC_SHIFT | KC_CTRL | KC_ALT))); + return (result); } DEFINE_PRIMITIVE ("OS2WIN-EVENT-READY?", Prim_OS2_window_event_ready, 2, 2, 0) @@ -1008,7 +1171,7 @@ DEFINE_PRIMITIVE ("OS2WIN-CONSOLE-WID", Prim_OS2_window_console_wid, 0, 0, 0) { extern wid_t OS2_console_wid (void); PRIMITIVE_HEADER (0); - PRIMITIVE_RETURN (long_to_integer (OS2_console_wid ())); + PRIMITIVE_RETURN (ulong_to_integer (OS2_console_wid ())); } DEFINE_PRIMITIVE ("OS2WIN-DESKTOP-WIDTH", Prim_OS2_window_desktop_width, 0, 0, 0) -- 2.25.1