winex11: Add an implementation for the PutImage entry point.
[wine] / dlls / winex11.drv / init.c
1 /*
2  * X11 graphics driver initialisation functions
3  *
4  * Copyright 1996 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "x11drv.h"
30 #include "x11font.h"
31 #include "ddrawi.h"
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
35
36 Display *gdi_display;  /* display to use for all GDI functions */
37
38 /* a few dynamic device caps */
39 static int log_pixels_x;  /* pixels per logical inch in x direction */
40 static int log_pixels_y;  /* pixels per logical inch in y direction */
41 static int horz_size;     /* horz. size of screen in millimeters */
42 static int vert_size;     /* vert. size of screen in millimeters */
43 static int palette_size;
44 static int device_init_done;
45 unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
46                           TC_CR_ANY | TC_SA_DOUBLE | TC_SA_INTEGER |
47                           TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE);
48                           /* X11R6 adds TC_SF_X_YINDEP, Xrender adds TC_VA_ABLE */
49
50
51 static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
52 static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
53
54
55 /******************************************************************************
56  *      get_dpi
57  *
58  * get the dpi from the registry
59  */
60 static DWORD get_dpi( void )
61 {
62     DWORD dpi = 96;
63     HKEY hkey;
64
65     if (RegOpenKeyW(HKEY_CURRENT_CONFIG, dpi_key_name, &hkey) == ERROR_SUCCESS)
66     {
67         DWORD type, size, new_dpi;
68
69         size = sizeof(new_dpi);
70         if(RegQueryValueExW(hkey, dpi_value_name, NULL, &type, (void *)&new_dpi, &size) == ERROR_SUCCESS)
71         {
72             if(type == REG_DWORD && new_dpi != 0)
73                 dpi = new_dpi;
74         }
75         RegCloseKey(hkey);
76     }
77     return dpi;
78 }
79
80 /**********************************************************************
81  *           device_init
82  *
83  * Perform initializations needed upon creation of the first device.
84  */
85 static void device_init(void)
86 {
87     device_init_done = TRUE;
88
89     /* Initialize XRender */
90     X11DRV_XRender_Init();
91
92     /* Init Xcursor */
93     X11DRV_Xcursor_Init();
94
95     palette_size = X11DRV_PALETTE_Init();
96
97     X11DRV_BITMAP_Init();
98
99     /* Initialize device caps */
100     log_pixels_x = log_pixels_y = get_dpi();
101     horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 );
102     vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 );
103
104     /* Initialize fonts and text caps */
105     X11DRV_FONT_Init(log_pixels_x, log_pixels_y);
106 }
107
108 /**********************************************************************
109  *           X11DRV_GDI_Finalize
110  */
111 void X11DRV_GDI_Finalize(void)
112 {
113     X11DRV_PALETTE_Cleanup();
114     /* don't bother to close the display, it often triggers X bugs */
115     /* XCloseDisplay( gdi_display ); */
116 }
117
118 /**********************************************************************
119  *           X11DRV_CreateDC
120  */
121 BOOL X11DRV_CreateDC( HDC hdc, PHYSDEV *pdev, LPCWSTR driver, LPCWSTR device,
122                       LPCWSTR output, const DEVMODEW* initData )
123 {
124     X11DRV_PDEVICE *physDev;
125
126     if (!device_init_done) device_init();
127
128     physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physDev) );
129     if (!physDev) return FALSE;
130
131     *pdev = &physDev->dev;
132
133     if (GetObjectType( hdc ) == OBJ_MEMDC)
134     {
135         if (!BITMAP_stock_phys_bitmap.hbitmap)
136             BITMAP_stock_phys_bitmap.hbitmap = GetCurrentObject( hdc, OBJ_BITMAP );
137         physDev->bitmap    = &BITMAP_stock_phys_bitmap;
138         physDev->drawable  = BITMAP_stock_phys_bitmap.pixmap;
139         physDev->depth     = 1;
140         physDev->color_shifts = NULL;
141         SetRect( &physDev->drawable_rect, 0, 0, 1, 1 );
142         physDev->dc_rect = physDev->drawable_rect;
143     }
144     else
145     {
146         physDev->bitmap    = NULL;
147         physDev->drawable  = root_window;
148         physDev->depth     = screen_depth;
149         physDev->color_shifts = &X11DRV_PALETTE_default_shifts;
150         physDev->drawable_rect = virtual_screen_rect;
151         SetRect( &physDev->dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
152                  virtual_screen_rect.bottom - virtual_screen_rect.top );
153     }
154     physDev->region = CreateRectRgn( 0, 0, 0, 0 );
155
156     wine_tsx11_lock();
157     physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
158     XSetGraphicsExposures( gdi_display, physDev->gc, False );
159     XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
160     XFlush( gdi_display );
161     wine_tsx11_unlock();
162     return TRUE;
163 }
164
165
166 /**********************************************************************
167  *           X11DRV_DeleteDC
168  */
169 BOOL X11DRV_DeleteDC( PHYSDEV dev )
170 {
171     X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
172
173     if(physDev->xrender)
174       X11DRV_XRender_DeleteDC( physDev );
175     DeleteObject( physDev->region );
176     wine_tsx11_lock();
177     XFreeGC( gdi_display, physDev->gc );
178     wine_tsx11_unlock();
179     HeapFree( GetProcessHeap(), 0, physDev );
180     return TRUE;
181 }
182
183
184 /***********************************************************************
185  *           GetDeviceCaps    (X11DRV.@)
186  */
187 INT X11DRV_GetDeviceCaps( PHYSDEV dev, INT cap )
188 {
189     switch(cap)
190     {
191     case DRIVERVERSION:
192         return 0x300;
193     case TECHNOLOGY:
194         return DT_RASDISPLAY;
195     case HORZSIZE:
196         return horz_size;
197     case VERTSIZE:
198         return vert_size;
199     case HORZRES:
200         return screen_width;
201     case VERTRES:
202         return screen_height;
203     case DESKTOPHORZRES:
204         return virtual_screen_rect.right - virtual_screen_rect.left;
205     case DESKTOPVERTRES:
206         return virtual_screen_rect.bottom - virtual_screen_rect.top;
207     case BITSPIXEL:
208         return screen_bpp;
209     case PLANES:
210         return 1;
211     case NUMBRUSHES:
212         return -1;
213     case NUMPENS:
214         return -1;
215     case NUMMARKERS:
216         return 0;
217     case NUMFONTS:
218         return 0;
219     case NUMCOLORS:
220         /* MSDN: Number of entries in the device's color table, if the device has
221          * a color depth of no more than 8 bits per pixel.For devices with greater
222          * color depths, -1 is returned. */
223         return (screen_depth > 8) ? -1 : (1 << screen_depth);
224     case PDEVICESIZE:
225         return sizeof(X11DRV_PDEVICE);
226     case CURVECAPS:
227         return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
228                 CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
229     case LINECAPS:
230         return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
231                 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
232     case POLYGONALCAPS:
233         return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
234                 PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
235     case TEXTCAPS:
236         return text_caps;
237     case CLIPCAPS:
238         return CP_REGION;
239     case COLORRES:
240         /* The observed correspondence between BITSPIXEL and COLORRES is:
241          * BITSPIXEL: 8  -> COLORRES: 18
242          * BITSPIXEL: 16 -> COLORRES: 16
243          * BITSPIXEL: 24 -> COLORRES: 24
244          * BITSPIXEL: 32 -> COLORRES: 24 */
245         return (screen_bpp <= 8) ? 18 : min( 24, screen_bpp );
246     case RASTERCAPS:
247         return (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
248                 RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS |
249                 (palette_size ? RC_PALETTE : 0));
250     case SHADEBLENDCAPS:
251         return (SB_GRAD_RECT | SB_GRAD_TRI | SB_CONST_ALPHA | SB_PIXEL_ALPHA);
252     case ASPECTX:
253     case ASPECTY:
254         return 36;
255     case ASPECTXY:
256         return 51;
257     case LOGPIXELSX:
258         return log_pixels_x;
259     case LOGPIXELSY:
260         return log_pixels_y;
261     case CAPS1:
262         FIXME("(%p): CAPS1 is unimplemented, will return 0\n", dev->hdc );
263         /* please see wingdi.h for the possible bit-flag values that need
264            to be returned. */
265         return 0;
266     case SIZEPALETTE:
267         return palette_size;
268     case NUMRESERVED:
269     case PHYSICALWIDTH:
270     case PHYSICALHEIGHT:
271     case PHYSICALOFFSETX:
272     case PHYSICALOFFSETY:
273     case SCALINGFACTORX:
274     case SCALINGFACTORY:
275     case VREFRESH:
276     case BLTALIGNMENT:
277         return 0;
278     default:
279         FIXME("(%p): unsupported capability %d, will return 0\n", dev->hdc, cap );
280         return 0;
281     }
282 }
283
284
285 /**********************************************************************
286  *           ExtEscape  (X11DRV.@)
287  */
288 INT X11DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
289                       INT out_count, LPVOID out_data )
290 {
291     X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
292
293     switch(escape)
294     {
295     case QUERYESCSUPPORT:
296         if (in_data)
297         {
298             switch (*(const INT *)in_data)
299             {
300             case DCICOMMAND:
301                 return DD_HAL_VERSION;
302             case X11DRV_ESCAPE:
303                 return TRUE;
304             }
305         }
306         break;
307
308     case X11DRV_ESCAPE:
309         if (in_data && in_count >= sizeof(enum x11drv_escape_codes))
310         {
311             switch(*(const enum x11drv_escape_codes *)in_data)
312             {
313             case X11DRV_GET_DISPLAY:
314                 if (out_count >= sizeof(Display *))
315                 {
316                     *(Display **)out_data = gdi_display;
317                     return TRUE;
318                 }
319                 break;
320             case X11DRV_GET_DRAWABLE:
321                 if (out_count >= sizeof(Drawable))
322                 {
323                     *(Drawable *)out_data = physDev->drawable;
324                     return TRUE;
325                 }
326                 break;
327             case X11DRV_GET_FONT:
328                 if (out_count >= sizeof(Font))
329                 {
330                     fontObject* pfo = XFONT_GetFontObject( physDev->font );
331                     if (pfo == NULL) return FALSE;
332                     *(Font *)out_data = pfo->fs->fid;
333                     return TRUE;
334                 }
335                 break;
336             case X11DRV_SET_DRAWABLE:
337                 if (in_count >= sizeof(struct x11drv_escape_set_drawable))
338                 {
339                     const struct x11drv_escape_set_drawable *data = in_data;
340                     if(physDev->xrender) X11DRV_XRender_UpdateDrawable( physDev );
341                     physDev->dc_rect = data->dc_rect;
342                     physDev->drawable = data->drawable;
343                     physDev->drawable_rect = data->drawable_rect;
344                     physDev->current_pf = pixelformat_from_fbconfig_id( data->fbconfig_id );
345                     physDev->gl_drawable = data->gl_drawable;
346                     physDev->pixmap = data->pixmap;
347                     physDev->gl_copy = data->gl_copy;
348                     wine_tsx11_lock();
349                     XSetSubwindowMode( gdi_display, physDev->gc, data->mode );
350                     wine_tsx11_unlock();
351                     TRACE( "SET_DRAWABLE hdc %p drawable %lx gl_drawable %lx pf %u dc_rect %s drawable_rect %s\n",
352                            dev->hdc, physDev->drawable, physDev->gl_drawable, physDev->current_pf,
353                            wine_dbgstr_rect(&physDev->dc_rect), wine_dbgstr_rect(&physDev->drawable_rect) );
354                     return TRUE;
355                 }
356                 break;
357             case X11DRV_START_EXPOSURES:
358                 wine_tsx11_lock();
359                 XSetGraphicsExposures( gdi_display, physDev->gc, True );
360                 wine_tsx11_unlock();
361                 physDev->exposures = 0;
362                 return TRUE;
363             case X11DRV_END_EXPOSURES:
364                 if (out_count >= sizeof(HRGN))
365                 {
366                     HRGN hrgn = 0, tmp = 0;
367
368                     wine_tsx11_lock();
369                     XSetGraphicsExposures( gdi_display, physDev->gc, False );
370                     wine_tsx11_unlock();
371                     if (physDev->exposures)
372                     {
373                         for (;;)
374                         {
375                             XEvent event;
376
377                             wine_tsx11_lock();
378                             XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
379                             wine_tsx11_unlock();
380                             if (event.type == NoExpose) break;
381                             if (event.type == GraphicsExpose)
382                             {
383                                 RECT rect;
384
385                                 rect.left   = event.xgraphicsexpose.x - physDev->dc_rect.left;
386                                 rect.top    = event.xgraphicsexpose.y - physDev->dc_rect.top;
387                                 rect.right  = rect.left + event.xgraphicsexpose.width;
388                                 rect.bottom = rect.top + event.xgraphicsexpose.height;
389                                 if (GetLayout( dev->hdc ) & LAYOUT_RTL)
390                                     mirror_rect( &physDev->dc_rect, &rect );
391
392                                 TRACE( "got %s count %d\n", wine_dbgstr_rect(&rect),
393                                        event.xgraphicsexpose.count );
394
395                                 if (!tmp) tmp = CreateRectRgnIndirect( &rect );
396                                 else SetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom );
397                                 if (hrgn) CombineRgn( hrgn, hrgn, tmp, RGN_OR );
398                                 else
399                                 {
400                                     hrgn = tmp;
401                                     tmp = 0;
402                                 }
403                                 if (!event.xgraphicsexpose.count) break;
404                             }
405                             else
406                             {
407                                 ERR( "got unexpected event %d\n", event.type );
408                                 break;
409                             }
410                         }
411                         if (tmp) DeleteObject( tmp );
412                     }
413                     *(HRGN *)out_data = hrgn;
414                     return TRUE;
415                 }
416                 break;
417             case X11DRV_GET_DCE:
418             case X11DRV_SET_DCE:
419                 FIXME( "%x escape no longer supported\n", *(const enum x11drv_escape_codes *)in_data );
420                 break;
421             case X11DRV_GET_GLX_DRAWABLE:
422                 if (out_count >= sizeof(Drawable))
423                 {
424                     *(Drawable *)out_data = get_glxdrawable(physDev);
425                     return TRUE;
426                 }
427                 break;
428             case X11DRV_SYNC_PIXMAP:
429                 if(physDev->bitmap)
430                 {
431                     X11DRV_CoerceDIBSection(physDev, DIB_Status_GdiMod);
432                     return TRUE;
433                 }
434                 return FALSE;
435             case X11DRV_FLUSH_GL_DRAWABLE:
436                 flush_gl_drawable(physDev);
437                 return TRUE;
438             }
439         }
440         break;
441     }
442     return 0;
443 }
444
445
446 static const struct gdi_dc_funcs x11drv_funcs =
447 {
448     NULL,                               /* pAbortDoc */
449     NULL,                               /* pAbortPath */
450     X11DRV_AlphaBlend,                  /* pAlphaBlend */
451     NULL,                               /* pAngleArc */
452     X11DRV_Arc,                         /* pArc */
453     NULL,                               /* pArcTo */
454     NULL,                               /* pBeginPath */
455     X11DRV_ChoosePixelFormat,           /* pChoosePixelFormat */
456     X11DRV_Chord,                       /* pChord */
457     NULL,                               /* pCloseFigure */
458     X11DRV_CreateBitmap,                /* pCreateBitmap */
459     X11DRV_CreateDC,                    /* pCreateDC */
460     X11DRV_CreateDIBSection,            /* pCreateDIBSection */
461     X11DRV_DeleteBitmap,                /* pDeleteBitmap */
462     X11DRV_DeleteDC,                    /* pDeleteDC */
463     NULL,                               /* pDeleteObject */
464     X11DRV_DescribePixelFormat,         /* pDescribePixelFormat */
465     NULL,                               /* pDeviceCapabilities */
466     X11DRV_Ellipse,                     /* pEllipse */
467     NULL,                               /* pEndDoc */
468     NULL,                               /* pEndPage */
469     NULL,                               /* pEndPath */
470     X11DRV_EnumDeviceFonts,             /* pEnumDeviceFonts */
471     X11DRV_EnumICMProfiles,             /* pEnumICMProfiles */
472     NULL,                               /* pExcludeClipRect */
473     NULL,                               /* pExtDeviceMode */
474     X11DRV_ExtEscape,                   /* pExtEscape */
475     X11DRV_ExtFloodFill,                /* pExtFloodFill */
476     NULL,                               /* pExtSelectClipRgn */
477     X11DRV_ExtTextOut,                  /* pExtTextOut */
478     NULL,                               /* pFillPath */
479     NULL,                               /* pFillRgn */
480     NULL,                               /* pFlattenPath */
481     NULL,                               /* pFrameRgn */
482     NULL,                               /* pGdiComment */
483     X11DRV_GetBitmapBits,               /* pGetBitmapBits */
484     X11DRV_GetCharWidth,                /* pGetCharWidth */
485     X11DRV_GetDIBits,                   /* pGetDIBits */
486     X11DRV_GetDeviceCaps,               /* pGetDeviceCaps */
487     X11DRV_GetDeviceGammaRamp,          /* pGetDeviceGammaRamp */
488     X11DRV_GetICMProfile,               /* pGetICMProfile */
489     X11DRV_GetImage,                    /* pGetImage */
490     X11DRV_GetNearestColor,             /* pGetNearestColor */
491     X11DRV_GetPixel,                    /* pGetPixel */
492     X11DRV_GetPixelFormat,              /* pGetPixelFormat */
493     X11DRV_GetSystemPaletteEntries,     /* pGetSystemPaletteEntries */
494     X11DRV_GetTextExtentExPoint,        /* pGetTextExtentExPoint */
495     X11DRV_GetTextMetrics,              /* pGetTextMetrics */
496     NULL,                               /* pIntersectClipRect */
497     NULL,                               /* pInvertRgn */
498     X11DRV_LineTo,                      /* pLineTo */
499     NULL,                               /* pModifyWorldTransform */
500     NULL,                               /* pMoveTo */
501     NULL,                               /* pOffsetClipRgn */
502     NULL,                               /* pOffsetViewportOrg */
503     NULL,                               /* pOffsetWindowOrg */
504     X11DRV_PaintRgn,                    /* pPaintRgn */
505     X11DRV_PatBlt,                      /* pPatBlt */
506     X11DRV_Pie,                         /* pPie */
507     NULL,                               /* pPolyBezier */
508     NULL,                               /* pPolyBezierTo */
509     NULL,                               /* pPolyDraw */
510     X11DRV_PolyPolygon,                 /* pPolyPolygon */
511     X11DRV_PolyPolyline,                /* pPolyPolyline */
512     X11DRV_Polygon,                     /* pPolygon */
513     X11DRV_Polyline,                    /* pPolyline */
514     NULL,                               /* pPolylineTo */
515     X11DRV_PutImage,                    /* pPutImage */
516     X11DRV_RealizeDefaultPalette,       /* pRealizeDefaultPalette */
517     X11DRV_RealizePalette,              /* pRealizePalette */
518     X11DRV_Rectangle,                   /* pRectangle */
519     NULL,                               /* pResetDC */
520     NULL,                               /* pRestoreDC */
521     X11DRV_RoundRect,                   /* pRoundRect */
522     NULL,                               /* pSaveDC */
523     NULL,                               /* pScaleViewportExt */
524     NULL,                               /* pScaleWindowExt */
525     X11DRV_SelectBitmap,                /* pSelectBitmap */
526     X11DRV_SelectBrush,                 /* pSelectBrush */
527     NULL,                               /* pSelectClipPath */
528     X11DRV_SelectFont,                  /* pSelectFont */
529     NULL,                               /* pSelectPalette */
530     X11DRV_SelectPen,                   /* pSelectPen */
531     NULL,                               /* pSetArcDirection */
532     X11DRV_SetBitmapBits,               /* pSetBitmapBits */
533     X11DRV_SetBkColor,                  /* pSetBkColor */
534     NULL,                               /* pSetBkMode */
535     X11DRV_SetDCBrushColor,             /* pSetDCBrushColor */
536     X11DRV_SetDCPenColor,               /* pSetDCPenColor */
537     X11DRV_SetDIBColorTable,            /* pSetDIBColorTable */
538     X11DRV_SetDIBits,                   /* pSetDIBits */
539     X11DRV_SetDIBitsToDevice,           /* pSetDIBitsToDevice */
540     X11DRV_SetDeviceClipping,           /* pSetDeviceClipping */
541     X11DRV_SetDeviceGammaRamp,          /* pSetDeviceGammaRamp */
542     NULL,                               /* pSetLayout */
543     NULL,                               /* pSetMapMode */
544     NULL,                               /* pSetMapperFlags */
545     X11DRV_SetPixel,                    /* pSetPixel */
546     X11DRV_SetPixelFormat,              /* pSetPixelFormat */
547     NULL,                               /* pSetPolyFillMode */
548     NULL,                               /* pSetROP2 */
549     NULL,                               /* pSetRelAbs */
550     NULL,                               /* pSetStretchBltMode */
551     NULL,                               /* pSetTextAlign */
552     NULL,                               /* pSetTextCharacterExtra */
553     X11DRV_SetTextColor,                /* pSetTextColor */
554     NULL,                               /* pSetTextJustification */
555     NULL,                               /* pSetViewportExt */
556     NULL,                               /* pSetViewportOrg */
557     NULL,                               /* pSetWindowExt */
558     NULL,                               /* pSetWindowOrg */
559     NULL,                               /* pSetWorldTransform */
560     NULL,                               /* pStartDoc */
561     NULL,                               /* pStartPage */
562     X11DRV_StretchBlt,                  /* pStretchBlt */
563     NULL,                               /* pStretchDIBits */
564     NULL,                               /* pStrokeAndFillPath */
565     NULL,                               /* pStrokePath */
566     X11DRV_SwapBuffers,                 /* pSwapBuffers */
567     X11DRV_UnrealizePalette,            /* pUnrealizePalette */
568     NULL,                               /* pWidenPath */
569     X11DRV_wglCopyContext,              /* pwglCopyContext */
570     X11DRV_wglCreateContext,            /* pwglCreateContext */
571     X11DRV_wglCreateContextAttribsARB,  /* pwglCreateContextAttribsARB */
572     X11DRV_wglDeleteContext,            /* pwglDeleteContext */
573     X11DRV_wglGetPbufferDCARB,          /* pwglGetPbufferDCARB */
574     X11DRV_wglGetProcAddress,           /* pwglGetProcAddress */
575     X11DRV_wglMakeContextCurrentARB,    /* pwglMakeContextCurrentARB */
576     X11DRV_wglMakeCurrent,              /* pwglMakeCurrent */
577     X11DRV_wglSetPixelFormatWINE,       /* pwglSetPixelFormatWINE */
578     X11DRV_wglShareLists,               /* pwglShareLists */
579     X11DRV_wglUseFontBitmapsA,          /* pwglUseFontBitmapsA */
580     X11DRV_wglUseFontBitmapsW,          /* pwglUseFontBitmapsW */
581 };
582
583
584 /******************************************************************************
585  *      X11DRV_get_gdi_driver
586  */
587 const struct gdi_dc_funcs * CDECL X11DRV_get_gdi_driver( unsigned int version )
588 {
589     if (version != WINE_GDI_DRIVER_VERSION)
590     {
591         ERR( "version mismatch, gdi32 wants %u but winex11 has %u\n", version, WINE_GDI_DRIVER_VERSION );
592         return NULL;
593     }
594     return &x11drv_funcs;
595 }