Better detection of XShm errors (should now run on remote displays).
This commit is contained in:
parent
21149d0943
commit
98db0be819
|
@ -106,6 +106,10 @@ static struct IDirect3D2_VTable d3d2vt;
|
||||||
static XF86VidModeModeInfo *orig_mode = NULL;
|
static XF86VidModeModeInfo *orig_mode = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBXXSHM
|
||||||
|
static int XShmErrorFlag = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOL32
|
BOOL32
|
||||||
DDRAW_DGA_Available(void)
|
DDRAW_DGA_Available(void)
|
||||||
{
|
{
|
||||||
|
@ -2312,12 +2316,17 @@ static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
|
||||||
#endif /* defined(HAVE_LIBXXF86DGA) */
|
#endif /* defined(HAVE_LIBXXF86DGA) */
|
||||||
}
|
}
|
||||||
|
|
||||||
static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
|
|
||||||
XImage *img;
|
|
||||||
void *img_data;
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBXXSHM
|
#ifdef HAVE_LIBXXSHM
|
||||||
if (this->e.xlib.xshm_active) {
|
/* Error handlers for Image creation */
|
||||||
|
static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
|
||||||
|
XShmErrorFlag = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static XImage *create_xshmimage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
|
||||||
|
XImage *img;
|
||||||
|
int (*WineXHandler)(Display *, XErrorEvent *);
|
||||||
|
|
||||||
img = TSXShmCreateImage(display,
|
img = TSXShmCreateImage(display,
|
||||||
DefaultVisualOfScreen(X11DRV_GetXScreen()),
|
DefaultVisualOfScreen(X11DRV_GetXScreen()),
|
||||||
this->d.screen_depth,
|
this->d.screen_depth,
|
||||||
|
@ -2327,11 +2336,16 @@ static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
|
||||||
lpdsf->s.surface_desc.dwWidth,
|
lpdsf->s.surface_desc.dwWidth,
|
||||||
lpdsf->s.surface_desc.dwHeight);
|
lpdsf->s.surface_desc.dwHeight);
|
||||||
|
|
||||||
if (img == NULL)
|
if (img == NULL) {
|
||||||
|
ERR(ddraw, "Error creating XShm image. Reverting to standard X images !\n");
|
||||||
|
this->e.xlib.xshm_active = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
|
lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
|
||||||
if (lpdsf->t.xlib.shminfo.shmid < 0) {
|
if (lpdsf->t.xlib.shminfo.shmid < 0) {
|
||||||
|
ERR(ddraw, "Error creating shared memory segment. Reverting to standard X images !\n");
|
||||||
|
this->e.xlib.xshm_active = 0;
|
||||||
TSXDestroyImage(img);
|
TSXDestroyImage(img);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2339,15 +2353,51 @@ static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
|
||||||
lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
|
lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
|
||||||
|
|
||||||
if (img->data == (char *) -1) {
|
if (img->data == (char *) -1) {
|
||||||
|
ERR(ddraw, "Error attaching shared memory segment. Reverting to standard X images !\n");
|
||||||
|
this->e.xlib.xshm_active = 0;
|
||||||
TSXDestroyImage(img);
|
TSXDestroyImage(img);
|
||||||
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
|
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
lpdsf->t.xlib.shminfo.readOnly = False;
|
lpdsf->t.xlib.shminfo.readOnly = False;
|
||||||
|
|
||||||
TSXShmAttach(display, &(lpdsf->t.xlib.shminfo));
|
/* This is where things start to get trickier....
|
||||||
|
First, we flush the current X connections to be sure to catch all non-XShm related
|
||||||
|
errors */
|
||||||
TSXSync(display, False);
|
TSXSync(display, False);
|
||||||
|
/* Then we enter in the non-thread safe part of the tests */
|
||||||
|
EnterCriticalSection( &X11DRV_CritSection );
|
||||||
|
|
||||||
|
/* Reset the error flag, sets our new error handler and try to attach the surface */
|
||||||
|
XShmErrorFlag = 0;
|
||||||
|
WineXHandler = XSetErrorHandler(XShmErrorHandler);
|
||||||
|
XShmAttach(display, &(lpdsf->t.xlib.shminfo));
|
||||||
|
XSync(display, False);
|
||||||
|
|
||||||
|
/* Check the error flag */
|
||||||
|
if (XShmErrorFlag) {
|
||||||
|
/* An error occured */
|
||||||
|
XFlush(display);
|
||||||
|
XShmErrorFlag = 0;
|
||||||
|
XDestroyImage(img);
|
||||||
|
shmdt(lpdsf->t.xlib.shminfo.shmaddr);
|
||||||
|
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
|
||||||
|
XSetErrorHandler(WineXHandler);
|
||||||
|
|
||||||
|
ERR(ddraw, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
|
||||||
|
this->e.xlib.xshm_active = 0;
|
||||||
|
|
||||||
|
/* Leave the critical section */
|
||||||
|
LeaveCriticalSection( &X11DRV_CritSection );
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
|
||||||
|
but it may be a bit overkill.... */
|
||||||
|
XSetErrorHandler(WineXHandler);
|
||||||
|
LeaveCriticalSection( &X11DRV_CritSection );
|
||||||
|
|
||||||
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
|
shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
|
||||||
|
|
||||||
if (this->d.depth != this->d.screen_depth) {
|
if (this->d.depth != this->d.screen_depth) {
|
||||||
|
@ -2358,7 +2408,21 @@ static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
|
||||||
} else {
|
} else {
|
||||||
lpdsf->s.surface_desc.y.lpSurface = img->data;
|
lpdsf->s.surface_desc.y.lpSurface = img->data;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_LIBXXSHM */
|
||||||
|
|
||||||
|
static XImage *create_ximage(LPDIRECTDRAW2 this, LPDIRECTDRAWSURFACE4 lpdsf) {
|
||||||
|
XImage *img = NULL;
|
||||||
|
void *img_data;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBXXSHM
|
||||||
|
if (this->e.xlib.xshm_active) {
|
||||||
|
img = create_xshmimage(this, lpdsf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (img == NULL) {
|
||||||
#endif
|
#endif
|
||||||
/* Allocate surface memory */
|
/* Allocate surface memory */
|
||||||
lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
|
lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
|
||||||
|
@ -3746,6 +3810,8 @@ HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
|
||||||
(*lplpDD)->ref = 1;
|
(*lplpDD)->ref = 1;
|
||||||
(*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
|
(*lplpDD)->d.drawable = 0; /* in SetDisplayMode */
|
||||||
|
|
||||||
|
/* At DirectDraw creation, the depth is the default depth */
|
||||||
|
(*lplpDD)->d.depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
|
||||||
(*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
|
(*lplpDD)->d.screen_depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
|
||||||
(*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
|
(*lplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
|
||||||
(*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
|
(*lplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
|
||||||
|
|
Loading…
Reference in New Issue