3
$Id: os2pm.c,v 1.33 2000/12/05 21:23:46 cph Exp $
5
Copyright (c) 1994-2000 Massachusetts Institute of Technology
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or (at
10
your option) any later version.
12
This program is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
extern void add_reload_cleanup (void (*) (void));
27
extern psid_t OS2_console_psid (void);
28
extern void OS2_console_font_change_hook (font_metrics_t *);
30
typedef enum { pst_window, pst_memory } pst_t;
34
psid_t id; /* psid for this ps */
35
qid_t qid; /* qid to send commands to */
37
COLOR foreground_color;
38
COLOR background_color;
39
pst_t visual_type; /* window or bitmap */
40
void * visual; /* the associated window or bitmap */
41
PLONG char_increments; /* character increments for outline fonts */
43
#define PS_ID(ps) ((ps) -> id)
44
#define PS_QID(ps) ((ps) -> qid)
45
#define PS_HANDLE(ps) ((ps) -> handle)
46
#define PS_FOREGROUND_COLOR(ps) ((ps) -> foreground_color)
47
#define PS_BACKGROUND_COLOR(ps) ((ps) -> background_color)
48
#define PS_VISUAL_TYPE(ps) ((ps) -> visual_type)
49
#define PS_VISUAL(ps) ((ps) -> visual)
50
#define PS_CHAR_INCREMENTS(ps) ((ps) -> char_increments)
52
typedef struct _window_t
54
HWND frame; /* frame window handle */
55
HWND client; /* client window handle */
56
ps_t * client_ps; /* presentation space for client window */
57
unsigned short grid_x; /* x dimension of resizing grid */
58
unsigned short grid_y; /* y dimension of resizing grid */
59
short cursor_x; /* x coordinate of the cursor */
60
short cursor_y; /* y coordinate of the cursor */
61
unsigned short cursor_width; /* width of the cursor */
62
unsigned short cursor_height; /* height of the cursor */
63
unsigned short cursor_style; /* style of the cursor */
64
qid_t qid; /* qid to send commands to */
65
qid_t event_qid; /* qid to send input events to */
66
wid_t id; /* wid for this window */
67
unsigned int cursor_createdp : 1; /* nonzero if cursor created */
68
unsigned int cursor_enabledp : 1; /* nonzero if cursor enabled */
69
unsigned int minimizingp : 1; /* nonzero if window being minimized */
70
unsigned int minimizedp : 1; /* nonzero if window is minimized */
71
unsigned int permanentp : 1; /* nonzero means don't close on reload */
72
unsigned int mousetrackp : 1; /* nonzero means generate WM_MOUSEMOVE msgs */
74
#define WINDOW_FRAME(window) ((window) -> frame)
75
#define WINDOW_CLIENT(window) ((window) -> client)
76
#define WINDOW_CLIENT_PS(window) ((window) -> client_ps)
77
#define WINDOW_GRID_X(window) ((window) -> grid_x)
78
#define WINDOW_GRID_Y(window) ((window) -> grid_y)
79
#define WINDOW_CURSOR_X(window) ((window) -> cursor_x)
80
#define WINDOW_CURSOR_Y(window) ((window) -> cursor_y)
81
#define WINDOW_CURSOR_WIDTH(window) ((window) -> cursor_width)
82
#define WINDOW_CURSOR_HEIGHT(window) ((window) -> cursor_height)
83
#define WINDOW_CURSOR_STYLE(window) ((window) -> cursor_style)
84
#define WINDOW_QID(window) ((window) -> qid)
85
#define WINDOW_EVENT_QID(window) ((window) -> event_qid)
86
#define WINDOW_ID(window) ((window) -> id)
87
#define WINDOW_CURSOR_CREATEDP(window) ((window) -> cursor_createdp)
88
#define WINDOW_CURSOR_ENABLEDP(window) ((window) -> cursor_enabledp)
89
#define WINDOW_MINIMIZINGP(window) ((window) -> minimizingp)
90
#define WINDOW_MINIMIZEDP(window) ((window) -> minimizedp)
91
#define WINDOW_PERMANENTP(window) ((window) -> permanentp)
92
#define WINDOW_MOUSETRACKP(window) ((window) -> mousetrackp)
94
typedef struct _bitmap_t
96
bid_t id; /* bid for this bitmap */
97
qid_t qid; /* qid to send commands to */
100
#define BITMAP_ID(bitmap) ((bitmap) -> id)
101
#define BITMAP_QID(bitmap) ((bitmap) -> qid)
102
#define BITMAP_HANDLE(bitmap) ((bitmap) -> handle)
109
#define PM_TQUEUE_HWND(q) (((pm_tqueue_t *) (q)) -> hwnd)
116
#define ID_TABLE_LENGTH(table) ((table) -> length)
117
#define ID_TABLE_POINTERS(table) ((table) -> pointers)
119
/* This machine-generated file contains forward references and
120
structure definitions for most of the procedures. */
121
#include "os2pm-id.h"
123
static void window_pos (window_t *, short *, short *);
124
static void handle_window_pos_request (msg_t *);
128
DECLARE_MSG_HEADER_FIELDS;
131
#define SM_POS_REQUEST_WINDOW(m) (((sm_pos_request_t *) (m)) -> window)
135
DECLARE_MSG_HEADER_FIELDS;
139
#define SM_POS_REPLY_X(m) (((sm_pos_reply_t *) (m)) -> x)
140
#define SM_POS_REPLY_Y(m) (((sm_pos_reply_t *) (m)) -> y)
142
static void window_size (window_t *, unsigned short *, unsigned short *);
143
static void handle_window_size_request (msg_t *);
147
DECLARE_MSG_HEADER_FIELDS;
150
#define SM_SIZE_REQUEST_WINDOW(m) (((sm_size_request_t *) (m)) -> window)
154
DECLARE_MSG_HEADER_FIELDS;
155
unsigned short width;
156
unsigned short height;
158
#define SM_SIZE_REPLY_WIDTH(m) (((sm_size_reply_t *) (m)) -> width)
159
#define SM_SIZE_REPLY_HEIGHT(m) (((sm_size_reply_t *) (m)) -> height)
161
static void window_frame_size
162
(window_t *, unsigned short *, unsigned short *);
163
static void handle_window_frame_size_request (msg_t *);
167
DECLARE_MSG_HEADER_FIELDS;
169
} sm_frame_size_request_t;
170
#define SM_FRAME_SIZE_REQUEST_WINDOW(m) \
171
(((sm_frame_size_request_t *) (m)) -> window)
175
DECLARE_MSG_HEADER_FIELDS;
176
unsigned short width;
177
unsigned short height;
178
} sm_frame_size_reply_t;
179
#define SM_FRAME_SIZE_REPLY_WIDTH(m) \
180
(((sm_frame_size_reply_t *) (m)) -> width)
181
#define SM_FRAME_SIZE_REPLY_HEIGHT(m) \
182
(((sm_frame_size_reply_t *) (m)) -> height)
184
static void handle_ps_set_bitmap_request (msg_t *);
185
static bitmap_t * ps_set_bitmap (ps_t *, bitmap_t *);
189
DECLARE_MSG_HEADER_FIELDS;
192
} sm_ps_set_bitmap_request_t;
193
#define SM_PS_SET_BITMAP_REQUEST_PS(m) \
194
(((sm_ps_set_bitmap_request_t *) (m)) -> ps)
195
#define SM_PS_SET_BITMAP_REQUEST_BITMAP(m) \
196
(((sm_ps_set_bitmap_request_t *) (m)) -> bitmap)
200
DECLARE_MSG_HEADER_FIELDS;
202
} sm_ps_set_bitmap_reply_t;
203
#define SM_PS_SET_BITMAP_REPLY_BITMAP(m) \
204
(((sm_ps_set_bitmap_reply_t *) (m)) -> bitmap)
206
static void close_all_windows (void);
208
static void sync_transaction (qid_t, msg_t *);
209
static void sync_reply (qid_t);
211
static void pm_thread_procedure (void *);
212
static tqueue_t * make_pm_tqueue (HWND);
214
static void initialize_id_table (id_table_t *);
215
static unsigned int allocate_id (id_table_t *, void *);
216
static void deallocate_id (id_table_t *, unsigned int);
217
static void * id_to_pointer (id_table_t *, unsigned int);
218
static int id_validp (id_table_t *, unsigned int);
219
static ps_t * psid_to_ps (psid_t);
220
static window_t * wid_to_window (wid_t);
221
static bitmap_t * bid_to_bitmap (bid_t);
223
static MRESULT EXPENTRY object_window_procedure (HWND, ULONG, MPARAM, MPARAM);
224
static MRESULT EXPENTRY frame_window_procedure (HWND, ULONG, MPARAM, MPARAM);
225
static MRESULT EXPENTRY window_procedure (HWND, ULONG, MPARAM, MPARAM);
227
static window_t * hwnd_to_window (HWND);
228
static msg_t * make_pm_event (wid_t, ULONG, MPARAM, MPARAM);
229
static msg_t * make_paint_event
230
(wid_t, unsigned short, unsigned short, unsigned short, unsigned short);
232
static void recreate_cursor (window_t *);
233
static void activate_cursor (window_t *);
234
static void deactivate_cursor (window_t *);
236
static window_t * make_window (qid_t, qid_t);
238
static void win_create_cursor (HWND, LONG, LONG, LONG, LONG, ULONG, PRECTL);
239
static void win_destroy_cursor (HWND);
240
static void win_show_cursor (HWND, BOOL);
241
static void recreate_cursor (window_t *);
242
static void activate_cursor (window_t *);
243
static void deactivate_cursor (window_t *);
244
static void maybe_activate_cursor (ps_t *);
245
static void maybe_deactivate_cursor (ps_t *);
247
static HDC get_ps_device (HPS);
248
static LONG get_device_capability (HDC, LONG);
249
static ps_t * create_ps (pst_t, HDC, qid_t);
250
static void destroy_ps (ps_t *);
252
static int ps_set_font (ps_t *, unsigned short, const char *);
253
static int parse_font_spec (const char *, PSZ *, LONG *, USHORT *);
254
static const char * unparse_font_spec (PSZ, LONG, USHORT);
255
static int ps_set_font_1 (ps_t * ps, PSZ, LONG, USHORT, LONG);
256
static PLONG ps_make_char_increments (LONG);
257
static int create_font (HPS, LONG, PFONTMETRICS, USHORT);
258
static void copy_fontmetrics_to_fattrs (FONTMETRICS *, FATTRS *);
259
static void ps_set_font_size (ps_t *, LONG);
263
#define UWM_ENCAPSULATION WM_USER
265
#define QWP_WINDOW QWL_USER
267
/* These should have been defined by PM header file. */
268
#define MRVOID MRFROMP (0)
269
#define MRTRUE MRFROMLONG (TRUE)
270
#define MRFALSE MRFROMLONG (FALSE)
272
static id_table_t psid_table;
273
static id_table_t wid_table;
274
static id_table_t bid_table;
275
static qid_t pm_init_qid;
279
static HWND pm_object_window;
280
static tqueue_t * pm_tqueue;
281
static PFNWP original_frame_window_procedure;
282
static window_t * capture_window;
284
static const char object_class [] = "mit-scheme.object";
285
static const char window_class [] = "mit-scheme.window";
287
#define SEND_EVENT(window, message) \
289
if ((WINDOW_EVENT_QID (window)) != QID_NONE) \
290
OS2_send_message ((WINDOW_EVENT_QID (window)), (message)); \
293
#define SEND_PM_EVENT(hwnd, msg, mp1, mp2) \
295
window_t * window = (hwnd_to_window (hwnd)); \
296
SEND_EVENT (window, \
297
(make_pm_event ((WINDOW_ID (window)), msg, mp1, mp2))); \
300
#define window_error(name) window_error_1 (#name, 1)
301
#define window_warning(name) window_error_1 (#name, 0)
304
window_error_1 (const char * name, int fatalp)
307
ERRORID code = (WinGetLastError (pm_hab));
310
sprintf (buffer, "Fatal error 0x%08x occurred in the %s procedure.",
312
OS2_logic_error (buffer);
316
sprintf (buffer, "Non-fatal error 0x%08x occurred in the %s procedure. \
317
This indicates a bug in the Scheme implementation. \
318
Please report this information to a Scheme wizard.",
320
(void) WinMessageBox (HWND_DESKTOP,
325
(MB_OK | MB_WARNING));
330
OS2_initialize_pm_thread (void)
332
/* This machine-generated file contains code to initialize the
333
message-type sizes for most of the procedure messages. */
334
#include "os2pm-mi.h"
336
SET_MSG_TYPE_LENGTH (mt_window_pos_request, sm_pos_request_t);
337
SET_MSG_TYPE_LENGTH (mt_window_pos_reply, sm_pos_reply_t);
338
SET_MSG_TYPE_LENGTH (mt_window_size_request, sm_size_request_t);
339
SET_MSG_TYPE_LENGTH (mt_window_size_reply, sm_size_reply_t);
340
SET_MSG_TYPE_LENGTH (mt_window_frame_size_request, sm_frame_size_request_t);
341
SET_MSG_TYPE_LENGTH (mt_window_frame_size_reply, sm_frame_size_reply_t);
343
SET_MSG_TYPE_LENGTH (mt_ps_set_bitmap_request, sm_ps_set_bitmap_request_t);
344
SET_MSG_TYPE_LENGTH (mt_ps_set_bitmap_reply, sm_ps_set_bitmap_reply_t);
346
SET_MSG_TYPE_LENGTH (mt_pm_event, sm_pm_event_t);
347
SET_MSG_TYPE_LENGTH (mt_paint_event, sm_paint_event_t);
349
initialize_id_table (& psid_table);
350
initialize_id_table (& wid_table);
351
initialize_id_table (& bid_table);
352
original_frame_window_procedure = 0;
356
OS2_make_qid_pair ((&pm_init_qid), (&qid));
357
OS2_open_qid (qid, OS2_scheme_tqueue);
358
OS2_pm_tid = (OS2_beginthread (pm_thread_procedure, 0, 0x8000));
359
/* Wait for init message from PM thread. This message tells us
360
that the other end of the connection is established and that it
361
is safe to send messages on the connection. */
362
OS2_destroy_message (OS2_wait_for_message (qid, mt_init));
365
add_reload_cleanup (close_all_windows);
369
close_all_windows (void)
371
window_t ** scan = ((window_t **) (ID_TABLE_POINTERS (& wid_table)));
372
window_t ** end = (scan + (ID_TABLE_LENGTH (& wid_table)));
375
window_t * window = (*scan++);
376
if ((window != 0) && (!WINDOW_PERMANENTP (window)))
377
window_close (window);
381
/* Define this to cause a calling thread to wait for the PM thread to
382
finish requests that have trivial replies. Otherwise, the calling
383
thread waits only when the request has a non-trivial reply.
384
Usually there is no good reason to wait for trivial replies, but
385
this could be useful during debugging. */
386
/* #define SYNC_SIMPLE_TRANSACTIONS */
387
#ifdef SYNC_SIMPLE_TRANSACTIONS
389
#define simple_transaction sync_transaction
390
#define simple_reply sync_reply
394
#define simple_transaction OS2_send_message
395
#define simple_reply(qid)
400
sync_transaction (qid_t qid, msg_t * message)
403
(OS2_message_transaction (qid, message, mt_generic_reply));
407
sync_reply (qid_t qid)
409
OS2_send_message (qid, (OS2_create_message (mt_generic_reply)));
412
/* These macros simplify the code needed to perform message
413
transactions, by hiding the many type-casts needed. */
415
#define CREATE_MESSAGE(mt) \
416
((void *) (OS2_create_message (mt)))
418
#define CREATE_MESSAGE_1(mt, extra) \
419
((void *) (OS2_create_message_1 ((mt), (extra))))
421
#define DESTROY_MESSAGE(msg) \
422
OS2_destroy_message ((msg_t *) (msg))
424
#define SEND_MESSAGE(qid, msg) \
425
OS2_send_message ((qid), ((msg_t *) (msg)))
427
#define SIMPLE_TRANSACTION(qid, msg) \
428
simple_transaction ((qid), ((msg_t *) (msg)))
430
#define SYNC_TRANSACTION(qid, msg) \
431
sync_transaction ((qid), ((msg_t *) (msg)))
433
#define MESSAGE_TRANSACTION(qid, msg, mt) \
434
((void *) (OS2_message_transaction ((qid), ((msg_t *) (msg)), (mt))))
436
#define MEMCPY(to, from, length) \
437
FASTCOPY (((const char *) (from)), ((char *) (to)), (length))
439
#define STRCPY(to, from) \
440
strcpy (((char *) (to)), (from))
443
pm_thread_procedure (void * arg)
445
EXCEPTIONREGISTRATIONRECORD registration;
448
if ((OS2_thread_initialize_1 ((®istration), QID_NONE)) != 0)
449
OS2_logic_error ("Error signalled within PM thread.");
450
pm_hab = (WinInitialize (0));
451
if (pm_hab == NULLHANDLE)
452
window_error (WinInitialize);
453
pm_hmq = (WinCreateMsgQueue (pm_hab, 1000));
454
if (pm_hmq == NULLHANDLE)
455
window_error (WinCreateMsgQueue);
456
if (!WinRegisterClass (pm_hab,
457
((PSZ) object_class),
458
object_window_procedure,
461
window_error (WinRegisterClass);
462
if (!WinRegisterClass (pm_hab,
463
((PSZ) window_class),
467
window_error (WinRegisterClass);
469
= (WinCreateWindow (HWND_OBJECT,
470
((PSZ) object_class),
473
0, 0, 0, 0, /* size and position */
474
NULLHANDLE, /* owner */
477
0, /* control data */
478
0 /* presentation parameters */
480
if (pm_object_window == NULLHANDLE)
481
window_error (WinCreateWindow);
482
pm_tqueue = (make_pm_tqueue (pm_object_window));
483
OS2_send_message (pm_init_qid, (OS2_create_message (mt_init)));
484
while (WinGetMsg (pm_hab, (&qmsg), 0, 0, 0))
485
WinDispatchMsg (pm_hab, (&qmsg));
486
if (!WinDestroyWindow (pm_object_window))
487
window_error (WinDestroyWindow);
488
WinDestroyMsgQueue (pm_hmq);
489
WinTerminate (pm_hab);
490
/* There's no way to exit properly, because the normal exit depends
491
on the PM thread being active enough to print the closing
492
messages. So just use exit. */
497
make_pm_tqueue (HWND hwnd)
499
tqueue_t * tqueue = (OS_malloc (sizeof (pm_tqueue_t)));
500
(TQUEUE_TYPE (tqueue)) = tqt_pm;
501
(PM_TQUEUE_HWND (tqueue)) = hwnd;
506
OS2_read_pm_tqueue (tqueue_t * tqueue, int blockp)
508
OS2_logic_error ("Read from PM tqueue.");
513
OS2_write_pm_tqueue (tqueue_t * tqueue, msg_t * message)
515
if (!WinPostMsg ((PM_TQUEUE_HWND (tqueue)),
519
window_warning (WinPostMsg);
524
These tables maintain data structures in the PM thread, and
525
associate those structures with ID numbers that are given out to
526
other threads (and to Scheme programs). */
529
initialize_id_table (id_table_t * table)
531
unsigned int length = 16;
532
void ** pointers = (OS_malloc ((sizeof (void *)) * length));
533
void ** scan = pointers;
534
void ** end = (scan + length);
537
(ID_TABLE_LENGTH (table)) = length;
538
(ID_TABLE_POINTERS (table)) = pointers;
542
allocate_id (id_table_t * table, void * pointer)
544
unsigned int length = (ID_TABLE_LENGTH (table));
545
void ** pointers = (ID_TABLE_POINTERS (table));
546
void ** scan = (pointers + 1); /* don't allocate ID zero */
547
void ** end = (pointers + length);
552
return (scan - pointers);
555
unsigned int id = length;
557
pointers = (OS_realloc (pointers, ((sizeof (void *)) * length)));
558
scan = (pointers + id + 1);
559
end = (pointers + length);
562
(ID_TABLE_LENGTH (table)) = length;
563
(ID_TABLE_POINTERS (table)) = pointers;
564
(pointers[id]) = pointer;
570
deallocate_id (id_table_t * table, unsigned int id)
572
((ID_TABLE_POINTERS (table)) [id]) = 0;
576
id_to_pointer (id_table_t * table, unsigned int id)
578
void * pointer = ((ID_TABLE_POINTERS (table)) [id]);
580
OS2_logic_error ("Invalid PM ID.");
585
id_validp (id_table_t * table, unsigned int id)
588
&& (id < (ID_TABLE_LENGTH (table)))
589
&& (((ID_TABLE_POINTERS (table)) [id]) != 0));
593
psid_to_ps (psid_t psid)
595
return (id_to_pointer ((& psid_table), psid));
599
wid_to_window (wid_t wid)
601
return (id_to_pointer ((& wid_table), wid));
605
bid_to_bitmap (bid_t bid)
607
return (id_to_pointer ((& bid_table), bid));
610
/* Implementation of the object window. The object window handles
611
encapsulated messages sent from the Scheme thread. This defines
612
the protocol used to communicate with the Scheme thread. */
614
static MRESULT EXPENTRY
615
object_window_procedure (HWND window, ULONG msg, MPARAM mp1, MPARAM mp2)
617
if (msg == UWM_ENCAPSULATION)
619
msg_t * message = (PVOIDFROMMP (mp1));
620
switch (MSG_TYPE (message))
622
/* This machine-generated file contains dispatch cases for
623
most of the procedure messages. */
624
#include "os2pm-dc.h"
626
case mt_window_pos_request:
627
handle_window_pos_request (message);
629
case mt_window_size_request:
630
handle_window_size_request (message);
632
case mt_window_frame_size_request:
633
handle_window_frame_size_request (message);
635
case mt_ps_set_bitmap_request:
636
handle_ps_set_bitmap_request (message);
640
OS2_logic_error ("Unknown message type sent to PM thread.");
647
/* Implementation of the Frame Window */
649
static MRESULT EXPENTRY
650
frame_window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
652
window_t * window = (hwnd_to_window (WinWindowFromID (hwnd, FID_CLIENT)));
655
case WM_QUERYTRACKINFO:
656
/* Set the tracking grid for the resize operation. */
659
= ((* original_frame_window_procedure) (hwnd, msg, mp1, mp2));
662
PTRACKINFO pti = (PVOIDFROMMP (mp2));
663
if ((((pti -> fs) & TF_MOVE) != TF_MOVE)
664
&& ((((pti -> fs) & TF_MOVE) != 0)
665
|| (((pti -> fs) & TF_SETPOINTERPOS) != 0)))
667
(pti -> fs) |= TF_GRID;
668
(pti -> cxGrid) = (WINDOW_GRID_X (window));
669
(pti -> cyGrid) = (WINDOW_GRID_Y (window));
670
(pti -> cxKeyboard) = (WINDOW_GRID_X (window));
671
(pti -> cyKeyboard) = (WINDOW_GRID_Y (window));
677
/* If minimizing, mark the window to indicate this. The client
678
will shortly receive a WM_SIZE which indicates that the
679
minimization has completed. */
681
PSWP pswp = (PVOIDFROMMP (mp1));
682
if ((!WINDOW_MINIMIZEDP (window))
683
&& (((pswp -> fl) & SWP_MINIMIZE) != 0))
685
(WINDOW_MINIMIZINGP (window)) = 1;
686
(WINDOW_MINIMIZEDP (window)) = 1;
688
else if ((WINDOW_MINIMIZEDP (window))
689
&& (((pswp -> fl) & (SWP_RESTORE | SWP_MAXIMIZE)) != 0))
690
(WINDOW_MINIMIZEDP (window)) = 0;
694
return ((* original_frame_window_procedure) (hwnd, msg, mp1, mp2));
697
/* Implementation of the Client Window */
699
static MRESULT EXPENTRY
700
window_procedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
706
window_t * window = (PVOIDFROMMP (mp1));
707
if (!WinSetWindowPtr (hwnd, QWP_WINDOW, window))
708
window_error (WinSetWindowPtr);
709
(WINDOW_CLIENT (window)) = hwnd;
710
(WINDOW_CLIENT_PS (window))
711
= (create_ps (pst_window,
712
(WinOpenWindowDC (hwnd)),
713
(WINDOW_QID (window))));
714
(PS_VISUAL (WINDOW_CLIENT_PS (window))) = window;
719
window_t * window = (hwnd_to_window (hwnd));
720
if (((WinQueryWindowULong ((WINDOW_FRAME (window)), QWL_STYLE))
725
HPS hps = (PS_HANDLE (WINDOW_CLIENT_PS (window)));
727
if ((WinBeginPaint ((WINDOW_CLIENT (window)), hps, (& rectl)))
729
window_error (WinBeginPaint);
730
if (!WinEndPaint (hps))
731
window_error (WinEndPaint);
733
(make_paint_event ((WINDOW_ID (window)),
743
window_t * window = (hwnd_to_window (hwnd));
744
if (SHORT1FROMMP (mp2))
745
recreate_cursor (window);
748
win_destroy_cursor (WINDOW_CLIENT (window));
749
(WINDOW_CURSOR_CREATEDP (window)) = 0;
752
SEND_PM_EVENT (hwnd, msg, mp1, mp2);
754
case WM_TRANSLATEACCEL:
756
PQMSG qmsg = (PVOIDFROMMP (mp1));
757
USHORT flags = (SHORT1FROMMP (qmsg -> mp1));
758
USHORT char_code = (SHORT1FROMMP (qmsg -> mp2));
759
USHORT virtual_key = (SHORT2FROMMP (qmsg -> mp2));
760
/* Disable specific default accelerator keys. */
761
if ((flags & KC_VIRTUALKEY) != 0)
766
/* Disable "Alt" keys, which normally pop up the system
767
menu. These keys are used often in Edwin and the
768
default behavior is unacceptable. */
773
/* Disable "Alt-SPC", "Alt-ESC", and "Alt-TAB", which
774
have standard key bindings in Edwin. */
775
if ((flags & KC_ALT) != 0)
778
else if ((flags & KC_CHAR) != 0)
784
/* Disable "Alt-SPC", "Alt-ESC", and "Alt-TAB", if for
785
some reason they are reported as ASCII characters
786
rather than as virtual keys. */
787
if ((flags & KC_ALT) != 0)
794
window_t * window = (hwnd_to_window (hwnd));
795
destroy_ps (WINDOW_CLIENT_PS (window));
796
(WINDOW_CLIENT_PS (window)) = 0;
801
window_t * window = (hwnd_to_window (hwnd));
802
/* If this message is part of a minimization, ignore it. */
803
if (WINDOW_MINIMIZINGP (window))
805
(WINDOW_MINIMIZINGP (window)) = 0;
806
(WINDOW_MINIMIZEDP (window)) = 1;
809
if (WINDOW_CURSOR_CREATEDP (window))
811
win_destroy_cursor (WINDOW_CLIENT (window));
812
(WINDOW_CURSOR_CREATEDP (window)) = 0;
813
(WINDOW_CURSOR_X (window)) = 0;
814
(WINDOW_CURSOR_Y (window)) = 0;
815
recreate_cursor (window);
818
SEND_PM_EVENT (hwnd, msg, mp1, mp2);
825
SEND_PM_EVENT (hwnd, msg, mp1, mp2);
830
case WM_BUTTON1CLICK:
831
case WM_BUTTON1DBLCLK:
834
case WM_BUTTON2CLICK:
835
case WM_BUTTON2DBLCLK:
838
case WM_BUTTON3CLICK:
839
case WM_BUTTON3DBLCLK:
840
SEND_PM_EVENT (hwnd, msg, mp1, mp2);
843
if (WINDOW_MOUSETRACKP (hwnd_to_window (hwnd)))
845
SEND_PM_EVENT (hwnd, msg, mp1, mp2);
852
return (WinDefWindowProc (hwnd, msg, mp1, mp2));
856
hwnd_to_window (HWND hwnd)
858
window_t * window = (WinQueryWindowPtr (hwnd, QWP_WINDOW));
860
window_error (WinQueryWindowPtr);
865
make_pm_event (wid_t wid, ULONG msg, MPARAM mp1, MPARAM mp2)
867
msg_t * message = (OS2_create_message (mt_pm_event));
868
(SM_PM_EVENT_WID (message)) = wid;
869
(SM_PM_EVENT_MSG (message)) = msg;
870
(SM_PM_EVENT_MP1 (message)) = mp1;
871
(SM_PM_EVENT_MP2 (message)) = mp2;
876
make_paint_event (wid_t wid,
877
unsigned short xl, unsigned short xh,
878
unsigned short yl, unsigned short yh)
880
msg_t * message = (OS2_create_message (mt_paint_event));
881
(SM_PAINT_EVENT_WID (message)) = wid;
882
(SM_PAINT_EVENT_XL (message)) = xl;
883
(SM_PAINT_EVENT_XH (message)) = xh;
884
(SM_PAINT_EVENT_YL (message)) = yl;
885
(SM_PAINT_EVENT_YH (message)) = yh;
890
OS2_translate_wm_char (MPARAM mp1, MPARAM mp2,
891
unsigned short * code,
892
unsigned short * flags,
893
unsigned char * repeat)
895
(*flags) = (SHORT1FROMMP (mp1));
896
(*repeat) = (CHAR3FROMMP (mp1));
897
/* Ignore compound keys for now. */
898
if (((*flags) & (KC_DEADKEY | KC_COMPOSITE | KC_INVALIDCOMP | KC_KEYUP))
901
if (((*flags) & KC_VIRTUALKEY) != 0)
903
(*code) = (SHORT2FROMMP (mp2));
906
if (((*flags) & (KC_CHAR | KC_CTRL | KC_ALT)) != 0)
908
(*code) = (SHORT1FROMMP (mp2));
916
These are exported operations that can be implemented directly in
917
the calling thread. Other operations that require communication
918
with the PM thread appear on following pages. */
921
OS2_psid_validp (psid_t psid)
923
return (id_validp ((& psid_table), psid));
927
OS2_wid_validp (wid_t wid)
929
return (id_validp ((& wid_table), wid));
933
OS2_bid_validp (bid_t bid)
935
return (id_validp ((& bid_table), bid));
939
OS2_window_client_ps (wid_t wid)
941
return (PS_ID (WINDOW_CLIENT_PS (wid_to_window (wid))));
945
OS2_create_pm_qid (tqueue_t * tqueue)
949
OS2_make_qid_pair ((&pm_side), (&client_side));
950
OS2_open_qid (pm_side, pm_tqueue);
951
OS2_open_qid (client_side, tqueue);
952
return (client_side);
956
OS2_window_permanent (wid_t wid)
958
(WINDOW_PERMANENTP (wid_to_window (wid))) = 1;
962
OS2_window_mousetrack (wid_t wid, int trackp)
964
(WINDOW_MOUSETRACKP (wid_to_window (wid))) = trackp;
968
OS2_window_frame_handle (wid_t wid)
970
return (WINDOW_FRAME (wid_to_window (wid)));
974
OS2_window_client_handle (wid_t wid)
976
return (WINDOW_CLIENT (wid_to_window (wid)));
980
OS2_memory_ps_p (psid_t psid)
982
return ((PS_VISUAL_TYPE (psid_to_ps (psid))) == pst_memory);
986
OS2_ps_get_bitmap (psid_t psid)
988
bitmap_t * bitmap = (PS_VISUAL (psid_to_ps (psid)));
989
return ((bitmap == 0) ? BID_NONE : (BITMAP_ID (bitmap)));
992
/* Relayed Operations
994
This page implements exported operations that require communication
995
with the PM thread. The PM-thread-side of these operations appear
996
on the following pages; this page implements only the mechanism to
997
communicate the operation to the PM thread. The bulk of these
998
communication procedures is machine-generated. */
1000
/* This macro supplies a NO-OP procedure needed by the
1001
machine-generated code for OS2_pm_synchronize. */
1002
#define pm_synchronize(qid)
1004
/* This machine-generated file contains most of the external procedure
1005
definitions, and their associated handler procedures. */
1006
#include "os2pm-rp.h"
1009
OS2_window_pos (wid_t wid, short * x, short * y)
1011
window_t * window = (wid_to_window (wid));
1012
msg_t * message = (OS2_create_message (mt_window_pos_request));
1013
(SM_POS_REQUEST_WINDOW (message)) = window;
1015
= (OS2_message_transaction ((WINDOW_QID (window)),
1017
mt_window_pos_reply));
1018
(* x) = (SM_POS_REPLY_X (message));
1019
(* y) = (SM_POS_REPLY_Y (message));
1020
OS2_destroy_message (message);
1024
handle_window_pos_request (msg_t * request)
1026
qid_t sender = (MSG_SENDER (request));
1027
msg_t * reply = (OS2_create_message (mt_window_pos_reply));
1028
window_pos ((SM_POS_REQUEST_WINDOW (request)),
1029
(& (SM_POS_REPLY_X (reply))),
1030
(& (SM_POS_REPLY_Y (reply))));
1031
OS2_destroy_message (request);
1032
OS2_send_message (sender, reply);
1036
OS2_window_size (wid_t wid, unsigned short * width, unsigned short * height)
1038
window_t * window = (wid_to_window (wid));
1039
msg_t * message = (OS2_create_message (mt_window_size_request));
1040
(SM_SIZE_REQUEST_WINDOW (message)) = window;
1042
= (OS2_message_transaction ((WINDOW_QID (window)),
1044
mt_window_size_reply));
1045
(* width) = (SM_SIZE_REPLY_WIDTH (message));
1046
(* height) = (SM_SIZE_REPLY_HEIGHT (message));
1047
OS2_destroy_message (message);
1051
handle_window_size_request (msg_t * request)
1053
qid_t sender = (MSG_SENDER (request));
1054
msg_t * reply = (OS2_create_message (mt_window_size_reply));
1055
window_size ((SM_SIZE_REQUEST_WINDOW (request)),
1056
(& (SM_SIZE_REPLY_WIDTH (reply))),
1057
(& (SM_SIZE_REPLY_HEIGHT (reply))));
1058
OS2_destroy_message (request);
1059
OS2_send_message (sender, reply);
1063
OS2_window_frame_size (wid_t wid,
1064
unsigned short * width, unsigned short * height)
1066
window_t * window = (wid_to_window (wid));
1067
msg_t * message = (OS2_create_message (mt_window_frame_size_request));
1068
(SM_FRAME_SIZE_REQUEST_WINDOW (message)) = window;
1070
= (OS2_message_transaction ((WINDOW_QID (window)),
1072
mt_window_frame_size_reply));
1073
(* width) = (SM_FRAME_SIZE_REPLY_WIDTH (message));
1074
(* height) = (SM_FRAME_SIZE_REPLY_HEIGHT (message));
1075
OS2_destroy_message (message);
1079
handle_window_frame_size_request (msg_t * request)
1081
qid_t sender = (MSG_SENDER (request));
1082
msg_t * reply = (OS2_create_message (mt_window_frame_size_reply));
1083
window_frame_size ((SM_FRAME_SIZE_REQUEST_WINDOW (request)),
1084
(& (SM_FRAME_SIZE_REPLY_WIDTH (reply))),
1085
(& (SM_FRAME_SIZE_REPLY_HEIGHT (reply))));
1086
OS2_destroy_message (request);
1087
OS2_send_message (sender, reply);
1091
OS2_ps_set_bitmap (psid_t psid, bid_t bid)
1093
ps_t * ps = (psid_to_ps (psid));
1094
bitmap_t * bitmap = ((bid == BID_NONE) ? 0 : (bid_to_bitmap (bid)));
1095
msg_t * message = (OS2_create_message (mt_ps_set_bitmap_request));
1096
(SM_PS_SET_BITMAP_REQUEST_PS (message)) = ps;
1097
(SM_PS_SET_BITMAP_REQUEST_BITMAP (message)) = bitmap;
1099
= (OS2_message_transaction ((PS_QID (ps)),
1101
mt_ps_set_bitmap_reply));
1102
bitmap = (SM_PS_SET_BITMAP_REPLY_BITMAP (message));
1103
OS2_destroy_message (message);
1104
return ((bitmap == 0) ? BID_NONE : (BITMAP_ID (bitmap)));
1108
handle_ps_set_bitmap_request (msg_t * request)
1110
qid_t sender = (MSG_SENDER (request));
1111
msg_t * reply = (OS2_create_message (mt_ps_set_bitmap_reply));
1112
(SM_PS_SET_BITMAP_REPLY_BITMAP (reply))
1113
= (ps_set_bitmap ((SM_PS_SET_BITMAP_REQUEST_PS (request)),
1114
(SM_PS_SET_BITMAP_REQUEST_BITMAP (request))));
1115
OS2_destroy_message (request);
1116
OS2_send_message (sender, reply);
1120
OS2_ps_set_font (psid_t psid, unsigned short id, const char * name)
1122
font_metrics_t * metrics = (OS2_ps_set_font_internal (psid, id, name));
1123
if ((metrics != 0) && (psid == (OS2_console_psid ())))
1124
OS2_console_font_change_hook (metrics);
1128
/* PM-thread Operation Implementations
1130
All of the procedures from this point on are implementations of
1131
exported operations. These implementations are the code that is
1132
run in the PM thread to implement the operations that are invoked
1133
in other threads. */
1138
window_open (qid_t qid, qid_t event_qid, ULONG flags, HMODULE module, ULONG id,
1139
ULONG style, const char * title)
1141
window_t * window = (make_window (qid, event_qid));
1142
FRAMECDATA frame_data;
1145
(frame_data . cb) = (sizeof (frame_data));
1146
(frame_data . flCreateFlags) = flags;
1147
(frame_data . hmodResources) = module;
1148
(frame_data . idResources) = id;
1150
= (WinCreateWindow (HWND_DESKTOP,
1152
((PSZ) title), /* title string */
1153
0, /* window style */
1154
0, 0, 0, 0, /* size and position */
1155
NULLHANDLE, /* owner window */
1157
ID_FRAME, /* window ID */
1160
if (frame_window == NULLHANDLE)
1161
window_error (WinCreateWindow);
1162
(WINDOW_FRAME (window)) = frame_window;
1165
= (WinSubclassWindow (frame_window, frame_window_procedure));
1167
window_error (WinSubclassWindow);
1168
if (original_frame_window_procedure == 0)
1169
original_frame_window_procedure = procedure;
1170
else if (original_frame_window_procedure != procedure)
1171
OS2_logic_error ("WinSubclassWindow returned two different answers.");
1173
if ((WinCreateWindow (frame_window,
1174
((PSZ) window_class),
1175
0, /* window text (class-specific) */
1176
style, /* window style */
1177
0, 0, 0, 0, /* size and position */
1178
frame_window, /* owner window */
1180
FID_CLIENT, /* window ID */
1184
window_error (WinCreateWindow);
1185
return (WINDOW_ID (window));
1189
make_window (qid_t qid, qid_t event_qid)
1191
window_t * window = (OS_malloc (sizeof (window_t)));
1192
(WINDOW_FRAME (window)) = NULLHANDLE;
1193
(WINDOW_CLIENT (window)) = NULLHANDLE;
1194
(WINDOW_CLIENT_PS (window)) = 0;
1195
(WINDOW_GRID_X (window)) = 1;
1196
(WINDOW_GRID_Y (window)) = 1;
1197
(WINDOW_CURSOR_X (window)) = 0;
1198
(WINDOW_CURSOR_Y (window)) = 0;
1199
(WINDOW_CURSOR_WIDTH (window)) = 0;
1200
(WINDOW_CURSOR_HEIGHT (window)) = 0;
1201
(WINDOW_CURSOR_STYLE (window)) = (CURSOR_SOLID | CURSOR_FLASH);
1202
(WINDOW_QID (window)) = qid;
1203
(WINDOW_EVENT_QID (window)) = event_qid;
1204
(WINDOW_ID (window)) = (allocate_id ((& wid_table), window));
1205
(WINDOW_CURSOR_CREATEDP (window)) = 0;
1206
(WINDOW_CURSOR_ENABLEDP (window)) = 0;
1207
(WINDOW_MINIMIZINGP (window)) = 0;
1208
(WINDOW_MINIMIZEDP (window)) = 0;
1209
(WINDOW_PERMANENTP (window)) = 0;
1210
(WINDOW_MOUSETRACKP (window)) = 0;
1215
window_close (window_t * window)
1217
if (!WinDestroyWindow (WINDOW_FRAME (window)))
1218
window_warning (WinDestroyWindow);
1219
deallocate_id ((& wid_table), (WINDOW_ID (window)));
1224
window_show (window_t * window, int showp)
1226
if (!WinShowWindow ((WINDOW_FRAME (window)), showp))
1227
window_warning (WinShowWindow);
1231
window_scroll (window_t * window, short xl, short xh, short yl, short yh,
1232
short x_delta, short y_delta)
1235
(rectl . xLeft) = xl;
1236
(rectl . xRight) = xh;
1237
(rectl . yBottom) = yl;
1238
(rectl . yTop) = yh;
1239
deactivate_cursor (window);
1240
if ((WinScrollWindow ((WINDOW_CLIENT (window)), x_delta, y_delta, (& rectl),
1241
0, NULLHANDLE, 0, 0))
1243
window_warning (WinScrollWindow);
1244
activate_cursor (window);
1248
window_invalidate (window_t * window, short xl, short xh, short yl, short yh)
1251
(rectl . xLeft) = xl;
1252
(rectl . xRight) = xh;
1253
(rectl . yBottom) = yl;
1254
(rectl . yTop) = yh;
1255
if (!WinInvalidateRect ((WINDOW_CLIENT (window)), (& rectl), FALSE))
1256
window_warning (WinInvalidateRect);
1260
window_set_grid (window_t * window, unsigned short x, unsigned short y)
1262
(WINDOW_GRID_X (window)) = x;
1263
(WINDOW_GRID_Y (window)) = y;
1267
window_activate (window_t * window)
1269
if (!WinSetActiveWindow (HWND_DESKTOP, (WINDOW_FRAME (window))))
1270
window_warning (WinSetActiveWindow);
1274
window_pos (window_t * window, short * x, short * y)
1277
if (!WinQueryWindowPos ((WINDOW_FRAME (window)), (& swp)))
1278
window_error (WinQueryWindowPos);
1284
window_set_pos (window_t * window, short x, short y)
1286
if (!WinSetWindowPos ((WINDOW_FRAME (window)), NULLHANDLE, x, y,
1288
window_warning (WinSetWindowPos);
1292
window_size (window_t * window,
1293
unsigned short * width, unsigned short * height)
1296
if (!WinQueryWindowPos ((WINDOW_CLIENT (window)), (& swp)))
1297
window_error (WinQueryWindowPos);
1298
(* width) = (swp . cx);
1299
(* height) = (swp . cy);
1303
window_frame_size (window_t * window,
1304
unsigned short * width, unsigned short * height)
1307
if (!WinQueryWindowPos ((WINDOW_FRAME (window)), (& swp)))
1308
window_error (WinQueryWindowPos);
1309
(* width) = (swp . cx);
1310
(* height) = (swp . cy);
1314
window_set_size (window_t * window,
1315
unsigned short width, unsigned short height)
1319
(rcl . xRight) = width;
1320
(rcl . yBottom) = 0;
1321
(rcl . yTop) = height;
1322
if (!WinMapWindowPoints ((WINDOW_CLIENT (window)), HWND_DESKTOP,
1323
((PPOINTL) (& rcl)), 2))
1324
window_error (WinMapWindowPoints);
1325
if (!WinCalcFrameRect ((WINDOW_FRAME (window)), (& rcl), FALSE))
1326
window_error (WinCalcFrameRect);
1327
if (!WinSetWindowPos ((WINDOW_FRAME (window)),
1329
((rcl . xRight) - (rcl . xLeft)),
1330
((rcl . yTop) - (rcl . yBottom)),
1332
window_warning (WinSetWindowPos);
1336
window_focusp (window_t * window)
1338
return ((WINDOW_CLIENT (window)) == (WinQueryFocus (HWND_DESKTOP)));
1342
window_set_state (window_t * window, window_state_t state)
1345
HWND behind = NULLHANDLE;
1354
behind = HWND_BOTTOM;
1362
case state_activate:
1365
case state_deactivate:
1366
op = SWP_DEACTIVATE;
1368
case state_minimize:
1371
case state_maximize:
1378
if (!WinSetWindowPos ((WINDOW_FRAME (window)), behind, 0, 0, 0, 0, op))
1379
window_warning (WinSetWindowPos);
1383
window_set_title (window_t * window, const char * title)
1385
if (!WinSetWindowText ((WINDOW_FRAME (window)), ((PSZ) title)))
1386
window_warning (WinSetWindowText);
1390
window_update_frame (window_t * window, USHORT flags)
1392
(void) WinSendMsg ((WINDOW_FRAME (window)), WM_UPDATEFRAME,
1393
(MPFROMSHORT (flags)),
1398
window_handle_from_id (qid_t qid, HWND window, ULONG id)
1400
return (WinWindowFromID (window, id));
1404
window_set_capture (window_t * window, int capturep)
1408
if (capture_window == 0)
1410
BOOL rc = (WinSetCapture (HWND_DESKTOP, (WINDOW_CLIENT (window))));
1412
capture_window = window;
1416
return (capture_window == window);
1421
return (WinSetCapture (HWND_DESKTOP, NULLHANDLE));
1426
window_query_sys_value (qid_t qid, HWND window, LONG id)
1428
LONG value = (WinQuerySysValue (window, id));
1430
window_error (WinQuerySysValue);
1437
window_move_cursor (window_t * window, short x, short y)
1439
(WINDOW_CURSOR_X (window)) = x;
1440
(WINDOW_CURSOR_Y (window)) = y;
1441
if (WINDOW_CURSOR_CREATEDP (window))
1442
win_create_cursor ((WINDOW_CLIENT (window)), x, y, 0, 0, CURSOR_SETPOS, 0);
1446
window_shape_cursor (window_t * window, unsigned short width,
1447
unsigned short height, unsigned short style)
1449
(WINDOW_CURSOR_WIDTH (window)) = width;
1450
(WINDOW_CURSOR_HEIGHT (window)) = height;
1451
(WINDOW_CURSOR_STYLE (window)) = style;
1452
if (WINDOW_CURSOR_CREATEDP (window))
1453
recreate_cursor (window);
1457
window_show_cursor (window_t * window, int showp)
1459
if ((WINDOW_CURSOR_CREATEDP (window))
1460
&& ((showp != 0) != (WINDOW_CURSOR_ENABLEDP (window))))
1461
win_show_cursor ((WINDOW_CLIENT (window)), showp);
1462
(WINDOW_CURSOR_ENABLEDP (window)) = (showp != 0);
1465
/* Helper Procedures */
1468
win_create_cursor (HWND client, LONG x, LONG y, LONG cx, LONG cy, ULONG fs,
1471
if (!WinCreateCursor (client, x, y, cx, cy, fs, clip_rectl))
1472
window_warning (WinCreateCursor);
1476
win_destroy_cursor (HWND client)
1478
if (!WinDestroyCursor (client))
1479
window_warning (WinDestroyCursor);
1483
win_show_cursor (HWND client, BOOL showp)
1485
if (!WinShowCursor (client, showp))
1486
window_warning (WinShowCursor);
1490
recreate_cursor (window_t * window)
1492
win_create_cursor ((WINDOW_CLIENT (window)),
1493
(WINDOW_CURSOR_X (window)),
1494
(WINDOW_CURSOR_Y (window)),
1495
(WINDOW_CURSOR_WIDTH (window)),
1496
(WINDOW_CURSOR_HEIGHT (window)),
1497
(WINDOW_CURSOR_STYLE (window)),
1499
(WINDOW_CURSOR_CREATEDP (window)) = 1;
1500
if (WINDOW_CURSOR_ENABLEDP (window))
1501
win_show_cursor ((WINDOW_CLIENT (window)), TRUE);
1505
activate_cursor (window_t * window)
1507
if ((WINDOW_CURSOR_CREATEDP (window)) && (WINDOW_CURSOR_ENABLEDP (window)))
1508
win_show_cursor ((WINDOW_CLIENT (window)), TRUE);
1512
deactivate_cursor (window_t * window)
1514
if ((WINDOW_CURSOR_CREATEDP (window)) && (WINDOW_CURSOR_ENABLEDP (window)))
1515
win_show_cursor ((WINDOW_CLIENT (window)), FALSE);
1519
maybe_activate_cursor (ps_t * ps)
1521
if ((PS_VISUAL_TYPE (ps)) == pst_window)
1522
activate_cursor (PS_VISUAL (ps));
1526
maybe_deactivate_cursor (ps_t * ps)
1528
if ((PS_VISUAL_TYPE (ps)) == pst_window)
1529
deactivate_cursor (PS_VISUAL (ps));
1532
/* Presentation Spaces */
1535
create_memory_ps (qid_t qid)
1537
HDC hdc = (DevOpenDC (pm_hab, OD_MEMORY, "*", 0, 0, NULLHANDLE));
1538
if (hdc == DEV_ERROR)
1539
window_error (DevOpenDC);
1540
return (create_ps (pst_memory, hdc, qid));
1544
destroy_memory_ps (ps_t * ps)
1546
HDC hdc = (get_ps_device (PS_HANDLE (ps)));
1547
bitmap_t * bitmap = (PS_VISUAL (ps));
1549
if ((hdc != NULLHANDLE) && ((DevCloseDC (hdc)) == DEV_ERROR))
1550
window_warning (DevCloseDC);
1552
destroy_bitmap (bitmap);
1556
create_bitmap (ps_t * ps, USHORT width, USHORT height)
1558
HPS hps = (PS_HANDLE (ps));
1559
HDC hdc = (get_ps_device (hps));
1560
BITMAPINFOHEADER2 header;
1564
memset ((& header), 0, (sizeof (header)));
1565
(header . cbFix) = (sizeof (header));
1566
(header . cx) = width;
1567
(header . cy) = height;
1568
(header . cPlanes) = (get_device_capability (hdc, CAPS_COLOR_PLANES));
1569
(header . cBitCount) = (get_device_capability (hdc, CAPS_COLOR_BITCOUNT));
1570
hbm = (GpiCreateBitmap (hps, (& header), 0, 0, 0));
1571
if (hbm == GPI_ERROR)
1572
window_error (GpiCreateBitmap);
1573
bitmap = (OS_malloc (sizeof (bitmap_t)));
1574
(BITMAP_ID (bitmap)) = (allocate_id ((& bid_table), bitmap));
1575
(BITMAP_QID (bitmap)) = (PS_QID (ps));
1576
(BITMAP_HANDLE (bitmap)) = hbm;
1581
destroy_bitmap (bitmap_t * bitmap)
1583
if (!GpiDeleteBitmap (BITMAP_HANDLE (bitmap)))
1584
window_warning (GpiDeleteBitmap);
1585
deallocate_id ((& bid_table), (BITMAP_ID (bitmap)));
1590
ps_set_bitmap (ps_t * ps, bitmap_t * bitmap)
1592
bitmap_t * previous_bitmap = (PS_VISUAL (ps));
1593
if ((GpiSetBitmap ((PS_HANDLE (ps)),
1594
((bitmap == 0) ? 0 : (BITMAP_HANDLE (bitmap)))))
1596
window_error (GpiSetBitmap);
1597
(PS_VISUAL (ps)) = bitmap;
1598
return (previous_bitmap);
1602
ps_bitblt (ps_t * target, ps_t * source, LONG npoints, PPOINTL points,
1603
LONG rop, ULONG options)
1605
maybe_deactivate_cursor (target);
1606
if ((GpiBitBlt ((PS_HANDLE (target)), (PS_HANDLE (source)), npoints, points,
1609
window_warning (GpiBitBlt);
1610
maybe_activate_cursor (target);
1614
ps_draw_text (ps_t * ps, short x, short y,
1615
const char * data, unsigned short size)
1617
HPS hps = (PS_HANDLE (ps));
1618
PLONG increments = (PS_CHAR_INCREMENTS (ps));
1622
maybe_deactivate_cursor (ps);
1625
if (increments == 0)
1626
GpiCharStringAt (hps, (& ptl), size, ((char *) data));
1628
GpiCharStringPosAt (hps, (& ptl), 0, CHS_VECTOR, size, ((char *) data),
1633
const char * scan = data;
1634
GpiMove (hps, (& ptl));
1637
unsigned short n = ((size > 512) ? 512 : size);
1638
if (increments == 0)
1639
GpiCharString (hps, n, ((char *) scan));
1641
GpiCharStringPos (hps, 0, CHS_VECTOR, n, ((char *) scan),
1647
maybe_activate_cursor (ps);
1650
static unsigned short
1651
ps_text_width (ps_t * ps, const char * data, unsigned short size)
1653
if ((PS_CHAR_INCREMENTS (ps)) == 0)
1655
POINTL points [TXTBOX_COUNT];
1656
if (!GpiQueryTextBox ((PS_HANDLE (ps)), size, ((char *) data),
1657
TXTBOX_COUNT, points))
1658
window_error (GpiQueryTextBox);
1659
return ((points [TXTBOX_CONCAT]) . x);
1662
return (size * ((PS_CHAR_INCREMENTS (ps)) [0]));
1666
ps_clear (ps_t * ps, short xl, short xh, short yl, short yh)
1669
(rectl . xLeft) = xl;
1670
(rectl . xRight) = xh;
1671
(rectl . yBottom) = yl;
1672
(rectl . yTop) = yh;
1673
maybe_deactivate_cursor (ps);
1674
if (!WinFillRect ((PS_HANDLE (ps)), (&rectl), (PS_BACKGROUND_COLOR (ps))))
1675
window_warning (WinFillRect);
1676
maybe_activate_cursor (ps);
1680
ps_get_foreground_color (ps_t * ps)
1682
return (PS_FOREGROUND_COLOR (ps));
1686
ps_get_background_color (ps_t * ps)
1688
return (PS_BACKGROUND_COLOR (ps));
1692
ps_set_colors (ps_t * ps, COLOR foreground, COLOR background)
1694
if (!GpiSetColor ((PS_HANDLE (ps)), foreground))
1695
window_warning (GpiSetColor);
1696
if (!GpiSetMix ((PS_HANDLE (ps)), FM_OVERPAINT))
1697
window_warning (GpiSetMix);
1698
if (!GpiSetBackColor ((PS_HANDLE (ps)), background))
1699
window_warning (GpiSetBackColor);
1700
if (!GpiSetBackMix ((PS_HANDLE (ps)), BM_OVERPAINT))
1701
window_warning (GpiSetBackMix);
1702
(PS_FOREGROUND_COLOR (ps)) = foreground;
1703
(PS_BACKGROUND_COLOR (ps)) = background;
1707
ps_move_gcursor (ps_t * ps, short x, short y)
1712
if (!GpiMove ((PS_HANDLE (ps)), (& ptl)))
1713
window_warning (GpiMove);
1717
ps_draw_line (ps_t * ps, short x, short y)
1722
if ((GpiLine ((PS_HANDLE (ps)), (& ptl))) == GPI_ERROR)
1723
window_warning (GpiLine);
1727
ps_draw_point (ps_t * ps, short x, short y)
1732
if ((GpiSetPel ((PS_HANDLE (ps)), (& ptl))) == GPI_ERROR)
1733
window_warning (GpiSetPel);
1737
ps_poly_line (ps_t * ps, unsigned long npoints, PPOINTL points)
1739
if ((GpiPolyLine ((PS_HANDLE (ps)), npoints, points)) == GPI_ERROR)
1740
window_warning (GpiPolyLine);
1744
ps_poly_line_disjoint (ps_t * ps, unsigned long npoints, PPOINTL points)
1746
if ((GpiPolyLineDisjoint ((PS_HANDLE (ps)), npoints, points))
1748
window_warning (GpiPolyLineDisjoint);
1752
ps_set_line_type (ps_t * ps, LONG type)
1754
if (!GpiSetLineType ((PS_HANDLE (ps)), type))
1755
window_warning (GpiSetLineType);
1759
ps_set_mix (ps_t * ps, LONG mix)
1761
if (!GpiSetMix ((PS_HANDLE (ps)), mix))
1762
window_warning (GpiSetMix);
1766
ps_query_caps (ps_t * ps, LONG start, LONG count, PLONG values)
1768
HDC hdc = (get_ps_device (PS_HANDLE (ps)));
1769
if (hdc == NULLHANDLE)
1770
window_error (GpiQueryDevice);
1771
if (!DevQueryCaps (hdc, start, count, values))
1772
window_error (DevQueryCaps);
1776
ps_reset_clip_rectangle (ps_t * ps)
1778
if (!GpiSetClipPath ((PS_HANDLE (ps)), 0, SCP_RESET))
1779
window_error (GpiSetClipPath);
1783
ps_set_clip_rectangle (ps_t * ps, short xl, short xh, short yl, short yh)
1785
HPS hps = (PS_HANDLE (ps));
1786
ps_reset_clip_rectangle (ps);
1787
if (!GpiBeginPath (hps, 1))
1788
window_error (GpiBeginPath);
1791
((points[0]) . x) = xl;
1792
((points[0]) . y) = yl;
1793
((points[1]) . x) = xl;
1794
((points[1]) . y) = yh;
1795
((points[2]) . x) = xh;
1796
((points[2]) . y) = yh;
1797
((points[3]) . x) = xh;
1798
((points[3]) . y) = yl;
1799
if (!GpiMove (hps, (&points[3])))
1800
window_warning (GpiMove);
1801
if ((GpiPolyLine (hps, 4, points)) == GPI_ERROR)
1802
window_warning (GpiPolyLine);
1804
if (!GpiEndPath (hps))
1805
window_error (GpiEndPath);
1806
if (!GpiSetClipPath (hps, 1, (SCP_AND | SCP_INCL)))
1807
window_error (GpiSetClipPath);
1811
get_bitmap_parameters (bitmap_t * bitmap, PBITMAPINFOHEADER params)
1813
if (!GpiQueryBitmapParameters ((BITMAP_HANDLE (bitmap)), params))
1814
window_error (GpiQueryBitmapParameters);
1817
static unsigned long
1818
ps_get_bitmap_bits (ps_t * ps, unsigned long start, unsigned long length,
1819
PBYTE data, PBITMAPINFO2 info)
1821
LONG r = (GpiQueryBitmapBits ((PS_HANDLE (ps)), start, length, data, info));
1823
window_error (GpiQueryBitmapBits);
1827
static unsigned long
1828
ps_set_bitmap_bits (ps_t * ps, unsigned long start, unsigned long length,
1829
PBYTE data, PBITMAPINFO2 info)
1831
LONG r = (GpiSetBitmapBits ((PS_HANDLE (ps)), start, length, data, info));
1833
window_error (GpiSetBitmapBits);
1837
/* Helper Procedures */
1840
get_ps_device (HPS hps)
1842
HDC hdc = (GpiQueryDevice (hps));
1843
if (hdc == HDC_ERROR)
1844
window_error (GpiQueryDevice);
1849
get_device_capability (HDC hdc, LONG index)
1852
if (!DevQueryCaps (hdc, index, 1, (& result)))
1853
window_error (DevQueryCaps);
1858
create_ps (pst_t type, HDC hdc, qid_t qid)
1860
ps_t * ps = (OS_malloc (sizeof (ps_t)));
1865
hps = (GpiCreatePS (pm_hab, hdc, (& sizel),
1866
(PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)));
1868
window_error (GpiCreatePS);
1869
/* Put color table in RGB mode so we can specify colors
1870
directly in RGB values rather than as indices. */
1871
if (!GpiCreateLogColorTable (hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, 0))
1872
window_warning (GpiCreateLogColorTable);
1873
(PS_HANDLE (ps)) = hps;
1874
(PS_ID (ps)) = (allocate_id ((& psid_table), ps));
1875
(PS_QID (ps)) = qid;
1876
(PS_VISUAL_TYPE (ps)) = type;
1877
(PS_VISUAL (ps)) = 0;
1878
(PS_CHAR_INCREMENTS (ps)) = 0;
1879
ps_set_colors (ps, RGB_BLACK, RGB_WHITE);
1884
destroy_ps (ps_t * ps)
1886
if ((PS_CHAR_INCREMENTS (ps)) != 0)
1887
OS_free (PS_CHAR_INCREMENTS (ps));
1888
if (!GpiDestroyPS (PS_HANDLE (ps)))
1889
window_warning (GpiDestroyPS);
1890
deallocate_id ((& psid_table), (PS_ID (ps)));
1897
clipboard_write_text (qid_t qid, const char * text)
1899
unsigned int len = ((strlen (text)) + 1);
1904
(dos_alloc_shared_mem,
1905
((&shared_copy), 0, len,
1906
(PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE)));
1907
FASTCOPY (text, ((char *) shared_copy), len);
1909
if (WinOpenClipbrd (pm_hab))
1911
if (WinEmptyClipbrd (pm_hab))
1913
= (WinSetClipbrdData
1914
(pm_hab, ((ULONG) shared_copy), CF_TEXT, CFI_POINTER));
1915
(void) WinCloseClipbrd (pm_hab);
1918
STD_API_CALL (dos_free_mem, (shared_copy));
1922
clipboard_read_text (qid_t qid)
1925
if (WinOpenClipbrd (pm_hab))
1927
const char * shared_copy
1928
= ((const char *) (WinQueryClipbrdData (pm_hab, CF_TEXT)));
1929
if (shared_copy != 0)
1931
unsigned int len = ((strlen (shared_copy)) + 1);
1932
result = (OS_malloc (len));
1933
FASTCOPY (shared_copy, result, len);
1935
(void) WinCloseClipbrd (pm_hab);
1943
menu_create (qid_t qid, HWND owner, USHORT style, USHORT id)
1946
(WinCreateWindow (owner, /* parent window */
1947
WC_MENU, /* class name */
1948
"", /* window text */
1949
style, /* window style */
1950
0, 0, 0, 0, /* size and position */
1951
owner, /* owner window */
1952
HWND_TOP, /* sibling window */
1954
0, /* control data */
1955
0 /* presentation parameters */
1960
menu_destroy (qid_t qid, HWND menu)
1962
return (WinDestroyWindow (menu));
1966
menu_insert_item (qid_t qid, HWND menu, USHORT position, USHORT style,
1967
USHORT attributes, USHORT id, HWND submenu, char * text)
1970
(item . iPosition) = position;
1971
(item . afStyle) = style;
1972
(item . afAttribute) = attributes;
1974
(item . hwndSubMenu) = submenu;
1976
return (SHORT1FROMMR (WinSendMsg (menu, MM_INSERTITEM,
1978
(MPFROMP (text)))));
1982
menu_remove_item (qid_t qid, HWND menu, USHORT id, USHORT submenup,
1985
return (SHORT1FROMMR (WinSendMsg (menu,
1986
(deletep ? MM_DELETEITEM : MM_REMOVEITEM),
1987
(MPFROM2SHORT (id, submenup)),
1992
menu_get_item (qid_t qid, HWND menu, USHORT id, USHORT submenup)
1994
PMENUITEM item = (OS_malloc (sizeof (MENUITEM)));
1995
if (LONGFROMMR (WinSendMsg (menu, MM_QUERYITEM,
1996
(MPFROM2SHORT (id, submenup)),
2004
menu_n_items (qid_t qid, HWND menu)
2006
return (SHORT1FROMMR (WinSendMsg (menu, MM_QUERYITEMCOUNT, 0, 0)));
2010
menu_nth_item_id (qid_t qid, HWND menu, USHORT position)
2012
return (SHORT1FROMMR (WinSendMsg (menu, MM_ITEMIDFROMPOSITION,
2013
(MPFROMSHORT (position)),
2018
menu_get_item_attributes (qid_t qid, HWND menu, USHORT id, USHORT submenup,
2021
return (SHORT1FROMMR (WinSendMsg (menu, MM_QUERYITEMATTR,
2022
(MPFROM2SHORT (id, submenup)),
2023
(MPFROMSHORT (mask)))));
2027
menu_set_item_attributes (qid_t qid, HWND menu, USHORT id, USHORT submenup,
2028
USHORT mask, USHORT attributes)
2030
return (LONGFROMMR (WinSendMsg (menu, MM_SETITEMATTR,
2031
(MPFROM2SHORT (id, submenup)),
2032
(MPFROM2SHORT (mask, attributes)))));
2036
window_load_menu (window_t * window, HMODULE module, ULONG id)
2038
return (WinLoadMenu ((WINDOW_FRAME (window)), module, id));
2042
window_popup_menu (qid_t qid, HWND parent, HWND owner, HWND menu,
2043
LONG x, LONG y, LONG id, ULONG options)
2045
return (WinPopupMenu (parent, owner, menu, x, y, id, options));
2050
static font_metrics_t *
2051
ps_get_font_metrics (ps_t * ps)
2053
font_metrics_t * metrics = (OS_malloc (sizeof (font_metrics_t)));
2055
if (!GpiQueryFontMetrics ((PS_HANDLE (ps)), (sizeof (fm)), (& fm)))
2056
window_error (GpiQueryFontMetrics);
2057
(FONT_METRICS_WIDTH (metrics)) = (fm . lMaxCharInc);
2058
(FONT_METRICS_HEIGHT (metrics)) = (fm . lMaxBaselineExt);
2059
(FONT_METRICS_DESCENDER (metrics)) = (fm . lMaxDescender);
2063
static font_metrics_t *
2064
ps_set_font_internal (ps_t * ps, unsigned short id, const char * spec)
2066
return ((ps_set_font (ps, id, spec)) ? (ps_get_font_metrics (ps)) : 0);
2070
window_font_dialog (window_t * window, const char * title)
2072
ps_t * ps = (WINDOW_CLIENT_PS (window));
2073
HPS hps = (PS_HANDLE (ps));
2075
char name_buffer [FACESIZE];
2078
memset ((&info), 0, (sizeof (info)));
2079
(name_buffer[0]) = '\0';
2080
(info . cbSize) = (sizeof (info));
2081
(info . hpsScreen) = hps;
2082
(info . pszTitle) = ((PSZ) title);
2083
(info . fl) = (FNTS_FIXEDWIDTHONLY | FNTS_CENTER); /* FNTS_INITFROMFATTRS */
2084
(info . pszFamilyname) = name_buffer;
2085
(info . usFamilyBufLen) = (sizeof (name_buffer));
2086
/* Because our PS is in RGB mode, the RGB color specs we are using
2087
are useless. It's undocumented, but only indexed colors work in
2088
the font dialog, so we must override with indexes. */
2089
(info . clrFore) = CLR_BLACK; /* (PS_FOREGROUND_COLOR (ps)) */
2090
(info . clrBack) = CLR_WHITE; /* (PS_BACKGROUND_COLOR (ps)) */
2093
if (GpiQueryFontMetrics (hps, (sizeof (fm)), (&fm)))
2095
strcpy (name_buffer, (fm . szFamilyname));
2096
(info . usWeight) = (fm . usWeightClass);
2097
(info . usWidth) = (fm . usWidthClass);
2098
(info . fxPointSize)
2099
= (MAKEFIXED (((fm . sNominalPointSize) / 10), 0));
2100
(info . flStyle) = (fm . fsSelection);
2101
copy_fontmetrics_to_fattrs ((&fm), (& (info . fAttrs)));
2103
/* The following, for some unknown reason, causes the
2104
selection of incorrect fonts: */
2105
(info . fl) |= FNTS_INITFROMFATTRS;
2109
result = (WinFontDlg (HWND_DESKTOP, (WINDOW_CLIENT (window)), (&info)));
2110
if ((result == NULLHANDLE) || ((info . lReturn) != DID_OK))
2114
const char * font_spec;
2117
ULONG face_name_length;
2118
char face_name_dummy [1];
2119
memset ((&desc), 0, (sizeof (desc)));
2120
(desc . usSize) = (sizeof (desc));
2121
(desc . usWeightClass) = (info . usWeight);
2122
(desc . usWidthClass) = (info . usWidth);
2123
(desc . flOptions) = (info . flType);
2124
face_name = face_name_dummy;
2126
= (GpiQueryFaceString (hps, (info . pszFamilyname), (&desc),
2128
if (face_name_length == GPI_ERROR)
2130
window_warning (GpiQueryFaceString);
2133
face_name = (OS_malloc (face_name_length));
2135
= (GpiQueryFaceString (hps, (info . pszFamilyname), (&desc),
2136
face_name_length, face_name));
2137
if (face_name_length == GPI_ERROR)
2139
OS_free (face_name);
2140
window_warning (GpiQueryFaceString);
2144
font_spec = (unparse_font_spec (face_name,
2145
((FIXEDINT (info . fxPointSize)) * 10),
2147
OS_free (face_name);
2152
/* Helper Procedures */
2155
ps_set_font (ps_t * ps, unsigned short id, const char * spec)
2160
if (!parse_font_spec (spec, (& name), (& size), (& selection)))
2162
if (!ps_set_font_1 (ps, name, size, selection, id))
2169
if (!GpiQueryFontMetrics ((PS_HANDLE (ps)), (sizeof (fm)), (& fm)))
2170
window_error (GpiQueryFontMetrics);
2171
if ((PS_CHAR_INCREMENTS (ps)) != 0)
2172
OS_free (PS_CHAR_INCREMENTS (ps));
2173
(PS_CHAR_INCREMENTS (ps))
2174
= ((((fm . fsDefn) & FM_DEFN_OUTLINE) != 0)
2175
? (ps_make_char_increments (fm . lMaxCharInc))
2182
ps_set_font_1 (ps_t * ps, PSZ name, LONG size, USHORT selection, LONG id)
2184
HPS hps = (PS_HANDLE (ps));
2190
nfonts = (GpiQueryFonts (hps,
2191
(QF_PUBLIC | QF_PRIVATE),
2194
(sizeof (FONTMETRICS)),
2196
if (nfonts == GPI_ALTERROR)
2197
window_error (GpiQueryFonts);
2200
pfm = (OS_malloc (nfonts * (sizeof (FONTMETRICS))));
2201
if ((GpiQueryFonts (hps,
2202
(QF_PUBLIC | QF_PRIVATE),
2205
(sizeof (FONTMETRICS)),
2208
window_error (GpiQueryFonts);
2211
/* Choose an image font if one is available. */
2212
for (index = 0; (index < nfonts); index += 1)
2213
if (((((pfm [index]) . fsType) & FM_TYPE_FIXED) != 0)
2214
&& ((((pfm [index]) . fsDefn) & FM_DEFN_OUTLINE) == 0)
2215
&& (((pfm [index]) . sNominalPointSize) == size)
2216
&& (create_font (hps, id, (& (pfm [index])), selection)))
2218
GpiSetCharSet (hps, id);
2222
/* Otherwise, look for an outline font. */
2223
for (index = 0; (index < nfonts); index += 1)
2224
if (((((pfm [index]) . fsType) & FM_TYPE_FIXED) != 0)
2225
&& ((((pfm [index]) . fsDefn) & FM_DEFN_OUTLINE) != 0)
2226
&& (create_font (hps, id, (& (pfm [index])), selection)))
2228
GpiSetCharSet (hps, id);
2229
ps_set_font_size (ps, size);
2240
create_font (HPS hps, LONG font_id, PFONTMETRICS pfm, USHORT selection)
2243
copy_fontmetrics_to_fattrs (pfm, (&fa));
2244
(fa . fsSelection) = selection;
2245
return ((GpiCreateLogFont (hps, 0, font_id, (&fa))) == FONT_MATCH);
2249
copy_fontmetrics_to_fattrs (FONTMETRICS * pfm, FATTRS * pfa)
2251
(pfa -> usRecordLength) = (sizeof (*pfa));
2252
(pfa -> fsSelection) = (pfm -> fsSelection);
2253
(pfa -> lMatch) = (pfm -> lMatch);
2254
strcpy ((pfa -> szFacename), (pfm -> szFacename));
2255
(pfa -> idRegistry) = (pfm -> idRegistry);
2256
(pfa -> usCodePage) = (pfm -> usCodePage);
2257
(pfa -> fsType) = 0;
2258
if (((pfm -> fsDefn) & FM_DEFN_OUTLINE) != 0)
2260
(pfa -> lMaxBaselineExt) = 0;
2261
(pfa -> lAveCharWidth) = 0;
2263
= (FATTR_FONTUSE_OUTLINE | FATTR_FONTUSE_TRANSFORMABLE);
2267
(pfa -> lMaxBaselineExt) = (pfm -> lMaxBaselineExt);
2268
(pfa -> lAveCharWidth) = (pfm -> lAveCharWidth);
2269
(pfa -> fsFontUse) = 0;
2274
ps_set_font_size (ps_t * ps, LONG size)
2282
ps_query_caps (ps, CAPS_HORIZONTAL_FONT_RES, 1, (&xres));
2283
((ptl[1]) . x) = ((((xres * size) << 4) + 360) / 720);
2287
ps_query_caps (ps, CAPS_VERTICAL_FONT_RES, 1, (&yres));
2288
((ptl[1]) . y) = ((((yres * size) << 4) + 360) / 720);
2290
if (!GpiConvert ((PS_HANDLE (ps)), CVTC_DEVICE, CVTC_WORLD, 2, ptl))
2291
window_error (GpiConvert);
2294
(s . cx) = ((((ptl[1]) . x) - ((ptl[0]) . x)) << 12);
2295
(s . cy) = ((((ptl[1]) . y) - ((ptl[0]) . y)) << 12);
2296
if (!GpiSetCharBox ((PS_HANDLE (ps)), (&s)))
2297
window_error (GpiSetCharBox);
2302
ps_make_char_increments (LONG increment)
2304
PLONG increments = (OS_malloc ((sizeof (LONG)) * 512));
2306
for (index = 0; (index < 512); index += 1)
2307
(increments[index]) = increment;
2308
return (increments);
2311
static struct font_selection
2314
unsigned int selector;
2315
} font_selections [] =
2317
{ ".bold", FATTR_SEL_BOLD },
2318
{ ".italic", FATTR_SEL_ITALIC },
2319
{ ".outline", FATTR_SEL_OUTLINE },
2320
{ ".strikeout", FATTR_SEL_STRIKEOUT },
2321
{ ".underscore", FATTR_SEL_UNDERSCORE },
2326
parse_font_spec (const char * spec,
2327
PSZ * pname, LONG * psize, USHORT * pselection)
2329
const char * scan = spec;
2330
unsigned int size = 0;
2331
unsigned int selection = 0;
2332
while (('0' <= (*scan)) && ((*scan) <= '9'))
2333
size = ((size * 10) + ((*scan++) - '0'));
2338
struct font_selection * selections = font_selections;
2339
unsigned int name_length;
2342
if ((selections -> name) == 0)
2343
goto no_more_selections;
2344
name_length = (strlen (selections -> name));
2345
if ((strncmp (scan, (selections -> name), name_length)) == 0)
2347
selection |= (selections -> selector);
2348
scan += name_length;
2355
if ((*scan++) != '.')
2357
(*pname) = (OS_malloc ((strlen (scan)) + 1));
2358
strcpy ((*pname), scan);
2359
(*psize) = (size * 10);
2360
(*pselection) = selection;
2365
unparse_font_spec (PSZ name, LONG size, USHORT selection)
2367
char size_buffer [16];
2368
char selection_buffer [16];
2369
struct font_selection * selections = font_selections;
2372
sprintf (size_buffer, "%d", (size / 10));
2373
strcpy (selection_buffer, "");
2376
if ((selections -> name) == 0)
2378
if ((selection & (selections -> selector)) != 0)
2379
strcat (selection_buffer, (selections -> name));
2383
= (OS_malloc ((strlen (size_buffer))
2385
+ (strlen (selection_buffer))
2387
strcpy (result, size_buffer);
2388
strcat (result, selection_buffer);
2389
strcat (result, ".");
2390
strcat (result, name);
2394
/* Pointers and Icons */
2397
query_system_pointer (qid_t qid, HWND desktop, LONG id, BOOL copyp)
2399
return (WinQuerySysPointer (desktop, id, copyp));
2403
set_pointer (qid_t qid, HWND desktop, HPOINTER pointer)
2405
return (WinSetPointer (desktop, pointer));
2409
window_load_pointer (qid_t qid, HWND desktop, HMODULE module, ULONG id)
2411
return (WinLoadPointer (desktop, module, id));
2415
window_destroy_pointer (qid_t qid, HPOINTER pointer)
2417
return (WinDestroyPointer (pointer));
2421
window_set_icon (window_t * window, HPOINTER icon)
2423
return (LONGFROMMR (WinSendMsg ((WINDOW_FRAME (window)), WM_SETICON,
2424
(MPFROMLONG (icon)),
2425
(MPFROMLONG (0)))));