1 /* $Id: winXXPilot.c,v 5.1 2001/04/24 20:40:18 bertg Exp $
2 *
3 * XPilot, a multiplayer gravity war game. Copyright (C) 1991-2001 by
4 *
5 * Bj�rn Stabell <bjoern@xpilot.org>
6 * Ken Ronny Schouten <ken@xpilot.org>
7 * Bert Gijsbers <bert@xpilot.org>
8 * Dick Balaska <dick@xpilot.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 /***************************************************************************\
26 * winX.c - X11 to Windoze converter *
27 * *
28 * This file is mostly Win32 translations of the X calls that xpilot uses. *
29 * Anything starting with WinX is a special wedge function that i needed *
30 * *
31 * $Id: winXXPilot.c,v 5.1 2001/04/24 20:40:18 bertg Exp $ *
32 \***************************************************************************/
33 #include "winXXPilot.h"
34 #include "../winX_.h"
35 #include "windows.h"
36 #include "winClient.h"
37 #include "winXThread.h"
38 #include <math.h>
39
40 #include "../../../src/error.h"
41 #include "../../../src/const.h"
42 #include "../../../src/paint.h"
43 //#include "../../../src/draw.h"
44 #include "../../../src/xinit.h"
45 #include "../../../src/widget.h"
46 #include "../../../src/protoclient.h"
47
48 int iScaleFactor;
49
50 // Radar window is updated every RadarDivisor frames.
51 int RadarDivisor;
52 int ThreadedDraw;
53
54 extern Window draw; // we only want this one
55
56 Window rootWindow = 0; // The whole screen
57
58 static double fTwoPi = 2.0 * PI;
59
60 HINSTANCE hInstance;
61 HPALETTE myPal;
62 LOGPALETTE* myLogPal;
63 HFONT hFixedFont;
64 HHOOK mousehook = NULL;
65
66 HDC itemsDC; // for blitting items onto the screen
67 #define WINMAXCOLORS 16
68
69 int winmaxcolors;
70 int TotalPens = 0;
71
72 XIDTYPE xid[MAX_XIDS];
73 //unsigned int max_xid = 0; // point to next free one in array
74
75 BOOL bWinNT = 0; // need this 'cause Win95 can't draw a simple circle
76 BOOL bHasPal = TRUE; // Are we palette or colour based?
77 BOOL drawPending = FALSE; // try to throttle the deadly frame backup syndrome
78
79 #ifdef PENS_OF_PLENTY
80 DWORD dwdashes[NUM_DASHES+1] = { NUM_DASHES, 8, 4 };
81 DWORD dwcdashes[NUM_CDASHES+1] = { NUM_CDASHES, 3, 9 };
82 winXobj objs[WINMAXCOLORS];
83 #else
84 int cur_color;
85 winXobj objs[WINMAXCOLORS+FUNKCOLORS];
86 #endif
87
88 // We need to parse and setup the colors during Windows screen init which happens
89 // before XPilot window init.
90 extern COLORREF GetXPilotColor(int which, COLORREF defcolor);
91 extern int GetMaxColors();
92 /*extern int GetScoreFontHeight();*/
93
WinXSetupRadarWindow()94 static void WinXSetupRadarWindow()
95 {
96 if (radar)
97 {
98 if (instruments & SHOW_SLIDING_RADAR)
99 {
100 if (xid[radar].hwnd.hSaveDC != NULL)
101 {
102 ReleaseDC(xid[radar].hwnd.hWnd, xid[radar].hwnd.hBmpDC);
103 xid[radar].hwnd.hBmpDC = xid[radar].hwnd.hSaveDC;
104 xid[radar].hwnd.hSaveDC = NULL;
105 }
106 }
107 else
108 {
109 if (xid[radar].hwnd.hSaveDC == NULL)
110 {
111 HDC hNewDC = GetDC(xid[radar].hwnd.hWnd);
112 xid[radar].hwnd.hSaveDC = xid[radar].hwnd.hBmpDC;
113 xid[radar].hwnd.hBmpDC = hNewDC;
114 if (bHasPal)
115 {
116 SelectPalette(hNewDC, myPal, FALSE);
117 RealizePalette(myPal);
118 }
119 }
120 }
121 }
122 }
123
WinXDeleteDraw(int xidno)124 static void WinXDeleteDraw(int xidno)
125 {
126 HDC hSaveDC = xid[xidno].hwnd.hSaveDC;
127 HDC hBmpDC = xid[xidno].hwnd.hBmpDC;
128
129 if (xid[xidno].hwnd.type == DT_2)
130 {
131 if (xid[xidno].hwnd.hBmpa[0])
132 DeleteObject(xid[xidno].hwnd.hBmpa[0]);
133 if (xid[xidno].hwnd.hBmpa[1])
134 DeleteObject(xid[xidno].hwnd.hBmpa[1]);
135 xid[xidno].hwnd.hBmpa[0] = xid[xidno].hwnd.hBmpa[0] = NULL;
136 if (xid[xidno].hwnd.hBmpDCa[0])
137 DeleteDC(xid[xidno].hwnd.hBmpDCa[0]);
138 if (xid[xidno].hwnd.hBmpDCa[1])
139 DeleteDC(xid[xidno].hwnd.hBmpDCa[1]);
140 xid[xidno].hwnd.hBmpDCa[0] = xid[xidno].hwnd.hBmpDCa[1] = NULL;
141
142 }
143 else
144 {
145 if (xid[xidno].hwnd.hBmp)
146 DeleteObject(xid[xidno].hwnd.hBmp);
147 }
148 xid[xidno].hwnd.hBmp = NULL;
149 if (hSaveDC)
150 {
151 DeleteDC(hSaveDC);
152 if (hBmpDC)
153 ReleaseDC(xid[xidno].hwnd.hWnd, hBmpDC);
154 }
155 else if (hBmpDC)
156 DeleteDC(hBmpDC);
157
158 xid[xidno].hwnd.hBmpDC = xid[xidno].hwnd.hSaveDC = NULL;
159 xid[xidno].hwnd.hBmp = NULL;
160 }
161
162 #if 0
163 static void WinXScaled(HDC hDC, int cx, int cy)
164 {
165 if (iScaleFactor != SCALEPREC)
166 {
167 SetMapMode(hDC, MM_ANISOTROPIC);
168
169 SetWindowExtEx(hDC, WinXUnscale(cx), WinXUnscale(cy), NULL);
170 SetWindowOrgEx(hDC, 0, 0, NULL);
171 SetViewportExtEx(hDC, cx, cy, NULL);
172 SetViewportOrgEx(hDC, 0, 0, NULL);
173 }
174 else SetMapMode(hDC, MM_TEXT);
175 }
176
177 static void WinXUnscaled(HDC hDC)
178 {
179 SetMapMode(hDC, MM_TEXT);
180 }
181 #endif
182
WinXCreateBitmapForXid(HWND hwnd,XID xidno,int cx,int cy)183 static void WinXCreateBitmapForXid(HWND hwnd, XID xidno, int cx, int cy)
184 {
185 HDC hBmpDC, hDC = GetDC(hwnd);
186 HBITMAP hBmp;
187 RECT r;
188
189 WinXDeleteDraw(xidno);
190 if (ThreadedDraw && xidno == draw)
191 {
192 xid[xidno].hwnd.hBmpa[1] = CreateCompatibleBitmap(hDC, cx, cy);
193 xid[xidno].hwnd.hBmpa[0] = CreateCompatibleBitmap(hDC, cx, cy);
194 hBmp = xid[xidno].hwnd.hBmp= xid[xidno].hwnd.hBmpa[0];
195 xid[xidno].hwnd.hBmpDCa[0] = CreateCompatibleDC(hDC);
196 xid[xidno].hwnd.hBmpDCa[1] = CreateCompatibleDC(hDC);
197 xid[xidno].hwnd.hBmpDC = xid[xidno].hwnd.hBmpDCa[0];
198 xid[xidno].hwnd.filling = 0;
199 xid[xidno].hwnd.drawtype = DT_2;
200 SelectObject(xid[xidno].hwnd.hBmpDCa[0], xid[xidno].hwnd.hBmpa[0]);
201 SelectObject(xid[xidno].hwnd.hBmpDCa[1], xid[xidno].hwnd.hBmpa[1]);
202 SetBkMode(xid[xidno].hwnd.hBmpDCa[0], TRANSPARENT);
203 SetBkMode(xid[xidno].hwnd.hBmpDCa[1], TRANSPARENT);
204 SelectPalette(xid[xidno].hwnd.hBmpDCa[0], myPal, FALSE);
205 RealizePalette(xid[xidno].hwnd.hBmpDCa[0]);
206 SelectPalette(xid[xidno].hwnd.hBmpDCa[1], myPal, FALSE);
207 RealizePalette(xid[xidno].hwnd.hBmpDCa[1]);
208 }
209 else
210 {
211 xid[xidno].hwnd.hBmp = hBmp = CreateCompatibleBitmap(hDC, cx, cy);
212 xid[xidno].hwnd.hBmpDC = hBmpDC = CreateCompatibleDC(hDC);
213 SelectObject(hBmpDC, hBmp);
214 }
215 // if (xidno == (int)draw)
216 // WinXScaled(hBmpDC, cx, cy);
217
218
219 if (bHasPal)
220 {
221 SelectPalette(hBmpDC, myPal, FALSE);
222 RealizePalette(hBmpDC);
223 }
224 SetBkMode(hBmpDC, TRANSPARENT);
225 r.left = 0; r.top = 0;
226 r.right = cx; r.bottom = cy;
227 FillRect(hBmpDC, &r, GetStockObject(BLACK_BRUSH));
228 WinXSetupRadarWindow();
229 ReleaseDC(hwnd, hDC);
230 }
231
ChangePalette(HWND hWnd)232 BOOL ChangePalette(HWND hWnd)
233 {
234 XID i;
235 HDC hDC;
236 HPALETTE hOldPal;
237
238 for (i = 0; i < MAX_XIDS; i += 1)
239 {
240 if (xid[i].type == XIDTYPE_HWND)
241 {
242 HWND hwnd = xid[i].hwnd.hWnd;
243
244 hDC = xid[i].hwnd.hBmpDC;
245 hOldPal = SelectPalette(hDC, myPal, FALSE);
246 RealizePalette(hDC);
247 SelectPalette(hDC, hOldPal, FALSE);
248
249 hDC = GetDC(hwnd);
250 hOldPal = SelectPalette(hDC, myPal, FALSE);
251 RealizePalette(hDC);
252 SelectPalette(hDC, hOldPal, FALSE);
253 ReleaseDC(hwnd, hDC);
254
255 InvalidateRect(hwnd, NULL, FALSE);
256 }
257 }
258
259 return TRUE;
260 }
261
WinXwindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)262 LRESULT CALLBACK WinXwindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
263 {
264 switch (uMsg)
265 {
266 case WM_CREATE:
267 {
268 LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
269 int xidno = (int)lpcs->lpCreateParams;
270
271 Trace("WM_CREATE %d %d/%d %s:%d\n", xidno, lpcs->cx, lpcs->cy, xid[xidno].any.file, xid[xidno].any.line);
272 WinXCreateBitmapForXid(hwnd, xidno, lpcs->cx, lpcs->cy);
273 SetWindowWord(hwnd, 0, (WORD)xidno);
274 return DefWindowProc(hwnd, uMsg, wParam, lParam);
275 }
276
277 case WM_DESTROY:
278 {
279 XID xidno = (int)GetWindowWord(hwnd, 0);
280
281 if (Widget_window(motd_viewer) == xidno)
282 Motd_destroy();
283 if (Widget_window(keys_viewer) == xidno)
284 Keys_destroy();
285 WinXDeleteDraw(xidno);
286 return DefWindowProc(hwnd, uMsg, wParam, lParam);
287 }
288
289 case WM_SIZE:
290 {
291 int xidno = (int)GetWindowWord(hwnd, 0);
292 if (xidno > 0 && xidno < MAX_XIDS && xid[xidno].hwnd.hBmp)
293 {
294 int width = LOWORD(lParam);
295 int height = HIWORD(lParam);
296 Trace("WM_SIZE %d %d/%d %s:%d\n", xidno, width, height, xid[xidno].any.file, xid[xidno].any.line);
297 WinXCreateBitmapForXid(hwnd, xidno, width, height);
298 }
299 return DefWindowProc(hwnd, uMsg, wParam, lParam);
300 }
301 case WM_LBUTTONDOWN:
302 {
303 int xidno = (int)GetWindowWord(hwnd, 0);
304 if (xid[xidno].hwnd.event_mask & ButtonPressMask)
305 {
306 XEvent event;
307 XButtonEvent* button = (XButtonEvent*)&event;
308 POINT pt;
309
310 pt.x = LOWORD(lParam);
311 pt.y = HIWORD(lParam);
312 MapWindowPoints(xid[xidno].hwnd.hWnd, xid[top].hwnd.hWnd,
313 &pt, 1);
314 button->type = ButtonPress;
315 button->window = xidno;
316 button->x = LOWORD(lParam);
317 button->y = HIWORD(lParam);
318 button->x_root = pt.x;
319 button->y_root = pt.y;
320 button->button = Button1;
321 win_xevent(event);
322 }
323 return DefWindowProc(hwnd, uMsg, wParam, lParam);
324 }
325 case WM_LBUTTONUP:
326 {
327 int xidno = (int)GetWindowWord(hwnd, 0);
328
329 if (xid[xidno].hwnd.event_mask & ButtonReleaseMask)
330 {
331 XEvent event;
332 XButtonEvent* button = (XButtonEvent*)&event;
333
334 Trace("ButtonUp in %d %s:%d\n", xidno, xid[xidno].any.file, xid[xidno].any.line);
335 button->type = ButtonRelease;
336 button->window = xidno;
337 button->x = LOWORD(lParam);
338 button->y = HIWORD(lParam);
339 button->button = Button1;
340 if (win_xevent(event) == -1)
341 {
342 WinXExit();
343 }
344 return(0);
345 }
346 return DefWindowProc(hwnd, uMsg, wParam, lParam);
347 }
348 case WM_MBUTTONDOWN:
349 {
350 int xidno = (int)GetWindowWord(hwnd, 0);
351 if (xid[xidno].hwnd.event_mask & ButtonPressMask)
352 {
353 XEvent event;
354 XButtonEvent* button = (XButtonEvent*)&event;
355 POINT pt;
356
357 pt.x = LOWORD(lParam);
358 pt.y = HIWORD(lParam);
359 MapWindowPoints(xid[xidno].hwnd.hWnd, xid[top].hwnd.hWnd,
360 &pt, 1);
361 button->type = ButtonPress;
362 button->window = xidno;
363 button->x = LOWORD(lParam);
364 button->y = HIWORD(lParam);
365 button->x_root = pt.x;
366 button->y_root = pt.y;
367 button->button = Button2;
368 win_xevent(event);
369 }
370 return DefWindowProc(hwnd, uMsg, wParam, lParam);
371 }
372 case WM_MBUTTONUP:
373 {
374 int xidno = (int)GetWindowWord(hwnd, 0);
375
376 if (xid[xidno].hwnd.event_mask & ButtonReleaseMask)
377 {
378 XEvent event;
379 XButtonEvent* button = (XButtonEvent*)&event;
380
381 Trace("ButtonUp in %d %s:%d\n", xidno, xid[xidno].any.file, xid[xidno].any.line);
382 button->type = ButtonRelease;
383 button->window = xidno;
384 button->x = LOWORD(lParam);
385 button->y = HIWORD(lParam);
386 button->button = Button2;
387 if (win_xevent(event) == -1)
388 {
389 WinXExit();
390 }
391 return(0);
392 }
393 return DefWindowProc(hwnd, uMsg, wParam, lParam);
394 }
395 case WM_RBUTTONDOWN:
396 {
397 int xidno = (int)GetWindowWord(hwnd, 0);
398 if (xid[xidno].hwnd.event_mask & ButtonPressMask)
399 {
400 XEvent event;
401 XButtonEvent* button = (XButtonEvent*)&event;
402 POINT pt;
403
404 pt.x = LOWORD(lParam);
405 pt.y = HIWORD(lParam);
406 MapWindowPoints(xid[xidno].hwnd.hWnd, xid[top].hwnd.hWnd,
407 &pt, 1);
408 button->type = ButtonPress;
409 button->window = xidno;
410 button->x = LOWORD(lParam);
411 button->y = HIWORD(lParam);
412 button->x_root = pt.x;
413 button->y_root = pt.y;
414 button->button = Button3;
415 win_xevent(event);
416 }
417 return DefWindowProc(hwnd, uMsg, wParam, lParam);
418 }
419 case WM_RBUTTONUP:
420 {
421 int xidno = (int)GetWindowWord(hwnd, 0);
422
423 if (xid[xidno].hwnd.event_mask & ButtonReleaseMask)
424 {
425 XEvent event;
426 XButtonEvent* button = (XButtonEvent*)&event;
427
428 Trace("ButtonUp in %d %s:%d\n", xidno, xid[xidno].any.file, xid[xidno].any.line);
429 button->type = ButtonRelease;
430 button->window = xidno;
431 button->x = LOWORD(lParam);
432 button->y = HIWORD(lParam);
433 button->button = Button3;
434 if (win_xevent(event) == -1)
435 {
436 WinXExit();
437 }
438 return(0);
439 }
440 return DefWindowProc(hwnd, uMsg, wParam, lParam);
441 }
442 case WM_MOUSEMOVE:
443 {
444 XID xidno = (int)GetWindowWord(hwnd, 0);
445 XEvent event;
446 XID i;
447 XAnyEvent* enter = (XAnyEvent*)&event;
448
449 Trace("MouseMove in %d %d/%d %s:%d\n", xidno,
450 LOWORD(lParam), HIWORD(lParam), xid[xidno].any.file, xid[xidno].any.line);
451
452 enter->type = LeaveNotify;
453 for (i=0; i<MAX_XIDS; i++)
454 {
455 if (i != xidno && xid[i].type == XIDTYPE_HWND && xid[i].hwnd.mouseover
456 && xid[i].hwnd.event_mask & LeaveWindowMask)
457 {
458 Trace("LeaveNotify %d %s:%d\n", xidno, xid[xidno].any.file, xid[xidno].any.line);
459 enter->window = i;
460 win_xevent(event);
461 xid[i].hwnd.mouseover = FALSE;
462 }
463 }
464 if (xid[xidno].hwnd.event_mask & PointerMotionMask)
465 {
466 XMotionEvent* me = (XMotionEvent*)&event;
467 me->type = MotionNotify;
468 me->window = xidno;
469 me->x = LOWORD(lParam);
470 me->y = HIWORD(lParam);
471 // if (me->x != draw_width/2 && me->y != draw_height/2)
472 {
473 win_xevent(event);
474 // SetCursorPos(draw_width/2, draw_height/2);
475 }
476 // return(0);
477 }
478 else if (!xid[xidno].hwnd.mouseover) /* PointerMotionMask is only on captured window */
479 { /* so don't do the mouseover event */
480 if (xid[xidno].hwnd.event_mask & EnterWindowMask)
481 {
482 Trace("EnterNotify %d %s:%d\n", xidno, xid[xidno].any.file, xid[xidno].any.line);
483 enter->type = EnterNotify;
484 enter->window = xidno;
485 win_xevent(event);
486 }
487 xid[xidno].hwnd.mouseover = TRUE;
488 }
489
490 return DefWindowProc(hwnd, uMsg, wParam, lParam);
491 }
492
493 case WM_ERASEBKGND:
494 {
495 RECT rect;
496 if (GetClientRect(hwnd, &rect))
497 {
498 HDC hBmpDC;
499 XID xidno = (int)GetWindowWord(hwnd, 0);
500 hBmpDC = xid[xidno].hwnd.hBmpDC;
501 if (hBmpDC)
502 {
503 Trace("WM_ERASEBKGND %d color=%d %d/%d %d/%d\n", xidno, xid[xidno].hwnd.bgcolor, rect.left, rect.top, rect.right, rect.bottom);
504 FillRect(hBmpDC, &rect, objs[xid[xidno].hwnd.bgcolor].brush);
505 }
506 }
507 return(0);
508 }
509 case WM_PAINT:
510 {
511 RECT rect;
512 if (GetUpdateRect(hwnd, &rect, FALSE))
513 {
514 XID xidno = (int)GetWindowWord(hwnd, 0);
515 // if (xidno == draw)
516 // return DefWindowProc(hwnd, uMsg, wParam, lParam);
517 if (xidno >= 0 && xidno < MAX_XIDS)
518 {
519 HDC hBmpDC;
520
521 hBmpDC = xid[xidno].hwnd.hBmpDC;
522 if (hBmpDC)
523 {
524 PAINTSTRUCT ps;
525 HDC hDC;
526 XEvent event;
527 XExposeEvent* expose = (XExposeEvent*)&event;
528
529 if (ThreadedDraw && xidno == (int)draw)
530 {
531 ValidateRect(hwnd, &rect);
532 winXTDraw(NULL, xidno, &rect);
533 }
534 else
535 {
536 hDC = BeginPaint(hwnd, &ps);
537
538 if (xid[xidno].hwnd.event_mask & ExposureMask)
539 {
540 expose->type = Expose;
541 expose->window = xidno;
542 expose->x = rect.left;
543 expose->y = rect.top;
544 expose->width = rect.right-rect.left;
545 expose->height = rect.bottom-rect.top;
546 expose->count = 0;
547 Trace("Expose %d %s:%d\n", xidno, xid[xidno].any.file, xid[xidno].any.line);
548 win_xevent(event);
549 }
550 if (bHasPal)
551 {
552 SelectPalette(hDC, myPal, FALSE);
553 RealizePalette(hDC);
554 }
555 if (xidno == (int)draw)
556 {
557 // RECT r;
558 // WinXUnscaled(hBmpDC);
559 if (ThreadedDraw)
560 {
561 ValidateRect(hwnd, &rect);
562 winXTDraw(hDC, xidno, &rect);
563 }
564 else
565 {
566 BitBlt(hDC, rect.left, rect.top, rect.right, rect.bottom,
567 hBmpDC, rect.left, rect.top, SRCCOPY);
568 }
569 // GetClientRect(hwnd, &r);
570 // WinXScaled(hBmpDC, r.right - r.left, r.bottom - r.top);
571 drawPending = FALSE;
572 }
573 else
574 { /* not the main playfield window */
575 BitBlt(hDC, rect.left, rect.top, rect.right, rect.bottom,
576 hBmpDC, rect.left, rect.top, SRCCOPY);
577 }
578 EndPaint(hwnd, &ps);
579 }
580 return 0;
581 }
582 }
583 }
584 return DefWindowProc(hwnd, uMsg, wParam, lParam);
585 }
586 default:
587 return DefWindowProc(hwnd, uMsg, wParam, lParam);
588 }
589 return 0;
590 }
591
WinXPColour(int ColourNo)592 COLORREF WinXPColour(int ColourNo)
593 {
594 if (bHasPal)
595 return PALETTEINDEX(ColourNo);
596 return objs[ColourNo].color;
597 }
598
599 #if 0
600 LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam, LPARAM lParam)
601 {
602 XEvent event;
603 XMotionEvent* me = (XMotionEvent*)&event;
604 if (nCode < 0)
605 return(CallNextHookEx(mousehook, nCode, wParam, lParam));
606 if (!pointerControl)
607 return(0);
608 me->type = MotionNotify;
609 me->window = draw;
610 me->x = ((MOUSEHOOKSTRUCT*)lParam)->pt.x;
611 me->y = ((MOUSEHOOKSTRUCT*)lParam)->pt.y;
612 win_xevent(event);
613
614 return(1);
615
616 }
617 #endif
618
InitWinXClass()619 static void InitWinXClass()
620 {
621 WNDCLASS wc;
622
623 // Fill in window class structure with parameters
624 wc.style = 0;
625 wc.lpfnWndProc = WinXwindowProc;
626 wc.cbClsExtra = 0;
627 wc.cbWndExtra = sizeof(WORD); // For the xidno of the window
628 wc.hInstance = hInstance;
629 wc.hIcon = NULL;
630 wc.hCursor = LoadCursor(0, IDC_ARROW);
631 wc.hbrBackground = GetStockObject(BLACK_BRUSH);
632 wc.lpszMenuName = NULL;
633 wc.lpszClassName = "XPilotWin";
634
635 RegisterClass(&wc);
636 }
637
InitWinX(HWND hWnd)638 void InitWinX(HWND hWnd)
639 {
640 int i;
641 char s[80];
642 HDC tDC = GetDC(hWnd);
643 // TEXTMETRIC tm;
644
645 memset(&xid, 0, sizeof(xid));
646 InitWinXClass();
647 xid[0].hwnd.hWnd = hWnd;
648 xid[0].type = XIDTYPE_HWND;
649 // max_xid = 1;
650
651 itemsDC = NULL;
652
653 bWinNT = GetVersion() & 0x80000000 ? FALSE : TRUE;
654
655 myLogPal = malloc(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*16);
656 myLogPal->palVersion = 0x300;
657 // "#000000", "#FFFFFF", "#4E7CFF", "#FF3A27",
658 // "#33BB44", "#992200", "#BB7700", "#EE9900",
659 // "#770000", "#CC4400", "#DD8800", "#FFBB11",
660 // "#9f9f9f", "#5f5f5f", "#dfdfdf", "#202020"
661 objs[0].color = GetXPilotColor ( 0, RGB(0x00,0x00,0x00));
662 objs[1].color = GetXPilotColor ( 1, RGB(0xFF,0xFF,0xFF));
663 objs[2].color = GetXPilotColor ( 2, RGB(0x4E,0x7C,0xFF));
664 objs[3].color = GetXPilotColor ( 3, RGB(0xFF,0x3A,0x27));
665 objs[4].color = GetXPilotColor ( 4, RGB(0x33,0xBB,0x44));
666 objs[5].color = GetXPilotColor ( 5, RGB(0x99,0x22,0x00));
667 objs[6].color = GetXPilotColor ( 6, RGB(0xBB,0x77,0x00));
668 objs[7].color = GetXPilotColor ( 7, RGB(0xEE,0x99,0x00));
669 objs[8].color = GetXPilotColor ( 8, RGB(0x77,0x00,0x00));
670 objs[9].color = GetXPilotColor ( 9, RGB(0xCC,0x44,0x00));
671 objs[10].color = GetXPilotColor(10, RGB(0xDD,0x88,0x00));
672 objs[11].color = GetXPilotColor(11, RGB(0xFF,0xBB,0x11));
673 objs[12].color = GetXPilotColor(12, RGB(0x9F,0x9F,0x9F));
674 objs[13].color = GetXPilotColor(13, RGB(0x5F,0x5F,0x5F));
675 objs[14].color = GetXPilotColor(14, RGB(0xDF,0xDF,0xDF));
676 objs[15].color = GetXPilotColor(15, RGB(0x20,0x20,0x20));
677
678 winmaxcolors = GetMaxColors();
679 //bHasPal = (GetDeviceCaps(tDC, RASTERCAPS) & RC_PALETTE) != 0;
680 if (!winmaxcolors)
681 winmaxcolors = 8;
682 if (winmaxcolors < 4)
683 error("I can't allocate 4 (colors or pens or brushes). XPilot is probably not going to look very nice on this display");
684 else if (winmaxcolors < 8)
685 winmaxcolors = 4;
686 else if (winmaxcolors < 16)
687 winmaxcolors = 8;
688 else
689 winmaxcolors = 16;
690 maxColors = winmaxcolors;
691 myLogPal->palNumEntries = winmaxcolors;
692 for (i=0; i<winmaxcolors; i++)
693 {
694 myLogPal->palPalEntry[i].peFlags = PC_RESERVED;
695 // myLogPal->palPalEntry[i].peFlags = PC_EXPLICIT;
696 myLogPal->palPalEntry[i].peRed = GetRValue(objs[i].color);
697 myLogPal->palPalEntry[i].peGreen = GetGValue(objs[i].color);
698 myLogPal->palPalEntry[i].peBlue = GetBValue(objs[i].color);
699
700 #ifdef PENS_OF_PLENTY
701 objs[i].brush = CreateSolidBrush(WinXPColour(i));
702 if (!objs[i].brush)
703 { sprintf(s, "maxcolors=%d can't create brush %d", winmaxcolors, i); error(s); }
704 #else
705 objs[i].pen = CreatePen(PS_SOLID, 1, WinXPColour(i));
706 if (!objs[i].pen)
707 { sprintf(s, "maxcolors=%d can't create pen %d", winmaxcolors, i); error(s); }
708 objs[i].brush = CreateSolidBrush(WinXPColour(i));
709 if (!objs[i].brush)
710 { sprintf(s, "maxcolors=%d can't create brush %d", winmaxcolors, i); error(s); }
711 Trace("%d: pen=%08X brush=%08X\n", i, objs[i].pen, objs[i].brush);
712 #endif
713 }
714
715 #ifndef PENS_OF_PLENTY
716 objs[WHITE+CLOAKCOLOROFS].color = objs[WHITE].color;
717 objs[WHITE+CLOAKCOLOROFS].brush = objs[WHITE].brush;
718 objs[WHITE+CLOAKCOLOROFS].pen = CreatePen(PS_DOT, 1, WinXPColour(WHITE));
719 if (!objs[WHITE+CLOAKCOLOROFS].pen)
720 { sprintf(s, "maxcolors=%d can't create pen %d", winmaxcolors, WHITE+CLOAKCOLOROFS); error(s); }
721 objs[BLUE+CLOAKCOLOROFS].color = objs[BLUE].color;
722 objs[BLUE+CLOAKCOLOROFS].brush = objs[BLUE].brush;
723 objs[BLUE+CLOAKCOLOROFS].pen = CreatePen(PS_DOT, 1, WinXPColour(BLUE));
724 if (!objs[BLUE+CLOAKCOLOROFS].pen)
725 { sprintf(s, "maxcolors=%d can't create pen %d", winmaxcolors, BLUE+CLOAKCOLOROFS); error(s); }
726 objs[LASERCOLOR].color = objs[RED].color;
727 objs[LASERCOLOR].brush = objs[RED].brush;
728 objs[LASERCOLOR].pen = CreatePen(PS_SOLID, 2, WinXPColour(RED));
729 if (!objs[LASERCOLOR].pen)
730 { sprintf(s, "maxcolors=%d can't create pen %d", winmaxcolors, LASERCOLOR); error(s); }
731 objs[MISSILECOLOR].color = objs[RED].color;
732 objs[MISSILECOLOR].brush = objs[RED].brush;
733 objs[MISSILECOLOR].pen = CreatePen(PS_SOLID, 2, WinXPColour(WHITE));
734 if (!objs[MISSILECOLOR].pen)
735 { sprintf(s, "maxcolors=%d can't create pen %d", winmaxcolors, MISSILECOLOR); error(s); }
736 objs[LASERTEAMCOLOR].color = objs[BLUE].color;
737 objs[LASERTEAMCOLOR].brush = objs[BLUE].brush;
738 objs[LASERTEAMCOLOR].pen = CreatePen(PS_SOLID, 2, WinXPColour(BLUE));
739 if (!objs[LASERTEAMCOLOR].pen)
740 { sprintf(s, "maxcolors=%d can't create pen %d", winmaxcolors, LASERTEAMCOLOR); error(s); }
741 #endif
742
743 myPal = CreatePalette(myLogPal);
744 SelectPalette(tDC, myPal, FALSE);
745 if (!myPal)
746 error("Can't create palette");
747
748 for (i=0; i<NUM_ITEMS; i++)
749 {
750 itemBitmaps[i][ITEM_HUD] = XIDTYPE_UNUSED;
751 itemBitmaps[i][ITEM_PLAYFIELD] = XIDTYPE_UNUSED;
752 }
753 // mousehook = SetWindowsHookEx(WH_MOUSE, MouseHook, NULL, GetCurrentThreadId());
754 }
WinXFree(XID i)755 void WinXFree(XID i)
756 {
757 switch (xid[i].type)
758 {
759 case XIDTYPE_FONT:
760 free(xid[i].font.font);
761 break;
762 case XIDTYPE_PIXMAP:
763 DeleteObject(xid[i].hpix.hbm);
764 DeleteDC(xid[i].hpix.hDC);
765 break;
766 case XIDTYPE_HWND:
767 WinXDeleteDraw(i);
768 break;
769 }
770 xid[i].type = XIDTYPE_UNUSED;
771 }
772
WinXShutdown()773 void WinXShutdown()
774 {
775 XID i;
776
777 if (mousehook)
778 UnhookWindowsHookEx(mousehook);
779 free(myLogPal);
780 for (i=0; i<MAX_XIDS; i++)
781 {
782 WinXFree(i);
783 }
784
785 for (i=0; i<(unsigned)maxColors; i++)
786 {
787 #ifdef PENS_OF_PLENTY
788 if (objs[i].pen != NULL)
789 DeleteObject(objs[i].pen);
790 if (objs[i].dashpen != NULL)
791 DeleteObject(objs[i].dashpen);
792 if (objs[i].cdashpen != NULL)
793 DeleteObject(objs[i].cdashpen);
794 if (objs[i].fatpen != NULL)
795 DeleteObject(objs[i].fatpen);
796 if (objs[i].brush != NULL)
797 DeleteObject(objs[i].brush);
798 #else
799 if (objs[i].pen)
800 DeleteObject(objs[i].pen);
801 if (objs[i].brush)
802 DeleteObject(objs[i].brush);
803
804 #endif
805 }
806 }
807
808 #ifdef PENS_OF_PLENTY
WinXMakePen(int cur_color,int Style,int Width)809 static HPEN WinXMakePen(int cur_color, int Style, int Width)
810 {
811 HPEN hPen;
812
813 if (bWinNT && Style != PS_SOLID)
814 {
815 LOGBRUSH lb;
816 DWORD *dshs;
817
818 lb.lbStyle = BS_SOLID;
819 lb.lbColor = WinXPColour(cur_color);
820 lb.lbHatch = 0;
821
822 if (Style = PS_DASH)
823 dshs = dwdashes;
824 else
825 dshs = dwcdashes;
826 hPen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, Width, &lb, dshs[0], &dshs[1]);
827 }
828 else hPen = CreatePen(Style, Width, WinXPColour(cur_color));
829
830 TotalPens += 1;
831
832 return hPen;
833 }
834
WinXSetPen(int xidno)835 static void WinXSetPen(int xidno)
836 {
837 HDC hDC = xid[xidno].hwnd.hBmpDC;
838 HPEN hPen = NULL;
839 int cur_color = xid[xidno].hwnd.cur_color;
840
841 if (xid[xidno].hwnd.line_style == LineSolid)
842 {
843 if (xid[xidno].hwnd.line_width > 2)
844 {
845 if (objs[cur_color].fatpen == NULL)
846 objs[cur_color].fatpen = WinXMakePen(WinXPColour(cur_color), PS_SOLID, 3);
847 hPen = objs[cur_color].fatpen;
848 }
849 else
850 {
851 if (objs[cur_color].pen == NULL)
852 objs[cur_color].pen = WinXMakePen(WinXPColour(cur_color), PS_SOLID, 0);
853 hPen = objs[cur_color].pen;
854 }
855 }
856 else
857 {
858 if (xid[xidno].hwnd.nodash)
859 {
860 if (objs[cur_color].cdashpen == NULL)
861 objs[cur_color].cdashpen = WinXMakePen(cur_color, PS_DOT, 0);
862 hPen = objs[cur_color].cdashpen;
863 }
864 else
865 {
866 if (objs[cur_color].dashpen == NULL)
867 objs[cur_color].dashpen = WinXMakePen(cur_color, PS_DASH, 0);
868 hPen = objs[cur_color].dashpen;
869 }
870 }
871 if (hPen)
872 SelectObject(hDC, hPen);
873 }
874 #endif
875
876 ////////////////////////////////////////////////////////
877 // These are for SysInfo, we hide the details from him
WinXGetDrawDC()878 HDC WinXGetDrawDC()
879 {
880 return(GetDC(xid[draw].hwnd.hWnd));
881 }
882
WinXReleaseDrawDC(HDC hDC)883 int WinXReleaseDrawDC(HDC hDC)
884 {
885 return(ReleaseDC(xid[draw].hwnd.hWnd, hDC));
886 }
887
888 ////////////////////////////////////////////////////////
WinXGetWindowRectangle(Window window,XRectangle * rect)889 int WinXGetWindowRectangle(Window window, XRectangle* rect)
890 {
891 RECT r;
892 GetClientRect(xid[window].hwnd.hWnd, &r);
893 rect->x = (short)WinXUnscale(r.left);
894 rect->y = (short)WinXUnscale(r.top);
895 rect->width = (unsigned short)WinXUnscale(r.right - r.left);
896 rect->height = (unsigned short)WinXUnscale(r.bottom - r.top);
897 return(1);
898 }
899
900 #if 0
901 void WinXSetBackColor(GC gc, unsigned long background)
902 {
903 HDC hDC = xid[xid[gc].hgc.xidhwnd].hwnd.hBmpDC;
904 SetBkColor(hDC, background);
905 SetBkMode(hDC, TRANSPARENT);
906 }
907 #endif
908
909 // scarfed from a M$ KB article. Apparently, Win95 doesn't support AngleArc
AngleArc2(HDC hdc,int X,int Y,DWORD dwRadius,double fStartDegrees,double fSweepDegrees,BOOL bFilled)910 BOOL AngleArc2(HDC hdc, int X, int Y, DWORD dwRadius,
911 double fStartDegrees, double fSweepDegrees, BOOL bFilled)
912 {
913 int iXStart, iYStart; // End point of starting radial line
914 int iXEnd, iYEnd; // End point of ending radial line
915 double fStartRadians; // Start angle in radians
916 double fEndRadians; // End angle in radians
917 BOOL bResult; // Function result
918
919 /* Get the starting and ending angle in radians */
920 if (fSweepDegrees > 0.0) {
921 fStartRadians = ((fStartDegrees / 360.0) * fTwoPi);
922 fEndRadians = (((fStartDegrees + fSweepDegrees) / 360.0) * fTwoPi);
923 } else {
924 fStartRadians = (((fStartDegrees + fSweepDegrees) / 360.0) * fTwoPi);
925 fEndRadians = ((fStartDegrees / 360.0) * fTwoPi);
926 }
927
928 /* Calculate a point on the starting radial line via */
929 /* polar -> cartesian conversion */
930 iXStart = X + (int)((double)dwRadius * (double)cos(fStartRadians));
931 iYStart = Y - (int)((double)dwRadius * (double)sin(fStartRadians));
932
933 /* Calculate a point on the ending radial line via */
934 /* polar -> cartesian conversion */
935 iXEnd = X + (int)((double)dwRadius * (double)cos(fEndRadians));
936 iYEnd = Y - (int)((double)dwRadius * (double)sin(fEndRadians));
937
938 /* Draw a line to the starting point */
939 LineTo(hdc, iXStart, iYStart);
940
941 /* Draw the arc */
942 if (bFilled)
943 bResult = Pie(hdc, X - dwRadius, Y - dwRadius,
944 X + dwRadius, Y + dwRadius,
945 iXStart, iYStart, iXEnd, iYEnd);
946 else
947 bResult = Arc(hdc, X - dwRadius, Y - dwRadius,
948 X + dwRadius, Y + dwRadius,
949 iXStart, iYStart, iXEnd, iYEnd);
950
951 /* Move to the ending point - Arc() wont do this and ArcTo() */
952 /* wont work on Win32s or Win16 */
953 MoveToEx(hdc, iXEnd, iYEnd, NULL);
954
955 return bResult;
956 }
957
WinXParseFont(LOGFONT * lf,const char * name)958 void WinXParseFont(LOGFONT* lf, const char* name)
959 {
960 #define MAX_FFLDS 14
961 static char sepa[] = "-\n\r";
962 char* t[MAX_FFLDS];
963 char* s = malloc(strlen(name)+1);
964 int i;
965
966 strcpy(s, name);
967
968 t[0] = strtok(s, sepa);
969 for (i=1; i<MAX_FFLDS; i++)
970 t[i] = strtok(NULL, sepa);
971 // lf->lfHeight = atoi(t[6]) * 100 / iScaleFactor;
972 // lf->lfHeight = (int)(atoi(t[6]) / scaleFactor);
973 lf->lfHeight = (int)(atoi(t[6]));
974 if (!lf->lfHeight)
975 lf->lfHeight = 14;
976 lf->lfWeight = *t[2] == 'b' ? FW_BOLD : FW_NORMAL;
977 lf->lfItalic = *t[3] == 'i' ? TRUE : FALSE;
978 switch (*t[1])
979 {
980 case 't': /* times */
981 lf->lfPitchAndFamily = FF_ROMAN;
982 break;
983 case 'f': /* fixed */
984 lf->lfPitchAndFamily = FIXED_PITCH;
985 break;
986 case 'c': /* courier */
987 lf->lfPitchAndFamily = FF_MODERN;
988 break;
989 }
990 free(s);
991 #undef MAX_FFLDS
992 }
993
WinXLoadFont(const char * name)994 XFontStruct* WinXLoadFont(const char* name)
995 {
996 XID txid;
997 XFontStruct* fs = malloc(sizeof(XFontStruct));
998 Trace("WinXLoadFont: creating font <%s>\n", name);
999 memset(fs, 0, sizeof(XFontStruct));
1000 WinXParseFont(&fs->lf, name);
1001 // fs->ascent = fs->lf.lfHeight * 100 / iScaleFactor;
1002 // fs->ascent = (int)(fs->lf.lfHeight / scaleFactor);
1003 fs->ascent = (int)(fs->lf.lfHeight);
1004 fs->hFont = CreateFontIndirect(&fs->lf);
1005
1006 txid = GetFreeXid();
1007 xid[txid].type = XIDTYPE_FONT;
1008 xid[txid].font.font = fs;
1009 fs->fid = txid;
1010 return(fs);
1011 }
1012
1013
XParseColor(Display * display,Colormap colormap,char * spec,XColor * exact_def_return)1014 XParseColor(Display* display, Colormap colormap, char* spec,
1015 XColor* exact_def_return)
1016 {
1017 Trace("Parsing color <%s>\n", spec);
1018 return(0);
1019 }
1020
WinXCreateBitmapFromData(Display * dpy,Drawable d,char * data,unsigned int width,unsigned int height,int color)1021 Pixmap WinXCreateBitmapFromData(Display* dpy, Drawable d, char* data,
1022 unsigned int width, unsigned int height, int color)
1023 {
1024 HBITMAP hbm;
1025 int i;
1026 int j;
1027 WORD* e;
1028
1029 BITMAP bm = {
1030 0, // LONG bmType;
1031 16, // LONG bmWidth;
1032 16, // LONG bmHeight;
1033 4, // LONG bmWidthBytes;
1034 1, // WORD bmPlanes;
1035 1, // WORD bmBitsPixel;
1036 NULL // LPVOID bmBits;
1037 };
1038 RECT rect = { 0,0,16,16};
1039
1040 HDC hDC = GetDC(xid[d].hwnd.hWnd);
1041 HDC hDCb = CreateCompatibleDC(hDC);
1042
1043 hbm = CreateCompatibleBitmap(hDC, width, height);
1044 SelectObject(hDCb, hbm);
1045 if (bHasPal)
1046 {
1047 SelectPalette(hDCb, myPal, FALSE);
1048 RealizePalette(hDCb);
1049 }
1050
1051 FillRect(hDCb, &rect, GetStockObject(BLACK_BRUSH));
1052 if (!hbm)
1053 error("Can't create item bitmaps");
1054 if (width != 16 || height != 16)
1055 error("Can only create 16x16 bitmaps");
1056 e = (WORD*)data;
1057 for (i=0; i<16; i++)
1058 {
1059 WORD w = *e++;
1060 WORD z = 0;
1061 for (j=0; j<16; j++) // swap the bits in the bytes
1062 if (w & (1<<j))
1063 SetPixelV(hDCb, j, i, WinXPColour(color));
1064 }
1065
1066 DeleteDC(hDCb);
1067 ReleaseDC(xid[d].hwnd.hWnd, hDC);
1068 return((Pixmap)hbm);
1069 }
1070
XResizeWindow(Display * dpy,Window w,unsigned int width,unsigned int height)1071 XResizeWindow(Display* dpy, Window w, unsigned int width, unsigned int height)
1072 {
1073 HWND hWnd = xid[w].hwnd.hWnd;
1074
1075 SetWindowPos(hWnd, NULL, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER);
1076 return(0);
1077 }
1078
WinXResize(void)1079 void WinXResize(void)
1080 {
1081 RECT rect;
1082
1083 draw_width = WinXUnscale(draw_width);
1084 draw_height = WinXUnscale(draw_height);
1085
1086 if (radar && (instruments & SHOW_SLIDING_RADAR))
1087 {
1088 GetClientRect(xid[radar].hwnd.hWnd, &rect);
1089 InvalidateRect(xid[radar].hwnd.hWnd, &rect, FALSE);
1090 }
1091 if (draw)
1092 {
1093 GetClientRect(xid[draw].hwnd.hWnd, &rect);
1094 InvalidateRect(xid[draw].hwnd.hWnd, &rect, FALSE);
1095 }
1096 if (players)
1097 {
1098 GetClientRect(xid[players].hwnd.hWnd, &rect);
1099 InvalidateRect(xid[players].hwnd.hWnd, &rect, FALSE);
1100 }
1101 }
1102
PaintWinClient()1103 void PaintWinClient()
1104 {
1105 #if 0
1106 RECT rect;
1107 static int updates = 0;
1108
1109 if (drawPending)
1110 return; // bogus dude.
1111
1112 if (!itemsDC)
1113 itemsDC = CreateCompatibleDC(NULL);
1114
1115 WinXSetupRadarWindow();
1116
1117 // Paint_frame();
1118
1119 GetClientRect(xid[draw].hwnd.hWnd, &rect);
1120 InvalidateRect(xid[draw].hwnd.hWnd, &rect, FALSE);
1121 drawPending = TRUE;
1122
1123 if (instruments & SHOW_SLIDING_RADAR)
1124 {
1125 GetClientRect(xid[radar].hwnd.hWnd, &rect);
1126 InvalidateRect(xid[radar].hwnd.hWnd, &rect, FALSE);
1127 }
1128
1129 // One time stuff for score window update
1130 if (updates == 0)
1131 {
1132 GetClientRect(xid[players].hwnd.hWnd, &rect);
1133 InvalidateRect(xid[players].hwnd.hWnd, &rect, FALSE);
1134 UpdateWindow(xid[players].hwnd.hWnd);
1135 }
1136 updates += 1;
1137 #else
1138 RECT rect;
1139 static int updates = 0;
1140 if (!itemsDC)
1141 itemsDC = CreateCompatibleDC(NULL);
1142
1143 WinXSetupRadarWindow();
1144
1145 // One time stuff for score window update
1146 if (updates == 0)
1147 {
1148 GetClientRect(xid[players].hwnd.hWnd, &rect);
1149 InvalidateRect(xid[players].hwnd.hWnd, &rect, FALSE);
1150 UpdateWindow(xid[players].hwnd.hWnd);
1151 }
1152 updates += 1;
1153 // SelectPalette(hDC, myPal, FALSE);
1154 // RealizePalette(hDC);
1155
1156 // xid[draw].hwnd.hDC = hDC;
1157 // if (!itemsDC)
1158 // itemsDC = CreateCompatibleDC(realDC);
1159
1160 // Paint_frame();
1161 // xid[draw].hwnd.hBmpDC = realDC;
1162 GetClientRect(xid[draw].hwnd.hWnd, &rect);
1163 if (ThreadedDraw)
1164 {
1165 // FillRect(xid[draw].hwnd.hBmpDC, &rect, GetStockObject(WHITE_BRUSH));
1166 winXTDraw(NULL, draw, &rect);
1167 }
1168 else
1169 {
1170 HDC realDC = GetDC(xid[draw].hwnd.hWnd);
1171 SelectPalette(realDC, myPal, FALSE);
1172 RealizePalette(realDC);
1173 BitBlt(realDC, 0, 0, rect.right, rect.bottom, xid[draw].hwnd.hBmpDC,
1174 0, 0, SRCCOPY);
1175 ReleaseDC(xid[draw].hwnd.hWnd, realDC);
1176 }
1177 #endif
1178 }
1179
MarkPlayersForRedraw()1180 void MarkPlayersForRedraw()
1181 {
1182 RECT rect;
1183
1184 GetClientRect(xid[players].hwnd.hWnd, &rect);
1185 InvalidateRect(xid[players].hwnd.hWnd, &rect, FALSE);
1186 UpdateWindow(xid[players].hwnd.hWnd);
1187 }
1188
paintItemSymbol(unsigned char type,Drawable d,GC gc,int x,int y,int color)1189 void paintItemSymbol(unsigned char type, Drawable d, GC gc, int x, int y, int color)
1190 {
1191 HDC hDC = xid[d].hwnd.hBmpDC;
1192
1193 SelectObject(itemsDC, (HBITMAP)itemBitmaps[type][color]);
1194 if (bHasPal)
1195 {
1196 SelectPalette(itemsDC, myPal, FALSE);
1197 RealizePalette(itemsDC);
1198 }
1199 BitBlt(hDC, x, y, 16, 16, itemsDC, 0, 0, SRCPAINT);
1200 }
1201
WinXBltPixToWin(Pixmap src,Window dest,int src_x,int src_y,unsigned int width,unsigned int height,int dest_x,int dest_y)1202 void WinXBltPixToWin(Pixmap src, Window dest,
1203 int src_x, int src_y, unsigned int width, unsigned int height,
1204 int dest_x, int dest_y)
1205 {
1206 HDC shDC = xid[src].hpix.hDC;
1207 HDC hDC = xid[dest].hwnd.hBmpDC;
1208
1209 BitBlt(hDC, dest_x, dest_y, width, height, shDC, src_x, src_y, SRCCOPY);
1210 }
1211
WinXBltWinToPix(Window src,Pixmap dest,int src_x,int src_y,unsigned int width,unsigned int height,int dest_x,int dest_y)1212 void WinXBltWinToPix(Window src, Pixmap dest,
1213 int src_x, int src_y, unsigned int width, unsigned int height,
1214 int dest_x, int dest_y)
1215 {
1216 HDC hDC = xid[src].hwnd.hBmpDC;
1217 HBITMAP hbm = xid[dest].hpix.hbm;
1218
1219 HDC hDCd = CreateCompatibleDC(NULL);
1220 int ret;
1221 SelectObject(hDC, hbm);
1222 if (bHasPal)
1223 {
1224 SelectPalette(hDC, myPal, FALSE);
1225 RealizePalette(hDC);
1226 }
1227 ret = BitBlt(hDC, dest_x, dest_y, width, height, hDC, src_x, src_y, BLACKNESS);
1228 DeleteDC(hDCd);
1229
1230 }
1231
1232 #if 0
1233 void WinXPaintPlayers()
1234 {
1235 }
1236 #endif
1237
WinXFlush(Window w)1238 void WinXFlush(Window w)
1239 {
1240 RECT r;
1241 GetClientRect(xid[w].hwnd.hWnd, &r);
1242 Trace("Flushing %d (%d/%d %d/%d)\n", w, r.left, r.top, r.right, r.bottom);
1243 InvalidateRect(xid[w].hwnd.hWnd, &r, TRUE);
1244 }
1245
WinXExit()1246 void WinXExit()
1247 {
1248 PostMessage(GetParent(xid[top].hwnd.hWnd), WM_CLOSE, 0, 0);
1249 }
1250
1251
WinXSetEventMask(Window w,long mask)1252 void WinXSetEventMask(Window w, long mask)
1253 {
1254 xid[w].hwnd.event_mask = mask; /* this could be a macro, */
1255 } /* but winX_.h is hidden from everyone */
1256
WinXGetParent(Window w)1257 Window WinXGetParent(Window w)
1258 {
1259 XID i;
1260 XID txid;
1261 HWND hwnd = GetParent(xid[w].hwnd.hWnd);
1262 if (!hwnd)
1263 return(top);
1264 for (i=0; i<MAX_XIDS; i++)
1265 {
1266 if (hwnd == xid[i].hwnd.hWnd)
1267 return(i);
1268 }
1269 /* create a new "Window" for the parent */
1270 txid = GetFreeXid();
1271 xid[txid].hwnd.hBmp = NULL;
1272 xid[txid].hwnd.hBmpDC = NULL;
1273 xid[txid].hwnd.hWnd = hwnd;
1274 xid[txid].hwnd.event_mask = 0;
1275 xid[txid].hwnd.event_mask = -1; // hell, let's take em all!
1276 xid[txid].hwnd.mouseover = 0; // mouse not over this window
1277 xid[txid].hwnd.type = XIDTYPE_HWND;
1278 xid[txid].hwnd.notmine = TRUE; // we don't destroy this one...
1279 #if 0
1280 if (++max_xid > MAX_XIDS)
1281 {
1282 error("Too many XIDS!\n");
1283 max_xid--;
1284 }
1285 return(max_xid-1);
1286 #endif
1287 return(txid);
1288 }
1289
WinXGetWindowRect(Window w,RECT * rect)1290 BOOL WinXGetWindowRect(Window w, RECT* rect)
1291 {
1292 return(GetWindowRect(xid[w].hwnd.hWnd, rect));
1293 }
1294
WinXGetWindowPlacement(Window w,WINDOWPLACEMENT * wp)1295 BOOL WinXGetWindowPlacement(Window w, WINDOWPLACEMENT* wp)
1296 {
1297 return(GetWindowPlacement(xid[w].hwnd.hWnd, wp));
1298 }
1299
GetFreeXid()1300 XID GetFreeXid()
1301 {
1302 int i;
1303 for (i=0; i<MAX_XIDS; i++)
1304 if (xid[i].type == XIDTYPE_UNUSED)
1305 return(i);
1306 error("No Free XIDs");
1307 return(MAX_XIDS);
1308 }
1309
1310 /*------------------------------------------------------*\
1311 * stubs for motd and talk window. I wrote these Windows *
1312 * dialogs differently... I should revisit these to use *
1313 * these new APIs. *
1314 \*------------------------------------------------------*/
1315 bool talk_mapped = FALSE;
Talk_resize(void)1316 void Talk_resize(void)
1317 { }
Talk_do_event(XEvent * event)1318 int Talk_do_event(XEvent* event)
1319 { return(FALSE); }
1320
1321