1 /*
2 Copyright 2013-2017 Jay Sorg
3 
4 Permission to use, copy, modify, distribute, and sell this software and its
5 documentation for any purpose is hereby granted without fee, provided that
6 the above copyright notice appear in all copies and that both that
7 copyright notice and this permission notice appear in supporting
8 documentation.
9 
10 The above copyright notice and this permission notice shall be included in
11 all copies or substantial portions of the Software.
12 
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
16 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 
20 This is the main driver file
21 
22 */
23 
24 #if defined(HAVE_CONFIG_H)
25 #include "config_ac.h"
26 #endif
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 /* this should be before all X11 .h files */
33 #include <xorg-server.h>
34 #include <xorgVersion.h>
35 
36 /* all driver need this */
37 #include <xf86.h>
38 #include <xf86_OSproc.h>
39 
40 #include <mipointer.h>
41 #include <fb.h>
42 #include <micmap.h>
43 #include <mi.h>
44 #include <randrstr.h>
45 
46 #include <xf86Modes.h>
47 
48 #include "rdp.h"
49 #include "rdpPri.h"
50 #include "rdpDraw.h"
51 #include "rdpGC.h"
52 #include "rdpCursor.h"
53 #include "rdpRandR.h"
54 #include "rdpMisc.h"
55 #include "rdpComposite.h"
56 #include "rdpTrapezoids.h"
57 #include "rdpTriangles.h"
58 #include "rdpCompositeRects.h"
59 #include "rdpGlyphs.h"
60 #include "rdpPixmap.h"
61 #include "rdpClientCon.h"
62 #include "rdpXv.h"
63 #include "rdpSimd.h"
64 
65 #if defined(XORGXRDP_GLAMOR)
66 #include "xrdpdri2.h"
67 #include "xrdpdri3.h"
68 #include "rdpEgl.h"
69 #include <glamor.h>
70 /* use environment variable XORGXRDP_DRM_DEVICE to override
71  * also read from xorg.conf file */
72 char g_drm_device[128] = "/dev/dri/renderD128";
73 Bool g_use_dri2 = TRUE;
74 Bool g_use_dri3 = TRUE;
75 #endif
76 
77 #define LLOG_LEVEL 1
78 #define LLOGLN(_level, _args) \
79   do \
80   { \
81     if (_level < LLOG_LEVEL) \
82     { \
83       ErrorF _args ; \
84       ErrorF("\n"); \
85     } \
86   } \
87   while (0)
88 
89 static int g_setup_done = 0;
90 static OsTimerPtr g_timer = 0;
91 
92 static char g_xrdp_driver_name[] = XRDP_DRIVER_NAME;
93 
94 /* Supported "chipsets" */
95 static SymTabRec g_Chipsets[] =
96 {
97     { 0, XRDP_DRIVER_NAME },
98     { -1, 0 }
99 };
100 
101 static XF86ModuleVersionInfo g_VersRec =
102 {
103     XRDP_DRIVER_NAME,
104     MODULEVENDORSTRING,
105     MODINFOSTRING1,
106     MODINFOSTRING2,
107     XORG_VERSION_CURRENT,
108     PACKAGE_VERSION_MAJOR,
109     PACKAGE_VERSION_MINOR,
110     PACKAGE_VERSION_PATCHLEVEL,
111     ABI_CLASS_VIDEODRV,
112     ABI_VIDEODRV_VERSION,
113     0,
114     { 0, 0, 0, 0 }
115 };
116 
117 /*****************************************************************************/
118 static Bool
rdpAllocRec(ScrnInfoPtr pScrn)119 rdpAllocRec(ScrnInfoPtr pScrn)
120 {
121     LLOGLN(10, ("rdpAllocRec:"));
122     if (pScrn->driverPrivate != 0)
123     {
124         return TRUE;
125     }
126     /* xnfcalloc exits if alloc failed */
127     pScrn->driverPrivate = xnfcalloc(sizeof(rdpRec), 1);
128     return TRUE;
129 }
130 
131 /*****************************************************************************/
132 static void
rdpFreeRec(ScrnInfoPtr pScrn)133 rdpFreeRec(ScrnInfoPtr pScrn)
134 {
135     LLOGLN(10, ("rdpFreeRec:"));
136     if (pScrn->driverPrivate == 0)
137     {
138         return;
139     }
140     free(pScrn->driverPrivate);
141     pScrn->driverPrivate = 0;
142 }
143 
144 /*****************************************************************************/
145 static Bool
rdpPreInit(ScrnInfoPtr pScrn,int flags)146 rdpPreInit(ScrnInfoPtr pScrn, int flags)
147 {
148     rgb zeros1;
149     Gamma zeros2;
150     int got_res_match;
151 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 16, 0, 0, 0)
152     char **modename;
153 #else
154     const char **modename;
155 #endif
156     DisplayModePtr mode;
157     rdpPtr dev;
158 
159     LLOGLN(0, ("rdpPreInit:"));
160     if (flags & PROBE_DETECT)
161     {
162         return FALSE;
163     }
164     if (pScrn->numEntities == 0)
165     {
166         return FALSE;
167     }
168 
169     rdpAllocRec(pScrn);
170     dev = XRDPPTR(pScrn);
171 
172     dev->glamor = FALSE;
173 
174 #if defined(XORGXRDP_GLAMOR)
175     if (getenv("XORGXRDP_DRM_DEVICE") != NULL)
176     {
177         strncpy(g_drm_device, getenv("XORGXRDP_DRM_DEVICE"), 127);
178         g_drm_device[127] = 0;
179     }
180     dev->fd = open(g_drm_device, O_RDWR, 0);
181     if (dev->fd == -1)
182     {
183         LLOGLN(0, ("rdpPreInit: %s open failed", g_drm_device));
184     }
185     else
186     {
187         LLOGLN(0, ("rdpPreInit: %s open ok, fd %d", g_drm_device, dev->fd));
188         dev->glamor = TRUE;
189     }
190 #endif
191 
192     dev->width = 800;
193     dev->height = 600;
194 
195     pScrn->monitor = pScrn->confScreen->monitor;
196     pScrn->bitsPerPixel = 32;
197     pScrn->virtualX = dev->width;
198     pScrn->displayWidth = dev->width;
199     pScrn->virtualY = dev->height;
200     pScrn->progClock = 1;
201     pScrn->rgbBits = 8;
202     pScrn->depth = 24;
203     pScrn->chipset = g_xrdp_driver_name;
204     pScrn->currentMode = pScrn->modes;
205 
206     pScrn->offset.blue = 0;
207     pScrn->offset.green = 8;
208     pScrn->offset.red = 16;
209     pScrn->mask.blue = ((1 << 8) - 1) << pScrn->offset.blue;
210     pScrn->mask.green = ((1 << 8) - 1) << pScrn->offset.green;
211     pScrn->mask.red = ((1 << 8) - 1) << pScrn->offset.red;
212 
213     if (!xf86SetDepthBpp(pScrn, pScrn->depth, pScrn->bitsPerPixel,
214                          pScrn->bitsPerPixel,
215                          Support24bppFb | Support32bppFb |
216                          SupportConvert32to24 | SupportConvert24to32))
217     {
218         LLOGLN(0, ("rdpPreInit: xf86SetDepthBpp failed"));
219         rdpFreeRec(pScrn);
220         return FALSE;
221     }
222     xf86PrintDepthBpp(pScrn);
223     g_memset(&zeros1, 0, sizeof(zeros1));
224     if (!xf86SetWeight(pScrn, zeros1, zeros1))
225     {
226         LLOGLN(0, ("rdpPreInit: xf86SetWeight failed"));
227         rdpFreeRec(pScrn);
228         return FALSE;
229     }
230     g_memset(&zeros2, 0, sizeof(zeros2));
231     if (!xf86SetGamma(pScrn, zeros2))
232     {
233         LLOGLN(0, ("rdpPreInit: xf86SetGamma failed"));
234         rdpFreeRec(pScrn);
235         return FALSE;
236     }
237     if (!xf86SetDefaultVisual(pScrn, -1))
238     {
239         LLOGLN(0, ("rdpPreInit: xf86SetDefaultVisual failed"));
240         rdpFreeRec(pScrn);
241         return FALSE;
242     }
243     xf86SetDpi(pScrn, 0, 0);
244     if (0 == pScrn->display->modes)
245     {
246         LLOGLN(0, ("rdpPreInit: modes error"));
247         rdpFreeRec(pScrn);
248         return FALSE;
249     }
250 
251     pScrn->virtualX = pScrn->display->virtualX;
252     pScrn->virtualY = pScrn->display->virtualY;
253 
254     got_res_match = 0;
255     for (modename = pScrn->display->modes; *modename != 0; modename++)
256     {
257         for (mode = pScrn->monitor->Modes; mode != 0; mode = mode->next)
258         {
259             LLOGLN(10, ("%s %s", mode->name, *modename));
260             if (0 == strcmp(mode->name, *modename))
261             {
262                 break;
263             }
264         }
265         if (0 == mode)
266         {
267             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tmode \"%s\" not found\n",
268                        *modename);
269             continue;
270         }
271         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tmode \"%s\" ok\n", *modename);
272         LLOGLN(10, ("%d %d %d %d", mode->HDisplay, dev->width,
273                mode->VDisplay, dev->height));
274         if ((mode->HDisplay == dev->width) && (mode->VDisplay == dev->height))
275         {
276             pScrn->virtualX = mode->HDisplay;
277             pScrn->virtualY = mode->VDisplay;
278             got_res_match = 1;
279         }
280         if (got_res_match)
281         {
282             pScrn->modes = xf86DuplicateMode(mode);
283             pScrn->modes->next = pScrn->modes;
284             pScrn->modes->prev = pScrn->modes;
285             dev->num_modes = 1;
286             break;
287         }
288     }
289     pScrn->currentMode = pScrn->modes;
290     xf86PrintModes(pScrn);
291     LLOGLN(10, ("rdpPreInit: out fPtr->num_modes %d", dev->num_modes));
292     if (!got_res_match)
293     {
294         LLOGLN(0, ("rdpPreInit: could not find screen resolution %dx%d",
295                dev->width, dev->height));
296         return FALSE;
297     }
298     if (dev->glamor)
299     {
300 #if defined(XORGXRDP_GLAMOR)
301         if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME))
302         {
303             LLOGLN(0, ("rdpPreInit: glamor module load ok"));
304             if (glamor_egl_init(pScrn, dev->fd))
305             {
306                 LLOGLN(0, ("rdpPreInit: glamor init ok"));
307             }
308             else
309             {
310                 LLOGLN(0, ("rdpPreInit: glamor init failed"));
311                 dev->glamor = FALSE;
312             }
313         }
314         else
315         {
316             LLOGLN(0, ("rdpPreInit: glamor module load failed"));
317             dev->glamor = FALSE;
318         }
319 #endif
320     }
321     return TRUE;
322 }
323 
324 /******************************************************************************/
325 static miPointerSpriteFuncRec g_rdpSpritePointerFuncs =
326 {
327     /* these are in rdpCursor.c */
328     rdpSpriteRealizeCursor,
329     rdpSpriteUnrealizeCursor,
330     rdpSpriteSetCursor,
331     rdpSpriteMoveCursor,
332     rdpSpriteDeviceCursorInitialize,
333     rdpSpriteDeviceCursorCleanup
334 };
335 
336 /******************************************************************************/
337 static Bool
rdpSaveScreen(ScreenPtr pScreen,int on)338 rdpSaveScreen(ScreenPtr pScreen, int on)
339 {
340     LLOGLN(10, ("rdpSaveScreen:"));
341     return TRUE;
342 }
343 
344 /******************************************************************************/
345 static Bool
rdpResizeSession(rdpPtr dev,int width,int height)346 rdpResizeSession(rdpPtr dev, int width, int height)
347 {
348     int mmwidth;
349     int mmheight;
350     ScrnInfoPtr pScrn;
351     Bool ok;
352 
353     LLOGLN(0, ("rdpResizeSession: width %d height %d", width, height));
354     pScrn = xf86Screens[dev->pScreen->myNum];
355     mmwidth = PixelToMM(width, pScrn->xDpi);
356     mmheight = PixelToMM(height, pScrn->yDpi);
357 
358     ok = TRUE;
359     if ((dev->width != width) || (dev->height != height))
360     {
361         LLOGLN(0, ("  calling RRScreenSizeSet"));
362         dev->allow_screen_resize = 1;
363         ok = RRScreenSizeSet(dev->pScreen, width, height, mmwidth, mmheight);
364         dev->allow_screen_resize = 0;
365         LLOGLN(0, ("  RRScreenSizeSet ok %d", ok));
366     }
367     return ok;
368 }
369 
370 /******************************************************************************/
371 /* returns error */
372 static CARD32
rdpDeferredRandR(OsTimerPtr timer,CARD32 now,pointer arg)373 rdpDeferredRandR(OsTimerPtr timer, CARD32 now, pointer arg)
374 {
375     ScreenPtr pScreen;
376     rrScrPrivPtr pRRScrPriv;
377     rdpPtr dev;
378     char *envvar;
379     int width;
380     int height;
381 
382     pScreen = (ScreenPtr) arg;
383     dev = rdpGetDevFromScreen(pScreen);
384     LLOGLN(0, ("rdpDeferredRandR:"));
385     pRRScrPriv = rrGetScrPriv(pScreen);
386     if (pRRScrPriv == 0)
387     {
388         LLOGLN(0, ("rdpDeferredRandR: rrGetScrPriv failed"));
389         return 1;
390     }
391 
392     dev->rrSetConfig          = pRRScrPriv->rrSetConfig;
393     dev->rrGetInfo            = pRRScrPriv->rrGetInfo;
394     dev->rrScreenSetSize      = pRRScrPriv->rrScreenSetSize;
395     dev->rrCrtcSet            = pRRScrPriv->rrCrtcSet;
396     dev->rrCrtcSetGamma       = pRRScrPriv->rrCrtcSetGamma;
397     dev->rrCrtcGetGamma       = pRRScrPriv->rrCrtcGetGamma;
398     dev->rrOutputSetProperty  = pRRScrPriv->rrOutputSetProperty;
399     dev->rrOutputValidateMode = pRRScrPriv->rrOutputValidateMode;
400     dev->rrModeDestroy        = pRRScrPriv->rrModeDestroy;
401     dev->rrOutputGetProperty  = pRRScrPriv->rrOutputGetProperty;
402     dev->rrGetPanning         = pRRScrPriv->rrGetPanning;
403     dev->rrSetPanning         = pRRScrPriv->rrSetPanning;
404 
405     LLOGLN(10, ("  rrSetConfig = %p", dev->rrSetConfig));
406     LLOGLN(10, ("  rrGetInfo = %p", dev->rrGetInfo));
407     LLOGLN(10, ("  rrScreenSetSize = %p", dev->rrScreenSetSize));
408     LLOGLN(10, ("  rrCrtcSet = %p", dev->rrCrtcSet));
409     LLOGLN(10, ("  rrCrtcSetGamma = %p", dev->rrCrtcSetGamma));
410     LLOGLN(10, ("  rrCrtcGetGamma = %p", dev->rrCrtcGetGamma));
411     LLOGLN(10, ("  rrOutputSetProperty = %p", dev->rrOutputSetProperty));
412     LLOGLN(10, ("  rrOutputValidateMode = %p", dev->rrOutputValidateMode));
413     LLOGLN(10, ("  rrModeDestroy = %p", dev->rrModeDestroy));
414     LLOGLN(10, ("  rrOutputGetProperty = %p", dev->rrOutputGetProperty));
415     LLOGLN(10, ("  rrGetPanning = %p", dev->rrGetPanning));
416     LLOGLN(10, ("  rrSetPanning = %p", dev->rrSetPanning));
417 
418     pRRScrPriv->rrSetConfig          = rdpRRSetConfig;
419     pRRScrPriv->rrGetInfo            = rdpRRGetInfo;
420     pRRScrPriv->rrScreenSetSize      = rdpRRScreenSetSize;
421     pRRScrPriv->rrCrtcSet            = rdpRRCrtcSet;
422     pRRScrPriv->rrCrtcSetGamma       = rdpRRCrtcSetGamma;
423     pRRScrPriv->rrCrtcGetGamma       = rdpRRCrtcGetGamma;
424     pRRScrPriv->rrOutputSetProperty  = rdpRROutputSetProperty;
425     pRRScrPriv->rrOutputValidateMode = rdpRROutputValidateMode;
426     pRRScrPriv->rrModeDestroy        = rdpRRModeDestroy;
427     pRRScrPriv->rrOutputGetProperty  = rdpRROutputGetProperty;
428     pRRScrPriv->rrGetPanning         = rdpRRGetPanning;
429     pRRScrPriv->rrSetPanning         = rdpRRSetPanning;
430 
431     rdpResizeSession(dev, 1024, 768);
432 
433     envvar = getenv("XRDP_START_WIDTH");
434     if (envvar != 0)
435     {
436         width = atoi(envvar);
437         if ((width >= 16) && (width < 8192))
438         {
439             envvar = getenv("XRDP_START_HEIGHT");
440             if (envvar != 0)
441             {
442                 height = atoi(envvar);
443                 if ((height >= 16) && (height < 8192))
444                 {
445                     rdpResizeSession(dev, width, height);
446                 }
447             }
448         }
449     }
450 
451     RRScreenSetSizeRange(pScreen, 256, 256, 16 * 1024, 16 * 1024);
452     RRTellChanged(pScreen);
453 
454     return 0;
455 }
456 
457 /******************************************************************************/
458 static void
459 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 18, 5, 0, 0)
rdpBlockHandler1(pointer blockData,OSTimePtr pTimeout,pointer pReadmask)460 rdpBlockHandler1(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
461 #else
462 rdpBlockHandler1(void *blockData, void *pTimeout)
463 #endif
464 {
465 }
466 
467 /******************************************************************************/
468 static void
469 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 18, 5, 0, 0)
rdpWakeupHandler1(pointer blockData,int result,pointer pReadmask)470 rdpWakeupHandler1(pointer blockData, int result, pointer pReadmask)
471 #else
472 rdpWakeupHandler1(void *blockData, int result)
473 #endif
474 {
475     rdpClientConCheck((ScreenPtr)blockData);
476 }
477 
478 #if defined(XORGXRDP_GLAMOR)
479 /*****************************************************************************/
480 static int
rdpSetPixmapVisitWindow(WindowPtr window,void * data)481 rdpSetPixmapVisitWindow(WindowPtr window, void *data)
482 {
483     ScreenPtr screen;
484 
485     LLOGLN(10, ("rdpSetPixmapVisitWindow:"));
486     screen = window->drawable.pScreen;
487     if (screen->GetWindowPixmap(window) == data)
488     {
489         screen->SetWindowPixmap(window, screen->GetScreenPixmap(screen));
490         return WT_WALKCHILDREN;
491     }
492     return WT_DONTWALKCHILDREN;
493 }
494 #endif
495 
496 /*****************************************************************************/
497 static Bool
rdpCreateScreenResources(ScreenPtr pScreen)498 rdpCreateScreenResources(ScreenPtr pScreen)
499 {
500     Bool ret;
501     rdpPtr dev;
502 
503     LLOGLN(0, ("rdpCreateScreenResources:"));
504     dev = rdpGetDevFromScreen(pScreen);
505     pScreen->CreateScreenResources = dev->CreateScreenResources;
506     ret = pScreen->CreateScreenResources(pScreen);
507     pScreen->CreateScreenResources = rdpCreateScreenResources;
508     if (!ret)
509     {
510         return FALSE;
511     }
512     dev->screenSwPixmap = pScreen->GetScreenPixmap(pScreen);
513     if (dev->glamor)
514     {
515 #if defined(XORGXRDP_GLAMOR)
516         PixmapPtr old_screen_pixmap;
517         PixmapPtr screen_pixmap;
518         uint32_t screen_tex;
519         old_screen_pixmap = dev->screenSwPixmap;
520         LLOGLN(0, ("rdpCreateScreenResources: create screen pixmap w %d h %d",
521                pScreen->width, pScreen->height));
522         screen_pixmap = pScreen->CreatePixmap(pScreen,
523                                               pScreen->width,
524                                               pScreen->height,
525                                               pScreen->rootDepth,
526                                               GLAMOR_CREATE_NO_LARGE);
527         if (screen_pixmap == NULL)
528         {
529             return FALSE;
530         }
531         screen_tex = glamor_get_pixmap_texture(screen_pixmap);
532         LLOGLN(0, ("rdpCreateScreenResources: screen_tex 0x%8.8x", screen_tex));
533         pScreen->SetScreenPixmap(screen_pixmap);
534         if ((pScreen->root != NULL) && (pScreen->SetWindowPixmap != NULL))
535         {
536             TraverseTree(pScreen->root, rdpSetPixmapVisitWindow, old_screen_pixmap);
537         }
538 #endif
539     }
540 
541     return TRUE;
542 }
543 
544 /*****************************************************************************/
545 static Bool
546 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpScreenInit(int scrnIndex,ScreenPtr pScreen,int argc,char ** argv)547 rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
548 #else
549 rdpScreenInit(ScreenPtr pScreen, int argc, char **argv)
550 #endif
551 {
552     ScrnInfoPtr pScrn;
553     rdpPtr dev;
554     VisualPtr vis;
555     Bool vis_found;
556     PictureScreenPtr ps;
557 
558     pScrn = xf86Screens[pScreen->myNum];
559     dev = XRDPPTR(pScrn);
560 
561     dev->pScreen = pScreen;
562 
563     miClearVisualTypes();
564     miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
565                      pScrn->rgbBits, TrueColor);
566     miSetPixmapDepths();
567     LLOGLN(0, ("rdpScreenInit: virtualX %d virtualY %d rgbBits %d depth %d",
568            pScrn->virtualX, pScrn->virtualY, pScrn->rgbBits, pScrn->depth));
569 
570     dev->depth = pScrn->depth;
571     dev->paddedWidthInBytes = PixmapBytePad(dev->width, dev->depth);
572     dev->bitsPerPixel = rdpBitsPerPixel(dev->depth);
573     dev->sizeInBytes = dev->paddedWidthInBytes * dev->height;
574     LLOGLN(0, ("rdpScreenInit: pfbMemory bytes %d", dev->sizeInBytes));
575     dev->pfbMemory_alloc = g_new0(uint8_t, dev->sizeInBytes + 16);
576     dev->pfbMemory = (uint8_t *) RDPALIGN(dev->pfbMemory_alloc, 16);
577     LLOGLN(0, ("rdpScreenInit: pfbMemory %p", dev->pfbMemory));
578     if (!fbScreenInit(pScreen, dev->pfbMemory,
579                       pScrn->virtualX, pScrn->virtualY,
580                       pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
581                       pScrn->bitsPerPixel))
582     {
583         LLOGLN(0, ("rdpScreenInit: fbScreenInit failed"));
584         return FALSE;
585     }
586 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 14, 0, 0, 0)
587     /* 1.13 has this function, 1.14 and up does not */
588     miInitializeBackingStore(pScreen);
589 #endif
590 
591     /* try to init simd functions */
592     rdpSimdInit(pScreen, pScrn);
593 
594     vis = pScreen->visuals + (pScreen->numVisuals - 1);
595     while (vis >= pScreen->visuals)
596     {
597         if ((vis->class | DynamicClass) == DirectColor)
598         {
599             vis->offsetBlue = pScrn->offset.blue;
600             vis->blueMask = pScrn->mask.blue;
601             vis->offsetGreen = pScrn->offset.green;
602             vis->greenMask = pScrn->mask.green;
603             vis->offsetRed = pScrn->offset.red;
604             vis->redMask = pScrn->mask.red;
605         }
606         vis--;
607     }
608     fbPictureInit(pScreen, 0, 0);
609     if (dev->glamor)
610     {
611 #if defined(XORGXRDP_GLAMOR)
612         /* it's not that we don't want dri3, we just want to init it ourself */
613         if (glamor_init(pScreen, GLAMOR_USE_EGL_SCREEN | GLAMOR_NO_DRI3))
614         {
615             LLOGLN(0, ("rdpScreenInit: glamor_init ok"));
616         }
617         else
618         {
619             LLOGLN(0, ("rdpScreenInit: glamor_init failed"));
620         }
621         if (g_use_dri2)
622         {
623             if (rdpDri2Init(pScreen) != 0)
624             {
625                 LLOGLN(0, ("rdpScreenInit: rdpDri2Init failed"));
626             }
627             else
628             {
629                 LLOGLN(0, ("rdpScreenInit: rdpDri2Init ok"));
630             }
631         }
632         if (g_use_dri3)
633         {
634             if (rdpDri3Init(pScreen) != 0)
635             {
636                 LLOGLN(0, ("rdpScreenInit: rdpDri3Init failed"));
637             }
638             else
639             {
640                 LLOGLN(0, ("rdpScreenInit: rdpDri3Init ok"));
641             }
642         }
643 #endif
644     }
645     xf86SetBlackWhitePixels(pScreen);
646     xf86SetBackingStore(pScreen);
647 
648 #if 1
649     /* hardware cursor */
650     dev->pCursorFuncs = xf86GetPointerScreenFuncs();
651     miPointerInitialize(pScreen, &g_rdpSpritePointerFuncs,
652                         dev->pCursorFuncs, 0);
653 #else
654     /* software cursor */
655     dev->pCursorFuncs = xf86GetPointerScreenFuncs();
656     miDCInitialize(pScreen, dev->pCursorFuncs);
657 #endif
658 
659     fbCreateDefColormap(pScreen);
660 
661     /* must assign this one */
662     pScreen->SaveScreen = rdpSaveScreen;
663 
664     vis_found = FALSE;
665     vis = pScreen->visuals + (pScreen->numVisuals - 1);
666     while (vis >= pScreen->visuals)
667     {
668         if (vis->vid == pScreen->rootVisual)
669         {
670             vis_found = TRUE;
671         }
672         vis--;
673     }
674     if (!vis_found)
675     {
676         LLOGLN(0, ("rdpScreenInit: no root visual"));
677         return FALSE;
678     }
679 
680     dev->privateKeyRecGC = rdpAllocateGCPrivate(pScreen, sizeof(rdpGCRec));
681     dev->privateKeyRecPixmap = rdpAllocatePixmapPrivate(pScreen, sizeof(rdpPixmapRec));
682 
683     dev->CloseScreen = pScreen->CloseScreen;
684     pScreen->CloseScreen = rdpCloseScreen;
685 
686     dev->CopyWindow = pScreen->CopyWindow;
687     pScreen->CopyWindow = rdpCopyWindow;
688 
689     dev->CreateGC = pScreen->CreateGC;
690     pScreen->CreateGC = rdpCreateGC;
691 
692     dev->CreatePixmap = pScreen->CreatePixmap;
693     pScreen->CreatePixmap = rdpCreatePixmap;
694 
695     dev->DestroyPixmap = pScreen->DestroyPixmap;
696     pScreen->DestroyPixmap = rdpDestroyPixmap;
697 
698     dev->ModifyPixmapHeader = pScreen->ModifyPixmapHeader;
699     pScreen->ModifyPixmapHeader = rdpModifyPixmapHeader;
700 
701     ps = GetPictureScreenIfSet(pScreen);
702     if (ps != 0)
703     {
704         /* composite */
705         dev->Composite = ps->Composite;
706         ps->Composite = rdpComposite;
707         /* glyphs */
708         dev->Glyphs = ps->Glyphs;
709         ps->Glyphs = rdpGlyphs;
710         /* trapezoids */
711         dev->Trapezoids = ps->Trapezoids;
712         ps->Trapezoids = rdpTrapezoids;
713         /* triangles */
714         dev->Triangles = ps->Triangles;
715         ps->Triangles = rdpTriangles;
716         /* composite rects */
717         dev->CompositeRects = ps->CompositeRects;
718         ps->CompositeRects = rdpCompositeRects;
719     }
720 
721     dev->CreateScreenResources = pScreen->CreateScreenResources;
722     pScreen->CreateScreenResources = rdpCreateScreenResources;
723 
724     RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, pScreen);
725 
726     g_timer = TimerSet(g_timer, 0, 10, rdpDeferredRandR, pScreen);
727 
728     if (rdpClientConInit(dev) != 0)
729     {
730         LLOGLN(0, ("rdpScreenInit: rdpClientConInit failed"));
731     }
732 
733     dev->Bpp_mask = 0x00FFFFFF;
734     dev->Bpp = 4;
735     dev->bitsPerPixel = 32;
736 
737 #if defined(XvExtension)
738     /* XVideo */
739     if (!rdpXvInit(pScreen, pScrn))
740     {
741         LLOGLN(0, ("rdpScreenInit: rdpXvInit failed"));
742     }
743 #endif
744 
745     if (dev->glamor)
746     {
747 #if defined(XORGXRDP_GLAMOR)
748         dev->egl = rdpEglCreate(pScreen);
749 #endif
750     }
751 
752     LLOGLN(0, ("rdpScreenInit: out"));
753     return TRUE;
754 }
755 
756 /*****************************************************************************/
757 static Bool
758 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpSwitchMode(int a,DisplayModePtr b,int c)759 rdpSwitchMode(int a, DisplayModePtr b, int c)
760 #else
761 rdpSwitchMode(ScrnInfoPtr a, DisplayModePtr b)
762 #endif
763 {
764     LLOGLN(0, ("rdpSwitchMode:"));
765     return TRUE;
766 }
767 
768 /*****************************************************************************/
769 static void
770 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpAdjustFrame(int a,int b,int c,int d)771 rdpAdjustFrame(int a, int b, int c, int d)
772 #else
773 rdpAdjustFrame(ScrnInfoPtr a, int b, int c)
774 #endif
775 {
776     LLOGLN(10, ("rdpAdjustFrame:"));
777 }
778 
779 /*****************************************************************************/
780 static Bool
781 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpEnterVT(int a,int b)782 rdpEnterVT(int a, int b)
783 #else
784 rdpEnterVT(ScrnInfoPtr a)
785 #endif
786 {
787     LLOGLN(0, ("rdpEnterVT:"));
788     return TRUE;
789 }
790 
791 /*****************************************************************************/
792 static void
793 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpLeaveVT(int a,int b)794 rdpLeaveVT(int a, int b)
795 #else
796 rdpLeaveVT(ScrnInfoPtr a)
797 #endif
798 {
799     LLOGLN(0, ("rdpLeaveVT:"));
800 }
801 
802 /*****************************************************************************/
803 static ModeStatus
804 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpValidMode(int a,DisplayModePtr b,Bool c,int d)805 rdpValidMode(int a, DisplayModePtr b, Bool c, int d)
806 #else
807 rdpValidMode(ScrnInfoPtr a, DisplayModePtr b, Bool c, int d)
808 #endif
809 {
810     LLOGLN(0, ("rdpValidMode:"));
811     return 0;
812 }
813 
814 /*****************************************************************************/
815 static void
816 #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpFreeScreen(int a,int b)817 rdpFreeScreen(int a, int b)
818 #else
819 rdpFreeScreen(ScrnInfoPtr a)
820 #endif
821 {
822     LLOGLN(0, ("rdpFreeScreen:"));
823 }
824 
825 /*****************************************************************************/
826 static Bool
rdpProbe(DriverPtr drv,int flags)827 rdpProbe(DriverPtr drv, int flags)
828 {
829     int num_dev_sections;
830     int i;
831     int entity;
832     GDevPtr *dev_sections;
833     Bool found_screen;
834     ScrnInfoPtr pscrn;
835     const char *val;
836 
837     LLOGLN(0, ("rdpProbe:"));
838     if (flags & PROBE_DETECT)
839     {
840         return FALSE;
841     }
842     /* fbScreenInit, fbPictureInit, ... */
843     if (!xf86LoadDrvSubModule(drv, "fb"))
844     {
845         LLOGLN(0, ("rdpProbe: xf86LoadDrvSubModule for fb failed"));
846         return FALSE;
847     }
848 
849     num_dev_sections = xf86MatchDevice(XRDP_DRIVER_NAME, &dev_sections);
850     if (num_dev_sections <= 0)
851     {
852         LLOGLN(0, ("rdpProbe: xf86MatchDevice failed"));
853         return FALSE;
854     }
855 
856     pscrn = 0;
857     found_screen = FALSE;
858     for (i = 0; i < num_dev_sections; i++)
859     {
860         val = xf86FindOptionValue(dev_sections[i]->options, "DRMDevice");
861         if (val != NULL)
862         {
863 #if defined(XORGXRDP_GLAMOR)
864             strncpy(g_drm_device, val, 127);
865             g_drm_device[127] = 0;
866             LLOGLN(0, ("rdpProbe: found DRMDevice xorg.conf value [%s]", val));
867 #endif
868         }
869         val = xf86FindOptionValue(dev_sections[i]->options, "DRI2");
870         if (val != NULL)
871         {
872 #if defined(XORGXRDP_GLAMOR)
873             if ((strcmp(val, "0") == 0) ||
874                 (strcmp(val, "no") == 0) ||
875                 (strcmp(val, "false") == 0))
876             {
877                g_use_dri2 = 0;
878             }
879             LLOGLN(0, ("rdpProbe: found DRI2 xorg.conf value [%s]", val));
880 #endif
881         }
882         val = xf86FindOptionValue(dev_sections[i]->options, "DRI3");
883         if (val != NULL)
884         {
885 #if defined(XORGXRDP_GLAMOR)
886             if ((strcmp(val, "0") == 0) ||
887                 (strcmp(val, "no") == 0) ||
888                 (strcmp(val, "false") == 0))
889             {
890                g_use_dri3 = 0;
891             }
892             LLOGLN(0, ("rdpProbe: found DRI3 xorg.conf value [%s]", val));
893 #endif
894         }
895         entity = xf86ClaimFbSlot(drv, 0, dev_sections[i], 1);
896         pscrn = xf86ConfigFbEntity(pscrn, 0, entity, 0, 0, 0, 0);
897         if (pscrn)
898         {
899             LLOGLN(10, ("rdpProbe: found screen"));
900             found_screen = 1;
901             pscrn->driverVersion = XRDP_VERSION;
902             pscrn->driverName    = g_xrdp_driver_name;
903             pscrn->name          = g_xrdp_driver_name;
904             pscrn->Probe         = rdpProbe;
905             pscrn->PreInit       = rdpPreInit;
906             pscrn->ScreenInit    = rdpScreenInit;
907             pscrn->SwitchMode    = rdpSwitchMode;
908             pscrn->AdjustFrame   = rdpAdjustFrame;
909             pscrn->EnterVT       = rdpEnterVT;
910             pscrn->LeaveVT       = rdpLeaveVT;
911             pscrn->ValidMode     = rdpValidMode;
912             pscrn->FreeScreen    = rdpFreeScreen;
913             xf86DrvMsg(pscrn->scrnIndex, X_INFO, "%s", "using default device\n");
914         }
915     }
916     free(dev_sections);
917     return found_screen;
918 }
919 
920 /*****************************************************************************/
921 static const OptionInfoRec *
rdpAvailableOptions(int chipid,int busid)922 rdpAvailableOptions(int chipid, int busid)
923 {
924     LLOGLN(0, ("rdpAvailableOptions:"));
925     return 0;
926 }
927 
928 #ifndef HW_SKIP_CONSOLE
929 #define HW_SKIP_CONSOLE 4
930 #endif
931 
932 /*****************************************************************************/
933 static Bool
rdpDriverFunc(ScrnInfoPtr pScrn,xorgDriverFuncOp op,pointer ptr)934 rdpDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
935 {
936     xorgHWFlags *flags;
937     int rv;
938 
939     rv = FALSE;
940     LLOGLN(0, ("rdpDriverFunc: op %d", (int)op));
941     if (op == GET_REQUIRED_HW_INTERFACES)
942     {
943         flags = (xorgHWFlags *) ptr;
944         *flags = HW_SKIP_CONSOLE;
945         rv = TRUE;
946     }
947     return rv;
948 }
949 
950 /*****************************************************************************/
951 static void
rdpIdentify(int flags)952 rdpIdentify(int flags)
953 {
954     LLOGLN(0, ("rdpIdentify:"));
955     xf86PrintChipsets(XRDP_DRIVER_NAME, "driver for xrdp", g_Chipsets);
956 }
957 
958 /*****************************************************************************/
959 _X_EXPORT DriverRec g_DriverRec =
960 {
961     XRDP_VERSION,
962     g_xrdp_driver_name,
963     rdpIdentify,
964     rdpProbe,
965     rdpAvailableOptions,
966     0,
967     0,
968     rdpDriverFunc
969 };
970 
971 /*****************************************************************************/
972 static pointer
xrdpdevSetup(pointer module,pointer opts,int * errmaj,int * errmin)973 xrdpdevSetup(pointer module, pointer opts, int *errmaj, int *errmin)
974 {
975     LLOGLN(0, ("xrdpdevSetup:"));
976     if (!g_setup_done)
977     {
978         g_setup_done = 1;
979         xf86AddDriver(&g_DriverRec, module, HaveDriverFuncs);
980         return (pointer)1;
981     }
982     else
983     {
984         if (errmaj != 0)
985         {
986             *errmaj = LDR_ONCEONLY;
987         }
988         return 0;
989     }
990 }
991 
992 /*****************************************************************************/
993 static void
xrdpdevTearDown(pointer Module)994 xrdpdevTearDown(pointer Module)
995 {
996     LLOGLN(0, ("xrdpdevTearDown:"));
997 }
998 
999 /* <drivername>ModuleData */
1000 _X_EXPORT XF86ModuleData xrdpdevModuleData =
1001 {
1002     &g_VersRec,
1003     xrdpdevSetup,
1004     xrdpdevTearDown
1005 };
1006