1 /* The routines in this file provide drivers for display and input under
2 the Microsoft Windows environment on an IBM-PC or compatible
3 computer.
4
5 Must be compiled with Borland C++ 2.0 or MSC 6.0 or later versions.
6
7 It should not be compiled if the WINDOW_MSWIN symbol is not set */
8
9 #define termdef 1 /* don't define term external */
10
11 #include "estruct.h"
12 #include "elang.h"
13 #include <stdio.h>
14 #include <time.h>
15 #include "eproto.h"
16 #include "edef.h"
17
18 #include "mswin.h"
19
20 #define NPAUSE 1000 /* pause for fence-showing, 1 second */
21 #define MARGIN 8 /* size of minimal margin and */
22 #define SCRSIZ 20 /* scroll size for extended lines */
23
24 /* terminal interface table entries */
25
26 static int PASCAL mswnop();
27 static int PASCAL mswopen();
28 static int PASCAL mswgetc();
29 static int PASCAL mswputc();
30 static int PASCAL mswflush();
31 static int PASCAL mswbeep();
32 static int PASCAL mswmove();
33 static int PASCAL msweeol();
34 static int PASCAL msweeop();
35 static int PASCAL mswbeep();
36 static int PASCAL mswrev();
37 static int PASCAL mswrez();
38 #if COLOR
39 static int PASCAL mswsetfor();
40 static int PASCAL mswsetback();
41 #endif
42 static int PASCAL mswsleep();
43 static int PASCAL mswnewscr();
44 static int PASCAL mswdelscr();
45 static int PASCAL mswselscr();
46 static int PASCAL mswsizscr();
47 static int PASCAL mswtopscr();
48
49 /* Standard terminal interface dispatch table.
50 */
51 NOSHARE TERM term = {
52 128,
53 128,
54 HUGE,
55 HUGE,
56 0,
57 0,
58 MARGIN,
59 SCRSIZ,
60 NPAUSE,
61 mswopen, /* t_open: Open terminal at the start */
62 mswnop, /* t_close: Close terminal at end */
63 mswnop, /* t_kopen: Open keyboard */
64 mswnop, /* t_kclose: close keyboard */
65 mswgetc, /* t_getchar: Get character from keyboard */
66 mswputc, /* t_putchar: Put character to display */
67 mswflush, /* t_flush: Flush output buffers */
68 mswmove, /* t_move: Move the cursor, origin 0 */
69 msweeol, /* t_eeol: Erase to end of line */
70 msweeop, /* t_eeop: Erase to end of page */
71 mswnop, /* t_clrdesk: Clear the page totally */
72 mswbeep, /* t_beep: Sound beep */
73 mswrev, /* t_rev: set reverse video state */
74 mswrez, /* t_rez: change screen resolution */
75 #if COLOR
76 mswsetfor, /* t_setfor: set forground color */
77 mswsetback, /* t_setback: set background color */
78 #endif
79 mswsleep, /* t_sleep: wait a while */
80 mswnewscr, /* t_newscr: create new "screen" display */
81 mswdelscr, /* t_delscr: destroy "screen" display */
82 mswselscr, /* t_selscr: select "screen" display for IO */
83 mswsizscr, /* t_sizscr: resize "screen" display */
84 mswtopscr /* t_topscr: bring "screen" to top */
85 };
86
87 #define MAXMLHIST 8 /* must be a power of 2 */
88 #define MLHISTMASK 0x7 /* corresponding bit mask */
89 static char *MLHistory[MAXMLHIST] = {NULL};
90 /* circular history of the last few message line entries */
91 static int MLHistOld = 0; /* index of the oldest message */
92 static int MLHistNew = 0; /* index of the first empty slot */
93
94 static HWND hIOWnd; /* current window where I/Os take place */
95
96 static int UpdateRow; /* Row being updated (-1 for no update) */
97
98 static struct {
99 int leftmost;
100 int rightmost; /* -1 indicates the range is empty */
101 } UpdateCol; /* Columns to invalidate on UpdateRow */
102
103 static SCREEN *IOScr; /* Screen affected by the I/Os */
104
105 #if COLOR
106 static int ForgColor; /* current selection of foreground and */
107 static int BackColor; /* background colors */
108 #endif
109
110 /* PushMLHist: store the last message line contents in the history */
111 /* ========== */
112
PushMLHist(void)113 static void PASCAL PushMLHist (void)
114 {
115 char *ml;
116 int i, e;
117
118 for (e = MLSIZE - 1; e >= 0; e--) if (MLBuf[e] != ' ') break;
119 /* e = index of the last non-space char */
120 if (e < 0) return;
121 if ((ml = MLHistory[MLHistNew] = room (e + 2)) != NULL) {
122 for (i = 0; i <= e; i++) *ml++ = MLBuf[i];
123 *ml = '\0'; /* terminate the string */
124 MLHistNew = (MLHistNew + 1) & MLHISTMASK;
125 if (MLHistOld == MLHistNew) {
126 /* the history is full. This old entry needs to be discarded */
127 free (MLHistory[MLHistOld]);
128 MLHistOld = (MLHistOld + 1) & MLHISTMASK;
129 }
130 }
131 } /* PushMLHist */
132
133 /* MLHistDlgProc: dialog proc for the Message Line History */
134 /* ============= */
135
MLHistDlgProc(HWND hDlg,UINT wMsg,UINT wParam,LONG lParam)136 int EXPORT FAR PASCAL MLHistDlgProc (HWND hDlg, UINT wMsg,
137 UINT wParam, LONG lParam)
138 {
139 switch (wMsg) {
140
141 case WM_INITDIALOG:
142 {
143 char s[50];
144
145 strcpy (s, PROGNAME);
146 strcat (s, TEXT330);
147 SetWindowText (hDlg, s);
148 }
149 /*-fill the list box */
150 while (MLHistOld != MLHistNew) {
151 SendDlgItemMessage (hDlg, ID_HIST, LB_ADDSTRING, 0,
152 (DWORD)MLHistory[MLHistOld]);
153 free (MLHistory[MLHistOld]);
154 MLHistOld = (MLHistOld + 1) & MLHISTMASK;
155 }
156 /*-scroll the last message into view */
157 {
158 int i;
159
160 i = SendDlgItemMessage (hDlg, ID_HIST, LB_GETCOUNT, 0, 0L);
161 SendDlgItemMessage (hDlg, ID_HIST, LB_SETCURSEL, i - 1, 0L);
162 SendDlgItemMessage (hDlg, ID_HIST, LB_SETCURSEL, -1, 0L);
163 }
164 return TRUE;
165
166 case WM_COMMAND:
167 if (NOTIFICATION_CODE != BN_CLICKED) break;
168 if (LOWORD(wParam) == 1) {
169 EndDialog (hDlg, 0);
170 return TRUE;
171 }
172 break;
173 }
174 return FALSE;
175 } /* MLHistDlgProc */
176
177 /* mlhistory: displays the message line history box */
178 /* ========= */
179
180 /* This function is needed because the message line only shows the last
181 message. If a macro fails, it usually generates a slew of errors
182 (each beginning by a \n). Eventually, calling this function in the
183 core editor loop will pop up a dialog box showing up to MAXMLHIST-1
184 past messages */
185
mlhistory(void)186 PASCAL mlhistory (void)
187 {
188 FARPROC ProcInstance;
189
190 PushMLHist ();
191 mlferase ();
192 ProcInstance = MakeProcInstance ((FARPROC)MLHistDlgProc,
193 hEmacsInstance);
194 DialogBox (hEmacsInstance, "MLHIST", hFrameWnd, ProcInstance);
195 FreeProcInstance (ProcInstance);
196 } /* mlhistory */
197
ChangeUpdateRow(int newrow)198 static void PASCAL ChangeUpdateRow (int newrow)
199 /* Set UpdateRow to newrow, invalidating the changed cells in the
200 previous update row */
201 {
202 if ((UpdateCol.rightmost >= 0) && (UpdateRow >= 0)) {
203 InvalidateCells (hIOWnd, UpdateCol.leftmost, UpdateRow,
204 UpdateCol.rightmost, UpdateRow);
205 }
206 UpdateRow = newrow;
207 } /* ChangeUpdateRow */
208
209 /*****************************************/
210 /* mswopen: initialize windows interface */
211 /* ======= */
212
mswopen()213 static int PASCAL mswopen ()
214 {
215 static BOOL FirstTime = TRUE;
216
217 if (FirstTime) {
218 int x;
219
220 revexist = TRUE;
221 eolexist = TRUE;
222 strcpy (sres, "MSWIN"); /* $SRES emacs variable */
223 strcpy(os, "MSWIN"); /* $OS emacs variable */
224 MLBuf = (char*)room(MLSIZE);
225 for (x = 0; x < MLSIZE;) MLBuf[x++] = ' ';
226 FirstTime = FALSE;
227 }
228 UpdateRow = -1;
229 UpdateCol.rightmost = -1;
230 UpdateCol.leftmost = HUGE; /* empty range */
231 return 0;
232 } /* mswopen */
233
234 /***************************************************/
235 /* mswgetc: get character from keyboard (or mouse) */
236 /* ======= */
237
mswgetc()238 static int PASCAL mswgetc ()
239 {
240 return GetInput ();
241 } /* mswgetc */
242
243 /*************************************/
244 /* mswputc: put character to display */
245 /* ======= */
246
mswputc(c)247 static int PASCAL mswputc (c)
248 int c; /* character to write (or 0 for dummy write) */
249 {
250 if (UpdateRow != CurrentRow) {
251 ChangeUpdateRow (CurrentRow);
252 UpdateCol.rightmost = -1;
253 UpdateCol.leftmost = HUGE; /* empty range */
254 }
255
256 /*-set the colors and reverse status in the display buffer */
257 if (hIOWnd != hFrameWnd) { /* not supported on message line */
258 register VIDEO *vp;
259
260 vp = IOScr->s_physical[UpdateRow];
261 vp->v_fcolor = ForgColor;
262 vp->v_bcolor = BackColor;
263 }
264
265 /*-update the cursor's position and the UpdateCol range. Update the
266 message line buffer if that's where the fun is */
267 if (c != 0) {
268 if (CurrentCol < UpdateCol.leftmost) UpdateCol.leftmost = CurrentCol;
269 if (CurrentCol > UpdateCol.rightmost) UpdateCol.rightmost = CurrentCol;
270 if (hIOWnd == hFrameWnd) { /* message line */
271 if (c == '\b') {
272 if (CurrentCol > 0) MLBuf[--CurrentCol] = ' ';
273 }
274 else {
275 if (c == '\n') PushMLHist();
276 else {
277 MLBuf[CurrentCol] = c;
278 if (CurrentCol < MLSIZE - 1) ++CurrentCol;
279 }
280 }
281 }
282 else ++CurrentCol;
283 }
284 return 0;
285 } /* mswputc */
286
287 /**************************************************/
288 /* mswflush: update display from output buffer */
289 /* ======== */
290
mswflush()291 static int PASCAL mswflush ()
292 {
293 ChangeUpdateRow (-1);
294 if (!InternalRequest && (hIOWnd == hFrameWnd)) UpdateWindow (hIOWnd);
295 /* note: we do not update screens in real time */
296 MoveEmacsCaret (hIOWnd, CurrentCol, CurrentRow);
297 /* some caret movement is directly handled by the driver (see
298 mswputc) */
299 return 0;
300 } /* mswflush */
301
302 /****************************/
303 /* mswmove: move the cursor */
304 /* ======= */
305
mswmove(int newrow,int newcol)306 static int PASCAL mswmove (int newrow, int newcol)
307 {
308 /*-perform IO windows switching depending on the addressed row: if
309 beyond the IO screen, the message line is addressed*/
310 if (!IOScr || (newrow >= IOScr->s_nrow)) {
311 if (hIOWnd != hFrameWnd) {
312 ChangeUpdateRow (-1);
313 hIOWnd = hFrameWnd;
314 }
315 CurrentRow = 0;
316 }
317 else {
318 if (hIOWnd != IOScr->s_drvhandle) {
319 ChangeUpdateRow (-1);
320 hIOWnd = IOScr->s_drvhandle;
321 }
322 CurrentRow = newrow;
323 }
324
325 CurrentCol = newcol;
326
327 /*-update the caret */
328 MoveEmacsCaret (hIOWnd, CurrentCol, CurrentRow);
329 return 0;
330 } /* mswmove */
331
332 /*********************************/
333 /* msweeol: erase to end of line */
334 /* ======= */
335
msweeol()336 static int PASCAL msweeol ()
337 {
338 mswputc (0); /* ensure change of row is properly handled */
339 UpdateCol.leftmost = min(UpdateCol.leftmost,CurrentCol);
340 if (hIOWnd == hFrameWnd) { /* message line */
341 int x;
342
343 for (x = CurrentCol; x < MLSIZE;) MLBuf[x++] = ' ';
344 UpdateCol.rightmost = MLSIZE - 1;
345 }
346 else {
347 UpdateCol.rightmost = IOScr->s_ncol;
348 }
349 mswflush ();
350 return 0;
351 } /* msweeol */
352
353 /*********************************/
354 /* msweeop: erase to end of page */
355 /* ======= */
356
msweeop()357 static int PASCAL msweeop ()
358 {
359 if (hIOWnd == hFrameWnd) { /* message line */
360 msweeol (); /* only one line here */
361 return 0;
362 }
363 mswputc (0); /* ensure change of row is properly handled */
364 UpdateCol.leftmost = min(UpdateCol.leftmost,CurrentCol);
365 InvalidateCells (hIOWnd, UpdateCol.leftmost, UpdateRow,
366 IOScr->s_ncol, UpdateRow);
367 if (CurrentRow + 1 < IOScr->s_nrow) {
368 register int r;
369 register VIDEO *vp;
370
371 /*-propagate the colors and reverse status */
372 for (r = CurrentRow + 1; r < IOScr->s_nrow; r++) {
373 vp = IOScr->s_physical[r];
374 vp->v_fcolor = ForgColor;
375 vp->v_bcolor = BackColor;
376 }
377 /*-flag the area for repaint */
378 InvalidateCells (hIOWnd, 0, CurrentRow + 1,
379 IOScr->s_ncol, IOScr->s_nrow);
380 }
381 mswflush ();
382 return 0;
383 } /* msweeop */
384
385 /*************************/
386 /* mswbeep: sound a beep */
387 /* ======= */
388
mswbeep()389 static int PASCAL mswbeep ()
390 {
391 MessageBeep (0);
392 return 0;
393 } /* mswbeep */
394
395 /************************************/
396 /* mswrev: set reverse video state */
397 /* ====== */
398
mswrev(state)399 static int PASCAL mswrev (state)
400 int state; /* TRUE = reverse, FALSE = normal */
401 {
402 /* nothing to do: the description of reverse video fields is kept
403 up to date in the physical screen by the display.c code */
404 return 0;
405 } /* mswrev */
406
407 /************************************/
408 /* mswrez: change "resolution" */
409 /* ====== */
410
mswrez(res)411 static int PASCAL mswrez (res)
412 char *res;
413 {
414 return TRUE; /* $SRES is read-only in MSWIN, but returning an
415 error may break existing macros */
416 } /* mswrez */
417
418 #if COLOR
419 /* mswsetfor: set foreground color */
420 /* ========= */
421
mswsetfor(color)422 static int PASCAL mswsetfor (color)
423 int color;
424 {
425 ForgColor = color;
426 return 0;
427 } /* mswsetfor */
428
429 /* mswsetback: set background color */
430 /* ========== */
431
mswsetback(color)432 static int PASCAL mswsetback (color)
433 int color;
434 {
435 BackColor = color;
436 return 0;
437 } /* mswsetback */
438 #endif
439
440 /* mswsleep: wait a specified time (in ms) in an unobtrusive way */
441 /* ======== */
442
mswsleep(int t)443 static int PASCAL mswsleep (int t)
444 {
445 return TakeANap (t);
446 } /* mswsleep */
447
448 /* mswnewscr: create new MDI window for new screen */
449 /* ========= */
450
mswnewscr(SCREEN * sp)451 static int PASCAL mswnewscr (SCREEN *sp)
452 /* called by screen.c after the screen structure has been allocated. The
453 size of the screen will be determined by the window's size. returns
454 TRUE if successful. */
455 {
456 MDICREATESTRUCT cs;
457 BOOL Maximized;
458
459 #if WINDOW_MSWIN32
460 Maximized = (GetWindowLong((HWND)SendMessage (hMDIClientWnd,
461 WM_MDIGETACTIVE,
462 0, 0L),
463 GWL_STYLE) & WS_MAXIMIZE);
464 #else
465 Maximized = HIWORD(SendMessage (hMDIClientWnd, WM_MDIGETACTIVE, 0, 0L));
466 #endif
467 if (Maximized) {
468 restorescreen (FALSE, 0); /* de-maximize previous one */
469 }
470 if (first_screen == NULL) Maximized = TRUE;
471 cs.szClass = ScreenClassName;
472 cs.szTitle = sp->s_screen_name;
473 cs.hOwner = hEmacsInstance;
474 cs.x = CW_USEDEFAULT;
475 cs.y = CW_USEDEFAULT;
476 cs.cx = CW_USEDEFAULT;
477 cs.cy = CW_USEDEFAULT;
478 if (Maximized) cs.style = WS_MAXIMIZE;
479 else cs.style = 0;
480 cs.style |= WS_HSCROLL | WS_VSCROLL;
481 cs.lParam = (DWORD)sp;
482 sp->s_virtual = NULL; /* not NULL will testify of success */
483 InternalRequest = TRUE;
484 SendMessage (hMDIClientWnd, WM_MDICREATE, 0, (DWORD)(LPSTR)&cs);
485 if (sp->s_virtual) {
486 if (hFrameWnd == GetActiveWindow ()) SetFocus (sp->s_drvhandle);
487 }
488 InternalRequest = FALSE;
489 if (!sp->s_virtual) {
490 mswdelscr (sp); /* failed, cleanup! */
491 return FALSE;
492 }
493 return TRUE;
494 } /* mswnewscr */
495
496 /* mswdelscr: destroys an MDI window for a disappearing screen */
497 /* ========= */
498
mswdelscr(SCREEN * sp)499 static int PASCAL mswdelscr (SCREEN *sp)
500 /* called by screen.c before the screen structure is deallocated */
501 {
502 if (sp->s_drvhandle == hIOWnd) mswflush ();
503 if (sp == IOScr) mswselscr (first_screen);
504 /* hopefully, at this time, sp!=first_screen */
505 SendMessage (hMDIClientWnd, WM_MDIDESTROY, (UINT)sp->s_drvhandle, 0L);
506 } /* mswdelscr */
507
508 /* mswselscr: select a window/screen combination for the next IOs */
509 /* ========= */
510
mswselscr(SCREEN * sp)511 static int PASCAL mswselscr (SCREEN *sp)
512 {
513 hIOWnd = sp->s_drvhandle;
514 IOScr = sp;
515 } /* mswselscr */
516
517 /* mswsizscr: resize an MDI window to fit the associated screen */
518 /* ========= */
519
mswsizscr(SCREEN * sp)520 static int PASCAL mswsizscr (SCREEN *sp)
521 /* called by Emacs when the screen's dimensions have been changed. A resize
522 through the MS-Windows interface is handled by the ReSize function in
523 mswdisp.c */
524 {
525 HWND hScrWnd;
526 BOOL Maximized;
527 int RetryCount = -1; /* prevents infinite loop if frame
528 window can't be resized properly */
529 BOOL FrameIconic;
530
531 WINDOWPLACEMENT WindowPlacement;
532
533 if (InternalRequest) return;
534 InternalRequest = TRUE;
535 hScrWnd = sp->s_drvhandle;
536
537 { /*-If this is iconized, we have to restore it first to be
538 allowed to change its size. If it is the active MDI child and
539 is maximized, we will actually resize the frame window so, if
540 the later is maximized, we restore it first. */
541
542 #if WINDOW_MSWIN32
543 HWND hActiveScr;
544
545 hActiveScr = (HWND)SendMessage (hMDIClientWnd, WM_MDIGETACTIVE, 0, 0L);
546 Maximized = (hScrWnd == hActiveScr) &&
547 (GetWindowLong(hScrWnd, GWL_STYLE) & WS_MAXIMIZE);
548 #else
549 DWORD ActiveScr;
550
551 ActiveScr = SendMessage (hMDIClientWnd, WM_MDIGETACTIVE, 0, 0L);
552 Maximized = (hScrWnd == LOWORD(ActiveScr)) && HIWORD(ActiveScr);
553 #endif
554 if (IsIconic (hScrWnd)) {
555 SendMessage (hMDIClientWnd, WM_MDIRESTORE, (UINT)hScrWnd, 0L);
556 }
557 if (Maximized && IsZoomed (hFrameWnd)) {
558 ShowWindow (hFrameWnd, SW_RESTORE);
559 }
560 }
561 FrameIconic = IsIconic (hFrameWnd);
562 do {/*-Now, proceed with resizing... */
563 int Delta;
564 RECT TargetRect, BoundingRect; /* in MDIClient coordinates */
565 RECT OldClientRect;
566 POINT ClientSize;
567
568 GetClientRect (hScrWnd, &OldClientRect);
569 MinimumClientSize (hScrWnd, sp->s_ncol, sp->s_nrow,
570 &ClientSize.x, &ClientSize.y);
571 if (Maximized) {
572 if (((OldClientRect.bottom == ClientSize.y)
573 && (OldClientRect.right == ClientSize.x))
574 || (RetryCount > 0)) break; /* exit the resize loop */
575 ++RetryCount;
576 BoundingRect.left = BoundingRect.top = 0;
577 BoundingRect.right = GetSystemMetrics (SM_CXSCREEN);
578 BoundingRect.bottom = GetSystemMetrics (SM_CYSCREEN);
579
580 if (FrameIconic && Win31API) {
581 GetWindowPlacement (hFrameWnd, &WindowPlacement);
582 TargetRect = WindowPlacement.rcNormalPosition;
583 }
584 else {
585 GetWindowRect (hFrameWnd, &TargetRect);
586 }
587 }
588 else {
589 GetClientRect (hMDIClientWnd, &BoundingRect);
590 GetWindowRect (hScrWnd, &TargetRect);
591 ScreenToClient (hMDIClientWnd, (LPPOINT)&TargetRect.right);
592 ScreenToClient (hMDIClientWnd, (LPPOINT)&TargetRect.left);
593 }
594
595 /*-process change of width: we move the right edge. If it would
596 go off bounds, we move the left edge back to compensate, but
597 never below 0 */
598 Delta = ClientSize.x - OldClientRect.right;
599 if ((TargetRect.right + Delta) > BoundingRect.right) {
600 TargetRect.left += (BoundingRect.right - TargetRect.right)
601 - Delta;
602 TargetRect.right = BoundingRect.right;
603 if (TargetRect.left < 0) {
604 TargetRect.right -= TargetRect.left;
605 TargetRect.left = 0;
606 }
607 }
608 else TargetRect.right += Delta;
609
610 /*-process change of height: we move the bottom edge. If it
611 would go off screen, we move the top edge up to compensate,
612 but never beyond 0 */
613 Delta = ClientSize.y - OldClientRect.bottom;
614 if ((TargetRect.bottom + Delta) > BoundingRect.bottom) {
615 TargetRect.top += (BoundingRect.bottom - TargetRect.bottom)
616 - Delta;
617 TargetRect.bottom = BoundingRect.bottom;
618 if (TargetRect.top < 0) {
619 TargetRect.bottom -= TargetRect.top;
620 TargetRect.top = 0;
621 }
622 }
623 else TargetRect.bottom += Delta;
624
625 if (Maximized && FrameIconic && Win31API) {
626 WindowPlacement.rcNormalPosition = TargetRect;
627 SetWindowPlacement (hFrameWnd, &WindowPlacement);
628 }
629 else {
630 SetWindowPos (Maximized ? hFrameWnd : hScrWnd, 0,
631 TargetRect.left, TargetRect.top,
632 TargetRect.right - TargetRect.left,
633 TargetRect.bottom - TargetRect.top,
634 SWP_DRAWFRAME | SWP_NOZORDER);
635 }
636 } while (Maximized); /* if Maximized, we loop once in case a
637 change of menu bar height has prevented
638 us from getting the expected client size
639 */
640 InternalRequest = FALSE;
641 } /* mswsizscr */
642
643 /* mswtopscr: bring a screen's window to top. */
644 /* ========= */
645
mswtopscr(SCREEN * sp)646 static int PASCAL mswtopscr (SCREEN *sp)
647
648 /* called by screen.c when selecting a screen for current */
649 {
650 if (!InternalRequest) {
651 InternalRequest = TRUE;
652 SendMessage (hMDIClientWnd, WM_MDIACTIVATE,
653 (UINT)sp->s_drvhandle, 0L);
654 #if WINDOW_MSWIN32
655 if (GetWindowLong(sp->s_drvhandle, GWL_STYLE) & WS_MAXIMIZE) {
656 #else
657 if (HIWORD(SendMessage (hMDIClientWnd, WM_MDIGETACTIVE, 0, 0L))) {
658 #endif
659 /* we have a maximized screen. Since we activated it under
660 InternalRequest, the new size has not yet been processed
661 by emacs, so we have to fix that */
662 newwidth (TRUE, DisplayableColumns (sp->s_drvhandle, 0, &EmacsCM));
663 newsize (TRUE, DisplayableRows (sp->s_drvhandle, 0, &EmacsCM));
664 }
665 InternalRequest = FALSE;
666 }
667 } /* mswtopscr */
668
669 /*************************/
670 /* mswnop: No Operation */
671 /* ====== */
672
673 static int PASCAL mswnop ()
674 {
675 return 0;
676 }
677