mirror the visuals of the host X at startup.
* hw/kdrive/ephyr/ephyr.c: make Xephyr mirror the visuals of the host X upon startup. This is important for GLX client apps. * hw/kdrive/ephyr/hostx.c,h: add a hostx_get_visuals_info() to get the visuals of the host X.
This commit is contained in:
parent
26da625055
commit
1dd589410c
|
@ -54,6 +54,7 @@ Bool EphyrWantGrayScale = 0;
|
||||||
|
|
||||||
#ifdef XEPHYR_DRI
|
#ifdef XEPHYR_DRI
|
||||||
extern void ephyrDRIExtensionInit(void) ;
|
extern void ephyrDRIExtensionInit(void) ;
|
||||||
|
static Bool EphyrMirrorHostVisuals (void) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
@ -630,6 +631,7 @@ ephyrInitScreen (ScreenPtr pScreen)
|
||||||
ephyrDRIExtensionInit () ;
|
ephyrDRIExtensionInit () ;
|
||||||
ephyrHijackGLXExtension () ;
|
ephyrHijackGLXExtension () ;
|
||||||
ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
|
ephyrProxyExtensionInit ("ATIFGLRXDRI") ;
|
||||||
|
EphyrMirrorHostVisuals () ;
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1046,6 +1048,168 @@ EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicates a visual of a_screen
|
||||||
|
* In screen a_screen, for depth a_depth, find a visual which
|
||||||
|
* bitsPerRGBValue and colormap size equal
|
||||||
|
* a_bits_per_rgb_values and a_colormap_entries.
|
||||||
|
* The ID of that duplicated visual is set to a_new_id.
|
||||||
|
* That duplicated visual is then added to the list of visuals
|
||||||
|
* of the screen.
|
||||||
|
*/
|
||||||
|
static Bool
|
||||||
|
EphyrDuplicateVisual (unsigned int a_screen,
|
||||||
|
short a_depth,
|
||||||
|
short a_class,
|
||||||
|
short a_bits_per_rgb_values,
|
||||||
|
short a_colormap_entries,
|
||||||
|
unsigned int a_red_mask,
|
||||||
|
unsigned int a_green_mask,
|
||||||
|
unsigned int a_blue_mask,
|
||||||
|
unsigned int a_new_id)
|
||||||
|
{
|
||||||
|
Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
|
||||||
|
ScreenPtr screen=NULL ;
|
||||||
|
VisualRec new_visual, *new_visuals=NULL ;
|
||||||
|
int i=0 ;
|
||||||
|
|
||||||
|
EPHYR_LOG ("enter\n") ;
|
||||||
|
if (a_screen > screenInfo.numScreens) {
|
||||||
|
EPHYR_LOG_ERROR ("bad screen number\n") ;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memset (&new_visual, 0, sizeof (VisualRec)) ;
|
||||||
|
|
||||||
|
/*get the screen pointed to by a_screen*/
|
||||||
|
screen = screenInfo.screens[a_screen] ;
|
||||||
|
EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In that screen, first look for an existing visual that has the
|
||||||
|
* same characteristics as those passed in parameter
|
||||||
|
* to this function and copy it.
|
||||||
|
*/
|
||||||
|
for (i=0; i < screen->numVisuals; i++) {
|
||||||
|
if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
|
||||||
|
screen->visuals[i].ColormapEntries == a_colormap_entries ) {
|
||||||
|
/*copy the visual found*/
|
||||||
|
memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
|
||||||
|
new_visual.vid = a_new_id ;
|
||||||
|
found_visual = TRUE ;
|
||||||
|
EPHYR_LOG ("found a visual that matches visual id: %d\n",
|
||||||
|
a_new_id) ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found_visual) {
|
||||||
|
EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
|
||||||
|
goto out ;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* be prepare to extend screen->visuals to add new_visual to it
|
||||||
|
*/
|
||||||
|
new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ;
|
||||||
|
memmove (new_visuals,
|
||||||
|
screen->visuals,
|
||||||
|
screen->numVisuals*sizeof (VisualRec)) ;
|
||||||
|
memmove (&new_visuals[screen->numVisuals],
|
||||||
|
&new_visual,
|
||||||
|
sizeof (VisualRec)) ;
|
||||||
|
/*
|
||||||
|
* Now, in that same screen, update the screen->allowedDepths member.
|
||||||
|
* In that array, each element represents the visuals applicable to
|
||||||
|
* a given depth. So we need to add an entry matching the new visual
|
||||||
|
* that we are going to add to screen->visuals
|
||||||
|
*/
|
||||||
|
for (i=0; i<screen->numDepths; i++) {
|
||||||
|
VisualID *vids=NULL;
|
||||||
|
DepthPtr cur_depth=NULL ;
|
||||||
|
/*find the entry matching a_depth*/
|
||||||
|
if (screen->allowedDepths[i].depth != a_depth)
|
||||||
|
continue ;
|
||||||
|
cur_depth = &screen->allowedDepths[i];
|
||||||
|
/*
|
||||||
|
* extend the list of visual IDs in that entry,
|
||||||
|
* so to add a_new_id in there.
|
||||||
|
*/
|
||||||
|
vids = xrealloc (cur_depth->vids,
|
||||||
|
(cur_depth->numVids+1)*sizeof (VisualID));
|
||||||
|
if (!vids) {
|
||||||
|
EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
|
||||||
|
goto out ;
|
||||||
|
}
|
||||||
|
vids[cur_depth->numVids] = a_new_id ;
|
||||||
|
/*
|
||||||
|
* Okay now commit our change.
|
||||||
|
* Do really update screen->allowedDepths[i]
|
||||||
|
*/
|
||||||
|
cur_depth->numVids++ ;
|
||||||
|
cur_depth->vids = vids ;
|
||||||
|
found_depth=TRUE;
|
||||||
|
}
|
||||||
|
if (!found_depth) {
|
||||||
|
EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
|
||||||
|
a_screen) ;
|
||||||
|
goto out ;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Commit our change to screen->visuals
|
||||||
|
*/
|
||||||
|
xfree (screen->visuals) ;
|
||||||
|
screen->visuals = new_visuals ;
|
||||||
|
screen->numVisuals++ ;
|
||||||
|
new_visuals = NULL ;
|
||||||
|
|
||||||
|
is_ok = TRUE ;
|
||||||
|
out:
|
||||||
|
if (new_visuals) {
|
||||||
|
xfree (new_visuals) ;
|
||||||
|
new_visuals = NULL ;
|
||||||
|
}
|
||||||
|
EPHYR_LOG ("leave\n") ;
|
||||||
|
return is_ok ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicates the visuals of the host X server.
|
||||||
|
* This is necessary to have visuals that have the same
|
||||||
|
* ID as those of the host X. It is important to have that for
|
||||||
|
* GLX.
|
||||||
|
*/
|
||||||
|
static Bool
|
||||||
|
EphyrMirrorHostVisuals (void)
|
||||||
|
{
|
||||||
|
Bool is_ok=FALSE;
|
||||||
|
EphyrHostVisualInfo *visuals=NULL;
|
||||||
|
int nb_visuals=0, i=0;
|
||||||
|
|
||||||
|
EPHYR_LOG ("enter\n") ;
|
||||||
|
if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
|
||||||
|
EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
|
||||||
|
goto out ;
|
||||||
|
}
|
||||||
|
for (i=0; i<nb_visuals; i++) {
|
||||||
|
if (!EphyrDuplicateVisual (visuals[i].screen,
|
||||||
|
visuals[i].depth,
|
||||||
|
visuals[i].class,
|
||||||
|
visuals[i].bits_per_rgb,
|
||||||
|
visuals[i].colormap_size,
|
||||||
|
visuals[i].red_mask,
|
||||||
|
visuals[i].blue_mask,
|
||||||
|
visuals[i].green_mask,
|
||||||
|
visuals[i].visualid)) {
|
||||||
|
EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
|
||||||
|
(int)visuals[i].visualid) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_ok = TRUE ;
|
||||||
|
out:
|
||||||
|
EPHYR_LOG ("leave\n") ;
|
||||||
|
return is_ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
KdKeyboardDriver EphyrKeyboardDriver = {
|
KdKeyboardDriver EphyrKeyboardDriver = {
|
||||||
"ephyr",
|
"ephyr",
|
||||||
EphyrKeyboardInit,
|
EphyrKeyboardInit,
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/extensions/XShm.h>
|
#include <X11/extensions/XShm.h>
|
||||||
|
#include "ephyrlog.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All xlib calls go here, which gets built as its own .a .
|
* All xlib calls go here, which gets built as its own .a .
|
||||||
|
@ -987,3 +988,54 @@ hostx_get_extension_info (const char *a_ext_name,
|
||||||
return 1 ;
|
return 1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
|
||||||
|
int *a_num_entries)
|
||||||
|
{
|
||||||
|
Display *dpy=hostx_get_display () ;
|
||||||
|
Bool is_ok=False ;
|
||||||
|
XVisualInfo templ, *visuals=NULL;
|
||||||
|
EphyrHostVisualInfo *host_visuals=NULL ;
|
||||||
|
int nb_items=0, i=0;
|
||||||
|
|
||||||
|
EPHYR_RETURN_VAL_IF_FAIL (a_visuals && a_num_entries && dpy,
|
||||||
|
False) ;
|
||||||
|
EPHYR_LOG ("enter\n") ;
|
||||||
|
memset (&templ, 0, sizeof (templ)) ;
|
||||||
|
visuals = XGetVisualInfo (dpy, VisualNoMask, &templ, &nb_items) ;
|
||||||
|
if (!visuals) {
|
||||||
|
EPHYR_LOG_ERROR ("host does not advertise any visual\n") ;
|
||||||
|
goto out ;
|
||||||
|
}
|
||||||
|
EPHYR_LOG ("host advertises %d visuals\n", nb_items) ;
|
||||||
|
host_visuals = calloc (nb_items, sizeof (EphyrHostVisualInfo)) ;
|
||||||
|
for (i=0; i<nb_items; i++) {
|
||||||
|
host_visuals[i].visualid = visuals[i].visualid ;
|
||||||
|
host_visuals[i].screen = visuals[i].screen ;
|
||||||
|
host_visuals[i].depth = visuals[i].depth ;
|
||||||
|
host_visuals[i].class = visuals[i].class ;
|
||||||
|
host_visuals[i].red_mask = visuals[i].red_mask ;
|
||||||
|
host_visuals[i].green_mask = visuals[i].green_mask ;
|
||||||
|
host_visuals[i].blue_mask = visuals[i].blue_mask ;
|
||||||
|
host_visuals[i].colormap_size = visuals[i].colormap_size ;
|
||||||
|
host_visuals[i].bits_per_rgb = visuals[i].bits_per_rgb ;
|
||||||
|
}
|
||||||
|
*a_visuals = host_visuals ;
|
||||||
|
*a_num_entries = nb_items;
|
||||||
|
host_visuals=NULL;
|
||||||
|
|
||||||
|
is_ok = TRUE;
|
||||||
|
out:
|
||||||
|
if (visuals) {
|
||||||
|
XFree (visuals) ;
|
||||||
|
visuals = NULL;
|
||||||
|
}
|
||||||
|
if (host_visuals) {
|
||||||
|
free (host_visuals) ;
|
||||||
|
host_visuals = NULL;
|
||||||
|
}
|
||||||
|
EPHYR_LOG ("leave\n") ;
|
||||||
|
return is_ok ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,18 @@ struct EphyrHostXEvent
|
||||||
int key_state;
|
int key_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VisualID visualid;
|
||||||
|
int screen;
|
||||||
|
int depth;
|
||||||
|
int class;
|
||||||
|
unsigned long red_mask;
|
||||||
|
unsigned long green_mask;
|
||||||
|
unsigned long blue_mask;
|
||||||
|
int colormap_size;
|
||||||
|
int bits_per_rgb;
|
||||||
|
} EphyrHostVisualInfo;
|
||||||
|
|
||||||
int
|
int
|
||||||
hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
|
hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
|
||||||
|
|
||||||
|
@ -183,5 +195,7 @@ hostx_get_extension_info (const char *a_ext_name,
|
||||||
int *a_major_opcode,
|
int *a_major_opcode,
|
||||||
int *a_first_even,
|
int *a_first_even,
|
||||||
int *a_first_error) ;
|
int *a_first_error) ;
|
||||||
|
int
|
||||||
|
hostx_get_visuals_info (EphyrHostVisualInfo **a_visuals,
|
||||||
|
int *a_num_entries) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue