1/*
2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3 *
4 *Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 *"Software"), to deal in the Software without restriction, including
7 *without limitation the rights to use, copy, modify, merge, publish,
8 *distribute, sublicense, and/or sell copies of the Software, and to
9 *permit persons to whom the Software is furnished to do so, subject to
10 *the following conditions:
11 *
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
14 *
15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 *Except as contained in this notice, the name of the XFree86 Project
24 *shall not be used in advertising or otherwise to promote the sale, use
25 *or other dealings in this Software without prior written authorization
26 *from the XFree86 Project.
27 *
28 * Authors:	Harold L Hunt II
29 */
30
31#ifdef HAVE_XWIN_CONFIG_H
32#include <xwin-config.h>
33#endif
34#include "win.h"
35
36
37/*
38 * Local function prototypes
39 */
40
41static Bool
42winAllocateFBNativeGDI (ScreenPtr pScreen);
43
44static void
45winShadowUpdateNativeGDI (ScreenPtr pScreen,
46			  shadowBufPtr pBuf);
47
48static Bool
49winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen);
50
51static Bool
52winInitVisualsNativeGDI (ScreenPtr pScreen);
53
54static Bool
55winAdjustVideoModeNativeGDI (ScreenPtr pScreen);
56
57#if 0
58static Bool
59winBltExposedRegionsNativeGDI (ScreenPtr pScreen);
60#endif
61
62static Bool
63winActivateAppNativeGDI (ScreenPtr pScreen);
64
65static Bool
66winRedrawScreenNativeGDI (ScreenPtr pScreen);
67
68static Bool
69winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen);
70
71static Bool
72winInstallColormapNativeGDI (ColormapPtr pColormap);
73
74static Bool
75winStoreColorsNativeGDI (ColormapPtr pmap,
76			 int ndef,
77			 xColorItem *pdefs);
78
79static Bool
80winCreateColormapNativeGDI (ColormapPtr pColormap);
81
82static Bool
83winDestroyColormapNativeGDI (ColormapPtr pColormap);
84
85
86
87static Bool
88winAllocateFBNativeGDI (ScreenPtr pScreen)
89{
90  FatalError ("winAllocateFBNativeGDI\n");
91
92  return TRUE;
93}
94
95static void
96winFreeFBNativeGDI (ScreenPtr pScreen)
97{
98  FatalError ("winFreeFBNativeGDI\n");
99}
100
101
102static Bool
103winInitScreenNativeGDI(ScreenPtr pScreen)
104{
105  FatalError ("winInitScreenNativeGDI\n");
106}
107
108/*
109 * We wrap whatever CloseScreen procedure was specified by fb;
110 * a pointer to said procedure is stored in our privates.
111 */
112
113static Bool
114winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen)
115{
116  winScreenPriv(pScreen);
117  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
118
119  ErrorF ("winCloseScreenNativeGDI - Freeing screen resources\n");
120
121  /* Flag that the screen is closed */
122  pScreenPriv->fClosed = TRUE;
123  pScreenPriv->fActive = FALSE;
124
125  /*
126   * NOTE: mi doesn't use a CloseScreen procedure, so we do not
127   * need to call a wrapped procedure here.
128   */
129
130  /* Delete the window property */
131  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
132
133  ErrorF ("winCloseScreenNativeGDI - Destroying window\n");
134
135  /* Delete tray icon, if we have one */
136  if (!pScreenInfo->fNoTrayIcon)
137    winDeleteNotifyIcon (pScreenPriv);
138
139  /* Free the exit confirmation dialog box, if it exists */
140  if (g_hDlgExit != NULL)
141    {
142      DestroyWindow (g_hDlgExit);
143      g_hDlgExit = NULL;
144    }
145
146  /* Kill our window */
147  if (pScreenPriv->hwndScreen)
148    {
149      DestroyWindow (pScreenPriv->hwndScreen);
150      pScreenPriv->hwndScreen = NULL;
151    }
152
153  /* Invalidate our screeninfo's pointer to the screen */
154  pScreenInfo->pScreen = NULL;
155
156  /* Free the screen privates for this screen */
157  free (pScreenPriv);
158
159  ErrorF ("winCloseScreenNativeGDI - Returning\n");
160
161  return TRUE;
162}
163
164
165static void
166winShadowUpdateNativeGDI (ScreenPtr pScreen,
167			  shadowBufPtr pBuf)
168{
169  FatalError ("winShadowUpdateNativeGDI\n");
170  return;
171}
172
173
174static Bool
175winInitVisualsNativeGDI (ScreenPtr pScreen)
176{
177  winScreenPriv(pScreen);
178  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
179
180  /* Set the bitsPerRGB and bit masks */
181  switch (pScreenInfo->dwDepth)
182    {
183    case 24:
184      pScreenPriv->dwBitsPerRGB = 8;
185      pScreenPriv->dwRedMask = 0x00FF0000;
186      pScreenPriv->dwGreenMask = 0x0000FF00;
187      pScreenPriv->dwBlueMask = 0x000000FF;
188      break;
189
190    case 16:
191      pScreenPriv->dwBitsPerRGB = 6;
192      pScreenPriv->dwRedMask = 0xF800;
193      pScreenPriv->dwGreenMask = 0x07E0;
194      pScreenPriv->dwBlueMask = 0x001F;
195      break;
196
197    case 15:
198      pScreenPriv->dwBitsPerRGB = 5;
199      pScreenPriv->dwRedMask = 0x7C00;
200      pScreenPriv->dwGreenMask = 0x03E0;
201      pScreenPriv->dwBlueMask = 0x001F;
202      break;
203
204    case 8:
205      pScreenPriv->dwBitsPerRGB = 8;
206      pScreenPriv->dwRedMask = 0;
207      pScreenPriv->dwGreenMask = 0;
208      pScreenPriv->dwBlueMask = 0;
209      break;
210
211    default:
212      ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n");
213      return FALSE;
214      break;
215    }
216
217  /* Tell the user how many bits per RGB we are using */
218  ErrorF ("winInitVisualsNativeGDI - Using dwBitsPerRGB: %d\n",
219	  (int) pScreenPriv->dwBitsPerRGB);
220
221  /* Create a single visual according to the Windows screen depth */
222  switch (pScreenInfo->dwDepth)
223    {
224    case 24:
225    case 16:
226    case 15:
227      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
228				     TrueColorMask,
229				     pScreenPriv->dwBitsPerRGB,
230				     TrueColor,
231				     pScreenPriv->dwRedMask,
232				     pScreenPriv->dwGreenMask,
233				     pScreenPriv->dwBlueMask))
234	{
235	  ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n");
236	  return FALSE;
237	}
238      break;
239
240    case 8:
241      ErrorF ("winInitVisuals - Calling miSetVisualTypesAndMasks\n");
242      if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
243				     StaticColorMask,
244				     pScreenPriv->dwBitsPerRGB,
245				     StaticColor,
246				     pScreenPriv->dwRedMask,
247				     pScreenPriv->dwGreenMask,
248				     pScreenPriv->dwBlueMask))
249	{
250	  ErrorF ("winInitVisuals - miSetVisualTypesAndMasks failed\n");
251	  return FALSE;
252	}
253      break;
254
255    default:
256      ErrorF ("winInitVisualsNativeGDI - Unknown screen depth\n");
257      return FALSE;
258    }
259
260#if 1
261  ErrorF ("winInitVisualsNativeGDI - Returning\n");
262#endif
263
264  return TRUE;
265}
266
267
268/* Adjust the video mode */
269static Bool
270winAdjustVideoModeNativeGDI (ScreenPtr pScreen)
271{
272  winScreenPriv(pScreen);
273  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
274  HDC			hdc = NULL;
275  DWORD			dwBPP;
276
277  hdc = GetDC (NULL);
278
279  /* We're in serious trouble if we can't get a DC */
280  if (hdc == NULL)
281    {
282      ErrorF ("winAdjustVideoModeNativeGDI - GetDC () failed\n");
283      return FALSE;
284    }
285
286  /* Query GDI for current display depth */
287  dwBPP = GetDeviceCaps (hdc, BITSPIXEL);
288  pScreenInfo->dwDepth = GetDeviceCaps (hdc, PLANES);
289
290  switch (pScreenInfo->dwDepth) {
291    case 24:
292    case 16:
293    case 15:
294    case 8:
295      break;
296    default:
297      if (dwBPP == 32)
298        pScreenInfo->dwDepth = 24;
299      else
300        pScreenInfo->dwDepth = dwBPP;
301      break;
302  }
303
304  /* GDI cannot change the screen depth, so we'll use GDI's depth */
305  pScreenInfo->dwBPP = dwBPP;
306
307  /* Release our DC */
308  ReleaseDC (NULL, hdc);
309
310  return TRUE;
311}
312
313
314static Bool
315winActivateAppNativeGDI (ScreenPtr pScreen)
316{
317  winScreenPriv(pScreen);
318  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
319
320  /*
321   * Are we active?
322   * Are we fullscreen?
323   */
324  if (pScreenPriv != NULL
325      && pScreenPriv->fActive
326      && pScreenInfo->fFullScreen)
327    {
328      /*
329       * Activating, attempt to bring our window
330       * to the top of the display
331       */
332      ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE);
333    }
334
335  /*
336   * Are we inactive?
337   * Are we fullscreen?
338   */
339  if (pScreenPriv != NULL
340      && !pScreenPriv->fActive
341      && pScreenInfo->fFullScreen)
342    {
343      /*
344       * Deactivating, stuff our window onto the
345       * task bar.
346       */
347      ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
348    }
349
350  return TRUE;
351}
352
353
354HBITMAP
355winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
356		       BYTE **ppbBits, BITMAPINFO **ppbmi)
357{
358  BITMAPINFOHEADER	*pbmih = NULL;
359  HBITMAP		hBitmap = NULL;
360  BITMAPINFO		*pbmi = NULL;
361
362  /* Don't create an invalid bitmap */
363  if (iWidth == 0
364      || iHeight == 0
365      || iDepth == 0)
366    {
367      ErrorF ("\nwinCreateDIBNativeGDI - Invalid specs w %d h %d d %d\n\n",
368	      iWidth, iHeight, iDepth);
369      return NULL;
370    }
371
372  /* Allocate bitmap info header */
373  pbmih = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
374				      + 256 * sizeof (RGBQUAD));
375  if (pbmih == NULL)
376    {
377      ErrorF ("winCreateDIBNativeGDI - malloc () failed\n");
378      return FALSE;
379    }
380  ZeroMemory (pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
381
382  /* Describe bitmap to be created */
383  pbmih->biSize = sizeof (BITMAPINFOHEADER);
384  pbmih->biWidth = iWidth;
385  pbmih->biHeight = -iHeight;
386  pbmih->biPlanes = 1;
387  pbmih->biBitCount = iDepth;
388  pbmih->biCompression = BI_RGB;
389  pbmih->biSizeImage = 0;
390  pbmih->biXPelsPerMeter = 0;
391  pbmih->biYPelsPerMeter = 0;
392  pbmih->biClrUsed = 0;
393  pbmih->biClrImportant = 0;
394
395  /* Setup color table for mono DIBs */
396  if (iDepth == 1)
397    {
398      pbmi = (BITMAPINFO*) pbmih;
399      pbmi->bmiColors[1].rgbBlue = 255;
400      pbmi->bmiColors[1].rgbGreen = 255;
401      pbmi->bmiColors[1].rgbRed = 255;
402    }
403
404  /* Create a DIB with a bit pointer */
405  hBitmap = CreateDIBSection (NULL,
406			      (BITMAPINFO *) pbmih,
407			      DIB_RGB_COLORS,
408			      (void **) ppbBits,
409			      NULL,
410			      0);
411  if (hBitmap == NULL)
412    {
413      ErrorF ("winCreateDIBNativeGDI - CreateDIBSection () failed\n");
414      return NULL;
415    }
416
417  /* Free the bitmap info header memory */
418  if (ppbmi != NULL)
419    {
420      /* Store the address of the BMIH in the ppbmih parameter */
421      *ppbmi = (BITMAPINFO *) pbmih;
422    }
423  else
424    {
425      free (pbmih);
426      pbmih = NULL;
427    }
428
429  return hBitmap;
430}
431
432
433#if 0
434static Bool
435winBltExposedRegionsNativeGDI (ScreenPtr pScreen)
436{
437
438  return TRUE;
439}
440#endif
441
442
443static Bool
444winRedrawScreenNativeGDI (ScreenPtr pScreen)
445{
446  FatalError ("winRedrawScreenNativeGDI\n");
447  return TRUE;
448}
449
450
451static Bool
452winRealizeInstalledPaletteNativeGDI (ScreenPtr pScreen)
453{
454  FatalError ("winRealizeInstalledPaletteNativeGDI\n");
455  return TRUE;
456}
457
458
459static Bool
460winInstallColormapNativeGDI (ColormapPtr pColormap)
461{
462  FatalError ("winInstallColormapNativeGDI\n");
463  return TRUE;
464}
465
466
467static Bool
468winStoreColorsNativeGDI (ColormapPtr pmap,
469			 int ndef,
470			 xColorItem *pdefs)
471{
472  FatalError ("winStoreColorsNativeGDI\n");
473  return TRUE;
474}
475
476
477static Bool
478winCreateColormapNativeGDI (ColormapPtr pColormap)
479{
480  FatalError ("winCreateColormapNativeGDI\n");
481  return TRUE;
482}
483
484
485static Bool
486winDestroyColormapNativeGDI (ColormapPtr pColormap)
487{
488  FatalError ("winDestroyColormapNativeGDI\n");
489  return TRUE;
490}
491
492
493/* Set engine specific funtions */
494Bool
495winSetEngineFunctionsNativeGDI (ScreenPtr pScreen)
496{
497  winScreenPriv(pScreen);
498  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
499
500  /* Set our pointers */
501  pScreenPriv->pwinAllocateFB = winAllocateFBNativeGDI;
502  pScreenPriv->pwinFreeFB = winFreeFBNativeGDI;
503  pScreenPriv->pwinShadowUpdate = winShadowUpdateNativeGDI;
504  pScreenPriv->pwinInitScreen = winInitScreenNativeGDI;
505  pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI;
506  pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI;
507  pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI;
508  if (pScreenInfo->fFullScreen)
509    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
510  else
511    pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
512  pScreenPriv->pwinFinishScreenInit = winFinishScreenInitNativeGDI;
513  /*
514   * WARNING: Do not set the BltExposedRegions procedure pointer to anything
515   * other than NULL until a working painting procedure is in place.
516   * Else, winWindowProc will get stuck in an infinite loop because
517   * Windows expects the BeginPaint and EndPaint functions to be called
518   * before a WM_PAINT message can be removed from the queue.  We are
519   * using NULL here as a signal for winWindowProc that it should
520   * not signal that the WM_PAINT message has been processed.
521   */
522  pScreenPriv->pwinBltExposedRegions = NULL;
523  pScreenPriv->pwinActivateApp = winActivateAppNativeGDI;
524  pScreenPriv->pwinRedrawScreen = winRedrawScreenNativeGDI;
525  pScreenPriv->pwinRealizeInstalledPalette =
526    winRealizeInstalledPaletteNativeGDI;
527  pScreenPriv->pwinInstallColormap = winInstallColormapNativeGDI;
528  pScreenPriv->pwinStoreColors = winStoreColorsNativeGDI;
529  pScreenPriv->pwinCreateColormap = winCreateColormapNativeGDI;
530  pScreenPriv->pwinDestroyColormap = winDestroyColormapNativeGDI;
531  pScreenPriv->pwinHotKeyAltTab = (winHotKeyAltTabProcPtr) (void (*)(void))NoopDDA;
532
533  return TRUE;
534}
535