Imported Upstream version 1.11.4
[ubuntu-omap:xserver.git] / hw / xwin / winscrinit.c
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:     Dakshinamurthy Karra
29  *              Suhaib M Siddiqi
30  *              Peter Busch
31  *              Harold L Hunt II
32  *              Kensuke Matsuzaki
33  */
34
35 #ifdef HAVE_XWIN_CONFIG_H
36 #include <xwin-config.h>
37 #endif
38 #include "win.h"
39 #include "winmsg.h"
40
41
42 #ifdef XWIN_MULTIWINDOWEXTWM
43 static RootlessFrameProcsRec
44 winMWExtWMProcs = {     
45   winMWExtWMCreateFrame,
46   winMWExtWMDestroyFrame,
47   
48   winMWExtWMMoveFrame,
49   winMWExtWMResizeFrame,
50   winMWExtWMRestackFrame,
51   winMWExtWMReshapeFrame,
52   winMWExtWMUnmapFrame,
53   
54   winMWExtWMStartDrawing,
55   winMWExtWMStopDrawing,
56   winMWExtWMUpdateRegion,
57   winMWExtWMDamageRects,
58   winMWExtWMRootlessSwitchWindow,
59   NULL,//winMWExtWMDoReorderWindow,
60   NULL,//winMWExtWMHideWindow,
61   NULL,//winMWExtWMUpdateColorMap,
62
63   NULL,//winMWExtWMCopyBytes,
64   winMWExtWMCopyWindow
65 };
66 #endif
67
68 /*
69  * Prototypes
70  */
71
72 /*
73  * Local functions
74  */
75
76 static Bool
77 winSaveScreen (ScreenPtr pScreen, int on);
78
79
80 /*
81  * Determine what type of screen we are initializing
82  * and call the appropriate procedure to intiailize
83  * that type of screen.
84  */
85
86 Bool
87 winScreenInit (int index,
88                ScreenPtr pScreen,
89                int argc, char **argv)
90 {
91   winScreenInfoPtr      pScreenInfo = &g_ScreenInfo[index];
92   winPrivScreenPtr      pScreenPriv;
93   HDC                   hdc;
94   DWORD dwInitialBPP;
95
96 #if CYGDEBUG || YES
97   winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n",
98           pScreenInfo->dwWidth, pScreenInfo->dwHeight);
99 #endif
100
101   /* Allocate privates for this screen */
102   if (!winAllocatePrivates (pScreen))
103     {
104       ErrorF ("winScreenInit - Couldn't allocate screen privates\n");
105       return FALSE;
106     }
107
108   /* Get a pointer to the privates structure that was allocated */
109   pScreenPriv = winGetScreenPriv (pScreen);
110
111   /* Save a pointer to this screen in the screen info structure */
112   pScreenInfo->pScreen = pScreen;
113
114   /* Save a pointer to the screen info in the screen privates structure */
115   /* This allows us to get back to the screen info from a screen pointer */
116   pScreenPriv->pScreenInfo = pScreenInfo;
117
118   /*
119    * Determine which engine to use.
120    *
121    * NOTE: This is done once per screen because each screen possibly has
122    * a preferred engine specified on the command line.
123    */
124   if (!winSetEngine (pScreen))
125     {
126       ErrorF ("winScreenInit - winSetEngine () failed\n");
127       return FALSE;
128     }
129
130   /* Horribly misnamed function: Allow engine to adjust BPP for screen */
131   dwInitialBPP = pScreenInfo->dwBPP;
132
133   if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen))
134     {
135       ErrorF ("winScreenInit - winAdjustVideoMode () failed\n");
136       return FALSE;
137     }
138
139   if (dwInitialBPP == WIN_DEFAULT_BPP)
140     {
141       /* No -depth parameter was passed, let the user know the depth being used */
142       ErrorF ("winScreenInit - Using Windows display depth of %d bits per pixel\n", (int) pScreenInfo->dwBPP);
143     }
144   else if (dwInitialBPP != pScreenInfo->dwBPP)
145     {
146       /* Warn user if engine forced a depth different to -depth parameter */
147       ErrorF ("winScreenInit - Command line depth of %d bpp overidden by engine, using %d bpp\n", (int) dwInitialBPP, (int) pScreenInfo->dwBPP);
148     }
149   else
150     {
151       ErrorF ("winScreenInit - Using command line depth of %d bpp\n", (int) pScreenInfo->dwBPP);
152     }
153
154   /* Check for supported display depth */
155   if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1))))
156     {
157       ErrorF ("winScreenInit - Unsupported display depth: %d\n" \
158               "Change your Windows display depth to 15, 16, 24, or 32 bits "
159               "per pixel.\n",
160               (int) pScreenInfo->dwBPP);
161       ErrorF ("winScreenInit - Supported depths: %08x\n",
162               WIN_SUPPORTED_BPPS);
163 #if WIN_CHECK_DEPTH
164       return FALSE;
165 #endif
166     }
167
168   /*
169    * Check that all monitors have the same display depth if we are using
170    * multiple monitors
171    */
172   if (pScreenInfo->fMultipleMonitors
173       && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT))
174     {
175       ErrorF ("winScreenInit - Monitors do not all have same pixel format / "
176               "display depth.\n");
177       if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI)
178         {
179           ErrorF ("winScreenInit - Performance may suffer off primary display.\n");
180         }
181       else
182         {
183           ErrorF ("winScreenInit - Using primary display only.\n");
184           pScreenInfo->fMultipleMonitors = FALSE;
185         }
186     }
187
188   /* Create display window */
189   if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen))
190     {
191       ErrorF ("winScreenInit - pwinCreateBoundingWindow () "
192               "failed\n");
193       return FALSE;
194     }
195
196   /* Get a device context */
197   hdc = GetDC (pScreenPriv->hwndScreen);
198
199   /* Are we using multiple monitors? */
200   if (pScreenInfo->fMultipleMonitors)
201     {
202       /* 
203        * In this case, some of the defaults set in
204        * winInitializeScreenDefaults() are not correct ...
205        */
206       if (!pScreenInfo->fUserGaveHeightAndWidth)
207         {
208           pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
209           pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
210         }
211     }
212
213   /* Release the device context */
214   ReleaseDC (pScreenPriv->hwndScreen, hdc);
215     
216   /* Clear the visuals list */
217   miClearVisualTypes ();
218
219   /* Call the engine dependent screen initialization procedure */
220   if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv)))
221     {
222       ErrorF ("winScreenInit - winFinishScreenInit () failed\n");
223
224       /* call the engine dependent screen close procedure to clean up from a failure */
225       pScreenPriv->pwinCloseScreen(index, pScreen);
226
227       return FALSE;
228     }
229
230   if (!g_fSoftwareCursor)
231     winInitCursor(pScreen);
232   else
233     winErrorFVerb(2, "winScreenInit - Using software cursor\n");  
234
235   /*
236      Note the screen origin in a normalized coordinate space where (0,0) is at the top left
237      of the native virtual desktop area
238   */
239   pScreen->x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
240   pScreen->y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
241
242   ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n",
243          index, pScreen->x, pScreen->y);
244
245 #if CYGDEBUG || YES
246   winDebug ("winScreenInit - returning\n");
247 #endif
248
249   return TRUE;
250 }
251
252 static Bool
253 winCreateScreenResources(ScreenPtr pScreen)
254 {
255   winScreenPriv(pScreen);
256   Bool result;
257
258   result = pScreenPriv->pwinCreateScreenResources(pScreen);
259
260   /* Now the screen bitmap has been wrapped in a pixmap,
261      add that to the Shadow framebuffer */
262   if (!shadowAdd(pScreen, pScreen->devPrivate,
263                  pScreenPriv->pwinShadowUpdate, NULL, 0, 0))
264     {
265       ErrorF ("winCreateScreenResources - shadowAdd () failed\n");
266       return FALSE;
267     }
268
269   return result;
270 }
271
272 /* See Porting Layer Definition - p. 20 */
273 Bool
274 winFinishScreenInitFB (int index,
275                        ScreenPtr pScreen,
276                        int argc, char **argv)
277 {
278   winScreenPriv(pScreen);
279   winScreenInfo         *pScreenInfo = pScreenPriv->pScreenInfo;
280   VisualPtr             pVisual = NULL;
281   char                  *pbits = NULL;
282 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
283   int                   iReturn;
284 #endif
285
286   /* Create framebuffer */
287   if (!(*pScreenPriv->pwinInitScreen) (pScreen))
288     {
289       ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n");
290       return FALSE;
291     }
292
293   /*
294    * Calculate the number of bits that are used to represent color in each pixel,
295    * the color depth for the screen
296    */
297   if (pScreenInfo->dwBPP == 8)
298     pScreenInfo->dwDepth = 8;
299   else
300     pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask)
301       + winCountBits (pScreenPriv->dwGreenMask)
302       + winCountBits (pScreenPriv->dwBlueMask);
303
304   winErrorFVerb (2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n",
305           (unsigned int) pScreenPriv->dwRedMask,
306           (unsigned int) pScreenPriv->dwGreenMask,
307           (unsigned int) pScreenPriv->dwBlueMask);
308
309   /* Init visuals */
310   if (!(*pScreenPriv->pwinInitVisuals) (pScreen))
311     {
312       ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n");
313       return FALSE;
314     }
315
316   /* Setup a local variable to point to the framebuffer */
317   pbits = pScreenInfo->pfb;
318   
319   /* Apparently we need this for the render extension */
320   miSetPixmapDepths ();
321
322   /* Start fb initialization */
323   if (!fbSetupScreen (pScreen,
324                       pScreenInfo->pfb,
325                       pScreenInfo->dwWidth, pScreenInfo->dwHeight,
326                       monitorResolution, monitorResolution,
327                       pScreenInfo->dwStride,
328                       pScreenInfo->dwBPP))
329     {
330       ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n");
331       return FALSE;
332     }
333
334   /* Override default colormap routines if visual class is dynamic */
335   if (pScreenInfo->dwDepth == 8
336       && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
337           || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
338               && pScreenInfo->fFullScreen)
339           || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
340               && pScreenInfo->fFullScreen)))
341     {
342       winSetColormapFunctions (pScreen);
343
344       /*
345        * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its
346        * own colormap, as it cannot allocate 7 planes in the default
347        * colormap.  Setting whitePixel to 1 allows Magic to get 7
348        * planes in the default colormap, so it doesn't create its
349        * own colormap.  This latter situation is highly desireable,
350        * as it keeps the Magic window viewable when switching to
351        * other X clients that use the default colormap.
352        */
353       pScreen->blackPixel = 0;
354       pScreen->whitePixel = 1;
355     }
356
357   /* Place our save screen function */
358   pScreen->SaveScreen = winSaveScreen;
359
360   /* Finish fb initialization */
361   if (!fbFinishScreenInit (pScreen,
362                            pScreenInfo->pfb,
363                            pScreenInfo->dwWidth, pScreenInfo->dwHeight,
364                            monitorResolution, monitorResolution,
365                            pScreenInfo->dwStride,
366                            pScreenInfo->dwBPP))
367     {
368       ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n");
369       return FALSE;
370     }
371
372   /* Save a pointer to the root visual */
373   for (pVisual = pScreen->visuals;
374        pVisual->vid != pScreen->rootVisual;
375        pVisual++);
376   pScreenPriv->pRootVisual = pVisual;
377
378   /* 
379    * Setup points to the block and wakeup handlers.  Pass a pointer
380    * to the current screen as pWakeupdata.
381    */
382   pScreen->BlockHandler = winBlockHandler;
383   pScreen->WakeupHandler = winWakeupHandler;
384   pScreen->blockData = pScreen;
385   pScreen->wakeupData = pScreen;
386
387   /* Render extension initialization, calls miPictureInit */
388   if (!fbPictureInit (pScreen, NULL, 0))
389     {
390       ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n");
391       return FALSE;
392     }
393
394 #ifdef RANDR
395   /* Initialize resize and rotate support */
396   if (!winRandRInit (pScreen))
397     {
398       ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n");
399       return FALSE;
400     }
401 #endif
402
403   /* Setup the cursor routines */
404 #if CYGDEBUG
405   winDebug ("winFinishScreenInitFB - Calling miDCInitialize ()\n");
406 #endif
407   miDCInitialize (pScreen, &g_winPointerCursorFuncs);
408
409   /* KDrive does winCreateDefColormap right after miDCInitialize */
410   /* Create a default colormap */
411 #if CYGDEBUG
412   winDebug ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n");
413 #endif
414   if (!winCreateDefColormap (pScreen))
415     {
416       ErrorF ("winFinishScreenInitFB - Could not create colormap\n");
417       return FALSE;
418     }
419
420   /* Initialize the shadow framebuffer layer */
421   if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
422        || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
423        || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)
424 #ifdef XWIN_MULTIWINDOWEXTWM
425       && !pScreenInfo->fMWExtWM
426 #endif
427       )
428     {
429 #if CYGDEBUG
430       winDebug ("winFinishScreenInitFB - Calling shadowSetup ()\n");
431 #endif
432       if (!shadowSetup(pScreen))
433         {
434           ErrorF ("winFinishScreenInitFB - shadowSetup () failed\n");
435           return FALSE;
436         }
437
438       /* Wrap CreateScreenResources so we can add the screen pixmap
439          to the Shadow framebuffer after it's been created */
440       pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources;
441       pScreen->CreateScreenResources = winCreateScreenResources;
442     }
443
444 #ifdef XWIN_MULTIWINDOWEXTWM
445   /* Handle multi-window external window manager mode */
446   if (pScreenInfo->fMWExtWM)
447     {
448       winDebug ("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n");
449       
450       RootlessInit(pScreen, &winMWExtWMProcs);
451       
452       winDebug ("winScreenInit - MultiWindowExtWM - RootlessInit returned\n");
453       
454       rootless_CopyBytes_threshold = 0;
455       /* FIXME: How many? Profiling needed? */
456       rootless_CopyWindow_threshold = 1;
457
458       winWindowsWMExtensionInit ();
459     }
460 #endif
461
462   /* Handle rootless mode */
463   if (pScreenInfo->fRootless)
464     {
465       /* Define the WRAP macro temporarily for local use */
466 #define WRAP(a) \
467     if (pScreen->a) { \
468         pScreenPriv->a = pScreen->a; \
469     } else { \
470         ErrorF("null screen fn " #a "\n"); \
471         pScreenPriv->a = NULL; \
472     }
473
474       /* Save a pointer to each lower-level window procedure */
475       WRAP(CreateWindow);
476       WRAP(DestroyWindow);
477       WRAP(RealizeWindow);
478       WRAP(UnrealizeWindow);
479       WRAP(PositionWindow);
480       WRAP(ChangeWindowAttributes);
481       WRAP(SetShape);
482
483       /* Assign rootless window procedures to be top level procedures */
484       pScreen->CreateWindow = winCreateWindowRootless;
485       pScreen->DestroyWindow = winDestroyWindowRootless;
486       pScreen->PositionWindow = winPositionWindowRootless;
487       /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless;*/
488       pScreen->RealizeWindow = winMapWindowRootless;
489       pScreen->UnrealizeWindow = winUnmapWindowRootless;
490       pScreen->SetShape = winSetShapeRootless;
491
492       /* Undefine the WRAP macro, as it is not needed elsewhere */
493 #undef WRAP
494     }
495
496
497 #ifdef XWIN_MULTIWINDOW
498   /* Handle multi window mode */
499   else if (pScreenInfo->fMultiWindow)
500     {
501       /* Define the WRAP macro temporarily for local use */
502 #define WRAP(a) \
503     if (pScreen->a) { \
504         pScreenPriv->a = pScreen->a; \
505     } else { \
506         ErrorF("null screen fn " #a "\n"); \
507         pScreenPriv->a = NULL; \
508     }
509
510       /* Save a pointer to each lower-level window procedure */
511       WRAP(CreateWindow);
512       WRAP(DestroyWindow);
513       WRAP(RealizeWindow);
514       WRAP(UnrealizeWindow);
515       WRAP(PositionWindow);
516       WRAP(ChangeWindowAttributes);
517       WRAP(ReparentWindow);
518       WRAP(RestackWindow);
519       WRAP(ResizeWindow);
520       WRAP(MoveWindow);
521       WRAP(CopyWindow);
522       WRAP(SetShape);
523
524       /* Assign multi-window window procedures to be top level procedures */
525       pScreen->CreateWindow = winCreateWindowMultiWindow;
526       pScreen->DestroyWindow = winDestroyWindowMultiWindow;
527       pScreen->PositionWindow = winPositionWindowMultiWindow;
528       /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;*/
529       pScreen->RealizeWindow = winMapWindowMultiWindow;
530       pScreen->UnrealizeWindow = winUnmapWindowMultiWindow;
531       pScreen->ReparentWindow = winReparentWindowMultiWindow;
532       pScreen->RestackWindow = winRestackWindowMultiWindow;
533       pScreen->ResizeWindow = winResizeWindowMultiWindow;
534       pScreen->MoveWindow = winMoveWindowMultiWindow;
535       pScreen->CopyWindow = winCopyWindowMultiWindow;
536       pScreen->SetShape = winSetShapeMultiWindow;
537
538       /* Undefine the WRAP macro, as it is not needed elsewhere */
539 #undef WRAP
540     }
541 #endif
542
543   /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */
544   pScreenPriv->CloseScreen = pScreen->CloseScreen;
545   pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
546
547 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
548   /* Create a mutex for modules in separate threads to wait for */
549   iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL);
550   if (iReturn != 0)
551     {
552       ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n",
553               iReturn);
554       return FALSE;
555     }
556
557   /* Own the mutex for modules in separate threads */
558   iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted);
559   if (iReturn != 0)
560     {
561       ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n",
562               iReturn);
563       return FALSE;
564     }
565
566   /* Set the ServerStarted flag to false */
567   pScreenPriv->fServerStarted = FALSE;
568 #endif
569
570 #ifdef XWIN_MULTIWINDOWEXTWM
571   pScreenPriv->fRestacking = FALSE;
572 #endif
573
574 #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
575   if (FALSE
576 #ifdef XWIN_MULTIWINDOW
577       || pScreenInfo->fMultiWindow
578 #endif
579 #ifdef XWIN_MULTIWINDOWEXTWM
580       || pScreenInfo->fInternalWM
581 #endif
582       )
583     { 
584 #if CYGDEBUG || YES
585       winDebug ("winFinishScreenInitFB - Calling winInitWM.\n");
586 #endif
587
588       /* Initialize multi window mode */
589       if (!winInitWM (&pScreenPriv->pWMInfo,
590                       &pScreenPriv->ptWMProc,
591                       &pScreenPriv->ptXMsgProc,
592                       &pScreenPriv->pmServerStarted,
593                       pScreenInfo->dwScreen,
594                       (HWND)&pScreenPriv->hwndScreen,
595 #ifdef XWIN_MULTIWINDOWEXTWM
596                       pScreenInfo->fInternalWM ||
597 #endif
598                       FALSE))
599         {
600           ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n");
601           return FALSE;
602         }
603     }      
604 #endif
605
606   /* Tell the server that we are enabled */
607   pScreenPriv->fEnabled = TRUE;
608
609   /* Tell the server that we have a valid depth */
610   pScreenPriv->fBadDepth = FALSE;
611
612 #if CYGDEBUG || YES
613   winDebug ("winFinishScreenInitFB - returning\n");
614 #endif
615
616   return TRUE;
617 }
618
619 #ifdef XWIN_NATIVEGDI
620 /* See Porting Layer Definition - p. 20 */
621
622 Bool
623 winFinishScreenInitNativeGDI (int index,
624                               ScreenPtr pScreen,
625                               int argc, char **argv)
626 {
627   winScreenPriv(pScreen);
628   winScreenInfoPtr      pScreenInfo = &g_ScreenInfo[index];
629   VisualPtr             pVisuals = NULL;
630   DepthPtr              pDepths = NULL;
631   VisualID              rootVisual = 0;
632   int                   nVisuals = 0, nDepths = 0, nRootDepth = 0;
633
634   /* Ignore user input (mouse, keyboard) */
635   pScreenInfo->fIgnoreInput = FALSE;
636
637   /* Get device contexts for the screen and shadow bitmap */
638   pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
639   if (pScreenPriv->hdcScreen == NULL)
640     FatalError ("winFinishScreenInitNativeGDI - Couldn't get a DC\n");
641
642   /* Init visuals */
643   if (!(*pScreenPriv->pwinInitVisuals) (pScreen))
644     {
645       ErrorF ("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n");
646       return FALSE;
647     }
648
649   /* Initialize the mi visuals */
650   if (!miInitVisuals (&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth,
651                       &rootVisual,
652                       ((unsigned long)1 << (pScreenInfo->dwDepth - 1)), 8,
653                       TrueColor))
654     {
655       ErrorF ("winFinishScreenInitNativeGDI - miInitVisuals () failed\n");
656       return FALSE;
657     }
658
659   /* Initialize the CloseScreen procedure pointer */
660   pScreen->CloseScreen = NULL;
661
662   /* Initialize the mi code */
663   if (!miScreenInit (pScreen,
664                      NULL, /* No framebuffer */
665                      pScreenInfo->dwWidth, pScreenInfo->dwHeight,
666                      monitorResolution, monitorResolution,
667                      pScreenInfo->dwStride,
668                      nRootDepth, nDepths, pDepths, rootVisual,
669                      nVisuals, pVisuals))
670     {
671       ErrorF ("winFinishScreenInitNativeGDI - miScreenInit failed\n");
672       return FALSE;
673     }
674
675   pScreen->defColormap = FakeClientID(0);
676
677   /*
678    * Register our block and wakeup handlers; these procedures
679    * process messages in our Windows message queue; specifically,
680    * they process mouse and keyboard input.
681    */
682   pScreen->BlockHandler = winBlockHandler;
683   pScreen->WakeupHandler = winWakeupHandler;
684   pScreen->blockData = pScreen;
685   pScreen->wakeupData = pScreen;
686
687   /* Place our save screen function */
688   pScreen->SaveScreen = winSaveScreen;
689
690   /* Pixmaps */
691   pScreen->CreatePixmap = winCreatePixmapNativeGDI;
692   pScreen->DestroyPixmap = winDestroyPixmapNativeGDI;
693
694   /* Other Screen Routines */
695   pScreen->QueryBestSize = winQueryBestSizeNativeGDI;
696   pScreen->SaveScreen = winSaveScreen;  
697   pScreen->GetImage = miGetImage;
698   pScreen->GetSpans = winGetSpansNativeGDI;
699
700   /* Window Procedures */
701   pScreen->CreateWindow = winCreateWindowNativeGDI;
702   pScreen->DestroyWindow = winDestroyWindowNativeGDI;
703   pScreen->PositionWindow = winPositionWindowNativeGDI;
704   /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI;*/
705   pScreen->RealizeWindow = winMapWindowNativeGDI;
706   pScreen->UnrealizeWindow = winUnmapWindowNativeGDI;
707
708   /* Paint window */
709   pScreen->CopyWindow = winCopyWindowNativeGDI;
710
711   /* Fonts */
712   pScreen->RealizeFont = winRealizeFontNativeGDI;
713   pScreen->UnrealizeFont = winUnrealizeFontNativeGDI;
714
715   /* GC */
716   pScreen->CreateGC = winCreateGCNativeGDI;
717
718   /* Colormap Routines */
719   pScreen->CreateColormap = miInitializeColormap;
720   pScreen->DestroyColormap = (DestroyColormapProcPtr) (void (*)(void)) NoopDDA;
721   pScreen->InstallColormap = miInstallColormap;
722   pScreen->UninstallColormap = miUninstallColormap;
723   pScreen->ListInstalledColormaps = miListInstalledColormaps;
724   pScreen->StoreColors = (StoreColorsProcPtr) (void (*)(void)) NoopDDA;
725   pScreen->ResolveColor = miResolveColor;
726
727   /* Bitmap */
728   pScreen->BitmapToRegion = winPixmapToRegionNativeGDI;
729
730   ErrorF ("winFinishScreenInitNativeGDI - calling miDCInitialize\n");
731
732   /* Set the default white and black pixel positions */
733   pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0;
734
735   /* Initialize the cursor */
736   if (!miDCInitialize (pScreen, &g_winPointerCursorFuncs))
737     {
738       ErrorF ("winFinishScreenInitNativeGDI - miDCInitialize failed\n");
739       return FALSE;
740     }
741   
742   /* Create a default colormap */
743   if (!miCreateDefColormap (pScreen))
744     {
745         ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () "
746                 "failed\n");
747         return FALSE;
748     }
749
750   ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () "
751           "returned\n");
752   
753   /* mi doesn't use a CloseScreen procedure, so no need to wrap */
754   pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
755
756   /* Tell the server that we are enabled */
757   pScreenPriv->fEnabled = TRUE;
758
759   ErrorF ("winFinishScreenInitNativeGDI - Successful addition of "
760           "screen %08x\n",
761           (unsigned int) pScreen);
762
763   return TRUE;
764 }
765 #endif
766
767
768 /* See Porting Layer Definition - p. 33 */
769 static Bool
770 winSaveScreen (ScreenPtr pScreen, int on)
771 {
772   return TRUE;
773 }