Merge remote-tracking branch 'anholt/ephyr-fixes'
This commit is contained in:
commit
f3b529bf25
|
@ -2116,12 +2116,12 @@ if test "$KDRIVE" = yes; then
|
|||
AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver])
|
||||
fi
|
||||
|
||||
XEPHYR_REQUIRED_LIBS="x11 >= 1.6 $LIBXEXT xau xdmcp"
|
||||
XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms"
|
||||
if test "x$XV" = xyes; then
|
||||
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv"
|
||||
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xcb-xv"
|
||||
fi
|
||||
if test "x$DRI" = xyes && test "x$GLX" = xyes; then
|
||||
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
|
||||
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS libdrm xcb-glx xcb-xf86dri > 1.6"
|
||||
fi
|
||||
|
||||
if test "x$XEPHYR" = xauto; then
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
# Copyright © 2013 Intel Corporation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice (including the next
|
||||
# paragraph) shall be included in all copies or substantial portions of the
|
||||
# Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
SUBDIRS = man
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
|
@ -9,81 +30,45 @@ AM_CPPFLAGS = \
|
|||
-I$(top_srcdir)/exa
|
||||
|
||||
if XV
|
||||
LIBXEPHYR_HOSTXV=libxephyr-hostxv.la
|
||||
XV_SRCS = ephyrvideo.c
|
||||
endif
|
||||
|
||||
if DRI
|
||||
LIBXEPHYR_HOSTDRI=libxephyr-hostdri.la
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES = libxephyr-hostx.la $(LIBXEPHYR_HOSTXV) $(LIBXEPHYR_HOSTDRI) libxephyr.la
|
||||
|
||||
bin_PROGRAMS = Xephyr
|
||||
|
||||
HOSTX_SRCS = \
|
||||
hostx.c \
|
||||
hostx.h
|
||||
|
||||
HOSTVIDEO_SRCS = \
|
||||
ephyrvideo.c \
|
||||
ephyrhostvideo.c \
|
||||
ephyrhostvideo.h
|
||||
|
||||
HOSTDRI_SRCS = \
|
||||
DRI_SRCS = \
|
||||
ephyrdriext.c \
|
||||
ephyrdriext.h \
|
||||
ephyrdri.c \
|
||||
ephyrdri.h \
|
||||
XF86dri.c \
|
||||
xf86dri.h \
|
||||
ephyrglxext.c \
|
||||
ephyrglxext.h \
|
||||
ephyrhostglx.c \
|
||||
ephyrhostglx.h
|
||||
|
||||
XEPHYR_SRCS = \
|
||||
ephyr.c \
|
||||
ephyr.h \
|
||||
ephyrlog.h \
|
||||
ephyr_draw.c \
|
||||
os.c
|
||||
|
||||
libxephyr_hostx_la_SOURCES = $(HOSTX_SRCS)
|
||||
|
||||
if XV
|
||||
libxephyr_hostxv_la_SOURCES = $(HOSTVIDEO_SRCS)
|
||||
ephyrhostglx.h \
|
||||
$()
|
||||
endif
|
||||
|
||||
if DRI
|
||||
libxephyr_hostdri_la_SOURCES = $(HOSTDRI_SRCS)
|
||||
endif
|
||||
|
||||
libxephyr_la_SOURCES = $(XEPHYR_SRCS)
|
||||
bin_PROGRAMS = Xephyr
|
||||
|
||||
Xephyr_SOURCES = \
|
||||
ephyrinit.c
|
||||
ephyr.c \
|
||||
ephyr.h \
|
||||
ephyrlog.h \
|
||||
ephyr_draw.c \
|
||||
os.c \
|
||||
ephyrinit.c \
|
||||
hostx.c \
|
||||
hostx.h \
|
||||
$(XV_SRCS) \
|
||||
$(DRI_SRCS) \
|
||||
$()
|
||||
|
||||
Xephyr_LDADD = \
|
||||
libxephyr.la \
|
||||
libxephyr-hostx.la \
|
||||
$(LIBXEPHYR_HOSTXV) \
|
||||
$(LIBXEPHYR_HOSTDRI) \
|
||||
$(top_builddir)/exa/libexa.la \
|
||||
@KDRIVE_LIBS@ \
|
||||
@XEPHYR_LIBS@
|
||||
|
||||
Xephyr_DEPENDENCIES = \
|
||||
libxephyr.la \
|
||||
libxephyr-hostx.la \
|
||||
$(LIBXEPHYR_HOSTXV) \
|
||||
$(LIBXEPHYR_HOSTDRI) \
|
||||
@KDRIVE_LOCAL_LIBS@
|
||||
Xephyr_DEPENDENCIES = @KDRIVE_LOCAL_LIBS@
|
||||
|
||||
Xephyr_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
|
||||
|
||||
relink:
|
||||
$(AM_V_at)rm -f $(bin_PROGRAMS) && $(MAKE) $(bin_PROGRAMS)
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(HOSTVIDEO_SRCS) \
|
||||
$(HOSTDRI_SRCS)
|
||||
|
|
|
@ -1,654 +0,0 @@
|
|||
/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
Copyright 2000 VA Linux Systems, Inc.
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sub license, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Jens Owen <jens@tungstengraphics.com>
|
||||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file has been copied from the mesa source tree and a little bit
|
||||
* modified by:
|
||||
*
|
||||
* Dodji Seketeli <dodji@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <kdrive-config.h>
|
||||
#endif
|
||||
/*
|
||||
* including some server headers (like kdrive-config.h)
|
||||
* might define the macro _XSERVER64
|
||||
* on 64 bits machines. That macro must _NOT_ be defined for Xlib
|
||||
* client code, otherwise bad things happen.
|
||||
* So let's undef that macro if necessary.
|
||||
*/
|
||||
#ifdef _XSERVER64
|
||||
#undef _XSERVER64
|
||||
#endif
|
||||
|
||||
/* THIS IS NOT AN X CONSORTIUM STANDARD */
|
||||
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/extensions/Xext.h>
|
||||
#include <X11/extensions/extutil.h>
|
||||
#include <GL/glx.h>
|
||||
#include "xf86dri.h"
|
||||
#include <X11/dri/xf86driproto.h>
|
||||
#include <limits.h>
|
||||
|
||||
static XExtensionInfo _xf86dri_info_data;
|
||||
static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
|
||||
static char xf86dri_extension_name[] = XF86DRINAME;
|
||||
|
||||
#define XF86DRICheckExtension(dpy,i,val) \
|
||||
XextCheckExtension (dpy, i, xf86dri_extension_name, val)
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* private utility routines *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
static int close_display(Display * dpy, XExtCodes * extCodes);
|
||||
|
||||
static /* const */ XExtensionHooks xf86dri_extension_hooks = {
|
||||
NULL, /* create_gc */
|
||||
NULL, /* copy_gc */
|
||||
NULL, /* flush_gc */
|
||||
NULL, /* free_gc */
|
||||
NULL, /* create_font */
|
||||
NULL, /* free_font */
|
||||
close_display, /* close_display */
|
||||
NULL, /* wire_to_event */
|
||||
NULL, /* event_to_wire */
|
||||
NULL, /* error */
|
||||
NULL, /* error_string */
|
||||
};
|
||||
|
||||
static
|
||||
XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
|
||||
xf86dri_extension_name,
|
||||
&xf86dri_extension_hooks, 0, NULL)
|
||||
|
||||
static
|
||||
XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* public XFree86-DRI Extension routines *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
|
||||
#else
|
||||
#define TRACE(msg)
|
||||
#endif
|
||||
Bool
|
||||
XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable);
|
||||
Bool
|
||||
XF86DRICloseFullScreen(Display * dpy, int screen, Drawable drawable);
|
||||
|
||||
Bool
|
||||
XF86DRIQueryExtension(Display * dpy, int *event_basep, int *error_basep)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
|
||||
TRACE("QueryExtension...");
|
||||
if (XextHasExtension(info)) {
|
||||
*event_basep = info->codes->first_event;
|
||||
*error_basep = info->codes->first_error;
|
||||
TRACE("QueryExtension... return True");
|
||||
return True;
|
||||
}
|
||||
else {
|
||||
TRACE("QueryExtension... return False");
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
|
||||
int *patchVersion)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIQueryVersionReply rep;
|
||||
xXF86DRIQueryVersionReq *req;
|
||||
|
||||
TRACE("QueryVersion...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIQueryVersion, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIQueryVersion;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("QueryVersion... return False");
|
||||
return False;
|
||||
}
|
||||
*majorVersion = rep.majorVersion;
|
||||
*minorVersion = rep.minorVersion;
|
||||
*patchVersion = rep.patchVersion;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("QueryVersion... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen, Bool *isCapable)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIQueryDirectRenderingCapableReply rep;
|
||||
xXF86DRIQueryDirectRenderingCapableReq *req;
|
||||
|
||||
TRACE("QueryDirectRenderingCapable...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIQueryDirectRenderingCapable, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
|
||||
req->screen = screen;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("QueryDirectRenderingCapable... return False");
|
||||
return False;
|
||||
}
|
||||
*isCapable = rep.isCapable;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("QueryDirectRenderingCapable... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIOpenConnection(Display * dpy, int screen,
|
||||
drm_handle_t * hSAREA, char **busIdString)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIOpenConnectionReply rep;
|
||||
xXF86DRIOpenConnectionReq *req;
|
||||
|
||||
TRACE("OpenConnection...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIOpenConnection, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIOpenConnection;
|
||||
req->screen = screen;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("OpenConnection... return False");
|
||||
return False;
|
||||
}
|
||||
|
||||
*hSAREA = rep.hSAREALow;
|
||||
if (sizeof(drm_handle_t) == 8) {
|
||||
int shift = 32; /* var to prevent warning on next line */
|
||||
|
||||
*hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
|
||||
}
|
||||
|
||||
if (rep.length) {
|
||||
if (rep.busIdStringLength < INT_MAX)
|
||||
*busIdString = calloc(rep.busIdStringLength + 1, 1);
|
||||
else
|
||||
*busIdString = NULL;
|
||||
if (*busIdString == NULL) {
|
||||
_XEatDataWords(dpy, rep.length);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("OpenConnection... return False");
|
||||
return False;
|
||||
}
|
||||
_XReadPad(dpy, *busIdString, rep.busIdStringLength);
|
||||
}
|
||||
else {
|
||||
*busIdString = NULL;
|
||||
}
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("OpenConnection... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIAuthConnectionReq *req;
|
||||
xXF86DRIAuthConnectionReply rep;
|
||||
|
||||
TRACE("AuthConnection...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIAuthConnection, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIAuthConnection;
|
||||
req->screen = screen;
|
||||
req->magic = magic;
|
||||
rep.authenticated = 0;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse) || !rep.authenticated) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("AuthConnection... return False");
|
||||
return False;
|
||||
}
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("AuthConnection... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRICloseConnection(Display * dpy, int screen)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRICloseConnectionReq *req;
|
||||
|
||||
TRACE("CloseConnection...");
|
||||
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRICloseConnection, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRICloseConnection;
|
||||
req->screen = screen;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("CloseConnection... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIGetClientDriverName(Display * dpy, int screen,
|
||||
int *ddxDriverMajorVersion,
|
||||
int *ddxDriverMinorVersion,
|
||||
int *ddxDriverPatchVersion, char **clientDriverName)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIGetClientDriverNameReply rep;
|
||||
xXF86DRIGetClientDriverNameReq *req;
|
||||
|
||||
TRACE("GetClientDriverName...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIGetClientDriverName, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIGetClientDriverName;
|
||||
req->screen = screen;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetClientDriverName... return False");
|
||||
return False;
|
||||
}
|
||||
|
||||
*ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
|
||||
*ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
|
||||
*ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
|
||||
|
||||
if (rep.length) {
|
||||
if (rep.clientDriverNameLength < INT_MAX)
|
||||
*clientDriverName = calloc(rep.clientDriverNameLength + 1, 1);
|
||||
else
|
||||
*clientDriverName = NULL;
|
||||
if (*clientDriverName == NULL) {
|
||||
_XEatDataWords(dpy, rep.length);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetClientDriverName... return False");
|
||||
return False;
|
||||
}
|
||||
_XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
|
||||
}
|
||||
else {
|
||||
*clientDriverName = NULL;
|
||||
}
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetClientDriverName... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID,
|
||||
XID *context, drm_context_t * hHWContext)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRICreateContextReply rep;
|
||||
xXF86DRICreateContextReq *req;
|
||||
|
||||
TRACE("CreateContext...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRICreateContext, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRICreateContext;
|
||||
req->visual = configID;
|
||||
req->screen = screen;
|
||||
*context = XAllocID(dpy);
|
||||
req->context = *context;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("CreateContext... return False");
|
||||
return False;
|
||||
}
|
||||
*hHWContext = rep.hHWContext;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("CreateContext... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRICreateContext(Display * dpy, int screen, Visual * visual,
|
||||
XID *context, drm_context_t * hHWContext)
|
||||
{
|
||||
return XF86DRICreateContextWithConfig(dpy, screen, visual->visualid,
|
||||
context, hHWContext);
|
||||
}
|
||||
|
||||
GLboolean
|
||||
XF86DRIDestroyContext(Display * dpy, int screen, XID context)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIDestroyContextReq *req;
|
||||
|
||||
TRACE("DestroyContext...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIDestroyContext, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIDestroyContext;
|
||||
req->screen = screen;
|
||||
req->context = context;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("DestroyContext... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
XF86DRICreateDrawable(Display * dpy, int screen,
|
||||
XID drawable, drm_drawable_t * hHWDrawable)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRICreateDrawableReply rep;
|
||||
xXF86DRICreateDrawableReq *req;
|
||||
|
||||
TRACE("CreateDrawable...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRICreateDrawable, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRICreateDrawable;
|
||||
req->screen = screen;
|
||||
req->drawable = drawable;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("CreateDrawable... return False");
|
||||
return False;
|
||||
}
|
||||
*hHWDrawable = rep.hHWDrawable;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("CreateDrawable... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
static int
|
||||
noopErrorHandler(Display * dpy, XErrorEvent * xerr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLboolean
|
||||
XF86DRIDestroyDrawable(Display * dpy, int screen, XID drawable)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIDestroyDrawableReq *req;
|
||||
int (*oldXErrorHandler) (Display *, XErrorEvent *);
|
||||
|
||||
TRACE("DestroyDrawable...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
/* This is called from the DRI driver, which used call it like this
|
||||
*
|
||||
* if (windowExists(drawable))
|
||||
* destroyDrawable(drawable);
|
||||
*
|
||||
* which is a textbook race condition - the window may disappear
|
||||
* from the server between checking for its existance and
|
||||
* destroying it. Instead we change the semantics of
|
||||
* __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
|
||||
* the windows is gone, by wrapping the destroy call in an error
|
||||
* handler. */
|
||||
|
||||
XSync(dpy, GL_FALSE);
|
||||
oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIDestroyDrawable, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIDestroyDrawable;
|
||||
req->screen = screen;
|
||||
req->drawable = drawable;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
XSetErrorHandler(oldXErrorHandler);
|
||||
|
||||
TRACE("DestroyDrawable... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
|
||||
unsigned int *index, unsigned int *stamp,
|
||||
int *X, int *Y, int *W, int *H,
|
||||
int *numClipRects, drm_clip_rect_t ** pClipRects,
|
||||
int *backX, int *backY,
|
||||
int *numBackClipRects, drm_clip_rect_t ** pBackClipRects)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIGetDrawableInfoReply rep;
|
||||
xXF86DRIGetDrawableInfoReq *req = NULL;
|
||||
int total_rects;
|
||||
|
||||
TRACE("GetDrawableInfo...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIGetDrawableInfo, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIGetDrawableInfo;
|
||||
req->screen = screen;
|
||||
req->drawable = drawable;
|
||||
|
||||
if (!_XReply(dpy, (xReply *) &rep, 1, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetDrawableInfo... return False");
|
||||
return False;
|
||||
}
|
||||
*index = rep.drawableTableIndex;
|
||||
*stamp = rep.drawableTableStamp;
|
||||
*X = (int) rep.drawableX;
|
||||
*Y = (int) rep.drawableY;
|
||||
*W = (int) rep.drawableWidth;
|
||||
*H = (int) rep.drawableHeight;
|
||||
*numClipRects = rep.numClipRects;
|
||||
total_rects = *numClipRects;
|
||||
|
||||
*backX = rep.backX;
|
||||
*backY = rep.backY;
|
||||
*numBackClipRects = rep.numBackClipRects;
|
||||
total_rects += *numBackClipRects;
|
||||
|
||||
#if 0
|
||||
/* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
|
||||
* backwards compatibility (Because of the >> 2 shift) but the fix
|
||||
* enables multi-threaded apps to work.
|
||||
*/
|
||||
if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
|
||||
SIZEOF(xGenericReply) +
|
||||
total_rects * sizeof(drm_clip_rect_t)) +
|
||||
3) & ~3) >> 2)) {
|
||||
_XEatDataWords(dpy, rep.length);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetDrawableInfo... return False");
|
||||
return False;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*numClipRects) {
|
||||
int len = sizeof(drm_clip_rect_t) * (*numClipRects);
|
||||
|
||||
*pClipRects = (drm_clip_rect_t *) calloc(len, 1);
|
||||
if (*pClipRects)
|
||||
_XRead(dpy, (char *) *pClipRects, len);
|
||||
}
|
||||
else {
|
||||
*pClipRects = NULL;
|
||||
}
|
||||
|
||||
if (*numBackClipRects) {
|
||||
int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
|
||||
|
||||
*pBackClipRects = (drm_clip_rect_t *) calloc(len, 1);
|
||||
if (*pBackClipRects)
|
||||
_XRead(dpy, (char *) *pBackClipRects, len);
|
||||
}
|
||||
else {
|
||||
*pBackClipRects = NULL;
|
||||
}
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetDrawableInfo... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIGetDeviceInfo(Display * dpy, int screen, drm_handle_t * hFrameBuffer,
|
||||
int *fbOrigin, int *fbSize, int *fbStride,
|
||||
int *devPrivateSize, void **pDevPrivate)
|
||||
{
|
||||
XExtDisplayInfo *info = find_display(dpy);
|
||||
xXF86DRIGetDeviceInfoReply rep;
|
||||
xXF86DRIGetDeviceInfoReq *req;
|
||||
|
||||
TRACE("GetDeviceInfo...");
|
||||
XF86DRICheckExtension(dpy, info, False);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(XF86DRIGetDeviceInfo, req);
|
||||
req->reqType = info->codes->major_opcode;
|
||||
req->driReqType = X_XF86DRIGetDeviceInfo;
|
||||
req->screen = screen;
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetDeviceInfo... return False");
|
||||
return False;
|
||||
}
|
||||
|
||||
*hFrameBuffer = rep.hFrameBufferLow;
|
||||
if (sizeof(drm_handle_t) == 8) {
|
||||
int shift = 32; /* var to prevent warning on next line */
|
||||
|
||||
*hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
|
||||
}
|
||||
|
||||
*fbOrigin = rep.framebufferOrigin;
|
||||
*fbSize = rep.framebufferSize;
|
||||
*fbStride = rep.framebufferStride;
|
||||
*devPrivateSize = rep.devPrivateSize;
|
||||
|
||||
if (rep.length) {
|
||||
if (!(*pDevPrivate = (void *) calloc(rep.devPrivateSize, 1))) {
|
||||
_XEatDataWords(dpy, rep.length);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetDeviceInfo... return False");
|
||||
return False;
|
||||
}
|
||||
_XRead(dpy, (char *) *pDevPrivate, rep.devPrivateSize);
|
||||
}
|
||||
else {
|
||||
*pDevPrivate = NULL;
|
||||
}
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
TRACE("GetDeviceInfo... return True");
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable)
|
||||
{
|
||||
/* This function and the underlying X protocol are deprecated.
|
||||
*/
|
||||
(void) dpy;
|
||||
(void) screen;
|
||||
(void) drawable;
|
||||
return False;
|
||||
}
|
||||
|
||||
Bool
|
||||
XF86DRICloseFullScreen(Display * dpy, int screen, Drawable drawable)
|
||||
{
|
||||
/* This function and the underlying X protocol are deprecated.
|
||||
*/
|
||||
(void) dpy;
|
||||
(void) screen;
|
||||
(void) drawable;
|
||||
return True;
|
||||
}
|
|
@ -26,6 +26,10 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include "ephyr.h"
|
||||
|
||||
#include "inputstr.h"
|
||||
|
@ -33,6 +37,7 @@
|
|||
#include "ephyrlog.h"
|
||||
|
||||
#ifdef XF86DRI
|
||||
#include <xcb/xf86dri.h>
|
||||
#include "ephyrdri.h"
|
||||
#include "ephyrdriext.h"
|
||||
#include "ephyrglxext.h"
|
||||
|
@ -58,6 +63,16 @@ typedef struct _EphyrInputPrivate {
|
|||
Bool EphyrWantGrayScale = 0;
|
||||
Bool EphyrWantResize = 0;
|
||||
|
||||
Bool
|
||||
host_has_extension(xcb_extension_t *extension)
|
||||
{
|
||||
const xcb_query_extension_reply_t *rep;
|
||||
|
||||
rep = xcb_get_extension_data(hostx_get_xcbconn(), extension);
|
||||
|
||||
return rep && rep->present;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrInitialize(KdCardInfo * card, EphyrPriv * priv)
|
||||
{
|
||||
|
@ -87,8 +102,9 @@ ephyrCardInit(KdCardInfo * card)
|
|||
}
|
||||
|
||||
Bool
|
||||
ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
|
||||
ephyrScreenInitialize(KdScreenInfo *screen)
|
||||
{
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
int width = 640, height = 480;
|
||||
CARD32 redMask, greenMask, blueMask;
|
||||
|
||||
|
@ -105,7 +121,7 @@ ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
|
|||
if (screen->fb.depth < hostx_get_depth()
|
||||
&& (screen->fb.depth == 24 || screen->fb.depth == 16
|
||||
|| screen->fb.depth == 8)) {
|
||||
hostx_set_server_depth(screen, screen->fb.depth);
|
||||
scrpriv->server_depth = screen->fb.depth;
|
||||
}
|
||||
else
|
||||
ErrorF
|
||||
|
@ -168,27 +184,6 @@ ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
|
|||
return ephyrMapFramebuffer(screen);
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrScreenInit(KdScreenInfo * screen)
|
||||
{
|
||||
EphyrScrPriv *scrpriv;
|
||||
|
||||
scrpriv = calloc(1, sizeof(EphyrScrPriv));
|
||||
|
||||
if (!scrpriv)
|
||||
return FALSE;
|
||||
|
||||
screen->driver = scrpriv;
|
||||
|
||||
if (!ephyrScreenInitialize(screen, scrpriv)) {
|
||||
screen->driver = 0;
|
||||
free(scrpriv);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void *
|
||||
ephyrWindowLinear(ScreenPtr pScreen,
|
||||
CARD32 row,
|
||||
|
@ -654,7 +649,7 @@ ephyrInitScreen(ScreenPtr pScreen)
|
|||
}
|
||||
#endif /*XV*/
|
||||
#ifdef XF86DRI
|
||||
if (!ephyrNoDRI && !hostx_has_dri()) {
|
||||
if (!ephyrNoDRI && !host_has_extension(&xcb_xf86dri_id)) {
|
||||
EPHYR_LOG("host x does not support DRI. Disabling DRI forwarding\n");
|
||||
ephyrNoDRI = TRUE;
|
||||
}
|
||||
|
@ -804,13 +799,13 @@ ephyrCrossScreen(ScreenPtr pScreen, Bool entering)
|
|||
{
|
||||
}
|
||||
|
||||
int ephyrCurScreen; /*current event screen */
|
||||
ScreenPtr ephyrCursorScreen; /* screen containing the cursor */
|
||||
|
||||
static void
|
||||
ephyrWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
|
||||
{
|
||||
OsBlockSIGIO();
|
||||
ephyrCurScreen = pScreen->myNum;
|
||||
ephyrCursorScreen = pScreen;
|
||||
miPointerWarpCursor(inputInfo.pointer, pScreen, x, y);
|
||||
|
||||
OsReleaseSIGIO();
|
||||
|
@ -856,123 +851,327 @@ ephyrExposePairedWindow(int a_remote)
|
|||
}
|
||||
#endif /* XF86DRI */
|
||||
|
||||
static KdScreenInfo *
|
||||
screen_from_window(Window w)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < screenInfo.numScreens; i++) {
|
||||
ScreenPtr pScreen = screenInfo.screens[i];
|
||||
KdPrivScreenPtr kdscrpriv = KdGetScreenPriv(pScreen);
|
||||
KdScreenInfo *screen = kdscrpriv->screen;
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
if (scrpriv->win == w
|
||||
|| scrpriv->peer_win == w
|
||||
|| scrpriv->win_pre_existing == w) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessErrorEvent(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_generic_error_t *e = (xcb_generic_error_t *)xev;
|
||||
|
||||
FatalError("X11 error\n"
|
||||
"Error code: %hhu\n"
|
||||
"Sequence number: %hu\n"
|
||||
"Major code: %hhu\tMinor code: %hu\n"
|
||||
"Error value: %u\n",
|
||||
e->error_code,
|
||||
e->sequence,
|
||||
e->major_code, e->minor_code,
|
||||
e->resource_id);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessExpose(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_expose_event_t *expose = (xcb_expose_event_t *)xev;
|
||||
KdScreenInfo *screen = screen_from_window(expose->window);
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
/* Wait for the last expose event in a series of cliprects
|
||||
* to actually paint our screen.
|
||||
*/
|
||||
if (expose->count != 0)
|
||||
return;
|
||||
|
||||
if (scrpriv) {
|
||||
hostx_paint_rect(scrpriv->screen, 0, 0, 0, 0,
|
||||
scrpriv->win_width,
|
||||
scrpriv->win_height);
|
||||
} else {
|
||||
EPHYR_LOG_ERROR("failed to get host screen\n");
|
||||
#ifdef XF86DRI
|
||||
/*
|
||||
* We only receive expose events when the expose event
|
||||
* have be generated for a drawable that is a host X
|
||||
* window managed by Xephyr. Host X windows managed by
|
||||
* Xephyr exists for instance when Xephyr is asked to
|
||||
* create a GL drawable in a DRI environment.
|
||||
*/
|
||||
ephyrExposePairedWindow(expose->window);
|
||||
#endif /* XF86DRI */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessMouseMotion(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev;
|
||||
KdScreenInfo *screen = screen_from_window(motion->event);
|
||||
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_LOG("skipping mouse motion:%d\n", screen->pScreen->myNum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ephyrCursorScreen != screen->pScreen) {
|
||||
EPHYR_LOG("warping mouse cursor. "
|
||||
"cur_screen%d, motion_screen:%d\n",
|
||||
ephyrCursorScreen, screen->pScreen->myNum);
|
||||
ephyrWarpCursor(inputInfo.pointer, screen->pScreen,
|
||||
motion->event_x, motion->event_y);
|
||||
}
|
||||
else {
|
||||
int x = 0, y = 0;
|
||||
|
||||
#ifdef XF86DRI
|
||||
EphyrWindowPair *pair = NULL;
|
||||
#endif
|
||||
EPHYR_LOG("enqueuing mouse motion:%d\n", ephyrCurScreen);
|
||||
x = motion->event_x;
|
||||
y = motion->event_y;
|
||||
EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y);
|
||||
#ifdef XF86DRI
|
||||
EPHYR_LOG("is this window peered by a gl drawable ?\n");
|
||||
if (findWindowPairFromRemote(motion->event, &pair)) {
|
||||
EPHYR_LOG("yes, it is peered\n");
|
||||
x += pair->local->drawable.x;
|
||||
y += pair->local->drawable.y;
|
||||
}
|
||||
else {
|
||||
EPHYR_LOG("no, it is not peered\n");
|
||||
}
|
||||
EPHYR_LOG("final (x,y):(%d,%d)\n", x, y);
|
||||
#endif
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessButtonPress(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev;
|
||||
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_LOG("skipping mouse press:%d\n", ephyrCurScreen);
|
||||
return;
|
||||
}
|
||||
|
||||
ephyrUpdateModifierState(button->state);
|
||||
/* This is a bit hacky. will break for button 5 ( defined as 0x10 )
|
||||
* Check KD_BUTTON defines in kdrive.h
|
||||
*/
|
||||
mouseState |= 1 << (button->detail - 1);
|
||||
|
||||
EPHYR_LOG("enqueuing mouse press:%d\n", ephyrCurScreen);
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessButtonRelease(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_button_press_event_t *button = (xcb_button_press_event_t *)xev;
|
||||
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ephyrUpdateModifierState(button->state);
|
||||
mouseState &= ~(1 << (button->detail - 1));
|
||||
|
||||
EPHYR_LOG("enqueuing mouse release:%d\n", ephyrCurScreen);
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessKeyPress(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_key_press_event_t *key = (xcb_key_press_event_t *)xev;
|
||||
|
||||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ephyrUpdateModifierState(key->state);
|
||||
KdEnqueueKeyboardEvent(ephyrKbd, key->detail, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessKeyRelease(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev;
|
||||
static xcb_key_symbols_t *keysyms;
|
||||
static int grabbed_screen = -1;
|
||||
|
||||
if (!keysyms)
|
||||
keysyms = xcb_key_symbols_alloc(conn);
|
||||
|
||||
if (((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L
|
||||
|| xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R)
|
||||
&& (key->state & XCB_MOD_MASK_CONTROL)) ||
|
||||
((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_L
|
||||
|| xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_R)
|
||||
&& (key->state & XCB_MOD_MASK_SHIFT))) {
|
||||
KdScreenInfo *screen = screen_from_window(key->event);
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
if (grabbed_screen != -1) {
|
||||
xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME);
|
||||
xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
|
||||
grabbed_screen = -1;
|
||||
hostx_set_win_title(screen,
|
||||
"(ctrl+shift grabs mouse and keyboard)");
|
||||
}
|
||||
else {
|
||||
/* Attempt grab */
|
||||
xcb_grab_keyboard_cookie_t kbgrabc =
|
||||
xcb_grab_keyboard(conn,
|
||||
TRUE,
|
||||
scrpriv->win,
|
||||
XCB_TIME_CURRENT_TIME,
|
||||
XCB_GRAB_MODE_ASYNC,
|
||||
XCB_GRAB_MODE_ASYNC);
|
||||
xcb_grab_keyboard_reply_t *kbgrabr;
|
||||
xcb_grab_pointer_cookie_t pgrabc =
|
||||
xcb_grab_pointer(conn,
|
||||
TRUE,
|
||||
scrpriv->win,
|
||||
0,
|
||||
XCB_GRAB_MODE_ASYNC,
|
||||
XCB_GRAB_MODE_ASYNC,
|
||||
scrpriv->win,
|
||||
XCB_NONE,
|
||||
XCB_TIME_CURRENT_TIME);
|
||||
xcb_grab_pointer_reply_t *pgrabr;
|
||||
kbgrabr = xcb_grab_keyboard_reply(conn, kbgrabc, NULL);
|
||||
if (!kbgrabr || kbgrabr->status != XCB_GRAB_STATUS_SUCCESS) {
|
||||
xcb_discard_reply(conn, pgrabc.sequence);
|
||||
xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
|
||||
} else {
|
||||
pgrabr = xcb_grab_pointer_reply(conn, pgrabc, NULL);
|
||||
if (!pgrabr || pgrabr->status != XCB_GRAB_STATUS_SUCCESS)
|
||||
{
|
||||
xcb_ungrab_keyboard(conn,
|
||||
XCB_TIME_CURRENT_TIME);
|
||||
} else {
|
||||
grabbed_screen = scrpriv->mynum;
|
||||
hostx_set_win_title
|
||||
(screen,
|
||||
"(ctrl+shift releases mouse and keyboard)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Still send the release event even if above has happened server
|
||||
* will get confused with just an up event. Maybe it would be
|
||||
* better to just block shift+ctrls getting to kdrive all
|
||||
* together.
|
||||
*/
|
||||
ephyrUpdateModifierState(key->state);
|
||||
KdEnqueueKeyboardEvent(ephyrKbd, key->detail, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProcessConfigureNotify(xcb_generic_event_t *xev)
|
||||
{
|
||||
xcb_configure_notify_event_t *configure =
|
||||
(xcb_configure_notify_event_t *)xev;
|
||||
KdScreenInfo *screen = screen_from_window(configure->window);
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
if (!scrpriv ||
|
||||
(scrpriv->win_pre_existing == None && !EphyrWantResize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef RANDR
|
||||
ephyrResizeScreen(screen->pScreen, configure->width, configure->height);
|
||||
#endif /* RANDR */
|
||||
}
|
||||
|
||||
void
|
||||
ephyrPoll(void)
|
||||
{
|
||||
EphyrHostXEvent ev;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
|
||||
while (hostx_get_event(&ev)) {
|
||||
switch (ev.type) {
|
||||
case EPHYR_EV_MOUSE_MOTION:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_LOG("skipping mouse motion:%d\n", ephyrCurScreen);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
if (ev.data.mouse_motion.screen >= 0
|
||||
&& (ephyrCurScreen != ev.data.mouse_motion.screen)) {
|
||||
EPHYR_LOG("warping mouse cursor. "
|
||||
"cur_screen%d, motion_screen:%d\n",
|
||||
ephyrCurScreen, ev.data.mouse_motion.screen);
|
||||
if (ev.data.mouse_motion.screen >= 0) {
|
||||
ephyrWarpCursor
|
||||
(inputInfo.pointer,
|
||||
screenInfo.screens[ev.data.mouse_motion.screen],
|
||||
ev.data.mouse_motion.x, ev.data.mouse_motion.y);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int x = 0, y = 0;
|
||||
|
||||
#ifdef XF86DRI
|
||||
EphyrWindowPair *pair = NULL;
|
||||
#endif
|
||||
EPHYR_LOG("enqueuing mouse motion:%d\n", ephyrCurScreen);
|
||||
x = ev.data.mouse_motion.x;
|
||||
y = ev.data.mouse_motion.y;
|
||||
EPHYR_LOG("initial (x,y):(%d,%d)\n", x, y);
|
||||
#ifdef XF86DRI
|
||||
EPHYR_LOG("is this window peered by a gl drawable ?\n");
|
||||
if (findWindowPairFromRemote(ev.data.mouse_motion.window,
|
||||
&pair)) {
|
||||
EPHYR_LOG("yes, it is peered\n");
|
||||
x += pair->local->drawable.x;
|
||||
y += pair->local->drawable.y;
|
||||
}
|
||||
else {
|
||||
EPHYR_LOG("no, it is not peered\n");
|
||||
}
|
||||
EPHYR_LOG("final (x,y):(%d,%d)\n", x, y);
|
||||
#endif
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EPHYR_EV_MOUSE_PRESS:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_LOG("skipping mouse press:%d\n", ephyrCurScreen);
|
||||
continue;
|
||||
}
|
||||
EPHYR_LOG("enqueuing mouse press:%d\n", ephyrCurScreen);
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
mouseState |= ev.data.mouse_down.button_num;
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case EPHYR_EV_MOUSE_RELEASE:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *) ephyrMouse->driverPrivate)->enabled)
|
||||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
mouseState &= ~ev.data.mouse_up.button_num;
|
||||
EPHYR_LOG("enqueuing mouse release:%d\n", ephyrCurScreen);
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState | KD_MOUSE_DELTA, 0, 0,
|
||||
0);
|
||||
break;
|
||||
|
||||
case EPHYR_EV_KEY_PRESS:
|
||||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled)
|
||||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
KdEnqueueKeyboardEvent(ephyrKbd, ev.data.key_down.scancode, FALSE);
|
||||
break;
|
||||
|
||||
case EPHYR_EV_KEY_RELEASE:
|
||||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled)
|
||||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
KdEnqueueKeyboardEvent(ephyrKbd, ev.data.key_up.scancode, TRUE);
|
||||
break;
|
||||
|
||||
#ifdef XF86DRI
|
||||
case EPHYR_EV_EXPOSE:
|
||||
/*
|
||||
* We only receive expose events when the expose event have
|
||||
* be generated for a drawable that is a host X window managed
|
||||
* by Xephyr. Host X windows managed by Xephyr exists for instance
|
||||
* when Xephyr is asked to create a GL drawable in a DRI environment.
|
||||
while (TRUE) {
|
||||
xcb_generic_event_t *xev = xcb_poll_for_event(conn);
|
||||
if (!xev) {
|
||||
/* If our XCB connection has died (for example, our window was
|
||||
* closed), exit now.
|
||||
*/
|
||||
ephyrExposePairedWindow(ev.data.expose.window);
|
||||
break;
|
||||
#endif /* XF86DRI */
|
||||
if (xcb_connection_has_error(conn)) {
|
||||
CloseWellKnownConnections();
|
||||
OsCleanup(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef RANDR
|
||||
case EPHYR_EV_CONFIGURE:
|
||||
ephyrResizeScreen(screenInfo.screens[ev.data.configure.screen],
|
||||
ev.data.configure.width,
|
||||
ev.data.configure.height);
|
||||
break;
|
||||
#endif /* RANDR */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (xev->response_type & 0x7f) {
|
||||
case 0:
|
||||
ephyrProcessErrorEvent(xev);
|
||||
break;
|
||||
|
||||
case XCB_EXPOSE:
|
||||
ephyrProcessExpose(xev);
|
||||
break;
|
||||
|
||||
case XCB_MOTION_NOTIFY:
|
||||
ephyrProcessMouseMotion(xev);
|
||||
break;
|
||||
|
||||
case XCB_KEY_PRESS:
|
||||
ephyrProcessKeyPress(xev);
|
||||
break;
|
||||
|
||||
case XCB_KEY_RELEASE:
|
||||
ephyrProcessKeyRelease(xev);
|
||||
break;
|
||||
|
||||
case XCB_BUTTON_PRESS:
|
||||
ephyrProcessButtonPress(xev);
|
||||
break;
|
||||
|
||||
case XCB_BUTTON_RELEASE:
|
||||
ephyrProcessButtonRelease(xev);
|
||||
break;
|
||||
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
ephyrProcessConfigureNotify(xev);
|
||||
break;
|
||||
}
|
||||
|
||||
free(xev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1086,7 +1285,7 @@ EphyrKeyboardInit(KdKeyboardInfo * ki)
|
|||
ki->driverPrivate = (EphyrKbdPrivate *)
|
||||
calloc(sizeof(EphyrKbdPrivate), 1);
|
||||
hostx_load_keymap();
|
||||
if (!ephyrKeySyms.map) {
|
||||
if (!ephyrKeySyms.minKeyCode) {
|
||||
ErrorF("Couldn't load keymap from host\n");
|
||||
return BadAlloc;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <libgen.h>
|
||||
#include <xcb/xcb_image.h>
|
||||
|
||||
#include "os.h" /* for OsSignal() */
|
||||
#include "kdrive.h"
|
||||
|
@ -61,10 +62,24 @@ typedef struct _ephyrFakexaPriv {
|
|||
} EphyrFakexaPriv;
|
||||
|
||||
typedef struct _ephyrScrPriv {
|
||||
/* ephyr server info */
|
||||
Rotation randr;
|
||||
Bool shadow;
|
||||
DamagePtr pDamage;
|
||||
EphyrFakexaPriv *fakexa;
|
||||
|
||||
/* Host X window info */
|
||||
xcb_window_t win;
|
||||
xcb_window_t win_pre_existing; /* Set via -parent option like xnest */
|
||||
xcb_window_t peer_win; /* Used for GL; should be at most one */
|
||||
xcb_image_t *ximg;
|
||||
int win_width, win_height;
|
||||
int server_depth;
|
||||
unsigned char *fb_data; /* only used when host bpp != server bpp */
|
||||
xcb_shm_segment_info_t shminfo;
|
||||
|
||||
KdScreenInfo *screen;
|
||||
int mynum; /* Screen number */
|
||||
} EphyrScrPriv;
|
||||
|
||||
extern KdCardFuncs ephyrFuncs;
|
||||
|
@ -80,10 +95,7 @@ Bool
|
|||
ephyrCardInit(KdCardInfo * card);
|
||||
|
||||
Bool
|
||||
ephyrScreenInit(KdScreenInfo * screen);
|
||||
|
||||
Bool
|
||||
ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv);
|
||||
ephyrScreenInitialize(KdScreenInfo *screen);
|
||||
|
||||
Bool
|
||||
ephyrInitScreen(ScreenPtr pScreen);
|
||||
|
|
|
@ -29,10 +29,8 @@
|
|||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <GL/glx.h>
|
||||
#include "xf86dri.h"
|
||||
#include <X11/Xdefs.h>
|
||||
#include <xcb/xf86dri.h>
|
||||
#include "hostx.h"
|
||||
#include "ephyrdri.h"
|
||||
#define _HAVE_XALLOC_DECLS
|
||||
|
@ -49,13 +47,21 @@
|
|||
Bool
|
||||
ephyrDRIQueryDirectRenderingCapable(int a_screen, Bool *a_is_capable)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
Bool is_ok = FALSE;
|
||||
xcb_xf86dri_query_direct_rendering_capable_cookie_t cookie;
|
||||
xcb_xf86dri_query_direct_rendering_capable_reply_t *reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_is_capable, FALSE);
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = XF86DRIQueryDirectRenderingCapable(dpy, DefaultScreen(dpy),
|
||||
a_is_capable);
|
||||
cookie = xcb_xf86dri_query_direct_rendering_capable(conn,
|
||||
hostx_get_screen());
|
||||
reply = xcb_xf86dri_query_direct_rendering_capable_reply(conn, cookie, NULL);
|
||||
if (reply) {
|
||||
is_ok = TRUE;
|
||||
*a_is_capable = reply->is_capable;
|
||||
free(reply);
|
||||
}
|
||||
EPHYR_LOG("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok);
|
||||
|
||||
return is_ok;
|
||||
|
@ -65,31 +71,48 @@ Bool
|
|||
ephyrDRIOpenConnection(int a_screen,
|
||||
drm_handle_t * a_sarea, char **a_bus_id_string)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
Bool is_ok = FALSE;
|
||||
xcb_xf86dri_open_connection_cookie_t cookie;
|
||||
xcb_xf86dri_open_connection_reply_t *reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_bus_id_string, FALSE);
|
||||
EPHYR_LOG("enter. screen:%d\n", a_screen);
|
||||
is_ok = XF86DRIOpenConnection(dpy, DefaultScreen(dpy),
|
||||
a_sarea, a_bus_id_string);
|
||||
if (*a_bus_id_string) {
|
||||
EPHYR_LOG("leave. bus_id_string:%s, is_ok:%d\n",
|
||||
*a_bus_id_string, is_ok);
|
||||
}
|
||||
else {
|
||||
EPHYR_LOG("leave. bus_id_string:null, is_ok:%d\n", is_ok);
|
||||
cookie = xcb_xf86dri_open_connection(conn, hostx_get_screen());
|
||||
reply = xcb_xf86dri_open_connection_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_sarea = reply->sarea_handle_low;
|
||||
if (sizeof(drm_handle_t) == 8) {
|
||||
int shift = 32;
|
||||
*a_sarea |= ((drm_handle_t) reply->sarea_handle_high) << shift;
|
||||
}
|
||||
*a_bus_id_string = malloc(reply->bus_id_len + 1);
|
||||
if (!*a_bus_id_string)
|
||||
goto out;
|
||||
memcpy(*a_bus_id_string, xcb_xf86dri_open_connection_bus_id(reply), reply->bus_id_len);
|
||||
*a_bus_id_string[reply->bus_id_len] = '\0';
|
||||
is_ok = TRUE;
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave. bus_id_string:%s, is_ok:%d\n", *a_bus_id_string, is_ok);
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrDRIAuthConnection(int a_screen, drm_magic_t a_magic)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
xcb_xf86dri_auth_connection_cookie_t cookie;
|
||||
xcb_xf86dri_auth_connection_reply_t *reply;
|
||||
Bool is_ok = FALSE;
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = XF86DRIAuthConnection(dpy, DefaultScreen(dpy), a_magic);
|
||||
cookie = xcb_xf86dri_auth_connection(conn, screen, a_magic);
|
||||
reply = xcb_xf86dri_auth_connection_reply(conn, cookie, NULL);
|
||||
is_ok = reply->authenticated;
|
||||
free(reply);
|
||||
EPHYR_LOG("leave. is_ok:%d\n", is_ok);
|
||||
return is_ok;
|
||||
}
|
||||
|
@ -97,13 +120,13 @@ ephyrDRIAuthConnection(int a_screen, drm_magic_t a_magic)
|
|||
Bool
|
||||
ephyrDRICloseConnection(int a_screen)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
Bool is_ok = FALSE;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = XF86DRICloseConnection(dpy, DefaultScreen(dpy));
|
||||
xcb_xf86dri_close_connection(conn, screen);
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@ -113,7 +136,10 @@ ephyrDRIGetClientDriverName(int a_screen,
|
|||
int *a_ddx_driver_patch_version,
|
||||
char **a_client_driver_name)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
xcb_xf86dri_get_client_driver_name_cookie_t cookie;
|
||||
xcb_xf86dri_get_client_driver_name_reply_t *reply;
|
||||
Bool is_ok = FALSE;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_ddx_driver_major_version
|
||||
|
@ -121,15 +147,27 @@ ephyrDRIGetClientDriverName(int a_screen,
|
|||
&& a_ddx_driver_patch_version
|
||||
&& a_client_driver_name, FALSE);
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = XF86DRIGetClientDriverName(dpy, DefaultScreen(dpy),
|
||||
a_ddx_driver_major_version,
|
||||
a_ddx_driver_minor_version,
|
||||
a_ddx_driver_patch_version,
|
||||
a_client_driver_name);
|
||||
cookie = xcb_xf86dri_get_client_driver_name(conn, screen);
|
||||
reply = xcb_xf86dri_get_client_driver_name_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_ddx_driver_major_version = reply->client_driver_major_version;
|
||||
*a_ddx_driver_minor_version = reply->client_driver_minor_version;
|
||||
*a_ddx_driver_patch_version = reply->client_driver_patch_version;
|
||||
*a_client_driver_name = malloc(reply->client_driver_name_len + 1);
|
||||
if (!*a_client_driver_name)
|
||||
goto out;
|
||||
memcpy(*a_client_driver_name,
|
||||
xcb_xf86dri_get_client_driver_name_client_driver_name(reply),
|
||||
reply->client_driver_name_len);
|
||||
(*a_client_driver_name)[reply->client_driver_name_len] = '\0';
|
||||
is_ok = TRUE;
|
||||
EPHYR_LOG("major:%d, minor:%d, patch:%d, name:%s\n",
|
||||
*a_ddx_driver_major_version,
|
||||
*a_ddx_driver_minor_version,
|
||||
*a_ddx_driver_patch_version, *a_client_driver_name);
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave:%d\n", is_ok);
|
||||
return is_ok;
|
||||
}
|
||||
|
@ -139,17 +177,23 @@ ephyrDRICreateContext(int a_screen,
|
|||
int a_visual_id,
|
||||
CARD32 ctxt_id, drm_context_t * a_hw_ctxt)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
Bool is_ok = FALSE;
|
||||
Visual v;
|
||||
XID returned_ctxt_id = ctxt_id;
|
||||
xcb_xf86dri_create_context_cookie_t cookie;
|
||||
xcb_xf86dri_create_context_reply_t *reply;
|
||||
|
||||
ctxt_id = xcb_generate_id(conn);
|
||||
|
||||
EPHYR_LOG("enter. screen:%d, visual:%d\n", a_screen, a_visual_id);
|
||||
memset(&v, 0, sizeof(v));
|
||||
v.visualid = a_visual_id;
|
||||
is_ok = XF86DRICreateContext(dpy,
|
||||
DefaultScreen(dpy),
|
||||
&v, &returned_ctxt_id, a_hw_ctxt);
|
||||
cookie = xcb_xf86dri_create_context(conn, screen, a_visual_id, ctxt_id);
|
||||
reply = xcb_xf86dri_create_context_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_hw_ctxt = reply->hw_context;
|
||||
is_ok = TRUE;
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave:%d\n", is_ok);
|
||||
return is_ok;
|
||||
}
|
||||
|
@ -157,13 +201,13 @@ ephyrDRICreateContext(int a_screen,
|
|||
Bool
|
||||
ephyrDRIDestroyContext(int a_screen, int a_context_id)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
Bool is_ok = FALSE;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn ();
|
||||
int screen = hostx_get_screen();
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = XF86DRIDestroyContext(dpy, DefaultScreen(dpy), a_context_id);
|
||||
EPHYR_LOG("leave:%d\n", is_ok);
|
||||
return is_ok;
|
||||
xcb_xf86dri_destroy_context(conn, screen, a_context_id);
|
||||
EPHYR_LOG("leave\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@ -171,11 +215,20 @@ ephyrDRICreateDrawable(int a_screen,
|
|||
int a_drawable, drm_drawable_t * a_hw_drawable)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
xcb_xf86dri_create_drawable_cookie_t cookie;
|
||||
xcb_xf86dri_create_drawable_reply_t *reply;
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = XF86DRICreateDrawable(dpy, DefaultScreen(dpy),
|
||||
a_drawable, a_hw_drawable);
|
||||
cookie = xcb_xf86dri_create_drawable(conn, screen, a_drawable);
|
||||
reply = xcb_xf86dri_create_drawable_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_hw_drawable = reply->hw_drawable_handle;
|
||||
is_ok = TRUE;
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave. is_ok:%d\n", is_ok);
|
||||
return is_ok;
|
||||
}
|
||||
|
@ -206,7 +259,10 @@ ephyrDRIGetDrawableInfo(int a_screen,
|
|||
drm_clip_rect_t ** a_back_clip_rects)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
xcb_xf86dri_get_drawable_info_cookie_t cookie;
|
||||
xcb_xf86dri_get_drawable_info_reply_t *reply = NULL;
|
||||
EphyrHostWindowAttributes attrs;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_x && a_y && a_w && a_h
|
||||
|
@ -218,16 +274,22 @@ ephyrDRIGetDrawableInfo(int a_screen,
|
|||
EPHYR_LOG_ERROR("failed to query host window attributes\n");
|
||||
goto out;
|
||||
}
|
||||
if (!XF86DRIGetDrawableInfo(dpy, DefaultScreen(dpy), a_drawable,
|
||||
a_index, a_stamp,
|
||||
a_x, a_y,
|
||||
a_w, a_h,
|
||||
a_num_clip_rects, a_clip_rects,
|
||||
a_back_x, a_back_y,
|
||||
a_num_back_clip_rects, a_back_clip_rects)) {
|
||||
EPHYR_LOG_ERROR("XF86DRIGetDrawableInfo ()\n");
|
||||
cookie = xcb_xf86dri_get_drawable_info(conn, screen, a_drawable);
|
||||
reply = xcb_xf86dri_get_drawable_info_reply(conn, cookie, NULL);
|
||||
if (!reply) {
|
||||
EPHYR_LOG_ERROR ("XF86DRIGetDrawableInfo ()\n");
|
||||
goto out;
|
||||
}
|
||||
*a_index = reply->drawable_table_index;
|
||||
*a_stamp = reply->drawable_table_stamp;
|
||||
*a_x = reply->drawable_origin_X;
|
||||
*a_y = reply->drawable_origin_Y;
|
||||
*a_w = reply->drawable_size_W;
|
||||
*a_h = reply->drawable_size_H;
|
||||
*a_num_clip_rects = reply->num_clip_rects;
|
||||
*a_clip_rects = calloc(*a_num_clip_rects, sizeof(drm_clip_rect_t));
|
||||
memcpy(*a_clip_rects, xcb_xf86dri_get_drawable_info_clip_rects(reply),
|
||||
*a_num_clip_rects * sizeof(drm_clip_rect_t));
|
||||
EPHYR_LOG("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h);
|
||||
if (*a_num_clip_rects) {
|
||||
free(*a_back_clip_rects);
|
||||
|
@ -247,6 +309,7 @@ ephyrDRIGetDrawableInfo(int a_screen,
|
|||
out:
|
||||
EPHYR_LOG("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n",
|
||||
*a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h);
|
||||
free(reply);
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
|
@ -259,13 +322,35 @@ ephyrDRIGetDeviceInfo(int a_screen,
|
|||
int *a_dev_private_size, void **a_dev_private)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
xcb_connection_t *conn = hostx_get_xcbconn ();
|
||||
int screen = hostx_get_screen();
|
||||
xcb_xf86dri_get_device_info_cookie_t cookie;
|
||||
xcb_xf86dri_get_device_info_reply_t *reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
EPHYR_RETURN_VAL_IF_FAIL(conn, FALSE);
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = XF86DRIGetDeviceInfo(dpy, DefaultScreen(dpy), a_frame_buffer,
|
||||
a_fb_origin, a_fb_size, a_fb_stride,
|
||||
a_dev_private_size, a_dev_private);
|
||||
cookie = xcb_xf86dri_get_device_info(conn, screen);
|
||||
reply = xcb_xf86dri_get_device_info_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_frame_buffer = reply->framebuffer_handle_low;
|
||||
if (sizeof(drm_handle_t) == 8) {
|
||||
int shift = 32;
|
||||
*a_frame_buffer |= ((drm_handle_t)reply->framebuffer_handle_high) << shift;
|
||||
}
|
||||
*a_fb_origin = reply->framebuffer_origin_offset;
|
||||
*a_fb_size = reply->framebuffer_size;
|
||||
*a_fb_stride = reply->framebuffer_stride;
|
||||
*a_dev_private_size = reply->device_private_size;
|
||||
*a_dev_private = calloc(reply->device_private_size, 1);
|
||||
if (!*a_dev_private)
|
||||
goto out;
|
||||
memcpy(*a_dev_private,
|
||||
xcb_xf86dri_get_device_info_device_private(reply),
|
||||
reply->device_private_size);
|
||||
is_ok = TRUE;
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave:%d\n", is_ok);
|
||||
return is_ok;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#define _XF86DRI_SERVER_
|
||||
#include <X11/dri/xf86dri.h>
|
||||
#include <X11/dri/xf86driproto.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/shape.h>
|
||||
#include <xcb/xf86dri.h>
|
||||
#include "misc.h"
|
||||
#include "privates.h"
|
||||
#include "dixstruct.h"
|
||||
|
@ -1319,12 +1322,12 @@ ephyrDRIExtensionInit(ScreenPtr a_screen)
|
|||
EphyrDRIScreenPrivPtr screen_priv = NULL;
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
if (!hostx_has_dri()) {
|
||||
if (!host_has_extension(&xcb_xf86dri_id)) {
|
||||
EPHYR_LOG("host does not have DRI extension\n");
|
||||
goto out;
|
||||
}
|
||||
EPHYR_LOG("host X does have DRI extension\n");
|
||||
if (!hostx_has_xshape()) {
|
||||
if (!host_has_extension(&xcb_shape_id)) {
|
||||
EPHYR_LOG("host does not have XShape extension\n");
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
#include <xcb/glx.h>
|
||||
#include "extnsionst.h"
|
||||
#include "ephyrglxext.h"
|
||||
#include "ephyrhostglx.h"
|
||||
|
@ -83,7 +84,7 @@ ephyrHijackGLXExtension(void)
|
|||
{
|
||||
const void *(*dispatch_functions)[2];
|
||||
|
||||
if (!hostx_has_glx()) {
|
||||
if (!host_has_extension(&xcb_glx_id)) {
|
||||
EPHYR_LOG("host X does not have GLX\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -380,10 +381,9 @@ ephyrGLXQueryServerString(__GLXclientState * a_cl, GLbyte * a_pc)
|
|||
int length = 0;
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
if (!ephyrHostGLXGetStringFromServer(req->screen,
|
||||
req->name,
|
||||
EPHYR_HOST_GLX_QueryServerString,
|
||||
&server_string)) {
|
||||
if (!ephyrHostGLXQueryServerString(req->screen,
|
||||
req->name,
|
||||
&server_string)) {
|
||||
EPHYR_LOG_ERROR("failed to query string from host\n");
|
||||
goto out;
|
||||
}
|
||||
|
@ -724,9 +724,7 @@ ephyrGLXGetStringReal(__GLXclientState * a_cl, GLbyte * a_pc, Bool a_do_swap)
|
|||
a_pc += __GLX_SINGLE_HDR_SIZE;
|
||||
name = *(GLenum *) (a_pc + 0);
|
||||
EPHYR_LOG("context_tag:%d, name:%d\n", context_tag, name);
|
||||
if (!ephyrHostGLXGetStringFromServer(context_tag,
|
||||
name,
|
||||
EPHYR_HOST_GLX_GetString, &string)) {
|
||||
if (!ephyrHostGLXGetString(context_tag, name, &string)) {
|
||||
EPHYR_LOG_ERROR("failed to get string from server\n");
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -31,22 +31,10 @@
|
|||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* including some server headers (like kdrive-config.h)
|
||||
* might define the macro _XSERVER64
|
||||
* on 64 bits machines. That macro must _NOT_ be defined for Xlib
|
||||
* client code, otherwise bad things happen.
|
||||
* So let's undef that macro if necessary.
|
||||
*/
|
||||
#ifdef _XSERVER64
|
||||
#undef _XSERVER64
|
||||
#endif
|
||||
|
||||
#include <X11/Xlibint.h>
|
||||
#include <GL/glx.h>
|
||||
#include <GL/internal/glcore.h>
|
||||
#include <X11/Xdefs.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include <GL/glxproto.h>
|
||||
#include <GL/glxint.h>
|
||||
#include <xcb/glx.h>
|
||||
#include "ephyrhostglx.h"
|
||||
#define _HAVE_XALLOC_DECLS
|
||||
#include "ephyrlog.h"
|
||||
|
@ -62,41 +50,20 @@ enum VisualConfRequestType {
|
|||
|
||||
static Bool ephyrHostGLXGetVisualConfigsInternal
|
||||
(enum VisualConfRequestType a_type,
|
||||
xcb_glx_get_visual_configs_reply_t *reply,
|
||||
int32_t a_screen,
|
||||
int32_t * a_num_visuals,
|
||||
int32_t * a_num_props, int32_t * a_props_buf_size, int32_t ** a_props_buf);
|
||||
Bool
|
||||
ephyrHostGLXGetMajorOpcode(int *a_opcode)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
static int opcode;
|
||||
int first_event_return = 0, first_error_return = 0;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
EPHYR_LOG("enter\n");
|
||||
if (!opcode) {
|
||||
if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &opcode,
|
||||
&first_event_return, &first_error_return)) {
|
||||
EPHYR_LOG_ERROR("XQueryExtension() failed\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
*a_opcode = opcode;
|
||||
is_ok = TRUE;
|
||||
out:
|
||||
EPHYR_LOG("release\n");
|
||||
return is_ok;
|
||||
}
|
||||
int32_t *a_num_visuals,
|
||||
int32_t *a_num_props,
|
||||
int32_t *a_props_buf_size,
|
||||
int32_t **a_props_buf);
|
||||
|
||||
Bool
|
||||
ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
int major_opcode = 0;
|
||||
xGLXQueryVersionReq *req = NULL;
|
||||
xGLXQueryVersionReply reply;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
xcb_glx_query_version_cookie_t cookie;
|
||||
xcb_glx_query_version_reply_t *reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_major && a_minor, FALSE);
|
||||
EPHYR_LOG("enter\n");
|
||||
|
@ -107,26 +74,14 @@ ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
goto out;
|
||||
}
|
||||
EPHYR_LOG("major opcode: %d\n", major_opcode);
|
||||
|
||||
/* Send the glXQueryVersion request */
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
LockDisplay(dpy);
|
||||
GetReq(GLXQueryVersion, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXQueryVersion;
|
||||
req->majorVersion = 2;
|
||||
req->minorVersion = 1;
|
||||
_XReply(dpy, (xReply *) &reply, 0, False);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
*a_major = glx_major = reply.majorVersion;
|
||||
*a_minor = glx_minor = reply.minorVersion;
|
||||
cookie = xcb_glx_query_version(conn, 2, 1);
|
||||
reply = xcb_glx_query_version_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_major = reply->major_version;
|
||||
*a_minor = reply->minor_version;
|
||||
free(reply);
|
||||
|
||||
EPHYR_LOG("major:%d, minor:%d\n", *a_major, *a_minor);
|
||||
|
||||
|
@ -136,129 +91,63 @@ ephyrHostGLXQueryVersion(int *a_major, int *a_minor)
|
|||
return is_ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* GLX protocol structure for the ficticious "GLXGenericGetString" request.
|
||||
*
|
||||
* This is a non-existant protocol packet. It just so happens that all of
|
||||
* the real protocol packets used to request a string from the server have
|
||||
* an identical binary layout. The only difference between them is the
|
||||
* meaning of the \c for_whom field and the value of the \c glxCode.
|
||||
* (this has been copied from the mesa source code)
|
||||
*/
|
||||
typedef struct GLXGenericGetString {
|
||||
CARD8 reqType;
|
||||
CARD8 glxCode;
|
||||
CARD16 length B16;
|
||||
CARD32 for_whom B32;
|
||||
CARD32 name B32;
|
||||
} xGLXGenericGetStringReq;
|
||||
|
||||
/* These defines are only needed to make the GetReq macro happy.
|
||||
*/
|
||||
#define sz_xGLXGenericGetStringReq 12
|
||||
#define X_GLXGenericGetString 0
|
||||
|
||||
Bool
|
||||
ephyrHostGLXGetStringFromServer(int a_screen_number,
|
||||
int a_string_name,
|
||||
enum EphyrHostGLXGetStringOps a_op,
|
||||
char **a_string)
|
||||
ephyrHostGLXGetString(int a_context_tag,
|
||||
int a_string_name,
|
||||
char **a_string)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
int default_screen = DefaultScreen(dpy);
|
||||
xGLXGenericGetStringReq *req = NULL;
|
||||
xGLXSingleReply reply;
|
||||
unsigned long length = 0, numbytes = 0;
|
||||
int major_opcode = 0, get_string_op = 0;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
xcb_glx_get_string_cookie_t cookie;
|
||||
xcb_glx_get_string_reply_t *reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy && a_string, FALSE);
|
||||
EPHYR_RETURN_VAL_IF_FAIL(conn && a_string, FALSE);
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
switch (a_op) {
|
||||
case EPHYR_HOST_GLX_QueryServerString:
|
||||
get_string_op = X_GLXQueryServerString;
|
||||
break;
|
||||
case EPHYR_HOST_GLX_GetString:
|
||||
get_string_op = X_GLsop_GetString;
|
||||
EPHYR_LOG("Going to glXGetString. strname:%#x, ctxttag:%d\n",
|
||||
a_string_name, a_screen_number);
|
||||
break;
|
||||
default:
|
||||
EPHYR_LOG_ERROR("unknown EphyrHostGLXGetStringOp:%d\n", a_op);
|
||||
cookie = xcb_glx_get_string(conn, a_context_tag, a_string_name);
|
||||
reply = xcb_glx_get_string_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
}
|
||||
*a_string = malloc(reply->n + 1);
|
||||
memcpy(*a_string, xcb_glx_get_string_string(reply), reply->n);
|
||||
(*a_string)[reply->n] = '\0';
|
||||
free(reply);
|
||||
is_ok = TRUE;
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
Bool ephyrHostGLXQueryServerString(int a_screen_number,
|
||||
int a_string_name,
|
||||
char **a_string)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int default_screen = hostx_get_screen();
|
||||
xcb_glx_query_server_string_cookie_t cookie;
|
||||
xcb_glx_query_server_string_reply_t *reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(conn && a_string, FALSE);
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
cookie = xcb_glx_query_server_string(conn, default_screen, a_string_name);
|
||||
reply = xcb_glx_query_server_string_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
}
|
||||
EPHYR_LOG("major opcode: %d\n", major_opcode);
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
/* All of the GLX protocol requests for getting a string from the server
|
||||
* look the same. The exact meaning of the a_for_whom field is usually
|
||||
* either the screen number (for glXQueryServerString) or the context tag
|
||||
* (for GLXSingle).
|
||||
*/
|
||||
GetReq(GLXGenericGetString, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = get_string_op;
|
||||
req->for_whom = default_screen;
|
||||
req->name = a_string_name;
|
||||
|
||||
_XReply(dpy, (xReply *) &reply, 0, False);
|
||||
|
||||
#if UINT32_MAX >= (ULONG_MAX / 4)
|
||||
if (reply.length >= (ULONG_MAX / 4)) {
|
||||
_XEatDataWords(dpy, reply.length);
|
||||
goto eat_out;
|
||||
}
|
||||
#endif
|
||||
if (reply.length > 0) {
|
||||
length = (unsigned long) reply.length * 4;
|
||||
numbytes = reply.size;
|
||||
if (numbytes > length) {
|
||||
EPHYR_LOG_ERROR("string length %d longer than reply length %d\n",
|
||||
numbytes, length);
|
||||
goto eat_out;
|
||||
}
|
||||
}
|
||||
EPHYR_LOG("going to get a string of size:%d\n", numbytes);
|
||||
|
||||
if (numbytes < INT_MAX)
|
||||
*a_string = Xcalloc(numbytes + 1, 1);
|
||||
else
|
||||
*a_string = NULL;
|
||||
if (*a_string == NULL) {
|
||||
EPHYR_LOG_ERROR("allocation failed\n");
|
||||
goto eat_out;
|
||||
}
|
||||
|
||||
if (_XRead(dpy, *a_string, numbytes)) {
|
||||
EPHYR_LOG_ERROR("read failed\n");
|
||||
length = 0; /* if read failed, no idea how much to eat */
|
||||
}
|
||||
else {
|
||||
length -= numbytes;
|
||||
EPHYR_LOG("strname:%#x, strvalue:'%s', strlen:%d\n",
|
||||
a_string_name, *a_string, numbytes);
|
||||
is_ok = TRUE;
|
||||
}
|
||||
|
||||
eat_out:
|
||||
_XEatData(dpy, length);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
out:
|
||||
*a_string = malloc(reply->str_len + 1);
|
||||
memcpy(*a_string, xcb_glx_query_server_string_string(reply), reply->str_len);
|
||||
(*a_string)[reply->str_len] = '\0';
|
||||
free(reply);
|
||||
is_ok = TRUE;
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
static Bool
|
||||
ephyrHostGLXGetVisualConfigsInternal(enum VisualConfRequestType a_type,
|
||||
xcb_glx_get_visual_configs_reply_t *reply,
|
||||
int32_t a_screen,
|
||||
int32_t * a_num_visuals,
|
||||
int32_t * a_num_props,
|
||||
|
@ -266,110 +155,36 @@ ephyrHostGLXGetVisualConfigsInternal(enum VisualConfRequestType a_type,
|
|||
int32_t ** a_props_buf)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
xGLXGetVisualConfigsReq *req;
|
||||
xGLXGetFBConfigsReq *fb_req;
|
||||
xGLXVendorPrivateWithReplyReq *vpreq;
|
||||
xGLXGetFBConfigsSGIXReq *sgi_req;
|
||||
xGLXGetVisualConfigsReply reply;
|
||||
char *server_glx_version = NULL, *server_glx_extensions = NULL;
|
||||
int j = 0,
|
||||
major_opcode = 0,
|
||||
num_props = 0,
|
||||
num_visuals = 0, props_buf_size = 0, props_per_visual_size = 0;
|
||||
int num_props = 0, num_visuals = 0, props_buf_size = 0;
|
||||
int props_per_visual_size = 0;
|
||||
int32_t *props_buf = NULL;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get opcode\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
LockDisplay(dpy);
|
||||
switch (a_type) {
|
||||
case EPHYR_GET_FB_CONFIG:
|
||||
GetReq(GLXGetFBConfigs, fb_req);
|
||||
fb_req->reqType = major_opcode;
|
||||
fb_req->glxCode = X_GLXGetFBConfigs;
|
||||
fb_req->screen = DefaultScreen(dpy);
|
||||
break;
|
||||
|
||||
case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX:
|
||||
GetReqExtra(GLXVendorPrivateWithReply,
|
||||
sz_xGLXGetFBConfigsSGIXReq
|
||||
- sz_xGLXVendorPrivateWithReplyReq, vpreq);
|
||||
sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
|
||||
sgi_req->reqType = major_opcode;
|
||||
sgi_req->glxCode = X_GLXVendorPrivateWithReply;
|
||||
sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
|
||||
sgi_req->screen = DefaultScreen(dpy);
|
||||
break;
|
||||
|
||||
case EPHYR_GET_VISUAL_CONFIGS:
|
||||
GetReq(GLXGetVisualConfigs, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXGetVisualConfigs;
|
||||
req->screen = DefaultScreen(dpy);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
|
||||
EPHYR_LOG_ERROR("unknown error\n");
|
||||
UnlockDisplay(dpy);
|
||||
goto out;
|
||||
}
|
||||
if (!reply.numVisuals) {
|
||||
if (!reply->num_visuals) {
|
||||
EPHYR_LOG_ERROR("screen does not support GL rendering\n");
|
||||
UnlockDisplay(dpy);
|
||||
goto out;
|
||||
}
|
||||
num_visuals = reply.numVisuals;
|
||||
num_visuals = reply->num_visuals;
|
||||
|
||||
/* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
|
||||
* FIXME: FBconfigs?
|
||||
*/
|
||||
/* Check number of properties */
|
||||
num_props = reply.numProps;
|
||||
if ((num_props < __GLX_MIN_CONFIG_PROPS) ||
|
||||
(num_props > __GLX_MAX_CONFIG_PROPS)) {
|
||||
/* Huh? Not in protocol defined limits. Punt */
|
||||
EPHYR_LOG_ERROR("got a bad reply to request\n");
|
||||
UnlockDisplay(dpy);
|
||||
goto out;
|
||||
}
|
||||
num_props = reply->num_properties;
|
||||
|
||||
if (a_type != EPHYR_GET_VISUAL_CONFIGS) {
|
||||
num_props *= 2;
|
||||
}
|
||||
props_per_visual_size = num_props * __GLX_SIZE_INT32;
|
||||
props_buf_size = props_per_visual_size * reply.numVisuals;
|
||||
props_per_visual_size = num_props * sizeof(uint32_t);
|
||||
props_buf_size = props_per_visual_size * reply->num_visuals;
|
||||
props_buf = malloc(props_buf_size);
|
||||
for (j = 0; j < reply.numVisuals; j++) {
|
||||
if (_XRead(dpy,
|
||||
&((char *) props_buf)[j * props_per_visual_size],
|
||||
props_per_visual_size) != Success) {
|
||||
EPHYR_LOG_ERROR("read failed\n");
|
||||
}
|
||||
}
|
||||
UnlockDisplay(dpy);
|
||||
if (!props_buf)
|
||||
goto out;
|
||||
memcpy(props_buf, xcb_glx_get_visual_configs_property_list(reply),
|
||||
props_buf_size);
|
||||
|
||||
*a_num_visuals = num_visuals;
|
||||
*a_num_props = reply.numProps;
|
||||
*a_num_props = reply->num_properties;
|
||||
*a_props_buf_size = props_buf_size;
|
||||
*a_props_buf = props_buf;
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
if (server_glx_version) {
|
||||
XFree(server_glx_version);
|
||||
server_glx_version = NULL;
|
||||
}
|
||||
if (server_glx_extensions) {
|
||||
XFree(server_glx_extensions);
|
||||
server_glx_extensions = NULL;
|
||||
}
|
||||
SyncHandle();
|
||||
out:
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
|
@ -380,14 +195,27 @@ ephyrHostGLXGetVisualConfigs(int32_t a_screen,
|
|||
int32_t * a_props_buf_size, int32_t ** a_props_buf)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
xcb_glx_get_visual_configs_cookie_t cookie;
|
||||
xcb_glx_get_visual_configs_reply_t *reply;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
is_ok = ephyrHostGLXGetVisualConfigsInternal(EPHYR_GET_VISUAL_CONFIGS,
|
||||
a_screen,
|
||||
a_num_visuals,
|
||||
a_num_props,
|
||||
a_props_buf_size, a_props_buf);
|
||||
cookie = xcb_glx_get_visual_configs(conn, screen);
|
||||
reply = xcb_glx_get_visual_configs_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
is_ok = ephyrHostGLXGetVisualConfigsInternal
|
||||
(EPHYR_GET_VISUAL_CONFIGS,
|
||||
reply,
|
||||
a_screen,
|
||||
a_num_visuals,
|
||||
a_num_props,
|
||||
a_props_buf_size,
|
||||
a_props_buf);
|
||||
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave:%d\n", is_ok);
|
||||
return is_ok;
|
||||
}
|
||||
|
@ -399,12 +227,32 @@ ephyrHostGLXVendorPrivGetFBConfigsSGIX(int a_screen,
|
|||
int32_t * a_props_buf_size,
|
||||
int32_t ** a_props_buf)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Bool is_ok=FALSE;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int screen = hostx_get_screen();
|
||||
xcb_glx_vendor_private_with_reply_cookie_t cookie;
|
||||
union {
|
||||
xcb_glx_vendor_private_with_reply_reply_t *vprep;
|
||||
xcb_glx_get_visual_configs_reply_t *rep;
|
||||
} reply;
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
cookie = xcb_glx_vendor_private_with_reply(conn,
|
||||
X_GLXvop_GetFBConfigsSGIX,
|
||||
0, 4, (uint8_t *)&screen);
|
||||
reply.vprep = xcb_glx_vendor_private_with_reply_reply(conn, cookie, NULL);
|
||||
if (!reply.vprep)
|
||||
goto out;
|
||||
is_ok = ephyrHostGLXGetVisualConfigsInternal
|
||||
(EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX,
|
||||
a_screen, a_num_visuals, a_num_props, a_props_buf_size, a_props_buf);
|
||||
reply.rep,
|
||||
a_screen,
|
||||
a_num_visuals,
|
||||
a_num_props,
|
||||
a_props_buf_size,
|
||||
a_props_buf);
|
||||
out:
|
||||
free(reply.vprep);
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
@ -413,39 +261,15 @@ Bool
|
|||
ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
|
||||
const char *a_extension_list)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
xGLXClientInfoReq *req;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
int size;
|
||||
int32_t major_opcode = 0;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy && a_extension_list, FALSE);
|
||||
EPHYR_RETURN_VAL_IF_FAIL(conn && a_extension_list, FALSE);
|
||||
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
goto out;
|
||||
}
|
||||
size = strlen (a_extension_list) + 1;
|
||||
xcb_glx_client_info(conn, a_major, a_minor, size, a_extension_list);
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
GetReq(GLXClientInfo, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXClientInfo;
|
||||
req->major = a_major;
|
||||
req->minor = a_minor;
|
||||
|
||||
size = strlen(a_extension_list) + 1;
|
||||
req->length += bytes_to_int32(size);
|
||||
req->numbytes = size;
|
||||
Data(dpy, a_extension_list, size);
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
return is_ok;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@ -457,9 +281,9 @@ ephyrHostGLXCreateContext(int a_screen,
|
|||
Bool a_direct,
|
||||
int code)
|
||||
{
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
int major_opcode = 0, remote_context_id = 0;
|
||||
int remote_context_id = 0;
|
||||
|
||||
EPHYR_LOG("enter. screen:%d, generic_id:%d, contextid:%d, rendertype:%d, "
|
||||
"direct:%d\n", a_screen, a_generic_id, a_context_id,
|
||||
|
@ -471,39 +295,24 @@ ephyrHostGLXCreateContext(int a_screen,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
switch (code) {
|
||||
case X_GLXCreateContext: {
|
||||
/* Send the glXCreateContext request */
|
||||
xGLXCreateContextReq *req;
|
||||
GetReq(GLXCreateContext, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXCreateContext;
|
||||
req->context = remote_context_id;
|
||||
req->visual = a_generic_id;
|
||||
req->screen = DefaultScreen(dpy);
|
||||
req->shareList = a_share_list_ctxt_id;
|
||||
req->isDirect = a_direct;
|
||||
}
|
||||
xcb_glx_create_context(conn,
|
||||
remote_context_id,
|
||||
a_generic_id,
|
||||
hostx_get_screen(),
|
||||
a_share_list_ctxt_id,
|
||||
a_direct);
|
||||
}
|
||||
|
||||
case X_GLXCreateNewContext: {
|
||||
/* Send the glXCreateNewContext request */
|
||||
xGLXCreateNewContextReq *req;
|
||||
GetReq(GLXCreateNewContext, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXCreateNewContext;
|
||||
req->context = remote_context_id;
|
||||
req->fbconfig = a_generic_id;
|
||||
req->screen = DefaultScreen(dpy);
|
||||
req->renderType = a_render_type;
|
||||
req->shareList = a_share_list_ctxt_id;
|
||||
req->isDirect = a_direct;
|
||||
xcb_glx_create_new_context(conn,
|
||||
remote_context_id,
|
||||
a_generic_id,
|
||||
hostx_get_screen(),
|
||||
a_render_type,
|
||||
a_share_list_ctxt_id,
|
||||
a_direct);
|
||||
}
|
||||
|
||||
default:
|
||||
|
@ -511,9 +320,6 @@ ephyrHostGLXCreateContext(int a_screen,
|
|||
EPHYR_LOG("Internal error! Invalid CreateContext code!\n");
|
||||
}
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
|
@ -524,30 +330,19 @@ ephyrHostGLXCreateContext(int a_screen,
|
|||
Bool
|
||||
ephyrHostDestroyContext(int a_ctxt_id)
|
||||
{
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
int major_opcode = 0, remote_ctxt_id = 0;
|
||||
xGLXDestroyContextReq *req = NULL;
|
||||
int remote_ctxt_id = 0;
|
||||
|
||||
EPHYR_LOG("enter:%d\n", a_ctxt_id);
|
||||
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
goto out;
|
||||
}
|
||||
if (!hostx_get_resource_id_peer(a_ctxt_id, &remote_ctxt_id)) {
|
||||
EPHYR_LOG_ERROR("failed to get remote glx ctxt id\n");
|
||||
goto out;
|
||||
}
|
||||
EPHYR_LOG("host context id:%d\n", remote_ctxt_id);
|
||||
|
||||
LockDisplay(dpy);
|
||||
GetReq(GLXDestroyContext, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXDestroyContext;
|
||||
req->context = remote_ctxt_id;
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
xcb_glx_destroy_context(conn, remote_ctxt_id);
|
||||
|
||||
is_ok = TRUE;
|
||||
|
||||
|
@ -560,81 +355,71 @@ Bool
|
|||
ephyrHostGLXMakeCurrent(int a_drawable, int a_readable,
|
||||
int a_glx_ctxt_id, int a_old_ctxt_tag, int *a_ctxt_tag)
|
||||
{
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
int32_t major_opcode = 0;
|
||||
int remote_glx_ctxt_id = 0;
|
||||
xGLXMakeCurrentReply reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_ctxt_tag, FALSE);
|
||||
|
||||
EPHYR_LOG("enter. drawable:%d, read:%d, context:%d, oldtag:%d\n",
|
||||
a_drawable, a_readable, a_glx_ctxt_id, a_old_ctxt_tag);
|
||||
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
goto out;
|
||||
}
|
||||
if (!hostx_get_resource_id_peer(a_glx_ctxt_id, &remote_glx_ctxt_id)) {
|
||||
EPHYR_LOG_ERROR("failed to get remote glx ctxt id\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
/* If both drawables are the same, use the old MakeCurrent request.
|
||||
* Otherwise, if we have GLX 1.3 or higher, use the MakeContextCurrent
|
||||
* request which supports separate read and draw targets. Failing that,
|
||||
* try the SGI MakeCurrentRead extension. Logic cribbed from Mesa. */
|
||||
if (a_drawable == a_readable) {
|
||||
xGLXMakeCurrentReq *req;
|
||||
|
||||
GetReq(GLXMakeCurrent, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXMakeCurrent;
|
||||
req->drawable = a_drawable;
|
||||
req->context = remote_glx_ctxt_id;
|
||||
req->oldContextTag = a_old_ctxt_tag;
|
||||
xcb_glx_make_current_cookie_t cookie;
|
||||
xcb_glx_make_current_reply_t *reply;
|
||||
cookie = xcb_glx_make_current(conn,
|
||||
a_drawable,
|
||||
remote_glx_ctxt_id,
|
||||
a_old_ctxt_tag);
|
||||
reply = xcb_glx_make_current_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_ctxt_tag = reply->context_tag;
|
||||
free(reply);
|
||||
}
|
||||
else if (glx_major > 1 || glx_minor >= 3) {
|
||||
xGLXMakeContextCurrentReq *req;
|
||||
|
||||
GetReq(GLXMakeContextCurrent, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXMakeContextCurrent;
|
||||
req->drawable = a_drawable;
|
||||
req->readdrawable = a_readable;
|
||||
req->context = remote_glx_ctxt_id;
|
||||
req->oldContextTag = a_old_ctxt_tag;
|
||||
xcb_glx_make_context_current_cookie_t cookie;
|
||||
xcb_glx_make_context_current_reply_t *reply;
|
||||
cookie = xcb_glx_make_context_current(conn,
|
||||
a_old_ctxt_tag,
|
||||
a_drawable,
|
||||
a_readable,
|
||||
remote_glx_ctxt_id);
|
||||
reply = xcb_glx_make_context_current_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
*a_ctxt_tag = reply->context_tag;
|
||||
free(reply);
|
||||
}
|
||||
else {
|
||||
xGLXVendorPrivateWithReplyReq *vpreq;
|
||||
xGLXMakeCurrentReadSGIReq *req;
|
||||
xcb_glx_vendor_private_with_reply_cookie_t cookie;
|
||||
xcb_glx_vendor_private_with_reply_reply_t *reply;
|
||||
uint32_t data[3] = {
|
||||
a_drawable, a_readable, remote_glx_ctxt_id,
|
||||
};
|
||||
|
||||
GetReqExtra(GLXVendorPrivateWithReply,
|
||||
(sz_xGLXMakeCurrentReadSGIReq -
|
||||
sz_xGLXVendorPrivateWithReplyReq),
|
||||
vpreq);
|
||||
req = (xGLXMakeCurrentReadSGIReq *) vpreq;
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXVendorPrivateWithReply;
|
||||
req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
|
||||
req->drawable = a_drawable;
|
||||
req->readable = a_readable;
|
||||
req->context = remote_glx_ctxt_id;
|
||||
req->oldContextTag = a_old_ctxt_tag;
|
||||
EPHYR_LOG("enter\n");
|
||||
cookie = xcb_glx_vendor_private_with_reply(conn,
|
||||
X_GLXvop_MakeCurrentReadSGI,
|
||||
a_old_ctxt_tag,
|
||||
sizeof(data),
|
||||
(uint8_t *)data);
|
||||
reply = xcb_glx_vendor_private_with_reply_reply(conn, cookie, NULL);
|
||||
|
||||
*a_ctxt_tag = reply->retval;
|
||||
|
||||
free(reply);
|
||||
}
|
||||
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
|
||||
EPHYR_LOG_ERROR("failed to get reply from host\n");
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
goto out;
|
||||
}
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
*a_ctxt_tag = reply.contextTag;
|
||||
EPHYR_LOG("context tag:%d\n", *a_ctxt_tag);
|
||||
is_ok = TRUE;
|
||||
|
||||
|
@ -643,79 +428,32 @@ ephyrHostGLXMakeCurrent(int a_drawable, int a_readable,
|
|||
return is_ok;
|
||||
}
|
||||
|
||||
#define X_GLXSingle 0
|
||||
|
||||
#define __EPHYR_GLX_SINGLE_PUT_CHAR(offset,a) \
|
||||
*((INT8 *) (pc + offset)) = a
|
||||
|
||||
#define EPHYR_GLX_SINGLE_PUT_SHORT(offset,a) \
|
||||
*((INT16 *) (pc + offset)) = a
|
||||
|
||||
#define EPHYR_GLX_SINGLE_PUT_LONG(offset,a) \
|
||||
*((INT32 *) (pc + offset)) = a
|
||||
|
||||
#define EPHYR_GLX_SINGLE_PUT_FLOAT(offset,a) \
|
||||
*((FLOAT32 *) (pc + offset)) = a
|
||||
|
||||
#define EPHYR_GLX_SINGLE_READ_XREPLY() \
|
||||
(void) _XReply(dpy, (xReply*) &reply, 0, False)
|
||||
|
||||
#define EPHYR_GLX_SINGLE_GET_RETVAL(a,cast) \
|
||||
a = (cast) reply.retval
|
||||
|
||||
#define EPHYR_GLX_SINGLE_GET_SIZE(a) \
|
||||
a = (GLint) reply.size
|
||||
|
||||
#define EPHYR_GLX_SINGLE_GET_CHAR(p) \
|
||||
*p = *(GLbyte *)&reply.pad3;
|
||||
|
||||
#define EPHYR_GLX_SINGLE_GET_SHORT(p) \
|
||||
*p = *(GLshort *)&reply.pad3;
|
||||
|
||||
#define EPHYR_GLX_SINGLE_GET_LONG(p) \
|
||||
*p = *(GLint *)&reply.pad3;
|
||||
|
||||
#define EPHYR_GLX_SINGLE_GET_FLOAT(p) \
|
||||
*p = *(GLfloat *)&reply.pad3;
|
||||
|
||||
Bool
|
||||
ephyrHostGetIntegerValue(int a_current_context_tag, int a_int, int *a_val)
|
||||
{
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
int major_opcode = 0, size = 0;
|
||||
xGLXSingleReq *req = NULL;
|
||||
xGLXSingleReply reply;
|
||||
unsigned char *pc = NULL;
|
||||
int size = 0;
|
||||
xcb_glx_get_integerv_cookie_t cookie;
|
||||
xcb_glx_get_integerv_reply_t *reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_val, FALSE);
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
cookie = xcb_glx_get_integerv(conn, a_current_context_tag, a_int);
|
||||
reply = xcb_glx_get_integerv_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
goto out;
|
||||
}
|
||||
LockDisplay(dpy);
|
||||
GetReqExtra(GLXSingle, 4, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLsop_GetIntegerv;
|
||||
req->contextTag = a_current_context_tag;
|
||||
pc = ((unsigned char *) (req) + sz_xGLXSingleReq);
|
||||
EPHYR_GLX_SINGLE_PUT_LONG(0, a_int);
|
||||
EPHYR_GLX_SINGLE_READ_XREPLY();
|
||||
EPHYR_GLX_SINGLE_GET_SIZE(size);
|
||||
size = reply->n;
|
||||
if (!size) {
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
EPHYR_LOG_ERROR("X_GLsop_GetIngerv failed\n");
|
||||
goto out;
|
||||
}
|
||||
EPHYR_GLX_SINGLE_GET_LONG(a_val);
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
*a_val = reply->datum;
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
@ -724,40 +462,29 @@ Bool
|
|||
ephyrHostIsContextDirect(int a_ctxt_id, int *a_is_direct)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
xGLXIsDirectReq *req = NULL;
|
||||
xGLXIsDirectReply reply;
|
||||
int major_opcode = 0, remote_glx_ctxt_id = 0;
|
||||
xcb_connection_t *conn = hostx_get_xcbconn();
|
||||
xcb_glx_is_direct_cookie_t cookie;
|
||||
xcb_glx_is_direct_reply_t *reply = NULL;
|
||||
int remote_glx_ctxt_id = 0;
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) {
|
||||
EPHYR_LOG_ERROR("failed to get major opcode\n");
|
||||
if (!hostx_get_resource_id_peer (a_ctxt_id, &remote_glx_ctxt_id)) {
|
||||
EPHYR_LOG_ERROR ("failed to get remote glx ctxt id\n");
|
||||
goto out;
|
||||
}
|
||||
if (!hostx_get_resource_id_peer(a_ctxt_id, &remote_glx_ctxt_id)) {
|
||||
EPHYR_LOG_ERROR("failed to get remote glx ctxt id\n");
|
||||
goto out;
|
||||
}
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
/* Send the glXIsDirect request */
|
||||
LockDisplay(dpy);
|
||||
GetReq(GLXIsDirect, req);
|
||||
req->reqType = major_opcode;
|
||||
req->glxCode = X_GLXIsDirect;
|
||||
req->context = remote_glx_ctxt_id;
|
||||
if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
|
||||
cookie = xcb_glx_is_direct(conn, remote_glx_ctxt_id);
|
||||
reply = xcb_glx_is_direct_reply(conn, cookie, NULL);
|
||||
if (!reply) {
|
||||
EPHYR_LOG_ERROR("fail in reading reply from host\n");
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
goto out;
|
||||
}
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
*a_is_direct = reply.isDirect;
|
||||
*a_is_direct = reply->is_direct;
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
out:
|
||||
free(reply);
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
|
|
@ -35,10 +35,12 @@ enum EphyrHostGLXGetStringOps {
|
|||
};
|
||||
|
||||
Bool ephyrHostGLXQueryVersion(int *a_maj, int *a_min);
|
||||
Bool ephyrHostGLXGetStringFromServer(int a_screen_number,
|
||||
int a_string_name,
|
||||
enum EphyrHostGLXGetStringOps a_op,
|
||||
char **a_string);
|
||||
Bool ephyrHostGLXGetString(int a_context_tag,
|
||||
int a_string_name,
|
||||
char **a_string);
|
||||
Bool ephyrHostGLXQueryServerString(int a_screen_number,
|
||||
int a_string_name,
|
||||
char **a_string);
|
||||
Bool ephyrHostGLXGetVisualConfigs(int a_screen,
|
||||
int32_t * a_num_visuals,
|
||||
int32_t * a_num_props,
|
||||
|
@ -51,7 +53,6 @@ ephyrHostGLXVendorPrivGetFBConfigsSGIX(int a_screen,
|
|||
int32_t * a_num_props,
|
||||
int32_t * a_props_buf_size,
|
||||
int32_t ** a_props_buf);
|
||||
Bool ephyrHostGLXGetMajorOpcode(int32_t * a_opcode);
|
||||
Bool ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor,
|
||||
const char *a_extension_list);
|
||||
Bool ephyrHostGLXCreateContext(int a_screen,
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Xephyr - A kdrive X server thats runs in a host X window.
|
||||
* Authored by Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright © 2007 OpenedHand Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of OpenedHand Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. OpenedHand Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Dodji Seketeli <dodji@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
#include <X11/Xlibint.h>
|
||||
#define _HAVE_XALLOC_DECLS
|
||||
#include "ephyrlog.h"
|
||||
#include "ephyrhostproxy.h"
|
||||
#include "hostx.h"
|
||||
|
||||
/* byte swap a short */
|
||||
#define swaps(x, n) { \
|
||||
n = ((char *) (x))[0];\
|
||||
((char *) (x))[0] = ((char *) (x))[1];\
|
||||
((char *) (x))[1] = n; }
|
||||
|
||||
#define GetXReq(req) \
|
||||
WORD64ALIGN ;\
|
||||
if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\
|
||||
_XFlush(dpy);\
|
||||
req = (xReq *)(dpy->last_req = dpy->bufptr);\
|
||||
dpy->bufptr += SIZEOF(xReq);\
|
||||
dpy->request++
|
||||
|
||||
Bool
|
||||
ephyrHostProxyDoForward(pointer a_request_buffer,
|
||||
struct XReply *a_reply, Bool a_do_swap)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
int n = 0;
|
||||
Display *dpy = hostx_get_display();
|
||||
xReq *in_req = (xReq *) a_request_buffer;
|
||||
xReq *forward_req = NULL;
|
||||
struct XReply reply;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(in_req && dpy, FALSE);
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
|
||||
if (a_do_swap) {
|
||||
swaps(&in_req->length);
|
||||
}
|
||||
EPHYR_LOG("Req {type:%d, data:%d, length:%d}\n",
|
||||
in_req->reqType, in_req->data, in_req->length);
|
||||
GetXReq(forward_req);
|
||||
memmove(forward_req, in_req, 4);
|
||||
|
||||
if (!_XReply(dpy, (xReply *) &reply, 0, FALSE)) {
|
||||
EPHYR_LOG_ERROR("failed to get reply\n");
|
||||
goto out;
|
||||
}
|
||||
EPHYR_LOG("XReply{type:%d, foo:%d, seqnum:%d, length:%d}\n",
|
||||
reply.type, reply.foo, reply.sequence_number, reply.length);
|
||||
|
||||
if (a_reply) {
|
||||
memmove(a_reply, &reply, sizeof(reply));
|
||||
}
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Xephyr - A kdrive X server thats runs in a host X window.
|
||||
* Authored by Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright © 2007 OpenedHand Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of OpenedHand Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. OpenedHand Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Dodji Seketeli <dodji@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifndef __EPHYRHOSTPROXY_H__
|
||||
#define __EPHYRHOSTPROXY_H__
|
||||
|
||||
struct XReply {
|
||||
int8_t type; /*X_Reply */
|
||||
int8_t foo;
|
||||
int16_t sequence_number;
|
||||
int32_t length;
|
||||
/*following is some data up to 32 bytes lenght */
|
||||
int32_t pad0;
|
||||
int32_t pad1;
|
||||
int32_t pad2;
|
||||
int32_t pad3;
|
||||
int32_t pad4;
|
||||
int32_t pad5;
|
||||
};
|
||||
|
||||
Bool
|
||||
|
||||
ephyrHostProxyDoForward(pointer a_request_buffer,
|
||||
struct XReply *a_reply, Bool a_do_swap);
|
||||
|
||||
#endif /*__EPHYRHOSTPROXY_H__*/
|
|
@ -1,975 +0,0 @@
|
|||
/*
|
||||
* Xephyr - A kdrive X server thats runs in a host X window.
|
||||
* Authored by Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright © 2007 OpenedHand Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of OpenedHand Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. OpenedHand Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Dodji Seketeli <dodji@openedhand.com>
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <kdrive-config.h>
|
||||
#endif
|
||||
/*
|
||||
* including some server headers (like kdrive-config.h)
|
||||
* might define the macro _XSERVER64
|
||||
* on 64 bits machines. That macro must _NOT_ be defined for Xlib
|
||||
* client code, otherwise bad things happen.
|
||||
* So let's undef that macro if necessary.
|
||||
*/
|
||||
#ifdef _XSERVER64
|
||||
#undef _XSERVER64
|
||||
#endif
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
#include <X11/extensions/Xvproto.h>
|
||||
#include <X11/extensions/Xext.h>
|
||||
#include <X11/extensions/extutil.h>
|
||||
#define _HAVE_XALLOC_DECLS
|
||||
|
||||
#include "hostx.h"
|
||||
#include "ephyrhostvideo.h"
|
||||
#include "ephyrlog.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /*TRUE*/
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /*FALSE*/
|
||||
static XExtensionInfo _xv_info_data;
|
||||
static XExtensionInfo *xv_info = &_xv_info_data;
|
||||
static const char *xv_extension_name = XvName;
|
||||
static char *xv_error_string(Display * dpy, int code, XExtCodes * codes,
|
||||
char *buf, int n);
|
||||
static int xv_close_display(Display * dpy, XExtCodes * codes);
|
||||
static Bool xv_wire_to_event(Display * dpy, XEvent * host, xEvent *wire);
|
||||
|
||||
static XExtensionHooks xv_extension_hooks = {
|
||||
NULL, /* create_gc */
|
||||
NULL, /* copy_gc */
|
||||
NULL, /* flush_gc */
|
||||
NULL, /* free_gc */
|
||||
NULL, /* create_font */
|
||||
NULL, /* free_font */
|
||||
xv_close_display, /* close_display */
|
||||
xv_wire_to_event, /* wire_to_event */
|
||||
NULL, /* event_to_wire */
|
||||
NULL, /* error */
|
||||
xv_error_string /* error_string */
|
||||
};
|
||||
|
||||
static const char *xv_error_list[] = {
|
||||
"BadPort", /* XvBadPort */
|
||||
"BadEncoding", /* XvBadEncoding */
|
||||
"BadControl" /* XvBadControl */
|
||||
};
|
||||
|
||||
#define XvCheckExtension(dpy, i, val) \
|
||||
XextCheckExtension(dpy, i, xv_extension_name, val)
|
||||
#define XvGetReq(name, req) \
|
||||
WORD64ALIGN\
|
||||
if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
|
||||
_XFlush(dpy);\
|
||||
req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
|
||||
req->reqType = info->codes->major_opcode;\
|
||||
req->xvReqType = xv_##name; \
|
||||
req->length = (SIZEOF(xv##name##Req))>>2;\
|
||||
dpy->bufptr += SIZEOF(xv##name##Req);\
|
||||
dpy->request++
|
||||
|
||||
static
|
||||
XEXT_GENERATE_CLOSE_DISPLAY(xv_close_display, xv_info)
|
||||
|
||||
static
|
||||
XEXT_GENERATE_FIND_DISPLAY(xv_find_display, xv_info,
|
||||
xv_extension_name,
|
||||
&xv_extension_hooks, XvNumEvents, NULL)
|
||||
|
||||
static
|
||||
XEXT_GENERATE_ERROR_STRING(xv_error_string, xv_extension_name,
|
||||
XvNumErrors, xv_error_list)
|
||||
|
||||
struct _EphyrHostXVAdaptorArray {
|
||||
XvAdaptorInfo *adaptors;
|
||||
unsigned int nb_adaptors;
|
||||
};
|
||||
|
||||
/*heavily copied from libx11*/
|
||||
#define BUFSIZE 2048
|
||||
static void
|
||||
ephyrHostXVLogXErrorEvent(Display * a_display,
|
||||
XErrorEvent * a_err_event, FILE * a_fp)
|
||||
{
|
||||
char buffer[BUFSIZ];
|
||||
char mesg[BUFSIZ];
|
||||
char number[32];
|
||||
const char *mtype = "XlibMessage";
|
||||
register _XExtension *ext = (_XExtension *) NULL;
|
||||
_XExtension *bext = (_XExtension *) NULL;
|
||||
Display *dpy = a_display;
|
||||
|
||||
XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
|
||||
XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
|
||||
(void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
|
||||
XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
|
||||
mesg, BUFSIZ);
|
||||
(void) fprintf(a_fp, mesg, a_err_event->request_code);
|
||||
if (a_err_event->request_code < 128) {
|
||||
snprintf(number, sizeof(number), "%d", a_err_event->request_code);
|
||||
XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
|
||||
}
|
||||
else {
|
||||
for (ext = dpy->ext_procs;
|
||||
ext && (ext->codes.major_opcode != a_err_event->request_code);
|
||||
ext = ext->next);
|
||||
if (ext)
|
||||
strcpy(buffer, ext->name);
|
||||
else
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
(void) fprintf(a_fp, " (%s)\n", buffer);
|
||||
if (a_err_event->request_code >= 128) {
|
||||
XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
|
||||
mesg, BUFSIZ);
|
||||
fputs(" ", a_fp);
|
||||
(void) fprintf(a_fp, mesg, a_err_event->minor_code);
|
||||
if (ext) {
|
||||
snprintf(mesg, sizeof(mesg), "%s.%d",
|
||||
ext->name, a_err_event->minor_code);
|
||||
XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
|
||||
(void) fprintf(a_fp, " (%s)", buffer);
|
||||
}
|
||||
fputs("\n", a_fp);
|
||||
}
|
||||
if (a_err_event->error_code >= 128) {
|
||||
/* kludge, try to find the extension that caused it */
|
||||
buffer[0] = '\0';
|
||||
for (ext = dpy->ext_procs; ext; ext = ext->next) {
|
||||
if (ext->error_string)
|
||||
(*ext->error_string) (dpy, a_err_event->error_code, &ext->codes,
|
||||
buffer, BUFSIZ);
|
||||
if (buffer[0]) {
|
||||
bext = ext;
|
||||
break;
|
||||
}
|
||||
if (ext->codes.first_error &&
|
||||
ext->codes.first_error < (int) a_err_event->error_code &&
|
||||
(!bext || ext->codes.first_error > bext->codes.first_error))
|
||||
bext = ext;
|
||||
}
|
||||
if (bext)
|
||||
snprintf(buffer, sizeof(buffer), "%s.%d", bext->name,
|
||||
a_err_event->error_code - bext->codes.first_error);
|
||||
else
|
||||
strcpy(buffer, "Value");
|
||||
XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
|
||||
if (mesg[0]) {
|
||||
fputs(" ", a_fp);
|
||||
(void) fprintf(a_fp, mesg, a_err_event->resourceid);
|
||||
fputs("\n", a_fp);
|
||||
}
|
||||
/* let extensions try to print the values */
|
||||
for (ext = dpy->ext_procs; ext; ext = ext->next) {
|
||||
if (ext->error_values)
|
||||
(*ext->error_values) (dpy, a_err_event, a_fp);
|
||||
}
|
||||
}
|
||||
else if ((a_err_event->error_code == BadWindow) ||
|
||||
(a_err_event->error_code == BadPixmap) ||
|
||||
(a_err_event->error_code == BadCursor) ||
|
||||
(a_err_event->error_code == BadFont) ||
|
||||
(a_err_event->error_code == BadDrawable) ||
|
||||
(a_err_event->error_code == BadColor) ||
|
||||
(a_err_event->error_code == BadGC) ||
|
||||
(a_err_event->error_code == BadIDChoice) ||
|
||||
(a_err_event->error_code == BadValue) ||
|
||||
(a_err_event->error_code == BadAtom)) {
|
||||
if (a_err_event->error_code == BadValue)
|
||||
XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
|
||||
mesg, BUFSIZ);
|
||||
else if (a_err_event->error_code == BadAtom)
|
||||
XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
|
||||
mesg, BUFSIZ);
|
||||
else
|
||||
XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
|
||||
mesg, BUFSIZ);
|
||||
fputs(" ", a_fp);
|
||||
(void) fprintf(a_fp, mesg, a_err_event->resourceid);
|
||||
fputs("\n", a_fp);
|
||||
}
|
||||
XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
|
||||
mesg, BUFSIZ);
|
||||
fputs(" ", a_fp);
|
||||
(void) fprintf(a_fp, mesg, a_err_event->serial);
|
||||
XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
|
||||
mesg, BUFSIZ);
|
||||
fputs("\n ", a_fp);
|
||||
(void) fprintf(a_fp, mesg, dpy->request);
|
||||
fputs("\n", a_fp);
|
||||
}
|
||||
|
||||
static int
|
||||
ephyrHostXVErrorHandler(Display * a_display, XErrorEvent * a_error_event)
|
||||
{
|
||||
EPHYR_LOG_ERROR("got an error from the host xserver:\n");
|
||||
ephyrHostXVLogXErrorEvent(a_display, a_error_event, stderr);
|
||||
return Success;
|
||||
}
|
||||
|
||||
void
|
||||
ephyrHostXVInit(void)
|
||||
{
|
||||
static Bool s_initialized;
|
||||
|
||||
if (s_initialized)
|
||||
return;
|
||||
XSetErrorHandler(ephyrHostXVErrorHandler);
|
||||
s_initialized = TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVQueryAdaptors(EphyrHostXVAdaptorArray ** a_adaptors)
|
||||
{
|
||||
EphyrHostXVAdaptorArray *result = NULL;
|
||||
int ret = 0;
|
||||
Bool is_ok = FALSE;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_adaptors, FALSE);
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
|
||||
result = calloc(1, sizeof(EphyrHostXVAdaptorArray));
|
||||
if (!result)
|
||||
goto out;
|
||||
|
||||
ret = XvQueryAdaptors(hostx_get_display(),
|
||||
DefaultRootWindow(hostx_get_display()),
|
||||
&result->nb_adaptors, &result->adaptors);
|
||||
if (ret != Success) {
|
||||
EPHYR_LOG_ERROR("failed to query host adaptors: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
*a_adaptors = result;
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
void
|
||||
ephyrHostXVAdaptorArrayDelete(EphyrHostXVAdaptorArray * a_adaptors)
|
||||
{
|
||||
if (!a_adaptors)
|
||||
return;
|
||||
if (a_adaptors->adaptors) {
|
||||
XvFreeAdaptorInfo(a_adaptors->adaptors);
|
||||
a_adaptors->adaptors = NULL;
|
||||
a_adaptors->nb_adaptors = 0;
|
||||
}
|
||||
XFree(a_adaptors);
|
||||
}
|
||||
|
||||
int
|
||||
ephyrHostXVAdaptorArrayGetSize(const EphyrHostXVAdaptorArray * a_this)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
|
||||
return a_this->nb_adaptors;
|
||||
}
|
||||
|
||||
EphyrHostXVAdaptor *
|
||||
ephyrHostXVAdaptorArrayAt(const EphyrHostXVAdaptorArray * a_this, int a_index)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this, NULL);
|
||||
|
||||
if (a_index >= a_this->nb_adaptors)
|
||||
return NULL;
|
||||
return (EphyrHostXVAdaptor *) &a_this->adaptors[a_index];
|
||||
}
|
||||
|
||||
char
|
||||
ephyrHostXVAdaptorGetType(const EphyrHostXVAdaptor * a_this)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
|
||||
return ((const XvAdaptorInfo *) a_this)->type;
|
||||
}
|
||||
|
||||
const char *
|
||||
ephyrHostXVAdaptorGetName(const EphyrHostXVAdaptor * a_this)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this, NULL);
|
||||
|
||||
return ((const XvAdaptorInfo *) a_this)->name;
|
||||
}
|
||||
|
||||
EphyrHostVideoFormat *
|
||||
ephyrHostXVAdaptorGetVideoFormats(const EphyrHostXVAdaptor * a_this,
|
||||
int *a_nb_formats)
|
||||
{
|
||||
EphyrHostVideoFormat *formats = NULL;
|
||||
int nb_formats = 0, i = 0;
|
||||
XVisualInfo *visual_info, visual_info_template;
|
||||
int nb_visual_info;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this, NULL);
|
||||
|
||||
nb_formats = ((const XvAdaptorInfo *) a_this)->num_formats;
|
||||
formats = calloc(nb_formats, sizeof(EphyrHostVideoFormat));
|
||||
for (i = 0; i < nb_formats; i++) {
|
||||
memset(&visual_info_template, 0, sizeof(visual_info_template));
|
||||
visual_info_template.visualid =
|
||||
((const XvAdaptorInfo *) a_this)->formats[i].visual_id;
|
||||
visual_info = XGetVisualInfo(hostx_get_display(),
|
||||
VisualIDMask,
|
||||
&visual_info_template, &nb_visual_info);
|
||||
formats[i].depth = ((const XvAdaptorInfo *) a_this)->formats[i].depth;
|
||||
formats[i].visual_class = visual_info->class;
|
||||
XFree(visual_info);
|
||||
}
|
||||
if (a_nb_formats)
|
||||
*a_nb_formats = nb_formats;
|
||||
return formats;
|
||||
}
|
||||
|
||||
int
|
||||
ephyrHostXVAdaptorGetNbPorts(const EphyrHostXVAdaptor * a_this)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
|
||||
|
||||
return ((const XvAdaptorInfo *) a_this)->num_ports;
|
||||
}
|
||||
|
||||
int
|
||||
ephyrHostXVAdaptorGetFirstPortID(const EphyrHostXVAdaptor * a_this)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this, -1);
|
||||
|
||||
return ((const XvAdaptorInfo *) a_this)->base_id;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVAdaptorHasPutVideo(const EphyrHostXVAdaptor * a_this, Bool *a_result)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
|
||||
|
||||
if ((((const XvAdaptorInfo *) a_this)->type &
|
||||
(XvVideoMask | XvInputMask)) == (XvVideoMask | XvInputMask))
|
||||
*a_result = TRUE;
|
||||
else
|
||||
*a_result = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVAdaptorHasGetVideo(const EphyrHostXVAdaptor * a_this, Bool *a_result)
|
||||
{
|
||||
if ((((const XvAdaptorInfo *) a_this)->type &
|
||||
(XvVideoMask | XvOutputMask)) == (XvVideoMask | XvOutputMask))
|
||||
*a_result = TRUE;
|
||||
else
|
||||
*a_result = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVAdaptorHasPutStill(const EphyrHostXVAdaptor * a_this, Bool *a_result)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
|
||||
|
||||
if ((((const XvAdaptorInfo *) a_this)->type &
|
||||
(XvStillMask | XvInputMask)) == (XvStillMask | XvInputMask))
|
||||
*a_result = TRUE;
|
||||
else
|
||||
*a_result = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVAdaptorHasGetStill(const EphyrHostXVAdaptor * a_this, Bool *a_result)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
|
||||
|
||||
if ((((const XvAdaptorInfo *) a_this)->type &
|
||||
(XvStillMask | XvOutputMask)) == (XvStillMask | XvOutputMask))
|
||||
*a_result = TRUE;
|
||||
else
|
||||
*a_result = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVAdaptorHasPutImage(const EphyrHostXVAdaptor * a_this, Bool *a_result)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_this && a_result, FALSE);
|
||||
|
||||
if ((((const XvAdaptorInfo *) a_this)->type &
|
||||
(XvImageMask | XvInputMask)) == (XvImageMask | XvInputMask))
|
||||
*a_result = TRUE;
|
||||
else
|
||||
*a_result = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVQueryEncodings(int a_port_id,
|
||||
EphyrHostEncoding ** a_encodings,
|
||||
unsigned int *a_num_encodings)
|
||||
{
|
||||
EphyrHostEncoding *encodings = NULL;
|
||||
XvEncodingInfo *encoding_info = NULL;
|
||||
unsigned int num_encodings = 0, i;
|
||||
int ret = 0;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_encodings && a_num_encodings, FALSE);
|
||||
|
||||
ret = XvQueryEncodings(hostx_get_display(),
|
||||
a_port_id, &num_encodings, &encoding_info);
|
||||
if (num_encodings && encoding_info) {
|
||||
encodings = calloc(num_encodings, sizeof(EphyrHostEncoding));
|
||||
for (i = 0; i < num_encodings; i++) {
|
||||
encodings[i].id = encoding_info[i].encoding_id;
|
||||
encodings[i].name = strdup(encoding_info[i].name);
|
||||
encodings[i].width = encoding_info[i].width;
|
||||
encodings[i].height = encoding_info[i].height;
|
||||
encodings[i].rate.numerator = encoding_info[i].rate.numerator;
|
||||
encodings[i].rate.denominator = encoding_info[i].rate.denominator;
|
||||
}
|
||||
}
|
||||
if (encoding_info) {
|
||||
XvFreeEncodingInfo(encoding_info);
|
||||
encoding_info = NULL;
|
||||
}
|
||||
*a_encodings = encodings;
|
||||
*a_num_encodings = num_encodings;
|
||||
|
||||
if (ret != Success)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
ephyrHostEncodingsDelete(EphyrHostEncoding * a_encodings, int a_num_encodings)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (!a_encodings)
|
||||
return;
|
||||
for (i = 0; i < a_num_encodings; i++) {
|
||||
free(a_encodings[i].name);
|
||||
a_encodings[i].name = NULL;
|
||||
}
|
||||
free(a_encodings);
|
||||
}
|
||||
|
||||
void
|
||||
ephyrHostAttributesDelete(EphyrHostAttribute * a_attributes)
|
||||
{
|
||||
if (!a_attributes)
|
||||
return;
|
||||
XFree(a_attributes);
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVQueryPortAttributes(int a_port_id,
|
||||
EphyrHostAttribute ** a_attributes,
|
||||
int *a_num_attributes)
|
||||
{
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_attributes && a_num_attributes, FALSE);
|
||||
|
||||
*a_attributes =
|
||||
(EphyrHostAttribute *) XvQueryPortAttributes(hostx_get_display(),
|
||||
a_port_id,
|
||||
a_num_attributes);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVQueryImageFormats(int a_port_id,
|
||||
EphyrHostImageFormat ** a_formats,
|
||||
int *a_num_format)
|
||||
{
|
||||
XvImageFormatValues *result = NULL;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_formats && a_num_format, FALSE);
|
||||
|
||||
result = XvListImageFormats(hostx_get_display(), a_port_id, a_num_format);
|
||||
*a_formats = (EphyrHostImageFormat *) result;
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVSetPortAttribute(int a_port_id, int a_atom, int a_attr_value)
|
||||
{
|
||||
int res = Success;
|
||||
|
||||
EPHYR_LOG("atom,name,value: (%d,%s,%d)\n",
|
||||
a_atom, XGetAtomName(hostx_get_display(), a_atom), a_attr_value);
|
||||
|
||||
res = XvSetPortAttribute(hostx_get_display(),
|
||||
a_port_id, a_atom, a_attr_value);
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvSetPortAttribute() failed: %d\n", res);
|
||||
return FALSE;
|
||||
}
|
||||
XFlush(hostx_get_display());
|
||||
EPHYR_LOG("leave\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVGetPortAttribute(int a_port_id, int a_atom, int *a_attr_value)
|
||||
{
|
||||
int res = Success;
|
||||
Bool ret = FALSE;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_attr_value, FALSE);
|
||||
|
||||
EPHYR_LOG("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
|
||||
a_port_id, a_atom, XGetAtomName(hostx_get_display(), a_atom));
|
||||
|
||||
res = XvGetPortAttribute(hostx_get_display(),
|
||||
a_port_id, a_atom, a_attr_value);
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvGetPortAttribute() failed: %d \n", res);
|
||||
goto out;
|
||||
}
|
||||
EPHYR_LOG("atom,value: (%d, %d)\n", a_atom, *a_attr_value);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVQueryBestSize(int a_port_id,
|
||||
Bool a_motion,
|
||||
unsigned int a_frame_w,
|
||||
unsigned int a_frame_h,
|
||||
unsigned int a_drw_w,
|
||||
unsigned int a_drw_h,
|
||||
unsigned int *a_actual_w, unsigned int *a_actual_h)
|
||||
{
|
||||
int res = 0;
|
||||
Bool is_ok = FALSE;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_actual_w && a_actual_h, FALSE);
|
||||
|
||||
EPHYR_LOG("enter: frame (%dx%d), drw (%dx%d)\n",
|
||||
a_frame_w, a_frame_h, a_drw_w, a_drw_h);
|
||||
|
||||
res = XvQueryBestSize(hostx_get_display(),
|
||||
a_port_id,
|
||||
a_motion,
|
||||
a_frame_w, a_frame_h,
|
||||
a_drw_w, a_drw_h, a_actual_w, a_actual_h);
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvQueryBestSize() failed: %d\n", res);
|
||||
goto out;
|
||||
}
|
||||
XSync(hostx_get_display(), FALSE);
|
||||
|
||||
EPHYR_LOG("actual (%dx%d)\n", *a_actual_w, *a_actual_h);
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xv_wire_to_event(Display * dpy, XEvent * host, xEvent *wire)
|
||||
{
|
||||
XExtDisplayInfo *info = xv_find_display(dpy);
|
||||
XvEvent *re = (XvEvent *) host;
|
||||
xvEvent *event = (xvEvent *) wire;
|
||||
|
||||
XvCheckExtension(dpy, info, False);
|
||||
|
||||
switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
|
||||
case XvVideoNotify:
|
||||
re->xvvideo.type = event->u.u.type & 0x7f;
|
||||
re->xvvideo.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
|
||||
re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
|
||||
re->xvvideo.display = dpy;
|
||||
re->xvvideo.time = event->u.videoNotify.time;
|
||||
re->xvvideo.reason = event->u.videoNotify.reason;
|
||||
re->xvvideo.drawable = event->u.videoNotify.drawable;
|
||||
re->xvvideo.port_id = event->u.videoNotify.port;
|
||||
break;
|
||||
case XvPortNotify:
|
||||
re->xvport.type = event->u.u.type & 0x7f;
|
||||
re->xvport.serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
|
||||
re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
|
||||
re->xvport.display = dpy;
|
||||
re->xvport.time = event->u.portNotify.time;
|
||||
re->xvport.port_id = event->u.portNotify.port;
|
||||
re->xvport.attribute = event->u.portNotify.attribute;
|
||||
re->xvport.value = event->u.portNotify.value;
|
||||
break;
|
||||
default:
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVQueryImageAttributes(int a_port_id,
|
||||
int a_image_id /*image fourcc code */ ,
|
||||
unsigned short *a_width,
|
||||
unsigned short *a_height,
|
||||
int *a_image_size,
|
||||
int *a_pitches, int *a_offsets)
|
||||
{
|
||||
Display *dpy = hostx_get_display();
|
||||
Bool ret = FALSE;
|
||||
XExtDisplayInfo *info = xv_find_display(dpy);
|
||||
xvQueryImageAttributesReq *req = NULL;
|
||||
xvQueryImageAttributesReply rep;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_width, FALSE);
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_height, FALSE);
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_image_size, FALSE);
|
||||
|
||||
XvCheckExtension(dpy, info, FALSE);
|
||||
|
||||
LockDisplay(dpy);
|
||||
|
||||
XvGetReq(QueryImageAttributes, req);
|
||||
req->id = a_image_id;
|
||||
req->port = a_port_id;
|
||||
req->width = *a_width;
|
||||
req->height = *a_height;
|
||||
/*
|
||||
* read the reply
|
||||
*/
|
||||
if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) {
|
||||
EPHYR_LOG_ERROR("QeryImageAttribute req failed\n");
|
||||
goto out;
|
||||
}
|
||||
if (a_pitches && a_offsets) {
|
||||
_XRead(dpy, (char *) a_pitches, rep.num_planes << 2);
|
||||
_XRead(dpy, (char *) a_offsets, rep.num_planes << 2);
|
||||
}
|
||||
else {
|
||||
_XEatDataWords(dpy, rep.length);
|
||||
}
|
||||
*a_width = rep.width;
|
||||
*a_height = rep.height;
|
||||
*a_image_size = rep.data_size;
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostGetAtom(const char *a_name, Bool a_create_if_not_exists, int *a_atom)
|
||||
{
|
||||
int atom = None;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_atom, FALSE);
|
||||
|
||||
atom = XInternAtom(hostx_get_display(), a_name, a_create_if_not_exists);
|
||||
if (atom == None) {
|
||||
return FALSE;
|
||||
}
|
||||
*a_atom = atom;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
ephyrHostGetAtomName(int a_atom)
|
||||
{
|
||||
return XGetAtomName(hostx_get_display(), a_atom);
|
||||
}
|
||||
|
||||
void
|
||||
ephyrHostFree(void *a_pointer)
|
||||
{
|
||||
if (a_pointer)
|
||||
XFree(a_pointer);
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVPutImage(int a_screen_num,
|
||||
int a_port_id,
|
||||
int a_image_id,
|
||||
int a_drw_x,
|
||||
int a_drw_y,
|
||||
int a_drw_w,
|
||||
int a_drw_h,
|
||||
int a_src_x,
|
||||
int a_src_y,
|
||||
int a_src_w,
|
||||
int a_src_h,
|
||||
int a_image_width,
|
||||
int a_image_height,
|
||||
unsigned char *a_buf,
|
||||
EphyrHostBox * a_clip_rects, int a_clip_rect_nums)
|
||||
{
|
||||
Bool is_ok = TRUE;
|
||||
XvImage *xv_image = NULL;
|
||||
GC gc = 0;
|
||||
XGCValues gc_values;
|
||||
Display *dpy = hostx_get_display();
|
||||
XRectangle *rects = NULL;
|
||||
int res = 0;
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(a_buf, FALSE);
|
||||
|
||||
EPHYR_LOG("enter, num_clip_rects: %d\n", a_clip_rect_nums);
|
||||
|
||||
memset(&gc_values, 0, sizeof(gc_values));
|
||||
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
|
||||
if (!gc) {
|
||||
EPHYR_LOG_ERROR("failed to create gc \n");
|
||||
goto out;
|
||||
}
|
||||
xv_image = (XvImage *) XvCreateImage(hostx_get_display(),
|
||||
a_port_id, a_image_id,
|
||||
NULL, a_image_width, a_image_height);
|
||||
if (!xv_image) {
|
||||
EPHYR_LOG_ERROR("failed to create image\n");
|
||||
goto out;
|
||||
}
|
||||
xv_image->data = (char *) a_buf;
|
||||
if (a_clip_rect_nums) {
|
||||
int i = 0;
|
||||
|
||||
rects = calloc(a_clip_rect_nums, sizeof(XRectangle));
|
||||
for (i = 0; i < a_clip_rect_nums; i++) {
|
||||
rects[i].x = a_clip_rects[i].x1;
|
||||
rects[i].y = a_clip_rects[i].y1;
|
||||
rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
|
||||
rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
|
||||
EPHYR_LOG("(x,y,w,h): (%d,%d,%d,%d)\n",
|
||||
rects[i].x, rects[i].y, rects[i].width, rects[i].height);
|
||||
}
|
||||
XSetClipRectangles(dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded);
|
||||
/*this always returns 1 */
|
||||
}
|
||||
res = XvPutImage(dpy, a_port_id,
|
||||
hostx_get_window(a_screen_num),
|
||||
gc, xv_image,
|
||||
a_src_x, a_src_y, a_src_w, a_src_h,
|
||||
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvPutImage() failed: %d\n", res);
|
||||
goto out;
|
||||
}
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
if (xv_image) {
|
||||
XFree(xv_image);
|
||||
xv_image = NULL;
|
||||
}
|
||||
if (gc) {
|
||||
XFreeGC(dpy, gc);
|
||||
gc = NULL;
|
||||
}
|
||||
free(rects);
|
||||
rects = NULL;
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVPutVideo(int a_screen_num, int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
int res = FALSE;
|
||||
GC gc = 0;
|
||||
XGCValues gc_values;
|
||||
Display *dpy = hostx_get_display();
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
|
||||
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
|
||||
if (!gc) {
|
||||
EPHYR_LOG_ERROR("failed to create gc \n");
|
||||
goto out;
|
||||
}
|
||||
res = XvPutVideo(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
|
||||
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
|
||||
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
|
||||
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvPutVideo() failed: %d\n", res);
|
||||
goto out;
|
||||
}
|
||||
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
if (gc) {
|
||||
XFreeGC(dpy, gc);
|
||||
gc = NULL;
|
||||
}
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVGetVideo(int a_screen_num, int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
int res = FALSE;
|
||||
GC gc = 0;
|
||||
XGCValues gc_values;
|
||||
Display *dpy = hostx_get_display();
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
|
||||
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
|
||||
if (!gc) {
|
||||
EPHYR_LOG_ERROR("failed to create gc \n");
|
||||
goto out;
|
||||
}
|
||||
res = XvGetVideo(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
|
||||
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
|
||||
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
|
||||
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvGetVideo() failed: %d\n", res);
|
||||
goto out;
|
||||
}
|
||||
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
if (gc) {
|
||||
XFreeGC(dpy, gc);
|
||||
gc = NULL;
|
||||
}
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVPutStill(int a_screen_num, int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
int res = FALSE;
|
||||
GC gc = 0;
|
||||
XGCValues gc_values;
|
||||
Display *dpy = hostx_get_display();
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
|
||||
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
|
||||
if (!gc) {
|
||||
EPHYR_LOG_ERROR("failed to create gc \n");
|
||||
goto out;
|
||||
}
|
||||
res = XvPutStill(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
|
||||
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
|
||||
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
|
||||
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvPutStill() failed: %d\n", res);
|
||||
goto out;
|
||||
}
|
||||
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
if (gc) {
|
||||
XFreeGC(dpy, gc);
|
||||
gc = NULL;
|
||||
}
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVGetStill(int a_screen_num, int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
int res = FALSE;
|
||||
GC gc = 0;
|
||||
XGCValues gc_values;
|
||||
Display *dpy = hostx_get_display();
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
|
||||
gc = XCreateGC(dpy, hostx_get_window(a_screen_num), 0L, &gc_values);
|
||||
if (!gc) {
|
||||
EPHYR_LOG_ERROR("failed to create gc \n");
|
||||
goto out;
|
||||
}
|
||||
res = XvGetStill(dpy, a_port_id, hostx_get_window(a_screen_num), gc,
|
||||
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
|
||||
a_drw_x, a_drw_y, a_drw_w, a_drw_h);
|
||||
|
||||
if (res != Success) {
|
||||
EPHYR_LOG_ERROR("XvGetStill() failed: %d\n", res);
|
||||
goto out;
|
||||
}
|
||||
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
if (gc) {
|
||||
XFreeGC(dpy, gc);
|
||||
gc = NULL;
|
||||
}
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrHostXVStopVideo(int a_screen_num, int a_port_id)
|
||||
{
|
||||
int ret = 0;
|
||||
Bool is_ok = FALSE;
|
||||
Display *dpy = hostx_get_display();
|
||||
|
||||
EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE);
|
||||
|
||||
EPHYR_LOG("enter\n");
|
||||
|
||||
ret = XvStopVideo(dpy, a_port_id, hostx_get_window(a_screen_num));
|
||||
if (ret != Success) {
|
||||
EPHYR_LOG_ERROR("XvStopVideo() failed: %d \n", ret);
|
||||
goto out;
|
||||
}
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
* Xephyr - A kdrive X server thats runs in a host X window.
|
||||
* Authored by Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright © 2007 OpenedHand Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of OpenedHand Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. OpenedHand Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Dodji Seketeli <dodji@openedhand.com>
|
||||
*/
|
||||
#ifndef __EPHYRHOSTVIDEO_H__
|
||||
#define __EPHYRHOSTVIDEO_H__
|
||||
|
||||
typedef void *EphyrHostXVAdaptor;
|
||||
typedef struct _EphyrHostXVAdaptorArray EphyrHostXVAdaptorArray;
|
||||
|
||||
typedef struct _EphyrHostVideoFormat {
|
||||
char depth;
|
||||
short visual_class;
|
||||
} EphyrHostVideoFormat;
|
||||
|
||||
typedef struct _EphyrHostRational {
|
||||
int numerator;
|
||||
int denominator;
|
||||
} EphyrHostRational;
|
||||
|
||||
typedef struct _EphyrHostEncoding {
|
||||
int id;
|
||||
char *name;
|
||||
unsigned short width, height;
|
||||
EphyrHostRational rate;
|
||||
} EphyrHostEncoding;
|
||||
|
||||
typedef struct _EphyrHostAttribute {
|
||||
int flags;
|
||||
int min_value;
|
||||
int max_value;
|
||||
char *name;
|
||||
} EphyrHostAttribute;
|
||||
|
||||
typedef struct _EphyrHostImageFormat {
|
||||
int id; /* Unique descriptor for the format */
|
||||
int type; /* XvRGB, XvYUV */
|
||||
int byte_order; /* LSBFirst, MSBFirst */
|
||||
char guid[16]; /* Globally Unique IDentifier */
|
||||
int bits_per_pixel;
|
||||
int format; /* XvPacked, XvPlanar */
|
||||
int num_planes;
|
||||
|
||||
/* for RGB formats only */
|
||||
int depth;
|
||||
unsigned int red_mask;
|
||||
unsigned int green_mask;
|
||||
unsigned int blue_mask;
|
||||
|
||||
/* for YUV formats only */
|
||||
unsigned int y_sample_bits;
|
||||
unsigned int u_sample_bits;
|
||||
unsigned int v_sample_bits;
|
||||
unsigned int horz_y_period;
|
||||
unsigned int horz_u_period;
|
||||
unsigned int horz_v_period;
|
||||
unsigned int vert_y_period;
|
||||
unsigned int vert_u_period;
|
||||
unsigned int vert_v_period;
|
||||
char component_order[32]; /* eg. UYVY */
|
||||
int scanline_order; /* XvTopToBottom, XvBottomToTop */
|
||||
} EphyrHostImageFormat;
|
||||
|
||||
typedef struct {
|
||||
unsigned short x1, y1, x2, y2;
|
||||
} EphyrHostBox;
|
||||
|
||||
void ephyrHostXVInit(void);
|
||||
|
||||
void ephyrHostFree(void *a_pointer);
|
||||
|
||||
/*
|
||||
* host adaptor array
|
||||
*/
|
||||
Bool ephyrHostXVQueryAdaptors(EphyrHostXVAdaptorArray ** a_adaptors);
|
||||
void ephyrHostXVAdaptorArrayDelete(EphyrHostXVAdaptorArray * a_adaptors);
|
||||
int ephyrHostXVAdaptorArrayGetSize(const EphyrHostXVAdaptorArray * a_this);
|
||||
EphyrHostXVAdaptor *ephyrHostXVAdaptorArrayAt(const EphyrHostXVAdaptorArray *
|
||||
a_this, int a_index);
|
||||
|
||||
/*
|
||||
* host adaptor
|
||||
*/
|
||||
|
||||
char ephyrHostXVAdaptorGetType(const EphyrHostXVAdaptor * a_this);
|
||||
const char *ephyrHostXVAdaptorGetName(const EphyrHostXVAdaptor * a_this);
|
||||
EphyrHostVideoFormat *ephyrHostXVAdaptorGetVideoFormats
|
||||
(const EphyrHostXVAdaptor * a_this, int *a_nb_formats);
|
||||
int ephyrHostXVAdaptorGetNbPorts(const EphyrHostXVAdaptor * a_this);
|
||||
int ephyrHostXVAdaptorGetFirstPortID(const EphyrHostXVAdaptor * a_this);
|
||||
|
||||
Bool ephyrHostXVAdaptorHasPutVideo(const EphyrHostXVAdaptor * a_this,
|
||||
Bool *a_result);
|
||||
Bool ephyrHostXVAdaptorHasGetVideo(const EphyrHostXVAdaptor * a_this,
|
||||
Bool *a_result);
|
||||
Bool ephyrHostXVAdaptorHasPutStill(const EphyrHostXVAdaptor * a_this,
|
||||
Bool *a_result);
|
||||
Bool ephyrHostXVAdaptorHasGetStill(const EphyrHostXVAdaptor * a_this,
|
||||
Bool *a_result);
|
||||
Bool ephyrHostXVAdaptorHasPutImage(const EphyrHostXVAdaptor * a_this,
|
||||
Bool *a_result);
|
||||
|
||||
/*
|
||||
* encoding
|
||||
*/
|
||||
Bool ephyrHostXVQueryEncodings(int a_port_id,
|
||||
EphyrHostEncoding ** a_encodings,
|
||||
unsigned int *a_num_encodings);
|
||||
|
||||
void ephyrHostEncodingsDelete(EphyrHostEncoding * a_encodings,
|
||||
int a_num_encodings);
|
||||
|
||||
/*
|
||||
* attribute
|
||||
*/
|
||||
Bool ephyrHostXVQueryPortAttributes(int a_port_id,
|
||||
EphyrHostAttribute ** a_attributes,
|
||||
int *a_num_attributes);
|
||||
|
||||
void ephyrHostAttributesDelete(EphyrHostAttribute * a_attributes);
|
||||
|
||||
/*
|
||||
* image format
|
||||
*/
|
||||
|
||||
Bool ephyrHostXVQueryImageFormats(int a_port_id,
|
||||
EphyrHostImageFormat ** a_formats,
|
||||
int *a_num_format);
|
||||
/*
|
||||
* Port Attribute Get/Set
|
||||
*/
|
||||
Bool ephyrHostXVSetPortAttribute(int a_port_id, int a_atom, int a_attr_value);
|
||||
Bool ephyrHostXVGetPortAttribute(int a_port_id, int a_atom, int *a_attr_value);
|
||||
|
||||
/*
|
||||
*size query
|
||||
*/
|
||||
Bool ephyrHostXVQueryBestSize(int a_port_id,
|
||||
Bool a_motion,
|
||||
unsigned int a_frame_w,
|
||||
unsigned int a_frame_h,
|
||||
unsigned int a_drw_w,
|
||||
unsigned int a_drw_h,
|
||||
unsigned int *a_actual_w,
|
||||
unsigned int *a_actual_h);
|
||||
|
||||
Bool ephyrHostXVQueryImageAttributes(int a_port_id,
|
||||
int a_image_id /*image fourcc code */ ,
|
||||
unsigned short *a_width,
|
||||
unsigned short *a_height,
|
||||
int *a_image_size,
|
||||
int *a_pitches, int *a_offsets);
|
||||
/*
|
||||
* atom
|
||||
*/
|
||||
Bool ephyrHostGetAtom(const char *a_name,
|
||||
Bool a_create_if_not_exists, int *a_atom);
|
||||
char *ephyrHostGetAtomName(int a_atom);
|
||||
|
||||
/*
|
||||
*PutImage
|
||||
* (ignore clipping for now)
|
||||
*/
|
||||
Bool ephyrHostXVPutImage(int a_screen_num,
|
||||
int a_port_id,
|
||||
int a_image_id,
|
||||
int a_drw_x,
|
||||
int a_drw_y,
|
||||
int a_drw_w,
|
||||
int a_drw_h,
|
||||
int a_src_x,
|
||||
int a_src_y,
|
||||
int a_src_w,
|
||||
int a_src_h,
|
||||
int a_image_width,
|
||||
int a_image_height,
|
||||
unsigned char *a_buf,
|
||||
EphyrHostBox * a_clip_rects, int a_clip_rect_nums);
|
||||
|
||||
/*
|
||||
* Putvideo/PutStill/GetVideo
|
||||
*/
|
||||
Bool ephyrHostXVPutVideo(int a_screen_num,
|
||||
int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
|
||||
|
||||
Bool ephyrHostXVGetVideo(int a_screen_num,
|
||||
int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
|
||||
|
||||
Bool ephyrHostXVPutStill(int a_screen_num,
|
||||
int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
|
||||
|
||||
Bool ephyrHostXVGetStill(int a_screen_num,
|
||||
int a_port_id,
|
||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h);
|
||||
|
||||
/*
|
||||
* StopVideo
|
||||
*/
|
||||
Bool ephyrHostXVStopVideo(int a_screen_num, int a_port_id);
|
||||
|
||||
#endif /*__EPHYRHOSTVIDEO_H__*/
|
|
@ -71,6 +71,22 @@ InitCard(char *name)
|
|||
KdCardInfoAdd(&ephyrFuncs, 0);
|
||||
}
|
||||
|
||||
static const ExtensionModule ephyrExtensions[] = {
|
||||
#ifdef GLXEXT
|
||||
{ GlxExtensionInit, "GLX", &noGlxExtension },
|
||||
#endif
|
||||
};
|
||||
|
||||
static
|
||||
void ephyrExtensionInit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ephyrExtensions); i++)
|
||||
LoadExtension(&ephyrExtensions[i], TRUE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
|
||||
{
|
||||
|
@ -134,7 +150,7 @@ ddxUseMsg(void)
|
|||
|
||||
ErrorF("\nXephyr Option Usage:\n");
|
||||
ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
|
||||
ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
|
||||
ErrorF("-sw-cursor Render cursors in software in Xephyr\n");
|
||||
ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
|
||||
ErrorF("-grayscale Simulate 8bit grayscale\n");
|
||||
ErrorF("-resizeable Make Xephyr windows resizeable\n");
|
||||
|
@ -167,6 +183,9 @@ processScreenArg(const char *screen_size, char *parent_id)
|
|||
|
||||
screen = KdScreenInfoAdd(card);
|
||||
KdParseScreen(screen, screen_size);
|
||||
screen->driver = calloc(1, sizeof(EphyrScrPriv));
|
||||
if (!screen->driver)
|
||||
FatalError("Couldn't alloc screen private\n");
|
||||
|
||||
if (parent_id) {
|
||||
p_id = strtol(parent_id, NULL, 0);
|
||||
|
@ -220,8 +239,12 @@ ddxProcessArgument(int argc, char **argv, int i)
|
|||
UseMsg();
|
||||
exit(1);
|
||||
}
|
||||
else if (!strcmp(argv[i], "-sw-cursor")) {
|
||||
hostx_use_sw_cursor();
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-host-cursor")) {
|
||||
hostx_use_host_cursor();
|
||||
/* Compatibility with the old command line argument, now the default. */
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-fullscreen")) {
|
||||
|
@ -389,7 +412,7 @@ ephyrCursorEnable(ScreenPtr pScreen)
|
|||
|
||||
KdCardFuncs ephyrFuncs = {
|
||||
ephyrCardInit, /* cardinit */
|
||||
ephyrScreenInit, /* scrinit */
|
||||
ephyrScreenInitialize, /* scrinit */
|
||||
ephyrInitScreen, /* initScreen */
|
||||
ephyrFinishInitScreen, /* finishInitScreen */
|
||||
ephyrCreateResources, /* createRes */
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Xephyr - A kdrive X server thats runs in a host X window.
|
||||
* Authored by Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright © 2007 OpenedHand Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of OpenedHand Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. OpenedHand Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Dodji Seketeli <dodji@openedhand.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* \file
|
||||
* This file defines a proxy extension that forwards requests.
|
||||
* When a request to extension FOO is sent to Xephyr, that request is forwared
|
||||
* to the host X, without even trying to know what the request means.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <kdrive-config.h>
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "dixstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "ephyrproxyext.h"
|
||||
#define _HAVE_XALLOC_DECLS
|
||||
#include "ephyrlog.h"
|
||||
#include "ephyrhostproxy.h"
|
||||
#include "hostx.h"
|
||||
|
||||
static Bool ephyrProxyGetHostExtensionInfo(const char *a_ext_name,
|
||||
int *a_major_opcode,
|
||||
int *a_first_event,
|
||||
int *a_first_error);
|
||||
|
||||
static int ephyrProxyProcDispatch(ClientPtr client);
|
||||
|
||||
static Bool
|
||||
ephyrProxyGetHostExtensionInfo(const char *a_ext_name,
|
||||
int *a_major_opcode,
|
||||
int *a_first_event, int *a_first_error)
|
||||
{
|
||||
return hostx_get_extension_info(a_ext_name, a_major_opcode,
|
||||
a_first_event, a_first_error);
|
||||
}
|
||||
|
||||
static int
|
||||
ephyrProxyProcDispatch(ClientPtr a_client)
|
||||
{
|
||||
int res = BadImplementation;
|
||||
struct XReply reply;
|
||||
|
||||
if (!ephyrHostProxyDoForward(a_client->requestBuffer, &reply, FALSE)) {
|
||||
EPHYR_LOG_ERROR("forwarding failed\n");
|
||||
goto out;
|
||||
}
|
||||
reply.sequence_number = a_client->sequence;
|
||||
res = Success;
|
||||
|
||||
WriteToClient(a_client, 32, &reply);
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrProxyProcReset(ExtensionEntry * a_entry)
|
||||
{
|
||||
}
|
||||
|
||||
Bool
|
||||
ephyrProxyExtensionInit(const char *a_extension_name)
|
||||
{
|
||||
Bool is_ok = FALSE;
|
||||
int major_opcode = 0, first_event = 0, first_error = 0;
|
||||
ExtensionEntry *ext = NULL;
|
||||
|
||||
if (!ephyrProxyGetHostExtensionInfo(a_extension_name,
|
||||
&major_opcode,
|
||||
&first_event, &first_error)) {
|
||||
EPHYR_LOG("failed to query extension %s from host\n", a_extension_name);
|
||||
goto out;
|
||||
}
|
||||
ext = AddExtension((char *) a_extension_name, 0, 0,
|
||||
ephyrProxyProcDispatch,
|
||||
ephyrProxyProcDispatch,
|
||||
ephyrProxyProcReset, StandardMinorOpcode);
|
||||
if (!ext) {
|
||||
EPHYR_LOG_ERROR("failed to add the extension\n");
|
||||
goto out;
|
||||
}
|
||||
is_ok = TRUE;
|
||||
|
||||
out:
|
||||
EPHYR_LOG("leave\n");
|
||||
return is_ok;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Xephyr - A kdrive X server thats runs in a host X window.
|
||||
* Authored by Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright © 2007 OpenedHand Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of OpenedHand Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. OpenedHand Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Dodji Seketeli <dodji@openedhand.com>
|
||||
*/
|
||||
#ifndef __EPHYRPROXYEXT_H__
|
||||
#define __EPHYRPROXYEXT_H__
|
||||
|
||||
Bool ephyrProxyExtensionInit(const char *a_extension_name);
|
||||
|
||||
#endif /*__EPHYRPROXYEXT_H__*/
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xmd.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include "ephyr.h"
|
||||
|
||||
#define EPHYR_WANT_DEBUG 0
|
||||
|
||||
|
@ -39,69 +41,12 @@
|
|||
#endif
|
||||
|
||||
typedef struct EphyrHostXVars EphyrHostXVars;
|
||||
typedef struct EphyrHostXEvent EphyrHostXEvent;
|
||||
typedef void *EphyrScreenInfo;
|
||||
typedef enum EphyrHostXEventType {
|
||||
EPHYR_EV_MOUSE_MOTION,
|
||||
EPHYR_EV_MOUSE_PRESS,
|
||||
EPHYR_EV_MOUSE_RELEASE,
|
||||
EPHYR_EV_KEY_PRESS,
|
||||
EPHYR_EV_KEY_RELEASE,
|
||||
EPHYR_EV_EXPOSE,
|
||||
EPHYR_EV_CONFIGURE,
|
||||
} EphyrHostXEventType;
|
||||
|
||||
/* I can't believe it's not a KeySymsRec. */
|
||||
typedef struct {
|
||||
int minKeyCode;
|
||||
int maxKeyCode;
|
||||
int mapWidth;
|
||||
CARD32 *map;
|
||||
} EphyrKeySyms;
|
||||
|
||||
struct EphyrHostXEvent {
|
||||
EphyrHostXEventType type;
|
||||
|
||||
union {
|
||||
struct mouse_motion {
|
||||
int x;
|
||||
int y;
|
||||
int screen;
|
||||
int window;
|
||||
} mouse_motion;
|
||||
|
||||
struct mouse_down {
|
||||
int button_num;
|
||||
} mouse_down;
|
||||
|
||||
struct mouse_up {
|
||||
int button_num;
|
||||
} mouse_up;
|
||||
|
||||
struct key_up {
|
||||
int scancode;
|
||||
} key_up;
|
||||
|
||||
struct key_down {
|
||||
int scancode;
|
||||
} key_down;
|
||||
|
||||
struct expose {
|
||||
int window;
|
||||
} expose;
|
||||
|
||||
struct configure {
|
||||
int width;
|
||||
int height;
|
||||
int screen;
|
||||
int window;
|
||||
} configure;
|
||||
|
||||
} data;
|
||||
|
||||
int key_state;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
VisualID visualid;
|
||||
int screen;
|
||||
|
@ -129,13 +74,13 @@ typedef struct {
|
|||
} EphyrRect;
|
||||
|
||||
int
|
||||
hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
|
||||
hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height);
|
||||
|
||||
int
|
||||
hostx_want_host_cursor(void);
|
||||
|
||||
void
|
||||
hostx_use_host_cursor(void);
|
||||
hostx_use_sw_cursor(void);
|
||||
|
||||
void
|
||||
hostx_use_fullscreen(void);
|
||||
|
@ -144,7 +89,7 @@ int
|
|||
hostx_want_fullscreen(void);
|
||||
|
||||
int
|
||||
hostx_want_preexisting_window(EphyrScreenInfo screen);
|
||||
hostx_want_preexisting_window(KdScreenInfo *screen);
|
||||
|
||||
void
|
||||
hostx_use_preexisting_window(unsigned long win_id);
|
||||
|
@ -162,52 +107,50 @@ int
|
|||
hostx_init(void);
|
||||
|
||||
void
|
||||
hostx_add_screen(EphyrScreenInfo screen, unsigned long win_id, int screen_num);
|
||||
hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num);
|
||||
|
||||
void
|
||||
hostx_set_display_name(char *name);
|
||||
|
||||
void
|
||||
hostx_set_screen_number(EphyrScreenInfo screen, int number);
|
||||
hostx_set_screen_number(KdScreenInfo *screen, int number);
|
||||
|
||||
void
|
||||
hostx_set_win_title(EphyrScreenInfo screen, const char *extra_text);
|
||||
hostx_set_win_title(KdScreenInfo *screen, const char *extra_text);
|
||||
|
||||
int
|
||||
hostx_get_depth(void);
|
||||
|
||||
int
|
||||
hostx_get_server_depth(EphyrScreenInfo screen);
|
||||
|
||||
void
|
||||
hostx_set_server_depth(EphyrScreenInfo screen, int depth);
|
||||
hostx_get_server_depth(KdScreenInfo *screen);
|
||||
|
||||
int
|
||||
hostx_get_bpp(void *info);
|
||||
hostx_get_bpp(KdScreenInfo *screen);
|
||||
|
||||
void
|
||||
hostx_get_visual_masks(void *info, CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
|
||||
hostx_get_visual_masks(KdScreenInfo *screen,
|
||||
CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
|
||||
void
|
||||
|
||||
hostx_set_cmap_entry(unsigned char idx,
|
||||
unsigned char r, unsigned char g, unsigned char b);
|
||||
|
||||
void *hostx_screen_init(EphyrScreenInfo screen,
|
||||
void *hostx_screen_init(KdScreenInfo *screen,
|
||||
int width, int height, int buffer_height,
|
||||
int *bytes_per_line, int *bits_per_pixel);
|
||||
|
||||
void
|
||||
|
||||
hostx_paint_rect(EphyrScreenInfo screen,
|
||||
hostx_paint_rect(KdScreenInfo *screen,
|
||||
int sx, int sy, int dx, int dy, int width, int height);
|
||||
|
||||
void
|
||||
hostx_load_keymap(void);
|
||||
|
||||
int
|
||||
hostx_get_event(EphyrHostXEvent * ev);
|
||||
xcb_connection_t *
|
||||
hostx_get_xcbconn(void);
|
||||
|
||||
void *hostx_get_display(void);
|
||||
int
|
||||
hostx_get_screen(void);
|
||||
|
||||
int
|
||||
hostx_get_window(int a_screen_number);
|
||||
|
@ -215,11 +158,6 @@ int
|
|||
int
|
||||
hostx_get_window_attributes(int a_window, EphyrHostWindowAttributes * a_attr);
|
||||
|
||||
int
|
||||
|
||||
hostx_get_extension_info(const char *a_ext_name,
|
||||
int *a_major_opcode,
|
||||
int *a_first_even, int *a_first_error);
|
||||
int
|
||||
hostx_get_visuals_info(EphyrHostVisualInfo ** a_visuals, int *a_num_entries);
|
||||
|
||||
|
@ -234,9 +172,7 @@ int hostx_set_window_geometry(int a_win, EphyrBox * a_geo);
|
|||
int hostx_set_window_bounding_rectangles(int a_window,
|
||||
EphyrRect * a_rects, int a_num_rects);
|
||||
|
||||
int hostx_set_window_clipping_rectangles(int a_window,
|
||||
EphyrRect * a_rects, int a_num_rects);
|
||||
int hostx_has_xshape(void);
|
||||
int host_has_extension(xcb_extension_t *extension);
|
||||
|
||||
#ifdef XF86DRI
|
||||
int hostx_lookup_peer_window(void *a_local_window,
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */
|
||||
/**************************************************************************
|
||||
|
||||
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
Copyright 2000 VA Linux Systems, Inc.
|
||||
All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sub license, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the
|
||||
next paragraph) shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \file xf86dri.h
|
||||
* Protocol numbers and function prototypes for DRI X protocol.
|
||||
*
|
||||
* \author Kevin E. Martin <martin@valinux.com>
|
||||
* \author Jens Owen <jens@tungstengraphics.com>
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
*/
|
||||
|
||||
#ifndef _XF86DRI_H_
|
||||
#define _XF86DRI_H_
|
||||
|
||||
#include <X11/Xfuncproto.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#define X_XF86DRIQueryVersion 0
|
||||
#define X_XF86DRIQueryDirectRenderingCapable 1
|
||||
#define X_XF86DRIOpenConnection 2
|
||||
#define X_XF86DRICloseConnection 3
|
||||
#define X_XF86DRIGetClientDriverName 4
|
||||
#define X_XF86DRICreateContext 5
|
||||
#define X_XF86DRIDestroyContext 6
|
||||
#define X_XF86DRICreateDrawable 7
|
||||
#define X_XF86DRIDestroyDrawable 8
|
||||
#define X_XF86DRIGetDrawableInfo 9
|
||||
#define X_XF86DRIGetDeviceInfo 10
|
||||
#define X_XF86DRIAuthConnection 11
|
||||
#define X_XF86DRIOpenFullScreen 12 /* Deprecated */
|
||||
#define X_XF86DRICloseFullScreen 13 /* Deprecated */
|
||||
|
||||
#define XF86DRINumberEvents 0
|
||||
|
||||
#define XF86DRIClientNotLocal 0
|
||||
#define XF86DRIOperationNotSupported 1
|
||||
#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
|
||||
|
||||
#ifndef _XF86DRI_SERVER_
|
||||
|
||||
_XFUNCPROTOBEGIN
|
||||
|
||||
Bool XF86DRIQueryExtension(Display * dpy, int *event_base, int *error_base);
|
||||
|
||||
Bool XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
|
||||
int *patchVersion);
|
||||
|
||||
Bool XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen,
|
||||
Bool *isCapable);
|
||||
|
||||
Bool XF86DRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
|
||||
char **busIDString);
|
||||
|
||||
Bool XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
|
||||
|
||||
Bool XF86DRICloseConnection(Display * dpy, int screen);
|
||||
|
||||
Bool XF86DRIGetClientDriverName(Display * dpy, int screen,
|
||||
int *ddxDriverMajorVersion,
|
||||
int *ddxDriverMinorVersion,
|
||||
int *ddxDriverPatchVersion,
|
||||
char **clientDriverName);
|
||||
|
||||
Bool XF86DRICreateContext(Display * dpy, int screen, Visual * visual,
|
||||
XID *ptr_to_returned_context_id,
|
||||
drm_context_t * hHWContext);
|
||||
|
||||
Bool XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID,
|
||||
XID *ptr_to_returned_context_id,
|
||||
drm_context_t * hHWContext);
|
||||
|
||||
extern GLboolean XF86DRIDestroyContext(Display * dpy, int screen,
|
||||
XID context_id);
|
||||
|
||||
extern GLboolean XF86DRICreateDrawable(Display * dpy, int screen,
|
||||
XID drawable,
|
||||
drm_drawable_t * hHWDrawable);
|
||||
|
||||
extern GLboolean XF86DRIDestroyDrawable(Display * dpy, int screen,
|
||||
XID drawable);
|
||||
|
||||
Bool XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
|
||||
unsigned int *index, unsigned int *stamp,
|
||||
int *X, int *Y, int *W, int *H,
|
||||
int *numClipRects, drm_clip_rect_t ** pClipRects,
|
||||
int *backX, int *backY,
|
||||
int *numBackClipRects,
|
||||
drm_clip_rect_t ** pBackClipRects);
|
||||
|
||||
Bool XF86DRIGetDeviceInfo(Display * dpy, int screen,
|
||||
drm_handle_t * hFrameBuffer, int *fbOrigin,
|
||||
int *fbSize, int *fbStride, int *devPrivateSize,
|
||||
void **pDevPrivate);
|
||||
|
||||
_XFUNCPROTOEND
|
||||
#endif /* _XF86DRI_SERVER_ */
|
||||
#endif /* _XF86DRI_H_ */
|
Loading…
Reference in New Issue