Compare commits
110 Commits
master
...
wip/xcb-xn
Author | SHA1 | Date | |
---|---|---|---|
|
0843fc86ac | ||
|
3a26b575b5 | ||
|
6dcb6bb77c | ||
|
66d7dbed01 | ||
|
3455cdcd3f | ||
|
6e4914ffd0 | ||
|
540043413b | ||
|
4fc95145ab | ||
|
546ae43250 | ||
|
0df9c49314 | ||
|
cd0b53a950 | ||
|
e391aa2d71 | ||
|
608650a95e | ||
|
e1ab85e768 | ||
|
b333dd017e | ||
|
b5ec55f862 | ||
|
2db318a341 | ||
|
17b27b2ec3 | ||
|
b51dd9e492 | ||
|
a8410a0670 | ||
|
825397cbfc | ||
|
143c1e0648 | ||
|
0913ee24d0 | ||
|
23d541fbba | ||
|
c6ca7b64f2 | ||
|
ecb8ca56b5 | ||
|
0042894dfb | ||
|
7603a5d6c1 | ||
|
1730573423 | ||
|
8e2614fe8a | ||
|
9e0615e54f | ||
|
cfcea4ef79 | ||
|
bc1d6fe9de | ||
|
90b30fef64 | ||
|
a1d0ad2155 | ||
|
ebe499b2c4 | ||
|
f702a02931 | ||
|
801716a695 | ||
|
73953d49f9 | ||
|
92a52d0190 | ||
|
8eddaa62ce | ||
|
ac34412efd | ||
|
d3bafdf49f | ||
|
2cd8b6c285 | ||
|
4a7a6cfb8d | ||
|
cce1ef3b95 | ||
|
072ac1ffdc | ||
|
d059954952 | ||
|
edc514e2bd | ||
|
fd607858da | ||
|
4d24903dfb | ||
|
cde9d848d6 | ||
|
3aa6daef7e | ||
|
aee6eefbd4 | ||
|
710a60406c | ||
|
c2215260a8 | ||
|
a26ca8e9bb | ||
|
8a068eb15a | ||
|
db2743387b | ||
|
1795698202 | ||
|
315469160c | ||
|
70acda3fba | ||
|
6d12f08fb2 | ||
|
463dd69d9b | ||
|
0fdcadba09 | ||
|
37d6d3ae98 | ||
|
6aef795cc3 | ||
|
4156c3ed2b | ||
|
d5b26664f7 | ||
|
5557fe78a5 | ||
|
feb70bfcc3 | ||
|
da897336e7 | ||
|
84926b8c55 | ||
|
a18d509fa3 | ||
|
d97f059bb8 | ||
|
ad7558aeda | ||
|
d1cd3b5ce5 | ||
|
c9cf170a19 | ||
|
9df52bc2fe | ||
|
813ab17323 | ||
|
9cf63422e2 | ||
|
e30eefaa43 | ||
|
9f87bef81a | ||
|
1314cbc8d4 | ||
|
1ab416220d | ||
|
d7e5f08aa8 | ||
|
2ef0038355 | ||
|
cf9eefa25a | ||
|
51b156e600 | ||
|
ec5254e80d | ||
|
8281c536c1 | ||
|
a883e7a9e8 | ||
|
6b205756dc | ||
|
9d964552f3 | ||
|
4d914beb6b | ||
|
9dd8e84b8a | ||
|
0300295de5 | ||
|
e744208359 | ||
|
e4844fe72c | ||
|
81349772b3 | ||
|
39cd6ff298 | ||
|
fd8d455c5c | ||
|
f9d5e6c318 | ||
|
428c23afaf | ||
|
93ec4c8613 | ||
|
f12944ce12 | ||
|
449b6ad6e0 | ||
|
87c328e81b | ||
|
05f8ca8d26 | ||
|
23e5868713 |
|
@ -28,29 +28,25 @@ is" without express or implied warranty.
|
||||||
#include "scrnintstr.h"
|
#include "scrnintstr.h"
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Args.h"
|
#include "Args.h"
|
||||||
|
|
||||||
char *xnestDisplayName = NULL;
|
char *xnestDisplayName = NULL;
|
||||||
Bool xnestSynchronize = False;
|
Bool xnestFullGeneration = FALSE;
|
||||||
Bool xnestFullGeneration = False;
|
|
||||||
int xnestDefaultClass;
|
int xnestDefaultClass;
|
||||||
Bool xnestUserDefaultClass = False;
|
Bool xnestUserDefaultClass = FALSE;
|
||||||
int xnestDefaultDepth;
|
int xnestDefaultDepth;
|
||||||
Bool xnestUserDefaultDepth = False;
|
Bool xnestUserDefaultDepth = FALSE;
|
||||||
Bool xnestSoftwareScreenSaver = False;
|
Bool xnestSoftwareScreenSaver = FALSE;
|
||||||
int xnestX;
|
xRectangle xnestGeometry = { 0 };
|
||||||
int xnestY;
|
|
||||||
unsigned int xnestWidth;
|
|
||||||
unsigned int xnestHeight;
|
|
||||||
int xnestUserGeometry = 0;
|
int xnestUserGeometry = 0;
|
||||||
int xnestBorderWidth;
|
int xnestBorderWidth;
|
||||||
Bool xnestUserBorderWidth = False;
|
Bool xnestUserBorderWidth = FALSE;
|
||||||
char *xnestWindowName = NULL;
|
char *xnestWindowName = NULL;
|
||||||
int xnestNumScreens = 0;
|
int xnestNumScreens = 0;
|
||||||
Bool xnestDoDirectColormaps = False;
|
Bool xnestDoDirectColormaps = FALSE;
|
||||||
Window xnestParentWindow = 0;
|
Window xnestParentWindow = 0;
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -63,44 +59,40 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-sync")) {
|
|
||||||
xnestSynchronize = True;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[i], "-full")) {
|
if (!strcmp(argv[i], "-full")) {
|
||||||
xnestFullGeneration = True;
|
xnestFullGeneration = TRUE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-class")) {
|
if (!strcmp(argv[i], "-class")) {
|
||||||
if (++i < argc) {
|
if (++i < argc) {
|
||||||
if (!strcmp(argv[i], "StaticGray")) {
|
if (!strcmp(argv[i], "StaticGray")) {
|
||||||
xnestDefaultClass = StaticGray;
|
xnestDefaultClass = StaticGray;
|
||||||
xnestUserDefaultClass = True;
|
xnestUserDefaultClass = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "GrayScale")) {
|
else if (!strcmp(argv[i], "GrayScale")) {
|
||||||
xnestDefaultClass = GrayScale;
|
xnestDefaultClass = GrayScale;
|
||||||
xnestUserDefaultClass = True;
|
xnestUserDefaultClass = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "StaticColor")) {
|
else if (!strcmp(argv[i], "StaticColor")) {
|
||||||
xnestDefaultClass = StaticColor;
|
xnestDefaultClass = StaticColor;
|
||||||
xnestUserDefaultClass = True;
|
xnestUserDefaultClass = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "PseudoColor")) {
|
else if (!strcmp(argv[i], "PseudoColor")) {
|
||||||
xnestDefaultClass = PseudoColor;
|
xnestDefaultClass = PseudoColor;
|
||||||
xnestUserDefaultClass = True;
|
xnestUserDefaultClass = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "TrueColor")) {
|
else if (!strcmp(argv[i], "TrueColor")) {
|
||||||
xnestDefaultClass = TrueColor;
|
xnestDefaultClass = TrueColor;
|
||||||
xnestUserDefaultClass = True;
|
xnestUserDefaultClass = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "DirectColor")) {
|
else if (!strcmp(argv[i], "DirectColor")) {
|
||||||
xnestDefaultClass = DirectColor;
|
xnestDefaultClass = DirectColor;
|
||||||
xnestUserDefaultClass = True;
|
xnestUserDefaultClass = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +101,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||||
if (!strcmp(argv[i], "-cc")) {
|
if (!strcmp(argv[i], "-cc")) {
|
||||||
if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultClass) == 1) {
|
if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultClass) == 1) {
|
||||||
if (xnestDefaultClass >= 0 && xnestDefaultClass <= 5) {
|
if (xnestDefaultClass >= 0 && xnestDefaultClass <= 5) {
|
||||||
xnestUserDefaultClass = True;
|
xnestUserDefaultClass = TRUE;
|
||||||
/* lex the OS layer process it as well, so return 0 */
|
/* lex the OS layer process it as well, so return 0 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,22 +110,19 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||||
if (!strcmp(argv[i], "-depth")) {
|
if (!strcmp(argv[i], "-depth")) {
|
||||||
if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultDepth) == 1) {
|
if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultDepth) == 1) {
|
||||||
if (xnestDefaultDepth > 0) {
|
if (xnestDefaultDepth > 0) {
|
||||||
xnestUserDefaultDepth = True;
|
xnestUserDefaultDepth = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-sss")) {
|
if (!strcmp(argv[i], "-sss")) {
|
||||||
xnestSoftwareScreenSaver = True;
|
xnestSoftwareScreenSaver = TRUE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-geometry")) {
|
if (!strcmp(argv[i], "-geometry")) {
|
||||||
if (++i < argc) {
|
if (++i < argc) {
|
||||||
xnestUserGeometry = XParseGeometry(argv[i],
|
if (xnestParseGeometry(argv[i], &xnestGeometry))
|
||||||
&xnestX, &xnestY,
|
|
||||||
&xnestWidth, &xnestHeight);
|
|
||||||
if (xnestUserGeometry)
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -141,7 +130,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||||
if (!strcmp(argv[i], "-bw")) {
|
if (!strcmp(argv[i], "-bw")) {
|
||||||
if (++i < argc && sscanf(argv[i], "%i", &xnestBorderWidth) == 1) {
|
if (++i < argc && sscanf(argv[i], "%i", &xnestBorderWidth) == 1) {
|
||||||
if (xnestBorderWidth >= 0) {
|
if (xnestBorderWidth >= 0) {
|
||||||
xnestUserBorderWidth = True;
|
xnestUserBorderWidth = TRUE;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +156,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-install")) {
|
if (!strcmp(argv[i], "-install")) {
|
||||||
xnestDoDirectColormaps = True;
|
xnestDoDirectColormaps = TRUE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-parent")) {
|
if (!strcmp(argv[i], "-parent")) {
|
||||||
|
@ -183,7 +172,6 @@ void
|
||||||
ddxUseMsg(void)
|
ddxUseMsg(void)
|
||||||
{
|
{
|
||||||
ErrorF("-display string display name of the real server\n");
|
ErrorF("-display string display name of the real server\n");
|
||||||
ErrorF("-sync sinchronize with the real server\n");
|
|
||||||
ErrorF("-full utilize full regeneration\n");
|
ErrorF("-full utilize full regeneration\n");
|
||||||
ErrorF("-class string default visual class\n");
|
ErrorF("-class string default visual class\n");
|
||||||
ErrorF("-depth int default depth\n");
|
ErrorF("-depth int default depth\n");
|
||||||
|
|
|
@ -19,17 +19,13 @@ is" without express or implied warranty.
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
|
|
||||||
extern char *xnestDisplayName;
|
extern char *xnestDisplayName;
|
||||||
extern Bool xnestSynchronize;
|
|
||||||
extern Bool xnestFullGeneration;
|
extern Bool xnestFullGeneration;
|
||||||
extern int xnestDefaultClass;
|
extern int xnestDefaultClass;
|
||||||
extern Bool xnestUserDefaultClass;
|
extern Bool xnestUserDefaultClass;
|
||||||
extern int xnestDefaultDepth;
|
extern int xnestDefaultDepth;
|
||||||
extern Bool xnestUserDefaultDepth;
|
extern Bool xnestUserDefaultDepth;
|
||||||
extern Bool xnestSoftwareScreenSaver;
|
extern Bool xnestSoftwareScreenSaver;
|
||||||
extern int xnestX;
|
extern xRectangle xnestGeometry;
|
||||||
extern int xnestY;
|
|
||||||
extern unsigned int xnestWidth;
|
|
||||||
extern unsigned int xnestHeight;
|
|
||||||
extern int xnestUserGeometry;
|
extern int xnestUserGeometry;
|
||||||
extern int xnestBorderWidth;
|
extern int xnestBorderWidth;
|
||||||
extern Bool xnestUserBorderWidth;
|
extern Bool xnestUserBorderWidth;
|
||||||
|
|
221
hw/xnest/Color.c
221
hw/xnest/Color.c
|
@ -26,15 +26,16 @@ is" without express or implied warranty.
|
||||||
#include "colormapst.h"
|
#include "colormapst.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include "Visual.h"
|
|
||||||
#include "XNWindow.h"
|
#include "XNWindow.h"
|
||||||
#include "Args.h"
|
#include "Args.h"
|
||||||
|
|
||||||
|
#include <xcb/xcb_icccm.h>
|
||||||
|
|
||||||
DevPrivateKeyRec xnestColormapPrivateKeyRec;
|
DevPrivateKeyRec xnestColormapPrivateKeyRec;
|
||||||
|
|
||||||
static DevPrivateKeyRec cmapScrPrivateKeyRec;
|
static DevPrivateKeyRec cmapScrPrivateKeyRec;
|
||||||
|
@ -44,59 +45,79 @@ static DevPrivateKeyRec cmapScrPrivateKeyRec;
|
||||||
#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
|
#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
|
||||||
#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
|
#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
|
||||||
|
|
||||||
|
static Bool loadColormap(ColormapPtr pCmap, int ncolors, uint32_t *colors)
|
||||||
|
{
|
||||||
|
xcb_generic_error_t *err = NULL;
|
||||||
|
xcb_query_colors_reply_t *reply = xcb_query_colors_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_query_colors(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xnestColormap(pCmap),
|
||||||
|
ncolors,
|
||||||
|
colors),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (!reply) {
|
||||||
|
LogMessage(X_WARNING, "loadColormap: missing reply for QueryColors request\n");
|
||||||
|
free(colors);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xcb_query_colors_colors_length(reply) != ncolors) {
|
||||||
|
LogMessage(X_WARNING, "loadColormap: received wrong number of entries: %d - expected %d\n",
|
||||||
|
xcb_query_colors_colors_length(reply), ncolors);
|
||||||
|
free(reply);
|
||||||
|
free(colors);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_rgb_t *rgb = xcb_query_colors_colors(reply);
|
||||||
|
for (int i = 0; i < ncolors; i++) {
|
||||||
|
pCmap->red[i].co.local.red = rgb[i].red;
|
||||||
|
pCmap->green[i].co.local.green = rgb[i].green;
|
||||||
|
pCmap->blue[i].co.local.blue = rgb[i].blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(colors);
|
||||||
|
free(reply);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xnestCreateColormap(ColormapPtr pCmap)
|
xnestCreateColormap(ColormapPtr pCmap)
|
||||||
{
|
{
|
||||||
VisualPtr pVisual;
|
VisualPtr pVisual = pCmap->pVisual;
|
||||||
XColor *colors;
|
int ncolors = pVisual->ColormapEntries;
|
||||||
int i, ncolors;
|
|
||||||
Pixel red, green, blue;
|
|
||||||
Pixel redInc, greenInc, blueInc;
|
|
||||||
|
|
||||||
pVisual = pCmap->pVisual;
|
uint32_t const cmap = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
ncolors = pVisual->ColormapEntries;
|
xnestColormapPriv(pCmap)->colormap = cmap;
|
||||||
|
|
||||||
xnestColormapPriv(pCmap)->colormap =
|
xcb_create_colormap(xnestUpstreamInfo.conn,
|
||||||
XCreateColormap(xnestDisplay,
|
(pVisual->class & DynamicClass) ? XCB_COLORMAP_ALLOC_ALL : XCB_COLORMAP_ALLOC_NONE,
|
||||||
|
cmap,
|
||||||
xnestDefaultWindows[pCmap->pScreen->myNum],
|
xnestDefaultWindows[pCmap->pScreen->myNum],
|
||||||
xnestVisual(pVisual),
|
xnest_visual_map_to_host(pVisual->vid));
|
||||||
(pVisual->class & DynamicClass) ? AllocAll : AllocNone);
|
|
||||||
|
|
||||||
switch (pVisual->class) {
|
switch (pVisual->class) {
|
||||||
case StaticGray: /* read only */
|
case StaticGray: /* read only */
|
||||||
colors = xallocarray(ncolors, sizeof(XColor));
|
|
||||||
for (i = 0; i < ncolors; i++)
|
|
||||||
colors[i].pixel = i;
|
|
||||||
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
|
|
||||||
for (i = 0; i < ncolors; i++) {
|
|
||||||
pCmap->red[i].co.local.red = colors[i].red;
|
|
||||||
pCmap->red[i].co.local.green = colors[i].red;
|
|
||||||
pCmap->red[i].co.local.blue = colors[i].red;
|
|
||||||
}
|
|
||||||
free(colors);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StaticColor: /* read only */
|
case StaticColor: /* read only */
|
||||||
colors = xallocarray(ncolors, sizeof(XColor));
|
{
|
||||||
for (i = 0; i < ncolors; i++)
|
uint32_t *colors = malloc(ncolors * sizeof(uint32_t));
|
||||||
colors[i].pixel = i;
|
for (int i = 0; i < ncolors; i++)
|
||||||
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
|
colors[i] = i;
|
||||||
for (i = 0; i < ncolors; i++) {
|
return loadColormap(pCmap, ncolors, colors);
|
||||||
pCmap->red[i].co.local.red = colors[i].red;
|
}
|
||||||
pCmap->red[i].co.local.green = colors[i].green;
|
break;
|
||||||
pCmap->red[i].co.local.blue = colors[i].blue;
|
|
||||||
}
|
|
||||||
free(colors);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TrueColor: /* read only */
|
case TrueColor: /* read only */
|
||||||
colors = xallocarray(ncolors, sizeof(XColor));
|
{
|
||||||
red = green = blue = 0L;
|
uint32_t *colors = malloc(ncolors * sizeof(uint32_t));
|
||||||
redInc = lowbit(pVisual->redMask);
|
Pixel red = 0, redInc = lowbit(pVisual->redMask);
|
||||||
greenInc = lowbit(pVisual->greenMask);
|
Pixel green = 0, greenInc = lowbit(pVisual->greenMask);
|
||||||
blueInc = lowbit(pVisual->blueMask);
|
Pixel blue = 0, blueInc = lowbit(pVisual->blueMask);
|
||||||
for (i = 0; i < ncolors; i++) {
|
|
||||||
colors[i].pixel = red | green | blue;
|
for (int i = 0; i < ncolors; i++) {
|
||||||
|
colors[i] = red | green | blue;
|
||||||
red += redInc;
|
red += redInc;
|
||||||
if (red > pVisual->redMask)
|
if (red > pVisual->redMask)
|
||||||
red = 0L;
|
red = 0L;
|
||||||
|
@ -107,14 +128,9 @@ xnestCreateColormap(ColormapPtr pCmap)
|
||||||
if (blue > pVisual->blueMask)
|
if (blue > pVisual->blueMask)
|
||||||
blue = 0L;
|
blue = 0L;
|
||||||
}
|
}
|
||||||
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
|
return loadColormap(pCmap, ncolors, colors);
|
||||||
for (i = 0; i < ncolors; i++) {
|
}
|
||||||
pCmap->red[i].co.local.red = colors[i].red;
|
break;
|
||||||
pCmap->green[i].co.local.green = colors[i].green;
|
|
||||||
pCmap->blue[i].co.local.blue = colors[i].blue;
|
|
||||||
}
|
|
||||||
free(colors);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GrayScale: /* read and write */
|
case GrayScale: /* read and write */
|
||||||
break;
|
break;
|
||||||
|
@ -126,17 +142,17 @@ xnestCreateColormap(ColormapPtr pCmap)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestDestroyColormap(ColormapPtr pCmap)
|
xnestDestroyColormap(ColormapPtr pCmap)
|
||||||
{
|
{
|
||||||
XFreeColormap(xnestDisplay, xnestColormap(pCmap));
|
xcb_free_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SEARCH_PREDICATE \
|
#define SEARCH_PREDICATE \
|
||||||
(xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
|
(xnestWindow(pWin) != XCB_WINDOW_NONE && wColormap(pWin) == icws->cmapIDs[i])
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xnestCountInstalledColormapWindows(WindowPtr pWin, void *ptr)
|
xnestCountInstalledColormapWindows(WindowPtr pWin, void *ptr)
|
||||||
|
@ -175,19 +191,19 @@ static Bool
|
||||||
xnestSameInstalledColormapWindows(Window *windows, int numWindows)
|
xnestSameInstalledColormapWindows(Window *windows, int numWindows)
|
||||||
{
|
{
|
||||||
if (xnestNumOldInstalledColormapWindows != numWindows)
|
if (xnestNumOldInstalledColormapWindows != numWindows)
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
if (xnestOldInstalledColormapWindows == windows)
|
if (xnestOldInstalledColormapWindows == windows)
|
||||||
return True;
|
return TRUE;
|
||||||
|
|
||||||
if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
|
if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
if (memcmp(xnestOldInstalledColormapWindows, windows,
|
if (memcmp(xnestOldInstalledColormapWindows, windows,
|
||||||
numWindows * sizeof(Window)))
|
numWindows * sizeof(Window)))
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -217,22 +233,10 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
|
||||||
if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
|
if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
|
||||||
free(xnestOldInstalledColormapWindows);
|
free(xnestOldInstalledColormapWindows);
|
||||||
|
|
||||||
#ifdef _XSERVER64
|
xnestWMColormapWindows(xnestUpstreamInfo.conn,
|
||||||
{
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
int i;
|
icws.windows,
|
||||||
Window64 *windows = xallocarray(numWindows, sizeof(Window64));
|
numWindows);
|
||||||
|
|
||||||
for (i = 0; i < numWindows; ++i)
|
|
||||||
windows[i] = icws.windows[i];
|
|
||||||
XSetWMColormapWindows(xnestDisplay,
|
|
||||||
xnestDefaultWindows[pScreen->myNum], windows,
|
|
||||||
numWindows);
|
|
||||||
free(windows);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
|
|
||||||
icws.windows, numWindows);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xnestOldInstalledColormapWindows = icws.windows;
|
xnestOldInstalledColormapWindows = icws.windows;
|
||||||
xnestNumOldInstalledColormapWindows = icws.numWindows;
|
xnestNumOldInstalledColormapWindows = icws.numWindows;
|
||||||
|
@ -244,13 +248,12 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
|
||||||
*/
|
*/
|
||||||
if (icws.numWindows) {
|
if (icws.numWindows) {
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
Visual *visual;
|
|
||||||
ColormapPtr pCmap;
|
ColormapPtr pCmap;
|
||||||
|
|
||||||
pWin = xnestWindowPtr(icws.windows[0]);
|
pWin = xnestWindowPtr(icws.windows[0]);
|
||||||
visual = xnestVisualFromID(pScreen, wVisual(pWin));
|
|
||||||
|
|
||||||
if (visual == xnestDefaultVisual(pScreen))
|
if (xnest_visual_map_to_host(wVisual(pWin)) ==
|
||||||
|
xnest_visual_map_to_host(pScreen->rootVisual))
|
||||||
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
||||||
X11_RESTYPE_COLORMAP, serverClient,
|
X11_RESTYPE_COLORMAP, serverClient,
|
||||||
DixUseAccess);
|
DixUseAccess);
|
||||||
|
@ -259,9 +262,11 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
|
||||||
pScreen->defColormap, X11_RESTYPE_COLORMAP,
|
pScreen->defColormap, X11_RESTYPE_COLORMAP,
|
||||||
serverClient, DixUseAccess);
|
serverClient, DixUseAccess);
|
||||||
|
|
||||||
XSetWindowColormap(xnestDisplay,
|
uint32_t cmap = xnestColormap(pCmap);
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
xnestColormap(pCmap));
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
XCB_CW_COLORMAP,
|
||||||
|
&cmap);
|
||||||
}
|
}
|
||||||
#endif /* DUMB_WINDOW_MANAGERS */
|
#endif /* DUMB_WINDOW_MANAGERS */
|
||||||
}
|
}
|
||||||
|
@ -274,19 +279,10 @@ xnestSetScreenSaverColormapWindow(ScreenPtr pScreen)
|
||||||
{
|
{
|
||||||
free(xnestOldInstalledColormapWindows);
|
free(xnestOldInstalledColormapWindows);
|
||||||
|
|
||||||
#ifdef _XSERVER64
|
xnestWMColormapWindows(xnestUpstreamInfo.conn,
|
||||||
{
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
Window64 window;
|
&xnestScreenSaverWindows[pScreen->myNum],
|
||||||
|
1);
|
||||||
window = xnestScreenSaverWindows[pScreen->myNum];
|
|
||||||
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
|
|
||||||
&window, 1);
|
|
||||||
xnestScreenSaverWindows[pScreen->myNum] = window;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
|
|
||||||
&xnestScreenSaverWindows[pScreen->myNum], 1);
|
|
||||||
#endif /* _XSERVER64 */
|
|
||||||
|
|
||||||
xnestOldInstalledColormapWindows = NULL;
|
xnestOldInstalledColormapWindows = NULL;
|
||||||
xnestNumOldInstalledColormapWindows = 0;
|
xnestNumOldInstalledColormapWindows = 0;
|
||||||
|
@ -311,7 +307,7 @@ xnestDirectInstallColormaps(ScreenPtr pScreen)
|
||||||
dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], X11_RESTYPE_COLORMAP,
|
dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], X11_RESTYPE_COLORMAP,
|
||||||
serverClient, DixInstallAccess);
|
serverClient, DixInstallAccess);
|
||||||
if (pCmap)
|
if (pCmap)
|
||||||
XInstallColormap(xnestDisplay, xnestColormap(pCmap));
|
xcb_install_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +328,7 @@ xnestDirectUninstallColormaps(ScreenPtr pScreen)
|
||||||
dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], X11_RESTYPE_COLORMAP,
|
dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], X11_RESTYPE_COLORMAP,
|
||||||
serverClient, DixUninstallAccess);
|
serverClient, DixUninstallAccess);
|
||||||
if (pCmap)
|
if (pCmap)
|
||||||
XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
|
xcb_uninstall_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +341,7 @@ xnestInstallColormap(ColormapPtr pCmap)
|
||||||
xnestDirectUninstallColormaps(pCmap->pScreen);
|
xnestDirectUninstallColormaps(pCmap->pScreen);
|
||||||
|
|
||||||
/* Uninstall pInstalledMap. Notify all interested parties. */
|
/* Uninstall pInstalledMap. Notify all interested parties. */
|
||||||
if (pOldCmap != (ColormapPtr) None)
|
if (pOldCmap != (ColormapPtr) XCB_COLORMAP_NONE)
|
||||||
WalkTree(pCmap->pScreen, TellLostMap, (void *) &pOldCmap->mid);
|
WalkTree(pCmap->pScreen, TellLostMap, (void *) &pOldCmap->mid);
|
||||||
|
|
||||||
SetInstalledColormap(pCmap->pScreen, pCmap);
|
SetInstalledColormap(pCmap->pScreen, pCmap);
|
||||||
|
@ -372,7 +368,7 @@ xnestUninstallColormap(ColormapPtr pCmap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool xnestInstalledDefaultColormap = False;
|
static Bool xnestInstalledDefaultColormap = FALSE;
|
||||||
|
|
||||||
int
|
int
|
||||||
xnestListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmapIDs)
|
xnestListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmapIDs)
|
||||||
|
@ -389,25 +385,10 @@ void
|
||||||
xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem * pColors)
|
xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem * pColors)
|
||||||
{
|
{
|
||||||
if (pCmap->pVisual->class & DynamicClass)
|
if (pCmap->pVisual->class & DynamicClass)
|
||||||
#ifdef _XSERVER64
|
xcb_store_colors(xnestUpstreamInfo.conn,
|
||||||
{
|
xnestColormap(pCmap),
|
||||||
int i;
|
nColors,
|
||||||
XColor *pColors64 = xallocarray(nColors, sizeof(XColor));
|
(xcb_coloritem_t*) pColors);
|
||||||
|
|
||||||
for (i = 0; i < nColors; ++i) {
|
|
||||||
pColors64[i].pixel = pColors[i].pixel;
|
|
||||||
pColors64[i].red = pColors[i].red;
|
|
||||||
pColors64[i].green = pColors[i].green;
|
|
||||||
pColors64[i].blue = pColors[i].blue;
|
|
||||||
pColors64[i].flags = pColors[i].flags;
|
|
||||||
}
|
|
||||||
XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
|
|
||||||
free(pColors64);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
XStoreColors(xnestDisplay, xnestColormap(pCmap),
|
|
||||||
(XColor *) pColors, nColors);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -474,7 +455,7 @@ xnestCreateDefaultColormap(ScreenPtr pScreen)
|
||||||
(pVisual->class & DynamicClass) ? AllocNone : AllocAll,
|
(pVisual->class & DynamicClass) ? AllocNone : AllocAll,
|
||||||
0)
|
0)
|
||||||
!= Success)
|
!= Success)
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
wp = pScreen->whitePixel;
|
wp = pScreen->whitePixel;
|
||||||
bp = pScreen->blackPixel;
|
bp = pScreen->blackPixel;
|
||||||
|
@ -486,7 +467,7 @@ xnestCreateDefaultColormap(ScreenPtr pScreen)
|
||||||
pScreen->blackPixel = bp;
|
pScreen->blackPixel = bp;
|
||||||
(*pScreen->InstallColormap) (pCmap);
|
(*pScreen->InstallColormap) (pCmap);
|
||||||
|
|
||||||
xnestInstalledDefaultColormap = True;
|
xnestInstalledDefaultColormap = TRUE;
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,11 @@ is" without express or implied warranty.
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
#include "mipointrst.h"
|
#include "mipointrst.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "XNCursor.h"
|
#include "XNCursor.h"
|
||||||
#include "Visual.h"
|
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
#include "Args.h"
|
#include "Args.h"
|
||||||
|
|
||||||
|
@ -42,97 +41,87 @@ xnestCursorFuncRec xnestCursorFuncs = { NULL };
|
||||||
Bool
|
Bool
|
||||||
xnestRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
|
xnestRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
|
||||||
{
|
{
|
||||||
XImage *ximage;
|
uint32_t valuemask = XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FOREGROUND
|
||||||
Pixmap source, mask;
|
| XCB_GC_BACKGROUND | XCB_GC_CLIP_MASK;
|
||||||
XColor fg_color, bg_color;
|
|
||||||
unsigned long valuemask;
|
|
||||||
XGCValues values;
|
|
||||||
|
|
||||||
valuemask = GCFunction |
|
XnGCValues values = {
|
||||||
GCPlaneMask | GCForeground | GCBackground | GCClipMask;
|
.function = XCB_GX_COPY,
|
||||||
|
.plane_mask = ((unsigned long)~0L),
|
||||||
|
.foreground = 1L,
|
||||||
|
};
|
||||||
|
|
||||||
values.function = GXcopy;
|
xnChangeGC(xnestUpstreamInfo.conn, xnestBitmapGC, values, valuemask);
|
||||||
values.plane_mask = AllPlanes;
|
|
||||||
values.foreground = 1L;
|
|
||||||
values.background = 0L;
|
|
||||||
values.clip_mask = None;
|
|
||||||
|
|
||||||
XChangeGC(xnestDisplay, xnestBitmapGC, valuemask, &values);
|
uint32_t const winId = xnestDefaultWindows[pScreen->myNum];
|
||||||
|
|
||||||
source = XCreatePixmap(xnestDisplay,
|
Pixmap const source = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
xcb_create_pixmap(xnestUpstreamInfo.conn, 1, source, winId, pCursor->bits->width, pCursor->bits->height);
|
||||||
pCursor->bits->width, pCursor->bits->height, 1);
|
|
||||||
|
|
||||||
mask = XCreatePixmap(xnestDisplay,
|
Pixmap const mask = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
xcb_create_pixmap(xnestUpstreamInfo.conn, 1, mask, winId, pCursor->bits->width, pCursor->bits->height);
|
||||||
pCursor->bits->width, pCursor->bits->height, 1);
|
|
||||||
|
|
||||||
ximage = XCreateImage(xnestDisplay,
|
int const pixmap_len = BitmapBytePad(pCursor->bits->width) * pCursor->bits->height;
|
||||||
xnestDefaultVisual(pScreen),
|
|
||||||
1, XYBitmap, 0,
|
|
||||||
(char *) pCursor->bits->source,
|
|
||||||
pCursor->bits->width,
|
|
||||||
pCursor->bits->height, BitmapPad(xnestDisplay), 0);
|
|
||||||
|
|
||||||
XPutImage(xnestDisplay, source, xnestBitmapGC, ximage,
|
xcb_put_image(xnestUpstreamInfo.conn,
|
||||||
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
|
XCB_IMAGE_FORMAT_XY_BITMAP,
|
||||||
|
source,
|
||||||
|
xnestBitmapGC,
|
||||||
|
pCursor->bits->width,
|
||||||
|
pCursor->bits->height,
|
||||||
|
0, // x
|
||||||
|
0, // y
|
||||||
|
0, // left_pad
|
||||||
|
1, // depth
|
||||||
|
pixmap_len,
|
||||||
|
(uint8_t*) pCursor->bits->source);
|
||||||
|
|
||||||
XFree(ximage);
|
xcb_put_image(xnestUpstreamInfo.conn,
|
||||||
|
XCB_IMAGE_FORMAT_XY_BITMAP,
|
||||||
ximage = XCreateImage(xnestDisplay,
|
mask,
|
||||||
xnestDefaultVisual(pScreen),
|
xnestBitmapGC,
|
||||||
1, XYBitmap, 0,
|
pCursor->bits->width,
|
||||||
(char *) pCursor->bits->mask,
|
pCursor->bits->height,
|
||||||
pCursor->bits->width,
|
0, // x
|
||||||
pCursor->bits->height, BitmapPad(xnestDisplay), 0);
|
0, // y
|
||||||
|
0, // left_pad
|
||||||
XPutImage(xnestDisplay, mask, xnestBitmapGC, ximage,
|
1, // depth
|
||||||
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
|
pixmap_len,
|
||||||
|
(uint8_t*) pCursor->bits->mask);
|
||||||
XFree(ximage);
|
|
||||||
|
|
||||||
fg_color.red = pCursor->foreRed;
|
|
||||||
fg_color.green = pCursor->foreGreen;
|
|
||||||
fg_color.blue = pCursor->foreBlue;
|
|
||||||
|
|
||||||
bg_color.red = pCursor->backRed;
|
|
||||||
bg_color.green = pCursor->backGreen;
|
|
||||||
bg_color.blue = pCursor->backBlue;
|
|
||||||
|
|
||||||
xnestSetCursorPriv(pCursor, pScreen, calloc(1, sizeof(xnestPrivCursor)));
|
xnestSetCursorPriv(pCursor, pScreen, calloc(1, sizeof(xnestPrivCursor)));
|
||||||
xnestCursor(pCursor, pScreen) =
|
uint32_t cursor = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
XCreatePixmapCursor(xnestDisplay, source, mask, &fg_color, &bg_color,
|
xcb_create_cursor(xnestUpstreamInfo.conn, cursor, source, mask,
|
||||||
pCursor->bits->xhot, pCursor->bits->yhot);
|
pCursor->foreRed, pCursor->foreGreen, pCursor->foreBlue,
|
||||||
|
pCursor->backRed, pCursor->backGreen, pCursor->backBlue,
|
||||||
|
pCursor->bits->xhot, pCursor->bits->yhot);
|
||||||
|
|
||||||
XFreePixmap(xnestDisplay, source);
|
xnestCursor(pCursor, pScreen) = cursor;
|
||||||
XFreePixmap(xnestDisplay, mask);
|
|
||||||
|
|
||||||
return True;
|
xcb_free_pixmap(xnestUpstreamInfo.conn, source);
|
||||||
|
xcb_free_pixmap(xnestUpstreamInfo.conn, mask);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xnestUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
|
xnestUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
|
||||||
{
|
{
|
||||||
XFreeCursor(xnestDisplay, xnestCursor(pCursor, pScreen));
|
xcb_free_cursor(xnestUpstreamInfo.conn, xnestCursor(pCursor, pScreen));
|
||||||
free(xnestGetCursorPriv(pCursor, pScreen));
|
free(xnestGetCursorPriv(pCursor, pScreen));
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
|
xnestRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
|
||||||
{
|
{
|
||||||
XColor fg_color, bg_color;
|
xcb_recolor_cursor(xnestUpstreamInfo.conn,
|
||||||
|
xnestCursor(pCursor, pScreen),
|
||||||
fg_color.red = pCursor->foreRed;
|
pCursor->foreRed,
|
||||||
fg_color.green = pCursor->foreGreen;
|
pCursor->foreGreen,
|
||||||
fg_color.blue = pCursor->foreBlue;
|
pCursor->foreBlue,
|
||||||
|
pCursor->backRed,
|
||||||
bg_color.red = pCursor->backRed;
|
pCursor->backGreen,
|
||||||
bg_color.green = pCursor->backGreen;
|
pCursor->backBlue);
|
||||||
bg_color.blue = pCursor->backBlue;
|
|
||||||
|
|
||||||
XRecolorCursor(xnestDisplay,
|
|
||||||
xnestCursor(pCursor, pScreen), &fg_color, &bg_color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -140,9 +129,12 @@ xnestSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x,
|
||||||
int y)
|
int y)
|
||||||
{
|
{
|
||||||
if (pCursor) {
|
if (pCursor) {
|
||||||
XDefineCursor(xnestDisplay,
|
uint32_t cursor = xnestCursor(pCursor, pScreen);
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
|
||||||
xnestCursor(pCursor, pScreen));
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
XCB_CW_CURSOR,
|
||||||
|
&cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ is" without express or implied warranty.
|
||||||
#include "scrnintstr.h"
|
#include "scrnintstr.h"
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Init.h"
|
#include "Init.h"
|
||||||
|
@ -39,173 +39,111 @@ is" without express or implied warranty.
|
||||||
#include "icon"
|
#include "icon"
|
||||||
#include "screensaver"
|
#include "screensaver"
|
||||||
|
|
||||||
Display *xnestDisplay = NULL;
|
|
||||||
XVisualInfo *xnestVisuals;
|
|
||||||
int xnestNumVisuals;
|
|
||||||
int xnestDefaultVisualIndex;
|
|
||||||
Colormap *xnestDefaultColormaps;
|
Colormap *xnestDefaultColormaps;
|
||||||
static uint16_t xnestNumDefaultColormaps;
|
|
||||||
int *xnestDepths;
|
|
||||||
int xnestNumDepths;
|
|
||||||
XPixmapFormatValues *xnestPixmapFormats;
|
|
||||||
int xnestNumPixmapFormats;
|
int xnestNumPixmapFormats;
|
||||||
Pixel xnestBlackPixel;
|
|
||||||
Pixel xnestWhitePixel;
|
|
||||||
Drawable xnestDefaultDrawables[MAXDEPTH + 1];
|
Drawable xnestDefaultDrawables[MAXDEPTH + 1];
|
||||||
Pixmap xnestIconBitmap;
|
Pixmap xnestIconBitmap;
|
||||||
Pixmap xnestScreenSaverPixmap;
|
Pixmap xnestScreenSaverPixmap;
|
||||||
XlibGC xnestBitmapGC;
|
uint32_t xnestBitmapGC;
|
||||||
unsigned long xnestEventMask;
|
uint32_t xnestEventMask;
|
||||||
|
|
||||||
static int _X_NORETURN
|
|
||||||
x_io_error_handler(Display * dpy)
|
|
||||||
{
|
|
||||||
ErrorF("Lost connection to X server: %s\n", strerror(errno));
|
|
||||||
CloseWellKnownConnections();
|
|
||||||
OsCleanup(1);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestOpenDisplay(int argc, char *argv[])
|
xnestOpenDisplay(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
XVisualInfo vi;
|
int i;
|
||||||
long mask;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
if (!xnestDoFullGeneration)
|
if (!xnestDoFullGeneration)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
XSetIOErrorHandler(x_io_error_handler);
|
|
||||||
|
|
||||||
xnestCloseDisplay();
|
xnestCloseDisplay();
|
||||||
|
|
||||||
xnestDisplay = XOpenDisplay(xnestDisplayName);
|
if (!xnest_upstream_setup(xnestDisplayName))
|
||||||
if (xnestDisplay == NULL)
|
FatalError("Unable to open display \"%s\".\n", xnestDisplayName);
|
||||||
FatalError("Unable to open display \"%s\".\n",
|
|
||||||
XDisplayName(xnestDisplayName));
|
|
||||||
|
|
||||||
if (xnestSynchronize)
|
|
||||||
XSynchronize(xnestDisplay, True);
|
|
||||||
|
|
||||||
mask = VisualScreenMask;
|
|
||||||
vi.screen = DefaultScreen(xnestDisplay);
|
|
||||||
xnestVisuals = XGetVisualInfo(xnestDisplay, mask, &vi, &xnestNumVisuals);
|
|
||||||
if (xnestNumVisuals == 0 || xnestVisuals == NULL)
|
|
||||||
FatalError("Unable to find any visuals.\n");
|
|
||||||
|
|
||||||
if (xnestUserDefaultClass || xnestUserDefaultDepth) {
|
|
||||||
xnestDefaultVisualIndex = UNDEFINED;
|
|
||||||
for (i = 0; i < xnestNumVisuals; i++)
|
|
||||||
if ((!xnestUserDefaultClass ||
|
|
||||||
xnestVisuals[i].class == xnestDefaultClass)
|
|
||||||
&&
|
|
||||||
(!xnestUserDefaultDepth ||
|
|
||||||
xnestVisuals[i].depth == xnestDefaultDepth)) {
|
|
||||||
xnestDefaultVisualIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (xnestDefaultVisualIndex == UNDEFINED)
|
|
||||||
FatalError("Unable to find desired default visual.\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vi.visualid = XVisualIDFromVisual(DefaultVisual(xnestDisplay,
|
|
||||||
DefaultScreen
|
|
||||||
(xnestDisplay)));
|
|
||||||
xnestDefaultVisualIndex = 0;
|
|
||||||
for (i = 0; i < xnestNumVisuals; i++)
|
|
||||||
if (vi.visualid == xnestVisuals[i].visualid)
|
|
||||||
xnestDefaultVisualIndex = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
xnestNumDefaultColormaps = xnestNumVisuals;
|
|
||||||
xnestDefaultColormaps = xallocarray(xnestNumDefaultColormaps,
|
|
||||||
sizeof(Colormap));
|
|
||||||
for (i = 0; i < xnestNumDefaultColormaps; i++)
|
|
||||||
xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay,
|
|
||||||
DefaultRootWindow
|
|
||||||
(xnestDisplay),
|
|
||||||
xnestVisuals[i].visual,
|
|
||||||
AllocNone);
|
|
||||||
|
|
||||||
xnestDepths = XListDepths(xnestDisplay, DefaultScreen(xnestDisplay),
|
|
||||||
&xnestNumDepths);
|
|
||||||
|
|
||||||
xnestPixmapFormats = XListPixmapFormats(xnestDisplay,
|
|
||||||
&xnestNumPixmapFormats);
|
|
||||||
|
|
||||||
xnestBlackPixel = BlackPixel(xnestDisplay, DefaultScreen(xnestDisplay));
|
|
||||||
xnestWhitePixel = WhitePixel(xnestDisplay, DefaultScreen(xnestDisplay));
|
|
||||||
|
|
||||||
if (xnestParentWindow != (Window) 0)
|
if (xnestParentWindow != (Window) 0)
|
||||||
xnestEventMask = StructureNotifyMask;
|
xnestEventMask = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||||
else
|
else
|
||||||
xnestEventMask = 0L;
|
xnestEventMask = 0L;
|
||||||
|
|
||||||
for (i = 0; i <= MAXDEPTH; i++)
|
for (i = 0; i <= MAXDEPTH; i++)
|
||||||
xnestDefaultDrawables[i] = None;
|
xnestDefaultDrawables[i] = XCB_WINDOW_NONE;
|
||||||
|
|
||||||
for (i = 0; i < xnestNumPixmapFormats; i++)
|
xcb_format_t *fmt = xcb_setup_pixmap_formats(xnestUpstreamInfo.setup);
|
||||||
for (j = 0; j < xnestNumDepths; j++)
|
const xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(xnestUpstreamInfo.setup);
|
||||||
if (xnestPixmapFormats[i].depth == 1 ||
|
for(; fmt != fmtend; ++fmt) {
|
||||||
xnestPixmapFormats[i].depth == xnestDepths[j]) {
|
xcb_depth_iterator_t depth_iter;
|
||||||
xnestDefaultDrawables[xnestPixmapFormats[i].depth] =
|
for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
|
||||||
XCreatePixmap(xnestDisplay, DefaultRootWindow(xnestDisplay),
|
depth_iter.rem;
|
||||||
1, 1, xnestPixmapFormats[i].depth);
|
xcb_depth_next(&depth_iter))
|
||||||
|
{
|
||||||
|
if (fmt->depth == 1 || fmt->depth == depth_iter.data->depth) {
|
||||||
|
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_create_pixmap(xnestUpstreamInfo.conn,
|
||||||
|
fmt->depth,
|
||||||
|
pixmap,
|
||||||
|
xnestUpstreamInfo.screenInfo->root,
|
||||||
|
1, 1);
|
||||||
|
xnestDefaultDrawables[fmt->depth] = pixmap;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xnestBitmapGC = XCreateGC(xnestDisplay, xnestDefaultDrawables[1], 0L, NULL);
|
xnestBitmapGC = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_create_gc(xnestUpstreamInfo.conn,
|
||||||
|
xnestBitmapGC,
|
||||||
|
xnestDefaultDrawables[1],
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!(xnestUserGeometry & XValue))
|
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_X))
|
||||||
xnestX = 0;
|
xnestGeometry.x = 0;
|
||||||
|
|
||||||
if (!(xnestUserGeometry & YValue))
|
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_Y))
|
||||||
xnestY = 0;
|
xnestGeometry.y = 0;
|
||||||
|
|
||||||
if (xnestParentWindow == 0) {
|
if (xnestParentWindow == 0) {
|
||||||
if (!(xnestUserGeometry & WidthValue))
|
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_WIDTH))
|
||||||
xnestWidth = 3 * DisplayWidth(xnestDisplay,
|
xnestGeometry.width = 3 * xnestUpstreamInfo.screenInfo->width_in_pixels / 4;
|
||||||
DefaultScreen(xnestDisplay)) / 4;
|
|
||||||
|
|
||||||
if (!(xnestUserGeometry & HeightValue))
|
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_HEIGHT))
|
||||||
xnestHeight = 3 * DisplayHeight(xnestDisplay,
|
xnestGeometry.height = 3 * xnestUpstreamInfo.screenInfo->height_in_pixels / 4;
|
||||||
DefaultScreen(xnestDisplay)) / 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!xnestUserBorderWidth)
|
if (!xnestUserBorderWidth)
|
||||||
xnestBorderWidth = 1;
|
xnestBorderWidth = 1;
|
||||||
|
|
||||||
xnestIconBitmap =
|
xnestIconBitmap =
|
||||||
XCreateBitmapFromData(xnestDisplay,
|
xnestCreateBitmapFromData(xnestUpstreamInfo.conn,
|
||||||
DefaultRootWindow(xnestDisplay),
|
xnestUpstreamInfo.screenInfo->root,
|
||||||
(char *) icon_bits, icon_width, icon_height);
|
(char *) icon_bits, icon_width, icon_height);
|
||||||
|
|
||||||
xnestScreenSaverPixmap =
|
xnestScreenSaverPixmap =
|
||||||
XCreatePixmapFromBitmapData(xnestDisplay,
|
xnestCreatePixmapFromBitmapData(xnestUpstreamInfo.conn,
|
||||||
DefaultRootWindow(xnestDisplay),
|
xnestUpstreamInfo.screenInfo->root,
|
||||||
(char *) screensaver_bits,
|
(char *) screensaver_bits,
|
||||||
screensaver_width,
|
screensaver_width,
|
||||||
screensaver_height,
|
screensaver_height,
|
||||||
xnestWhitePixel,
|
xnestUpstreamInfo.screenInfo->white_pixel,
|
||||||
xnestBlackPixel,
|
xnestUpstreamInfo.screenInfo->black_pixel,
|
||||||
DefaultDepth(xnestDisplay,
|
xnestUpstreamInfo.screenInfo->root_depth);
|
||||||
DefaultScreen(xnestDisplay)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestCloseDisplay(void)
|
xnestCloseDisplay(void)
|
||||||
{
|
{
|
||||||
if (!xnestDoFullGeneration || !xnestDisplay)
|
if (!xnestDoFullGeneration || !xnestUpstreamInfo.conn)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If xnestDoFullGeneration all x resources will be destroyed upon closing
|
If xnestDoFullGeneration all x resources will be destroyed upon closing
|
||||||
the display connection. There is no need to generate extra protocol.
|
the display connection. There is no need to generate extra protocol.
|
||||||
*/
|
*/
|
||||||
|
free(xnestVisualMap);
|
||||||
|
xnestVisualMap = NULL;
|
||||||
|
xnestNumVisualMap = 0;
|
||||||
|
|
||||||
free(xnestDefaultColormaps);
|
xcb_disconnect(xnestUpstreamInfo.conn);
|
||||||
XFree(xnestVisuals);
|
xnestUpstreamInfo.conn = NULL;
|
||||||
XFree(xnestDepths);
|
xnestUpstreamInfo.screenInfo = NULL;
|
||||||
XFree(xnestPixmapFormats);
|
xnestUpstreamInfo.setup = NULL;
|
||||||
XCloseDisplay(xnestDisplay);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,28 +15,19 @@ is" without express or implied warranty.
|
||||||
#ifndef XNESTCOMMON_H
|
#ifndef XNESTCOMMON_H
|
||||||
#define XNESTCOMMON_H
|
#define XNESTCOMMON_H
|
||||||
|
|
||||||
|
#include "colormap.h"
|
||||||
|
|
||||||
#define UNDEFINED -1
|
#define UNDEFINED -1
|
||||||
|
|
||||||
#define MAXDEPTH 32
|
#define MAXDEPTH 32
|
||||||
#define MAXVISUALSPERDEPTH 256
|
#define MAXVISUALSPERDEPTH 256
|
||||||
|
|
||||||
extern Display *xnestDisplay;
|
|
||||||
extern XVisualInfo *xnestVisuals;
|
|
||||||
extern int xnestNumVisuals;
|
|
||||||
extern int xnestDefaultVisualIndex;
|
|
||||||
extern Colormap *xnestDefaultColormaps;
|
|
||||||
extern int xnestNumDefaultClormaps;
|
|
||||||
extern int *xnestDepths;
|
|
||||||
extern int xnestNumDepths;
|
|
||||||
extern XPixmapFormatValues *xnestPixmapFormats;
|
|
||||||
extern int xnestNumPixmapFormats;
|
extern int xnestNumPixmapFormats;
|
||||||
extern Pixel xnestBlackPixel;
|
|
||||||
extern Pixel xnestWhitePixel;
|
|
||||||
extern Drawable xnestDefaultDrawables[MAXDEPTH + 1];
|
extern Drawable xnestDefaultDrawables[MAXDEPTH + 1];
|
||||||
extern Pixmap xnestIconBitmap;
|
extern Pixmap xnestIconBitmap;
|
||||||
extern Pixmap xnestScreenSaverPixmap;
|
extern Pixmap xnestScreenSaverPixmap;
|
||||||
extern XlibGC xnestBitmapGC;
|
extern uint32_t xnestBitmapGC;
|
||||||
extern unsigned long xnestEventMask;
|
extern uint32_t xnestEventMask;
|
||||||
|
|
||||||
void xnestOpenDisplay(int argc, char *argv[]);
|
void xnestOpenDisplay(int argc, char *argv[]);
|
||||||
void xnestCloseDisplay(void);
|
void xnestCloseDisplay(void);
|
||||||
|
|
|
@ -31,7 +31,7 @@ is" without express or implied warranty.
|
||||||
|
|
||||||
#include "mi.h"
|
#include "mi.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Args.h"
|
#include "Args.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
@ -65,42 +65,6 @@ SetTimeSinceLastInputEvent(void)
|
||||||
lastEventTime = GetTimeInMillis();
|
lastEventTime = GetTimeInMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
|
||||||
xnestExposurePredicate(Display * dpy, XEvent * event, char *args)
|
|
||||||
{
|
|
||||||
return event->type == Expose || event->type == ProcessedExpose;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
|
||||||
xnestNotExposurePredicate(Display * dpy, XEvent * event, char *args)
|
|
||||||
{
|
|
||||||
return !xnestExposurePredicate(dpy, event, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xnestCollectExposures(void)
|
|
||||||
{
|
|
||||||
XEvent X;
|
|
||||||
WindowPtr pWin;
|
|
||||||
RegionRec Rgn;
|
|
||||||
BoxRec Box;
|
|
||||||
|
|
||||||
while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
|
|
||||||
pWin = xnestWindowPtr(X.xexpose.window);
|
|
||||||
|
|
||||||
if (pWin && X.xexpose.width && X.xexpose.height) {
|
|
||||||
Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
|
|
||||||
Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
|
|
||||||
Box.x2 = Box.x1 + X.xexpose.width;
|
|
||||||
Box.y2 = Box.y1 + X.xexpose.height;
|
|
||||||
|
|
||||||
RegionInit(&Rgn, &Box, 1);
|
|
||||||
|
|
||||||
miSendExposures(pWin, &Rgn, Box.x2, Box.y2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestQueueKeyEvent(int type, unsigned int keycode)
|
xnestQueueKeyEvent(int type, unsigned int keycode)
|
||||||
{
|
{
|
||||||
|
@ -108,78 +72,106 @@ xnestQueueKeyEvent(int type, unsigned int keycode)
|
||||||
QueueKeyboardEvents(xnestKeyboardDevice, type, keycode);
|
QueueKeyboardEvents(xnestKeyboardDevice, type, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
#define EVTYPE(tname) tname *ev = (tname*)event
|
||||||
xnestCollectEvents(void)
|
|
||||||
{
|
|
||||||
XEvent X;
|
|
||||||
int valuators[2];
|
|
||||||
ValuatorMask mask;
|
|
||||||
ScreenPtr pScreen;
|
|
||||||
|
|
||||||
while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
|
static void
|
||||||
switch (X.type) {
|
xnest_handle_event(xcb_generic_event_t *event)
|
||||||
|
{
|
||||||
|
if (!event)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (event->response_type & ~0x80) {
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
xnestUpdateModifierState(X.xkey.state);
|
{
|
||||||
xnestQueueKeyEvent(KeyPress, X.xkey.keycode);
|
EVTYPE(xcb_key_press_event_t);
|
||||||
|
xnestUpdateModifierState(ev->state);
|
||||||
|
xnestQueueKeyEvent(KeyPress, ev->detail);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
xnestUpdateModifierState(X.xkey.state);
|
{
|
||||||
xnestQueueKeyEvent(KeyRelease, X.xkey.keycode);
|
EVTYPE(xcb_key_release_event_t);
|
||||||
|
xnestUpdateModifierState(ev->state);
|
||||||
|
xnestQueueKeyEvent(KeyRelease, ev->detail);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
|
{
|
||||||
|
ValuatorMask mask;
|
||||||
|
EVTYPE(xcb_button_press_event_t);
|
||||||
valuator_mask_set_range(&mask, 0, 0, NULL);
|
valuator_mask_set_range(&mask, 0, 0, NULL);
|
||||||
xnestUpdateModifierState(X.xkey.state);
|
xnestUpdateModifierState(ev->state);
|
||||||
lastEventTime = GetTimeInMillis();
|
lastEventTime = GetTimeInMillis();
|
||||||
QueuePointerEvents(xnestPointerDevice, ButtonPress,
|
QueuePointerEvents(xnestPointerDevice, ButtonPress,
|
||||||
X.xbutton.button, POINTER_RELATIVE, &mask);
|
ev->detail, POINTER_RELATIVE, &mask);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
|
{
|
||||||
|
ValuatorMask mask;
|
||||||
|
EVTYPE(xcb_button_release_event_t);
|
||||||
valuator_mask_set_range(&mask, 0, 0, NULL);
|
valuator_mask_set_range(&mask, 0, 0, NULL);
|
||||||
xnestUpdateModifierState(X.xkey.state);
|
xnestUpdateModifierState(ev->state);
|
||||||
lastEventTime = GetTimeInMillis();
|
lastEventTime = GetTimeInMillis();
|
||||||
QueuePointerEvents(xnestPointerDevice, ButtonRelease,
|
QueuePointerEvents(xnestPointerDevice, ButtonRelease,
|
||||||
X.xbutton.button, POINTER_RELATIVE, &mask);
|
ev->detail, POINTER_RELATIVE, &mask);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
valuators[0] = X.xmotion.x;
|
{
|
||||||
valuators[1] = X.xmotion.y;
|
EVTYPE(xcb_motion_notify_event_t);
|
||||||
|
ValuatorMask mask;
|
||||||
|
int valuators[2];
|
||||||
|
valuators[0] = ev->event_x;
|
||||||
|
valuators[1] = ev->event_y;
|
||||||
valuator_mask_set_range(&mask, 0, 2, valuators);
|
valuator_mask_set_range(&mask, 0, 2, valuators);
|
||||||
lastEventTime = GetTimeInMillis();
|
lastEventTime = GetTimeInMillis();
|
||||||
QueuePointerEvents(xnestPointerDevice, MotionNotify,
|
QueuePointerEvents(xnestPointerDevice, MotionNotify,
|
||||||
0, POINTER_ABSOLUTE, &mask);
|
0, POINTER_ABSOLUTE, &mask);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
if (X.xfocus.detail != NotifyInferior) {
|
{
|
||||||
pScreen = xnestScreen(X.xfocus.window);
|
EVTYPE(xcb_focus_in_event_t);
|
||||||
|
if (ev->detail != NotifyInferior) {
|
||||||
|
ScreenPtr pScreen = xnestScreen(ev->event);
|
||||||
if (pScreen)
|
if (pScreen)
|
||||||
xnestDirectInstallColormaps(pScreen);
|
xnestDirectInstallColormaps(pScreen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
if (X.xfocus.detail != NotifyInferior) {
|
{
|
||||||
pScreen = xnestScreen(X.xfocus.window);
|
EVTYPE(xcb_focus_out_event_t);
|
||||||
|
if (ev->detail != NotifyInferior) {
|
||||||
|
ScreenPtr pScreen = xnestScreen(ev->event);
|
||||||
if (pScreen)
|
if (pScreen)
|
||||||
xnestDirectUninstallColormaps(pScreen);
|
xnestDirectUninstallColormaps(pScreen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case KeymapNotify:
|
case KeymapNotify:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
if (X.xcrossing.detail != NotifyInferior) {
|
{
|
||||||
pScreen = xnestScreen(X.xcrossing.window);
|
EVTYPE(xcb_enter_notify_event_t);
|
||||||
|
if (ev->detail != NotifyInferior) {
|
||||||
|
ScreenPtr pScreen = xnestScreen(ev->event);
|
||||||
if (pScreen) {
|
if (pScreen) {
|
||||||
NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x,
|
ValuatorMask mask;
|
||||||
X.xcrossing.y);
|
int valuators[2];
|
||||||
valuators[0] = X.xcrossing.x;
|
NewCurrentScreen(inputInfo.pointer, pScreen,
|
||||||
valuators[1] = X.xcrossing.y;
|
ev->event_x, ev->event_y);
|
||||||
|
valuators[0] = ev->event_x;
|
||||||
|
valuators[1] = ev->event_y;
|
||||||
valuator_mask_set_range(&mask, 0, 2, valuators);
|
valuator_mask_set_range(&mask, 0, 2, valuators);
|
||||||
lastEventTime = GetTimeInMillis();
|
lastEventTime = GetTimeInMillis();
|
||||||
QueuePointerEvents(xnestPointerDevice, MotionNotify,
|
QueuePointerEvents(xnestPointerDevice, MotionNotify,
|
||||||
|
@ -188,21 +180,28 @@ xnestCollectEvents(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
if (X.xcrossing.detail != NotifyInferior) {
|
{
|
||||||
pScreen = xnestScreen(X.xcrossing.window);
|
EVTYPE(xcb_leave_notify_event_t);
|
||||||
|
if (ev->detail != NotifyInferior) {
|
||||||
|
ScreenPtr pScreen = xnestScreen(ev->event);
|
||||||
if (pScreen) {
|
if (pScreen) {
|
||||||
xnestDirectUninstallColormaps(pScreen);
|
xnestDirectUninstallColormaps(pScreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case DestroyNotify:
|
case DestroyNotify:
|
||||||
if (xnestParentWindow != (Window) 0 &&
|
{
|
||||||
X.xdestroywindow.window == xnestParentWindow)
|
xcb_destroy_notify_event_t *ev = (xcb_destroy_notify_event_t*)event;
|
||||||
|
if (xnestParentWindow &&
|
||||||
|
ev->window == xnestParentWindow)
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CirculateNotify:
|
case CirculateNotify:
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
|
@ -210,12 +209,65 @@ xnestCollectEvents(void)
|
||||||
case MapNotify:
|
case MapNotify:
|
||||||
case ReparentNotify:
|
case ReparentNotify:
|
||||||
case UnmapNotify:
|
case UnmapNotify:
|
||||||
case NoExpose:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case Expose:
|
||||||
ErrorF("xnest warning: unhandled event: %d\n", X.type);
|
{
|
||||||
break;
|
EVTYPE(xcb_expose_event_t);
|
||||||
|
WindowPtr pWin = xnestWindowPtr(ev->window);
|
||||||
|
if (pWin && ev->width && ev->height) {
|
||||||
|
RegionRec Rgn;
|
||||||
|
BoxRec Box = {
|
||||||
|
.x1 = pWin->drawable.x + wBorderWidth(pWin) + ev->x,
|
||||||
|
.y1 = pWin->drawable.y + wBorderWidth(pWin) + ev->y,
|
||||||
|
.x2 = Box.x1 + ev->width,
|
||||||
|
.y2 = Box.y1 + ev->height,
|
||||||
|
};
|
||||||
|
RegionInit(&Rgn, &Box, 1);
|
||||||
|
miSendExposures(pWin, &Rgn, Box.x1, Box.y1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NoExpose:
|
||||||
|
ErrorF("xnest: received stray NoExpose\n");
|
||||||
|
break;
|
||||||
|
case GraphicsExpose:
|
||||||
|
ErrorF("xnest: received stray GraphicsExpose\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ErrorF("xnest warning: unhandled event: %d\n", event->response_type);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xnestCollectEvents(void)
|
||||||
|
{
|
||||||
|
/* process queued events */
|
||||||
|
xnestEventQueue *tmp = NULL, *walk = NULL;
|
||||||
|
xorg_list_for_each_entry_safe(walk, tmp, &xnestUpstreamInfo.eventQueue.entry, entry) {
|
||||||
|
xnest_handle_event(walk->event);
|
||||||
|
xorg_list_del(&walk->entry);
|
||||||
|
free(walk->event);
|
||||||
|
free(walk);
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_flush(xnestUpstreamInfo.conn);
|
||||||
|
|
||||||
|
int err = xcb_connection_has_error(xnestUpstreamInfo.conn);
|
||||||
|
if (err) {
|
||||||
|
ErrorF("Xnest: upstream connection error: %d\n", err);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fetch new events from xcb */
|
||||||
|
xcb_generic_event_t *event = NULL;
|
||||||
|
while ((event = xcb_poll_for_event(xnestUpstreamInfo.conn))) {
|
||||||
|
xnest_handle_event(event);
|
||||||
|
free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_flush(xnestUpstreamInfo.conn);
|
||||||
|
}
|
||||||
|
|
|
@ -17,12 +17,9 @@ is" without express or implied warranty.
|
||||||
|
|
||||||
#include <X11/Xmd.h>
|
#include <X11/Xmd.h>
|
||||||
|
|
||||||
#define ProcessedExpose (LASTEvent + 1)
|
|
||||||
|
|
||||||
extern CARD32 lastEventTime;
|
extern CARD32 lastEventTime;
|
||||||
|
|
||||||
void SetTimeSinceLastInputEvent(void);
|
void SetTimeSinceLastInputEvent(void);
|
||||||
void xnestCollectExposures(void);
|
|
||||||
void xnestCollectEvents(void);
|
void xnestCollectEvents(void);
|
||||||
void xnestQueueKeyEvent(int type, unsigned int keycode);
|
void xnestQueueKeyEvent(int type, unsigned int keycode);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ is" without express or implied warranty.
|
||||||
#include "dixfontstr.h"
|
#include "dixfontstr.h"
|
||||||
#include "scrnintstr.h"
|
#include "scrnintstr.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "XNFont.h"
|
#include "XNFont.h"
|
||||||
|
@ -38,7 +38,7 @@ int xnestFontPrivateIndex;
|
||||||
Bool
|
Bool
|
||||||
xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||||
{
|
{
|
||||||
void *priv;
|
xnestPrivFont *priv;
|
||||||
Atom name_atom, value_atom;
|
Atom name_atom, value_atom;
|
||||||
int nprops;
|
int nprops;
|
||||||
FontPropPtr props;
|
FontPropPtr props;
|
||||||
|
@ -47,7 +47,7 @@ xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||||
|
|
||||||
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
|
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
|
||||||
|
|
||||||
name_atom = MakeAtom("FONT", 4, True);
|
name_atom = MakeAtom("FONT", 4, TRUE);
|
||||||
value_atom = 0L;
|
value_atom = 0L;
|
||||||
|
|
||||||
nprops = pFont->info.nprops;
|
nprops = pFont->info.nprops;
|
||||||
|
@ -60,32 +60,46 @@ xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!value_atom)
|
if (!value_atom)
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
name = NameForAtom(value_atom);
|
name = NameForAtom(value_atom);
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
priv = (void *) malloc(sizeof(xnestPrivFont));
|
priv = (void *) malloc(sizeof(xnestPrivFont));
|
||||||
xfont2_font_set_private(pFont, xnestFontPrivateIndex, priv);
|
xfont2_font_set_private(pFont, xnestFontPrivateIndex, priv);
|
||||||
|
|
||||||
xnestFontPriv(pFont)->font_struct = XLoadQueryFont(xnestDisplay, name);
|
priv->font_id = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_open_font(xnestUpstreamInfo.conn, priv->font_id, strlen(name), name);
|
||||||
|
|
||||||
if (!xnestFontStruct(pFont))
|
xcb_generic_error_t *err = NULL;
|
||||||
return False;
|
priv->font_reply = xcb_query_font_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_query_font(xnestUpstreamInfo.conn, priv->font_id),
|
||||||
|
&err);
|
||||||
|
if (err) {
|
||||||
|
ErrorF("failed to query font \"%s\": %d", name, err->error_code);
|
||||||
|
free(err);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!priv->font_reply) {
|
||||||
|
ErrorF("failed to query font \"%s\": no reply", name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
priv->chars_len = xcb_query_font_char_infos_length(priv->font_reply);
|
||||||
|
priv->chars = xcb_query_font_char_infos(priv->font_reply);
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||||
{
|
{
|
||||||
if (xnestFontPriv(pFont)) {
|
if (xnestFontPriv(pFont)) {
|
||||||
if (xnestFontStruct(pFont))
|
xcb_close_font(xnestUpstreamInfo.conn, xnestFontPriv(pFont)->font_id);
|
||||||
XFreeFont(xnestDisplay, xnestFontStruct(pFont));
|
|
||||||
free(xnestFontPriv(pFont));
|
free(xnestFontPriv(pFont));
|
||||||
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
|
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
|
||||||
}
|
}
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
140
hw/xnest/GC.c
140
hw/xnest/GC.c
|
@ -28,7 +28,7 @@ is" without express or implied warranty.
|
||||||
#include "mistruct.h"
|
#include "mistruct.h"
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "XNGC.h"
|
#include "XNGC.h"
|
||||||
|
@ -80,11 +80,14 @@ xnestCreateGC(GCPtr pGC)
|
||||||
|
|
||||||
pGC->miTranslate = 1;
|
pGC->miTranslate = 1;
|
||||||
|
|
||||||
xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
|
xnestGCPriv(pGC)->gc = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
xnestDefaultDrawables[pGC->depth],
|
xcb_create_gc(xnestUpstreamInfo.conn,
|
||||||
0L, NULL);
|
xnestGCPriv(pGC)->gc,
|
||||||
|
xnestDefaultDrawables[pGC->depth],
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -95,7 +98,7 @@ xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
||||||
void
|
void
|
||||||
xnestChangeGC(GCPtr pGC, unsigned long mask)
|
xnestChangeGC(GCPtr pGC, unsigned long mask)
|
||||||
{
|
{
|
||||||
XGCValues values;
|
XnGCValues values;
|
||||||
|
|
||||||
if (mask & GCFunction)
|
if (mask & GCFunction)
|
||||||
values.function = pGC->alu;
|
values.function = pGC->alu;
|
||||||
|
@ -144,7 +147,7 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
|
||||||
values.ts_y_origin = pGC->patOrg.y;
|
values.ts_y_origin = pGC->patOrg.y;
|
||||||
|
|
||||||
if (mask & GCFont)
|
if (mask & GCFont)
|
||||||
values.font = xnestFont(pGC->font);
|
values.font = xnestFontPriv(pGC->font)->font_id;
|
||||||
|
|
||||||
if (mask & GCSubwindowMode)
|
if (mask & GCSubwindowMode)
|
||||||
values.subwindow_mode = pGC->subWindowMode;
|
values.subwindow_mode = pGC->subWindowMode;
|
||||||
|
@ -166,62 +169,89 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
|
||||||
|
|
||||||
if (mask & GCDashList) {
|
if (mask & GCDashList) {
|
||||||
mask &= ~GCDashList;
|
mask &= ~GCDashList;
|
||||||
XSetDashes(xnestDisplay, xnestGC(pGC),
|
xcb_set_dashes(xnestUpstreamInfo.conn,
|
||||||
pGC->dashOffset, (char *) pGC->dash, pGC->numInDashList);
|
xnestUpstreamGC(pGC),
|
||||||
|
pGC->dashOffset,
|
||||||
|
pGC->numInDashList,
|
||||||
|
(uint8_t*) pGC->dash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & GCArcMode)
|
if (mask & GCArcMode)
|
||||||
values.arc_mode = pGC->arcMode;
|
values.arc_mode = pGC->arcMode;
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
|
xnChangeGC(xnestUpstreamInfo.conn, xnestUpstreamGC(pGC), values, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
|
xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
|
||||||
{
|
{
|
||||||
XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
|
xcb_copy_gc(xnestUpstreamInfo.conn,
|
||||||
|
xnestGC(pGCSrc),
|
||||||
|
xnestGC(pGCDst),
|
||||||
|
mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestDestroyGC(GCPtr pGC)
|
xnestDestroyGC(GCPtr pGC)
|
||||||
{
|
{
|
||||||
XFreeGC(xnestDisplay, xnestGC(pGC));
|
xcb_free_gc(xnestUpstreamInfo.conn, xnestGC(pGC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
|
xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
BoxPtr pBox;
|
|
||||||
XRectangle *pRects;
|
|
||||||
|
|
||||||
xnestDestroyClip(pGC);
|
xnestDestroyClip(pGC);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CT_NONE:
|
case CT_NONE:
|
||||||
XSetClipMask(xnestDisplay, xnestGC(pGC), None);
|
{
|
||||||
|
uint32_t pixmap = XCB_PIXMAP_NONE;
|
||||||
|
xcb_change_gc(xnestUpstreamInfo.conn,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
XCB_GC_CLIP_MASK,
|
||||||
|
&pixmap);
|
||||||
|
}
|
||||||
pValue = NULL;
|
pValue = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_REGION:
|
case CT_REGION:
|
||||||
nRects = RegionNumRects((RegionPtr) pValue);
|
{
|
||||||
pRects = xallocarray(nRects, sizeof(*pRects));
|
nRects = RegionNumRects((RegionPtr) pValue);
|
||||||
pBox = RegionRects((RegionPtr) pValue);
|
xcb_rectangle_t *rects= calloc(nRects, sizeof(xcb_rectangle_t));
|
||||||
for (i = nRects; i-- > 0;) {
|
if (rects == NULL) {
|
||||||
pRects[i].x = pBox[i].x1;
|
ErrorF("xnestChangeClip: memory alloc failure");
|
||||||
pRects[i].y = pBox[i].y1;
|
return;
|
||||||
pRects[i].width = pBox[i].x2 - pBox[i].x1;
|
}
|
||||||
pRects[i].height = pBox[i].y2 - pBox[i].y1;
|
BoxPtr pBox = RegionRects((RegionPtr) pValue);
|
||||||
|
for (int i = nRects; i-- > 0;)
|
||||||
|
rects[i] = (xcb_rectangle_t) {
|
||||||
|
.x = pBox[i].x1,
|
||||||
|
.y = pBox[i].y1,
|
||||||
|
.width = pBox[i].x2 - pBox[i].x1,
|
||||||
|
.height = pBox[i].y2 - pBox[i].y1,
|
||||||
|
};
|
||||||
|
xcb_set_clip_rectangles(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
XCB_CLIP_ORDERING_UNSORTED,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
nRects,
|
||||||
|
rects);
|
||||||
|
|
||||||
|
free(rects);
|
||||||
}
|
}
|
||||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0,
|
|
||||||
pRects, nRects, Unsorted);
|
|
||||||
free((char *) pRects);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_PIXMAP:
|
case CT_PIXMAP:
|
||||||
XSetClipMask(xnestDisplay, xnestGC(pGC),
|
{
|
||||||
xnestPixmap((PixmapPtr) pValue));
|
uint32_t val = xnestPixmap((PixmapPtr) pValue);
|
||||||
|
xcb_change_gc(xnestUpstreamInfo.conn,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
XCB_GC_CLIP_MASK,
|
||||||
|
&val);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Need to change into region, so subsequent uses are with
|
* Need to change into region, so subsequent uses are with
|
||||||
* current pixmap contents.
|
* current pixmap contents.
|
||||||
|
@ -232,27 +262,47 @@ xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_UNSORTED:
|
case CT_UNSORTED:
|
||||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
xcb_set_clip_rectangles(
|
||||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
xnestUpstreamInfo.conn,
|
||||||
(XRectangle *) pValue, nRects, Unsorted);
|
XCB_CLIP_ORDERING_UNSORTED,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
pGC->clipOrg.x, pGC->clipOrg.y,
|
||||||
|
nRects,
|
||||||
|
(xcb_rectangle_t*)pValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_YSORTED:
|
case CT_YSORTED:
|
||||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
xcb_set_clip_rectangles(
|
||||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
xnestUpstreamInfo.conn,
|
||||||
(XRectangle *) pValue, nRects, YSorted);
|
XCB_CLIP_ORDERING_Y_SORTED,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
pGC->clipOrg.x,
|
||||||
|
pGC->clipOrg.y,
|
||||||
|
nRects,
|
||||||
|
(xcb_rectangle_t*)pValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_YXSORTED:
|
case CT_YXSORTED:
|
||||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
xcb_set_clip_rectangles(
|
||||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
xnestUpstreamInfo.conn,
|
||||||
(XRectangle *) pValue, nRects, YXSorted);
|
XCB_CLIP_ORDERING_YX_SORTED,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
pGC->clipOrg.x,
|
||||||
|
pGC->clipOrg.y,
|
||||||
|
nRects,
|
||||||
|
(xcb_rectangle_t*)pValue);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_YXBANDED:
|
case CT_YXBANDED:
|
||||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
xcb_set_clip_rectangles(
|
||||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
xnestUpstreamInfo.conn,
|
||||||
(XRectangle *) pValue, nRects, YXBanded);
|
XCB_CLIP_ORDERING_YX_BANDED,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
pGC->clipOrg.x,
|
||||||
|
pGC->clipOrg.y,
|
||||||
|
nRects,
|
||||||
|
(xcb_rectangle_t*)pValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +329,11 @@ xnestDestroyClip(GCPtr pGC)
|
||||||
{
|
{
|
||||||
if (pGC->clientClip) {
|
if (pGC->clientClip) {
|
||||||
RegionDestroy(pGC->clientClip);
|
RegionDestroy(pGC->clientClip);
|
||||||
XSetClipMask(xnestDisplay, xnestGC(pGC), None);
|
uint32_t val = XCB_PIXMAP_NONE;
|
||||||
|
xcb_change_gc(xnestUpstreamInfo.conn,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
XCB_GC_CLIP_MASK,
|
||||||
|
&val);
|
||||||
pGC->clientClip = NULL;
|
pGC->clientClip = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
350
hw/xnest/GCOps.c
350
hw/xnest/GCOps.c
|
@ -29,7 +29,7 @@ is" without express or implied warranty.
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
@ -37,7 +37,6 @@ is" without express or implied warranty.
|
||||||
#include "XNFont.h"
|
#include "XNFont.h"
|
||||||
#include "GCOps.h"
|
#include "GCOps.h"
|
||||||
#include "Drawable.h"
|
#include "Drawable.h"
|
||||||
#include "Visual.h"
|
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, xPoint * pPoints,
|
xnestFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, xPoint * pPoints,
|
||||||
|
@ -64,74 +63,81 @@ void
|
||||||
xnestQueryBestSize(int class, unsigned short *pWidth, unsigned short *pHeight,
|
xnestQueryBestSize(int class, unsigned short *pWidth, unsigned short *pHeight,
|
||||||
ScreenPtr pScreen)
|
ScreenPtr pScreen)
|
||||||
{
|
{
|
||||||
unsigned int width, height;
|
xcb_generic_error_t *err = NULL;
|
||||||
|
xcb_query_best_size_reply_t *reply = xcb_query_best_size_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_query_best_size(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
class,
|
||||||
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
*pWidth,
|
||||||
|
*pHeight),
|
||||||
|
&err);
|
||||||
|
|
||||||
width = *pWidth;
|
if (err) {
|
||||||
height = *pHeight;
|
ErrorF("QueryBestSize request failed: %d\n", err->error_code);
|
||||||
|
free(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
XQueryBestSize(xnestDisplay, class,
|
if (!reply) {
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
ErrorF("QueryBestSize request failed: no reply\n");
|
||||||
width, height, &width, &height);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
*pWidth = width;
|
*pWidth = reply->width;
|
||||||
*pHeight = height;
|
*pHeight = reply->height;
|
||||||
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
xnestPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||||
int w, int h, int leftPad, int format, char *pImage)
|
int w, int h, int leftPad, int format, char *pImage)
|
||||||
{
|
{
|
||||||
XImage *ximage;
|
xcb_put_image(xnestUpstreamInfo.conn,
|
||||||
|
format,
|
||||||
ximage = XCreateImage(xnestDisplay, xnestDefaultVisual(pDrawable->pScreen),
|
xnestDrawable(pDrawable),
|
||||||
depth, format, leftPad, (char *) pImage,
|
xnestUpstreamGC(pGC),
|
||||||
w, h, BitmapPad(xnestDisplay),
|
w,
|
||||||
(format == ZPixmap) ?
|
h,
|
||||||
PixmapBytePad(w, depth) : BitmapBytePad(w + leftPad));
|
x,
|
||||||
|
y,
|
||||||
if (ximage) {
|
leftPad,
|
||||||
XPutImage(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
depth,
|
||||||
ximage, 0, 0, x, y, w, h);
|
(format == XCB_IMAGE_FORMAT_Z_PIXMAP ? PixmapBytePad(w, depth)
|
||||||
XFree(ximage);
|
: BitmapBytePad(w + leftPad)) * h,
|
||||||
}
|
(uint8_t*)pImage);
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
xnestIgnoreErrorHandler (Display *dpy,
|
|
||||||
XErrorEvent *event)
|
|
||||||
{
|
|
||||||
return False; /* return value is ignored */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
|
xnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
|
||||||
unsigned int format, unsigned long planeMask, char *pImage)
|
unsigned int format, unsigned long planeMask, char *pImage)
|
||||||
{
|
{
|
||||||
XImage *ximage;
|
xcb_generic_error_t * err = NULL;
|
||||||
int length;
|
xcb_get_image_reply_t *reply= xcb_get_image_reply(
|
||||||
int (*old_handler)(Display*, XErrorEvent*);
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_image(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
format,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
x, y, w, h, planeMask),
|
||||||
|
&err);
|
||||||
|
|
||||||
/* we may get BadMatch error when xnest window is minimized */
|
if (err) {
|
||||||
XSync(xnestDisplay, False);
|
// badMatch may happeen if the upstream window is currently minimized
|
||||||
old_handler = XSetErrorHandler (xnestIgnoreErrorHandler);
|
if (err->error_code != BadMatch)
|
||||||
|
LogMessage(X_WARNING, "xnestGetImage: received error %d\n", err->error_code);
|
||||||
ximage = XGetImage(xnestDisplay, xnestDrawable(pDrawable),
|
free(err);
|
||||||
x, y, w, h, planeMask, format);
|
return;
|
||||||
XSetErrorHandler(old_handler);
|
|
||||||
|
|
||||||
if (ximage) {
|
|
||||||
length = ximage->bytes_per_line * ximage->height;
|
|
||||||
|
|
||||||
memmove(pImage, ximage->data, length);
|
|
||||||
|
|
||||||
XDestroyImage(ximage);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static Bool
|
if (!reply) {
|
||||||
xnestBitBlitPredicate(Display * dpy, XEvent * event, char *args)
|
LogMessage(X_WARNING, "xnestGetImage: received no reply\n");
|
||||||
{
|
return;
|
||||||
return event->type == GraphicsExpose || event->type == NoExpose;
|
}
|
||||||
|
|
||||||
|
memmove(pImage, xcb_get_image_data(reply), xcb_get_image_data_length(reply));
|
||||||
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegionPtr
|
static RegionPtr
|
||||||
|
@ -140,9 +146,7 @@ xnestBitBlitHelper(GCPtr pGC)
|
||||||
if (!pGC->graphicsExposures)
|
if (!pGC->graphicsExposures)
|
||||||
return NullRegion;
|
return NullRegion;
|
||||||
else {
|
else {
|
||||||
XEvent event;
|
|
||||||
RegionPtr pReg, pTmpReg;
|
RegionPtr pReg, pTmpReg;
|
||||||
BoxRec Box;
|
|
||||||
Bool pending, overlap;
|
Bool pending, overlap;
|
||||||
|
|
||||||
pReg = RegionCreate(NULL, 1);
|
pReg = RegionCreate(NULL, 1);
|
||||||
|
@ -150,24 +154,43 @@ xnestBitBlitHelper(GCPtr pGC)
|
||||||
if (!pReg || !pTmpReg)
|
if (!pReg || !pTmpReg)
|
||||||
return NullRegion;
|
return NullRegion;
|
||||||
|
|
||||||
pending = True;
|
xcb_flush(xnestUpstreamInfo.conn);
|
||||||
|
|
||||||
|
pending = TRUE;
|
||||||
while (pending) {
|
while (pending) {
|
||||||
XIfEvent(xnestDisplay, &event, xnestBitBlitPredicate, NULL);
|
xcb_generic_event_t *event = xcb_wait_for_event(xnestUpstreamInfo.conn);
|
||||||
|
if (!event) {
|
||||||
switch (event.type) {
|
pending = FALSE;
|
||||||
case NoExpose:
|
|
||||||
pending = False;
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GraphicsExpose:
|
switch (event->response_type & ~0x80) {
|
||||||
Box.x1 = event.xgraphicsexpose.x;
|
case NoExpose:
|
||||||
Box.y1 = event.xgraphicsexpose.y;
|
pending = FALSE;
|
||||||
Box.x2 = event.xgraphicsexpose.x + event.xgraphicsexpose.width;
|
free(event);
|
||||||
Box.y2 = event.xgraphicsexpose.y + event.xgraphicsexpose.height;
|
break;
|
||||||
RegionReset(pTmpReg, &Box);
|
|
||||||
RegionAppend(pReg, pTmpReg);
|
case GraphicsExpose:
|
||||||
pending = event.xgraphicsexpose.count;
|
{
|
||||||
break;
|
xcb_graphics_exposure_event_t* ev = (xcb_graphics_exposure_event_t*)event;
|
||||||
|
BoxRec Box = {
|
||||||
|
.x1 = ev->x,
|
||||||
|
.y1 = ev->y,
|
||||||
|
.x2 = ev->x + ev->width,
|
||||||
|
.y2 = ev->y + ev->height,
|
||||||
|
};
|
||||||
|
RegionReset(pTmpReg, &Box);
|
||||||
|
RegionAppend(pReg, pTmpReg);
|
||||||
|
pending = ev->count;
|
||||||
|
free(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
xnestEventQueue *q = malloc(sizeof(xnestEventQueue));
|
||||||
|
q->event = event;
|
||||||
|
xorg_list_add(&q->entry, &xnestUpstreamInfo.eventQueue.entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,9 +205,11 @@ xnestCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
|
||||||
GCPtr pGC, int srcx, int srcy, int width, int height,
|
GCPtr pGC, int srcx, int srcy, int width, int height,
|
||||||
int dstx, int dsty)
|
int dstx, int dsty)
|
||||||
{
|
{
|
||||||
XCopyArea(xnestDisplay,
|
xcb_copy_area(xnestUpstreamInfo.conn,
|
||||||
xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
|
xnestDrawable(pSrcDrawable),
|
||||||
xnestGC(pGC), srcx, srcy, width, height, dstx, dsty);
|
xnestDrawable(pDstDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
srcx, srcy, dstx, dsty, width, height);
|
||||||
|
|
||||||
return xnestBitBlitHelper(pGC);
|
return xnestBitBlitHelper(pGC);
|
||||||
}
|
}
|
||||||
|
@ -194,9 +219,11 @@ xnestCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
|
||||||
GCPtr pGC, int srcx, int srcy, int width, int height,
|
GCPtr pGC, int srcx, int srcy, int width, int height,
|
||||||
int dstx, int dsty, unsigned long plane)
|
int dstx, int dsty, unsigned long plane)
|
||||||
{
|
{
|
||||||
XCopyPlane(xnestDisplay,
|
xcb_copy_plane(xnestUpstreamInfo.conn,
|
||||||
xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
|
xnestDrawable(pSrcDrawable),
|
||||||
xnestGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
|
xnestDrawable(pDstDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
srcx, srcy, dstx, dsty, width, height, plane);
|
||||||
|
|
||||||
return xnestBitBlitHelper(pGC);
|
return xnestBitBlitHelper(pGC);
|
||||||
}
|
}
|
||||||
|
@ -205,106 +232,184 @@ void
|
||||||
xnestPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
|
xnestPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
|
||||||
DDXPointPtr pPoints)
|
DDXPointPtr pPoints)
|
||||||
{
|
{
|
||||||
XDrawPoints(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xPoint and xcb_segment_t are defined in the same way, both matching
|
||||||
(XPoint *) pPoints, nPoints, mode);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_poly_point(xnestUpstreamInfo.conn,
|
||||||
|
mode,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
nPoints,
|
||||||
|
(xcb_point_t*)pPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
|
xnestPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
|
||||||
DDXPointPtr pPoints)
|
DDXPointPtr pPoints)
|
||||||
{
|
{
|
||||||
XDrawLines(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xPoint and xcb_segment_t are defined in the same way, both matching
|
||||||
(XPoint *) pPoints, nPoints, mode);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_poly_line(xnestUpstreamInfo.conn,
|
||||||
|
mode,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
nPoints,
|
||||||
|
(xcb_point_t*)pPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
|
xnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
|
||||||
xSegment * pSegments)
|
xSegment * pSegments)
|
||||||
{
|
{
|
||||||
XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xSegment and xcb_segment_t are defined in the same way, both matching
|
||||||
(XSegment *) pSegments, nSegments);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_poly_segment(xnestUpstreamInfo.conn,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
nSegments,
|
||||||
|
(xcb_segment_t*)pSegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
|
xnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
|
||||||
xRectangle *pRectangles)
|
xRectangle *pRectangles)
|
||||||
{
|
{
|
||||||
XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xRectangle and xcb_rectangle_t are defined in the same way, both matching
|
||||||
(XRectangle *) pRectangles, nRectangles);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_poly_rectangle(xnestUpstreamInfo.conn,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
nRectangles,
|
||||||
|
(xcb_rectangle_t*)pRectangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
|
xnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
|
||||||
{
|
{
|
||||||
XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xArc and xcb_arc_t are defined in the same way, both matching
|
||||||
(XArc *) pArcs, nArcs);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_poly_arc(xnestUpstreamInfo.conn,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
nArcs,
|
||||||
|
(xcb_arc_t*)pArcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode,
|
xnestFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode,
|
||||||
int nPoints, DDXPointPtr pPoints)
|
int nPoints, DDXPointPtr pPoints)
|
||||||
{
|
{
|
||||||
XFillPolygon(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xPoint and xcb_segment_t are defined in the same way, both matching
|
||||||
(XPoint *) pPoints, nPoints, shape, mode);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_fill_poly(xnestUpstreamInfo.conn,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
shape,
|
||||||
|
mode,
|
||||||
|
nPoints,
|
||||||
|
(xcb_point_t*)pPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
|
xnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
|
||||||
xRectangle *pRectangles)
|
xRectangle *pRectangles)
|
||||||
{
|
{
|
||||||
XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xRectangle and xcb_rectangle_t are defined in the same way, both matching
|
||||||
(XRectangle *) pRectangles, nRectangles);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_poly_fill_rectangle(xnestUpstreamInfo.conn,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
nRectangles,
|
||||||
|
(xcb_rectangle_t*)pRectangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
|
xnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
|
||||||
{
|
{
|
||||||
XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
/* xArc and xcb_arc_t are defined in the same way, both matching
|
||||||
(XArc *) pArcs, nArcs);
|
the protocol layout, so we can directly typecast them */
|
||||||
|
xcb_poly_fill_arc(xnestUpstreamInfo.conn,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
nArcs,
|
||||||
|
(xcb_arc_t*)pArcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||||
char *string)
|
char *string)
|
||||||
{
|
{
|
||||||
int width;
|
// we need to prepend a xTextElt struct before our actual characters
|
||||||
|
// won't get more than 254 elements, since it's already processed by doPolyText()
|
||||||
|
int const bufsize = sizeof(xTextElt) + count;
|
||||||
|
uint8_t *buffer = malloc(bufsize);
|
||||||
|
xTextElt *elt = (xTextElt*)buffer;
|
||||||
|
elt->len = count;
|
||||||
|
elt->delta = 0;
|
||||||
|
memcpy(buffer+2, string, count);
|
||||||
|
|
||||||
XDrawString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
xcb_poly_text_8(xnestUpstreamInfo.conn,
|
||||||
x, y, string, count);
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
bufsize,
|
||||||
|
(uint8_t*)buffer);
|
||||||
|
|
||||||
width = XTextWidth(xnestFontStruct(pGC->font), string, count);
|
free(buffer);
|
||||||
|
|
||||||
return width + x;
|
return x + xnestTextWidth(xnestFontPriv(pGC->font), string, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||||
unsigned short *string)
|
unsigned short *string)
|
||||||
{
|
{
|
||||||
int width;
|
// we need to prepend a xTextElt struct before our actual characters
|
||||||
|
// won't get more than 254 elements, since it's already processed by doPolyText()
|
||||||
|
int const bufsize = sizeof(xTextElt) + count*2;
|
||||||
|
uint8_t *buffer = malloc(bufsize);
|
||||||
|
xTextElt *elt = (xTextElt*)buffer;
|
||||||
|
elt->len = count;
|
||||||
|
elt->delta = 0;
|
||||||
|
memcpy(buffer+2, string, count*2);
|
||||||
|
|
||||||
XDrawString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
xcb_poly_text_16(xnestUpstreamInfo.conn,
|
||||||
x, y, (XChar2b *) string, count);
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
bufsize,
|
||||||
|
buffer);
|
||||||
|
|
||||||
width = XTextWidth16(xnestFontStruct(pGC->font), (XChar2b *) string, count);
|
free(buffer);
|
||||||
|
|
||||||
return width + x;
|
return x + xnestTextWidth16(xnestFontPriv(pGC->font), string, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
xnestImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||||
char *string)
|
char *string)
|
||||||
{
|
{
|
||||||
XDrawImageString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
xcb_image_text_8(xnestUpstreamInfo.conn,
|
||||||
x, y, string, count);
|
count,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||||
unsigned short *string)
|
unsigned short *string)
|
||||||
{
|
{
|
||||||
XDrawImageString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
xcb_image_text_16(xnestUpstreamInfo.conn,
|
||||||
x, y, (XChar2b *) string, count);
|
count,
|
||||||
|
xnestDrawable(pDrawable),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
(xcb_char2b_t*)string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -329,12 +434,35 @@ xnestPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst,
|
||||||
{
|
{
|
||||||
/* only works for solid bitmaps */
|
/* only works for solid bitmaps */
|
||||||
if (pGC->fillStyle == FillSolid) {
|
if (pGC->fillStyle == FillSolid) {
|
||||||
XSetStipple(xnestDisplay, xnestGC(pGC), xnestPixmap(pBitmap));
|
xnChangeGC(xnestUpstreamInfo.conn,
|
||||||
XSetTSOrigin(xnestDisplay, xnestGC(pGC), x, y);
|
xnestUpstreamGC(pGC),
|
||||||
XSetFillStyle(xnestDisplay, xnestGC(pGC), FillStippled);
|
(XnGCValues) {
|
||||||
XFillRectangle(xnestDisplay, xnestDrawable(pDst),
|
.fill_style = XCB_FILL_STYLE_STIPPLED,
|
||||||
xnestGC(pGC), x, y, width, height);
|
.ts_x_origin = x,
|
||||||
XSetFillStyle(xnestDisplay, xnestGC(pGC), FillSolid);
|
.ts_y_origin = y,
|
||||||
|
.stipple = xnestPixmap(pBitmap),
|
||||||
|
},
|
||||||
|
XCB_GC_FILL_STYLE | XCB_GC_TILE_STIPPLE_ORIGIN_X |
|
||||||
|
XCB_GC_TILE_STIPPLE_ORIGIN_Y | XCB_GC_STIPPLE);
|
||||||
|
|
||||||
|
xcb_rectangle_t rect = {
|
||||||
|
.x = x, .y = y, .width = width, .height = height,
|
||||||
|
};
|
||||||
|
xcb_poly_fill_rectangle(xnestUpstreamInfo.conn,
|
||||||
|
xnestDrawable(pDst),
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
1,
|
||||||
|
&rect);
|
||||||
|
|
||||||
|
xnChangeGC(xnestUpstreamInfo.conn,
|
||||||
|
xnestUpstreamGC(pGC),
|
||||||
|
(XnGCValues) {
|
||||||
|
.fill_style = XCB_FILL_STYLE_SOLID,
|
||||||
|
.ts_x_origin = x,
|
||||||
|
.ts_y_origin = y,
|
||||||
|
.stipple = xnestPixmap(pBitmap),
|
||||||
|
},
|
||||||
|
XCB_GC_FILL_STYLE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ErrorF("xnest warning: function xnestPushPixels not implemented\n");
|
ErrorF("xnest warning: function xnestPushPixels not implemented\n");
|
||||||
|
|
|
@ -25,8 +25,6 @@ is" without express or implied warranty.
|
||||||
#include "windowstr.h"
|
#include "windowstr.h"
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Events.h"
|
#include "Events.h"
|
||||||
#include "Handlers.h"
|
#include "Handlers.h"
|
||||||
|
@ -34,8 +32,7 @@ is" without express or implied warranty.
|
||||||
void
|
void
|
||||||
xnestBlockHandler(void *blockData, void *timeout)
|
xnestBlockHandler(void *blockData, void *timeout)
|
||||||
{
|
{
|
||||||
xnestCollectExposures();
|
xnestCollectEvents();
|
||||||
XFlush(xnestDisplay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -34,8 +34,8 @@ is" without express or implied warranty.
|
||||||
#include "mi.h"
|
#include "mi.h"
|
||||||
#include "dixfontstr.h"
|
#include "dixfontstr.h"
|
||||||
#include "extinit_priv.h"
|
#include "extinit_priv.h"
|
||||||
#include "Xnest.h"
|
|
||||||
|
|
||||||
|
#include "xnest-xcb.h"
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "Pointer.h"
|
#include "Pointer.h"
|
||||||
|
@ -51,7 +51,7 @@ is" without express or implied warranty.
|
||||||
#include "dpmsproc.h"
|
#include "dpmsproc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Bool xnestDoFullGeneration = True;
|
Bool xnestDoFullGeneration = TRUE;
|
||||||
|
|
||||||
#ifdef GLXEXT
|
#ifdef GLXEXT
|
||||||
void
|
void
|
||||||
|
@ -63,29 +63,37 @@ GlxExtensionInit(void)
|
||||||
void
|
void
|
||||||
InitOutput(ScreenInfo * screen_info, int argc, char *argv[])
|
InitOutput(ScreenInfo * screen_info, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
xnestOpenDisplay(argc, argv);
|
xnestOpenDisplay(argc, argv);
|
||||||
|
|
||||||
screen_info->imageByteOrder = ImageByteOrder(xnestDisplay);
|
screen_info->imageByteOrder = xnestUpstreamInfo.setup->image_byte_order;
|
||||||
screen_info->bitmapScanlineUnit = BitmapUnit(xnestDisplay);
|
screen_info->bitmapScanlineUnit = xnestUpstreamInfo.setup->bitmap_format_scanline_unit;
|
||||||
screen_info->bitmapScanlinePad = BitmapPad(xnestDisplay);
|
screen_info->bitmapScanlinePad = xnestUpstreamInfo.setup->bitmap_format_scanline_pad;
|
||||||
screen_info->bitmapBitOrder = BitmapBitOrder(xnestDisplay);
|
screen_info->bitmapBitOrder = xnestUpstreamInfo.setup->bitmap_format_bit_order;
|
||||||
|
|
||||||
screen_info->numPixmapFormats = 0;
|
screen_info->numPixmapFormats = 0;
|
||||||
for (i = 0; i < xnestNumPixmapFormats; i++)
|
|
||||||
for (j = 0; j < xnestNumDepths; j++)
|
xcb_format_t *fmt = xcb_setup_pixmap_formats(xnestUpstreamInfo.setup);
|
||||||
if ((xnestPixmapFormats[i].depth == 1) ||
|
const xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(xnestUpstreamInfo.setup);
|
||||||
(xnestPixmapFormats[i].depth == xnestDepths[j])) {
|
for(; fmt != fmtend; ++fmt) {
|
||||||
|
xcb_depth_iterator_t depth_iter;
|
||||||
|
for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
|
||||||
|
depth_iter.rem;
|
||||||
|
xcb_depth_next(&depth_iter))
|
||||||
|
{
|
||||||
|
if ((fmt->depth == 1) ||
|
||||||
|
(fmt->depth == depth_iter.data->depth)) {
|
||||||
screen_info->formats[screen_info->numPixmapFormats].depth =
|
screen_info->formats[screen_info->numPixmapFormats].depth =
|
||||||
xnestPixmapFormats[i].depth;
|
fmt->depth;
|
||||||
screen_info->formats[screen_info->numPixmapFormats].bitsPerPixel =
|
screen_info->formats[screen_info->numPixmapFormats].bitsPerPixel =
|
||||||
xnestPixmapFormats[i].bits_per_pixel;
|
fmt->bits_per_pixel;
|
||||||
screen_info->formats[screen_info->numPixmapFormats].scanlinePad =
|
screen_info->formats[screen_info->numPixmapFormats].scanlinePad =
|
||||||
xnestPixmapFormats[i].scanline_pad;
|
fmt->scanline_pad;
|
||||||
screen_info->numPixmapFormats++;
|
screen_info->numPixmapFormats++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xnestFontPrivateIndex = xfont2_allocate_font_private_index();
|
xnestFontPrivateIndex = xfont2_allocate_font_private_index();
|
||||||
|
|
||||||
|
@ -121,7 +129,10 @@ InitInput(int argc, char *argv[])
|
||||||
|
|
||||||
mieqInit();
|
mieqInit();
|
||||||
|
|
||||||
SetNotifyFd(XConnectionNumber(xnestDisplay), xnestNotifyConnection, X_NOTIFY_READ, NULL);
|
SetNotifyFd(xcb_get_file_descriptor(xnestUpstreamInfo.conn),
|
||||||
|
xnestNotifyConnection,
|
||||||
|
X_NOTIFY_READ,
|
||||||
|
NULL);
|
||||||
|
|
||||||
RegisterBlockAndWakeupHandlers(xnestBlockHandler, xnestWakeupHandler, NULL);
|
RegisterBlockAndWakeupHandlers(xnestBlockHandler, xnestWakeupHandler, NULL);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +146,7 @@ CloseInput(void)
|
||||||
void
|
void
|
||||||
ddxGiveUp(enum ExitCode error)
|
ddxGiveUp(enum ExitCode error)
|
||||||
{
|
{
|
||||||
xnestDoFullGeneration = True;
|
xnestDoFullGeneration = TRUE;
|
||||||
xnestCloseDisplay();
|
xnestCloseDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ is" without express or implied warranty.
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
|
||||||
#include "screenint.h"
|
#include "screenint.h"
|
||||||
#include "inputstr.h"
|
#include "inputstr.h"
|
||||||
|
@ -31,7 +32,7 @@ is" without express or implied warranty.
|
||||||
#include "scrnintstr.h"
|
#include "scrnintstr.h"
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
@ -41,39 +42,19 @@ is" without express or implied warranty.
|
||||||
|
|
||||||
#include <X11/extensions/XKB.h>
|
#include <X11/extensions/XKB.h>
|
||||||
#include "xkbsrv.h"
|
#include "xkbsrv.h"
|
||||||
#include <X11/extensions/XKBconfig.h>
|
|
||||||
|
|
||||||
extern Bool
|
|
||||||
XkbQueryExtension(Display * /* dpy */ ,
|
|
||||||
int * /* opcodeReturn */ ,
|
|
||||||
int * /* eventBaseReturn */ ,
|
|
||||||
int * /* errorBaseReturn */ ,
|
|
||||||
int * /* majorRtrn */ ,
|
|
||||||
int * /* minorRtrn */
|
|
||||||
);
|
|
||||||
|
|
||||||
extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ ,
|
|
||||||
unsigned int /* which */ ,
|
|
||||||
unsigned int /* deviceSpec */
|
|
||||||
);
|
|
||||||
|
|
||||||
extern Status XkbGetControls(Display * /* dpy */ ,
|
|
||||||
unsigned long /* which */ ,
|
|
||||||
XkbDescPtr /* desc */
|
|
||||||
);
|
|
||||||
|
|
||||||
DeviceIntPtr xnestKeyboardDevice = NULL;
|
DeviceIntPtr xnestKeyboardDevice = NULL;
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls)
|
xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls)
|
||||||
{
|
{
|
||||||
XBell(xnestDisplay, volume);
|
xcb_bell(xnestUpstreamInfo.conn, volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DDXRingBell(int volume, int pitch, int duration)
|
DDXRingBell(int volume, int pitch, int duration)
|
||||||
{
|
{
|
||||||
XBell(xnestDisplay, volume);
|
xcb_bell(xnestUpstreamInfo.conn, volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -81,7 +62,7 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
unsigned long value_mask;
|
unsigned long value_mask;
|
||||||
XKeyboardControl values;
|
XnKeyboardControl values;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
value_mask = KBKeyClickPercent |
|
value_mask = KBKeyClickPercent |
|
||||||
|
@ -94,7 +75,9 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
||||||
values.auto_repeat_mode = ctrl->autoRepeat ?
|
values.auto_repeat_mode = ctrl->autoRepeat ?
|
||||||
AutoRepeatModeOn : AutoRepeatModeOff;
|
AutoRepeatModeOn : AutoRepeatModeOff;
|
||||||
|
|
||||||
XChangeKeyboardControl(xnestDisplay, value_mask, &values);
|
uint32_t value_list[16];
|
||||||
|
xnestEncodeKeyboardControl(values, value_mask, value_list);
|
||||||
|
xcb_change_keyboard_control(xnestUpstreamConn(), value_mask, value_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
value_mask = KBKey | KBAutoRepeatMode;
|
value_mask = KBKey | KBAutoRepeatMode;
|
||||||
|
@ -107,7 +90,9 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
||||||
values.led = i;
|
values.led = i;
|
||||||
values.led_mode =
|
values.led_mode =
|
||||||
(ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
|
(ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
|
||||||
XChangeKeyboardControl(xnestDisplay, value_mask, &values);
|
|
||||||
|
xnestEncodeKeyboardControl(values, value_mask, value_list);
|
||||||
|
xcb_change_keyboard_control(xnestUpstreamConn(), value_mask, value_list);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -115,73 +100,60 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
||||||
int
|
int
|
||||||
xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
||||||
{
|
{
|
||||||
XModifierKeymap *modifier_keymap;
|
|
||||||
KeySym *keymap;
|
|
||||||
int mapWidth;
|
|
||||||
int min_keycode, max_keycode;
|
|
||||||
KeySymsRec keySyms;
|
|
||||||
CARD8 modmap[MAP_LENGTH];
|
|
||||||
int i, j;
|
int i, j;
|
||||||
XKeyboardState values;
|
|
||||||
XkbDescPtr xkb;
|
|
||||||
int op, event, error, major, minor;
|
|
||||||
|
|
||||||
switch (onoff) {
|
switch (onoff) {
|
||||||
case DEVICE_INIT:
|
case DEVICE_INIT:
|
||||||
XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
|
{
|
||||||
#ifdef _XSERVER64
|
const int min_keycode = xnestUpstreamInfo.setup->min_keycode;
|
||||||
{
|
const int max_keycode = xnestUpstreamInfo.setup->max_keycode;
|
||||||
KeySym64 *keymap64;
|
const int num_keycode = max_keycode - min_keycode + 1;
|
||||||
int len;
|
|
||||||
|
|
||||||
keymap64 = XGetKeyboardMapping(xnestDisplay,
|
xcb_get_keyboard_mapping_reply_t * keymap_reply = xnestGetKeyboardMapping(
|
||||||
min_keycode,
|
xnestUpstreamInfo.conn,
|
||||||
max_keycode - min_keycode + 1,
|
min_keycode,
|
||||||
&mapWidth);
|
num_keycode);
|
||||||
len = (max_keycode - min_keycode + 1) * mapWidth;
|
|
||||||
keymap = xallocarray(len, sizeof(KeySym));
|
if (!keymap_reply) {
|
||||||
for (i = 0; i < len; ++i)
|
ErrorF("Couldn't get keyboard mappings: no reply");
|
||||||
keymap[i] = keymap64[i];
|
goto XkbError;
|
||||||
XFree(keymap64);
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
keymap = XGetKeyboardMapping(xnestDisplay,
|
|
||||||
min_keycode,
|
|
||||||
max_keycode - min_keycode + 1, &mapWidth);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(modmap, 0, sizeof(modmap));
|
KeySymsRec keySyms = {
|
||||||
modifier_keymap = XGetModifierMapping(xnestDisplay);
|
.minKeyCode = min_keycode,
|
||||||
|
.maxKeyCode = max_keycode,
|
||||||
|
.mapWidth = keymap_reply->keysyms_per_keycode,
|
||||||
|
.map = xcb_get_keyboard_mapping_keysyms(keymap_reply),
|
||||||
|
};
|
||||||
|
|
||||||
|
xcb_generic_error_t *mod_err = NULL;
|
||||||
|
xcb_get_modifier_mapping_reply_t *mod_reply = xcb_get_modifier_mapping_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_modifier_mapping(xnestUpstreamInfo.conn),
|
||||||
|
&mod_err);
|
||||||
|
|
||||||
|
if (mod_err) {
|
||||||
|
free(keymap_reply);
|
||||||
|
ErrorF("Couldn't get keyboard modifier mapping: %d\n", mod_err->error_code);
|
||||||
|
goto XkbError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mod_reply) {
|
||||||
|
free(keymap_reply);
|
||||||
|
ErrorF("Couldn't get keyboard modifier mapping: no reply\n");
|
||||||
|
goto XkbError;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_keycode_t *mod_keycodes = xcb_get_modifier_mapping_keycodes(mod_reply);
|
||||||
|
CARD8 modmap[MAP_LENGTH] = { 0 };
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
for (i = 0; i < modifier_keymap->max_keypermod; i++) {
|
for (i = 0; i < mod_reply->keycodes_per_modifier; i++) {
|
||||||
CARD8 keycode;
|
CARD8 keycode;
|
||||||
|
|
||||||
if ((keycode =
|
if ((keycode =
|
||||||
modifier_keymap->modifiermap[j *
|
mod_keycodes[j * mod_reply->keycodes_per_modifier + i]))
|
||||||
modifier_keymap->
|
|
||||||
max_keypermod + i]))
|
|
||||||
modmap[keycode] |= 1 << j;
|
modmap[keycode] |= 1 << j;
|
||||||
}
|
}
|
||||||
XFreeModifiermap(modifier_keymap);
|
|
||||||
|
|
||||||
keySyms.minKeyCode = min_keycode;
|
|
||||||
keySyms.maxKeyCode = max_keycode;
|
|
||||||
keySyms.mapWidth = mapWidth;
|
|
||||||
keySyms.map = keymap;
|
|
||||||
|
|
||||||
if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor)
|
|
||||||
== 0) {
|
|
||||||
ErrorF("Unable to initialize XKEYBOARD extension.\n");
|
|
||||||
goto XkbError;
|
|
||||||
}
|
|
||||||
xkb =
|
|
||||||
XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask,
|
|
||||||
XkbUseCoreKbd);
|
|
||||||
if (xkb == NULL || xkb->geom == NULL) {
|
|
||||||
ErrorF("Couldn't get keyboard.\n");
|
|
||||||
goto XkbError;
|
|
||||||
}
|
|
||||||
XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
|
|
||||||
|
|
||||||
InitKeyboardDeviceStruct(pDev, NULL,
|
InitKeyboardDeviceStruct(pDev, NULL,
|
||||||
xnestBell, xnestChangeKeyboardControl);
|
xnestBell, xnestChangeKeyboardControl);
|
||||||
|
@ -190,32 +162,109 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
||||||
keySyms.maxKeyCode - keySyms.minKeyCode + 1,
|
keySyms.maxKeyCode - keySyms.minKeyCode + 1,
|
||||||
modmap, serverClient);
|
modmap, serverClient);
|
||||||
|
|
||||||
XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
|
free(keymap_reply);
|
||||||
XkbFreeKeyboard(xkb, 0, False);
|
|
||||||
free(keymap);
|
xnestXkbInit(xnestUpstreamInfo.conn);
|
||||||
|
|
||||||
|
int device_id = xnestXkbDeviceId(xnestUpstreamInfo.conn);
|
||||||
|
|
||||||
|
xcb_generic_error_t *err = NULL;
|
||||||
|
xcb_xkb_get_controls_reply_t *reply = xcb_xkb_get_controls_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_xkb_get_controls(xnestUpstreamInfo.conn, device_id),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ErrorF("Couldn't get keyboard controls for %d: error %d\n", device_id, err->error_code);
|
||||||
|
free(err);
|
||||||
|
goto XkbError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reply) {
|
||||||
|
ErrorF("Couldn't get keyboard controls for %d: no reply", device_id);
|
||||||
|
goto XkbError;
|
||||||
|
}
|
||||||
|
|
||||||
|
XkbControlsRec ctrls = {
|
||||||
|
.mk_dflt_btn = reply->mouseKeysDfltBtn,
|
||||||
|
.num_groups = reply->numGroups,
|
||||||
|
.groups_wrap = reply->groupsWrap,
|
||||||
|
.internal = (XkbModsRec) {
|
||||||
|
.mask = reply->internalModsMask,
|
||||||
|
.real_mods = reply->internalModsRealMods,
|
||||||
|
.vmods = reply->internalModsVmods,
|
||||||
|
},
|
||||||
|
.ignore_lock = (XkbModsRec) {
|
||||||
|
.mask = reply->ignoreLockModsMask,
|
||||||
|
.real_mods = reply->ignoreLockModsRealMods,
|
||||||
|
.vmods = reply->ignoreLockModsVmods,
|
||||||
|
},
|
||||||
|
.enabled_ctrls = reply->enabledControls,
|
||||||
|
.repeat_delay = reply->repeatDelay,
|
||||||
|
.repeat_interval = reply->repeatInterval,
|
||||||
|
.slow_keys_delay = reply->slowKeysDelay,
|
||||||
|
.debounce_delay = reply->debounceDelay,
|
||||||
|
.mk_delay = reply->mouseKeysDelay,
|
||||||
|
.mk_interval = reply->mouseKeysInterval,
|
||||||
|
.mk_time_to_max = reply->mouseKeysTimeToMax,
|
||||||
|
.mk_max_speed = reply->mouseKeysMaxSpeed,
|
||||||
|
.mk_curve = reply->mouseKeysCurve,
|
||||||
|
.ax_options = reply->accessXOption,
|
||||||
|
.ax_timeout = reply->accessXTimeout,
|
||||||
|
.axt_opts_mask = reply->accessXTimeoutOptionsMask,
|
||||||
|
.axt_opts_values = reply->accessXTimeoutOptionsValues,
|
||||||
|
.axt_ctrls_mask = reply->accessXTimeoutMask,
|
||||||
|
.axt_ctrls_values = reply->accessXTimeoutValues,
|
||||||
|
};
|
||||||
|
memcpy(&ctrls.per_key_repeat, reply->perKeyRepeat, sizeof(ctrls.per_key_repeat));
|
||||||
|
|
||||||
|
XkbDDXChangeControls(pDev, &ctrls, &ctrls);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DEVICE_ON:
|
case DEVICE_ON:
|
||||||
xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
|
xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
|
||||||
for (i = 0; i < xnestNumScreens; i++)
|
for (i = 0; i < xnestNumScreens; i++)
|
||||||
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[i],
|
||||||
|
XCB_CW_EVENT_MASK,
|
||||||
|
&xnestEventMask);
|
||||||
break;
|
break;
|
||||||
case DEVICE_OFF:
|
case DEVICE_OFF:
|
||||||
xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
|
xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
|
||||||
for (i = 0; i < xnestNumScreens; i++)
|
for (i = 0; i < xnestNumScreens; i++)
|
||||||
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[i],
|
||||||
|
XCB_CW_EVENT_MASK,
|
||||||
|
&xnestEventMask);
|
||||||
break;
|
break;
|
||||||
case DEVICE_CLOSE:
|
case DEVICE_CLOSE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return Success;
|
return Success;
|
||||||
|
|
||||||
XkbError:
|
XkbError:
|
||||||
XGetKeyboardControl(xnestDisplay, &values);
|
{
|
||||||
memmove((char *) defaultKeyboardControl.autoRepeats,
|
xcb_generic_error_t *ctrl_err = NULL;
|
||||||
(char *) values.auto_repeats, sizeof(values.auto_repeats));
|
xcb_get_keyboard_control_reply_t *ctrl_reply =
|
||||||
|
xcb_get_keyboard_control_reply(xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_keyboard_control(xnestUpstreamInfo.conn),
|
||||||
|
&ctrl_err);
|
||||||
|
if (ctrl_err) {
|
||||||
|
ErrorF("failed retrieving keyboard control: %d\n", ctrl_err->error_code);
|
||||||
|
free(ctrl_err);
|
||||||
|
}
|
||||||
|
else if (!ctrl_reply) {
|
||||||
|
ErrorF("failed retrieving keyboard control: no reply\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(defaultKeyboardControl.autoRepeats,
|
||||||
|
ctrl_reply->auto_repeats,
|
||||||
|
sizeof(ctrl_reply->auto_repeats));
|
||||||
|
free(ctrl_reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
|
InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
|
||||||
free(keymap);
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,8 @@ is" without express or implied warranty.
|
||||||
#define XNESTKEYBOARD_H
|
#define XNESTKEYBOARD_H
|
||||||
|
|
||||||
#define XNEST_KEYBOARD_EVENT_MASK \
|
#define XNEST_KEYBOARD_EVENT_MASK \
|
||||||
(KeyPressMask | KeyReleaseMask | FocusChangeMask | KeymapStateMask)
|
(XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE | \
|
||||||
|
XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_KEYMAP_STATE)
|
||||||
|
|
||||||
extern DeviceIntPtr xnestKeyboardDevice;
|
extern DeviceIntPtr xnestKeyboardDevice;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ is" without express or implied warranty.
|
||||||
#include "privates.h"
|
#include "privates.h"
|
||||||
#include "mi.h"
|
#include "mi.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
@ -59,11 +59,12 @@ xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
|
||||||
pPixmap->refcnt = 1;
|
pPixmap->refcnt = 1;
|
||||||
pPixmap->devKind = PixmapBytePad(width, depth);
|
pPixmap->devKind = PixmapBytePad(width, depth);
|
||||||
pPixmap->usage_hint = usage_hint;
|
pPixmap->usage_hint = usage_hint;
|
||||||
if (width && height)
|
if (width && height) {
|
||||||
xnestPixmapPriv(pPixmap)->pixmap =
|
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
XCreatePixmap(xnestDisplay,
|
xcb_create_pixmap(xnestUpstreamInfo.conn, depth, pixmap,
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
xnestDefaultWindows[pScreen->myNum], width, height);
|
||||||
width, height, depth);
|
xnestPixmapPriv(pPixmap)->pixmap = pixmap;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
xnestPixmapPriv(pPixmap)->pixmap = 0;
|
xnestPixmapPriv(pPixmap)->pixmap = 0;
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ xnestDestroyPixmap(PixmapPtr pPixmap)
|
||||||
{
|
{
|
||||||
if (--pPixmap->refcnt)
|
if (--pPixmap->refcnt)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
|
xcb_free_pixmap(xnestUpstreamInfo.conn, xnestPixmap(pPixmap));
|
||||||
FreePixmap(pPixmap);
|
FreePixmap(pPixmap);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -85,10 +86,11 @@ xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
int bitsPerPixel, int devKind, void *pPixData)
|
int bitsPerPixel, int devKind, void *pPixData)
|
||||||
{
|
{
|
||||||
if(!xnestPixmapPriv(pPixmap)->pixmap && width > 0 && height > 0) {
|
if(!xnestPixmapPriv(pPixmap)->pixmap && width > 0 && height > 0) {
|
||||||
xnestPixmapPriv(pPixmap)->pixmap =
|
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
XCreatePixmap(xnestDisplay,
|
xcb_create_pixmap(xnestUpstreamInfo.conn, depth, pixmap,
|
||||||
xnestDefaultWindows[pPixmap->drawable.pScreen->myNum],
|
xnestDefaultWindows[pPixmap->drawable.pScreen->myNum],
|
||||||
width, height, depth);
|
width, height);
|
||||||
|
xnestPixmapPriv(pPixmap)->pixmap = pixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
return miModifyPixmapHeader(pPixmap, width, height, depth,
|
return miModifyPixmapHeader(pPixmap, width, height, depth,
|
||||||
|
@ -98,30 +100,60 @@ xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
|
||||||
RegionPtr
|
RegionPtr
|
||||||
xnestPixmapToRegion(PixmapPtr pPixmap)
|
xnestPixmapToRegion(PixmapPtr pPixmap)
|
||||||
{
|
{
|
||||||
XImage *ximage;
|
|
||||||
register RegionPtr pReg, pTmpReg;
|
register RegionPtr pReg, pTmpReg;
|
||||||
register int x, y;
|
register int x, y;
|
||||||
unsigned long previousPixel, currentPixel;
|
unsigned long previousPixel, currentPixel;
|
||||||
BoxRec Box = { 0, 0, 0, 0 };
|
BoxRec Box = { 0, 0, 0, 0 };
|
||||||
Bool overlap;
|
Bool overlap;
|
||||||
|
|
||||||
ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0,
|
if (pPixmap->drawable.depth != 1) {
|
||||||
pPixmap->drawable.width, pPixmap->drawable.height,
|
LogMessage(X_WARNING, "xnestPixmapToRegion() depth != 1: %d\n", pPixmap->drawable.depth);
|
||||||
1, XYPixmap);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_generic_error_t *err = NULL;
|
||||||
|
xcb_get_image_reply_t *reply = xcb_get_image_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_image(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
XCB_IMAGE_FORMAT_XY_PIXMAP,
|
||||||
|
xnestPixmap(pPixmap),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
pPixmap->drawable.width,
|
||||||
|
pPixmap->drawable.height,
|
||||||
|
~0),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
// badMatch may happeen if the upstream window is currently minimized
|
||||||
|
if (err->error_code != BadMatch)
|
||||||
|
ErrorF("xnestGetImage: received error %d\n", err->error_code);
|
||||||
|
free(err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reply) {
|
||||||
|
ErrorF("xnestGetImage: received no reply\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pReg = RegionCreate(NULL, 1);
|
pReg = RegionCreate(NULL, 1);
|
||||||
pTmpReg = RegionCreate(NULL, 1);
|
pTmpReg = RegionCreate(NULL, 1);
|
||||||
if (!pReg || !pTmpReg) {
|
if (!pReg || !pTmpReg) {
|
||||||
XDestroyImage(ximage);
|
free(reply);
|
||||||
return NullRegion;
|
return NullRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t *image_data = xcb_get_image_data(reply);
|
||||||
for (y = 0; y < pPixmap->drawable.height; y++) {
|
for (y = 0; y < pPixmap->drawable.height; y++) {
|
||||||
Box.y1 = y;
|
Box.y1 = y;
|
||||||
Box.y2 = y + 1;
|
Box.y2 = y + 1;
|
||||||
previousPixel = 0L;
|
previousPixel = 0L;
|
||||||
|
const int line_start = BitmapBytePad(pPixmap->drawable.width) * y;
|
||||||
|
|
||||||
for (x = 0; x < pPixmap->drawable.width; x++) {
|
for (x = 0; x < pPixmap->drawable.width; x++) {
|
||||||
currentPixel = XGetPixel(ximage, x, y);
|
currentPixel = ((image_data[line_start + (x/8)]) >> (x % 8)) & 1;
|
||||||
if (previousPixel != currentPixel) {
|
if (previousPixel != currentPixel) {
|
||||||
if (previousPixel == 0L) {
|
if (previousPixel == 0L) {
|
||||||
/* left edge */
|
/* left edge */
|
||||||
|
@ -145,7 +177,7 @@ xnestPixmapToRegion(PixmapPtr pPixmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionDestroy(pTmpReg);
|
RegionDestroy(pTmpReg);
|
||||||
XDestroyImage(ximage);
|
free(reply);
|
||||||
|
|
||||||
RegionValidate(pReg, &overlap);
|
RegionValidate(pReg, &overlap);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ is" without express or implied warranty.
|
||||||
#include "servermd.h"
|
#include "servermd.h"
|
||||||
#include "mipointer.h"
|
#include "mipointer.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
@ -41,25 +41,24 @@ DeviceIntPtr xnestPointerDevice = NULL;
|
||||||
void
|
void
|
||||||
xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl * ctrl)
|
xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl * ctrl)
|
||||||
{
|
{
|
||||||
XChangePointerControl(xnestDisplay, True, True,
|
xcb_change_pointer_control(xnestUpstreamInfo.conn,
|
||||||
ctrl->num, ctrl->den, ctrl->threshold);
|
ctrl->num,
|
||||||
|
ctrl->den,
|
||||||
|
ctrl->threshold,
|
||||||
|
TRUE,
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
xnestPointerProc(DeviceIntPtr pDev, int onoff)
|
xnestPointerProc(DeviceIntPtr pDev, int onoff)
|
||||||
{
|
{
|
||||||
CARD8 map[MAXBUTTONS];
|
|
||||||
Atom btn_labels[MAXBUTTONS] = { 0 };
|
Atom btn_labels[MAXBUTTONS] = { 0 };
|
||||||
Atom axes_labels[2] = { 0 };
|
Atom axes_labels[2] = { 0 };
|
||||||
int nmap;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch (onoff) {
|
switch (onoff) {
|
||||||
case DEVICE_INIT:
|
case DEVICE_INIT:
|
||||||
nmap = XGetPointerMapping(xnestDisplay, map, MAXBUTTONS);
|
{
|
||||||
for (i = 0; i <= nmap; i++)
|
|
||||||
map[i] = i; /* buttons are already mapped */
|
|
||||||
|
|
||||||
btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
|
btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
|
||||||
btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
|
btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
|
||||||
btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
|
btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
|
||||||
|
@ -71,23 +70,57 @@ xnestPointerProc(DeviceIntPtr pDev, int onoff)
|
||||||
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
|
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
|
||||||
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
|
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
|
||||||
|
|
||||||
XGetPointerControl(xnestDisplay,
|
xnestGetPointerControl(xnestUpstreamInfo.conn,
|
||||||
&defaultPointerControl.num,
|
&defaultPointerControl.num,
|
||||||
&defaultPointerControl.den,
|
&defaultPointerControl.den,
|
||||||
&defaultPointerControl.threshold);
|
&defaultPointerControl.threshold);
|
||||||
InitPointerDeviceStruct(&pDev->public, map, nmap, btn_labels,
|
|
||||||
|
xcb_generic_error_t *pm_err = NULL;
|
||||||
|
xcb_get_pointer_mapping_reply_t *pm_reply =
|
||||||
|
xcb_get_pointer_mapping_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_pointer_mapping(xnestUpstreamInfo.conn),
|
||||||
|
&pm_err);
|
||||||
|
if (pm_err) {
|
||||||
|
ErrorF("failed getting pointer mapping %d\n", pm_err->error_code);
|
||||||
|
free(pm_err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pm_reply) {
|
||||||
|
ErrorF("failed getting pointer mapping: no reply\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int nmap = xcb_get_pointer_mapping_map_length(pm_reply);
|
||||||
|
uint8_t *map = xcb_get_pointer_mapping_map(pm_reply);
|
||||||
|
for (i=0; i<nmap; i++)
|
||||||
|
map[i] = i; /* buttons are already mapped */
|
||||||
|
|
||||||
|
InitPointerDeviceStruct(&pDev->public,
|
||||||
|
map,
|
||||||
|
nmap,
|
||||||
|
btn_labels,
|
||||||
xnestChangePointerControl,
|
xnestChangePointerControl,
|
||||||
GetMotionHistorySize(), 2, axes_labels);
|
GetMotionHistorySize(), 2, axes_labels);
|
||||||
|
free(pm_reply);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DEVICE_ON:
|
case DEVICE_ON:
|
||||||
xnestEventMask |= XNEST_POINTER_EVENT_MASK;
|
xnestEventMask |= XNEST_POINTER_EVENT_MASK;
|
||||||
for (i = 0; i < xnestNumScreens; i++)
|
for (i = 0; i < xnestNumScreens; i++)
|
||||||
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[i],
|
||||||
|
XCB_CW_EVENT_MASK,
|
||||||
|
&xnestEventMask);
|
||||||
break;
|
break;
|
||||||
case DEVICE_OFF:
|
case DEVICE_OFF:
|
||||||
xnestEventMask &= ~XNEST_POINTER_EVENT_MASK;
|
xnestEventMask &= ~XNEST_POINTER_EVENT_MASK;
|
||||||
for (i = 0; i < xnestNumScreens; i++)
|
for (i = 0; i < xnestNumScreens; i++)
|
||||||
XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[i],
|
||||||
|
XCB_CW_EVENT_MASK,
|
||||||
|
&xnestEventMask);
|
||||||
break;
|
break;
|
||||||
case DEVICE_CLOSE:
|
case DEVICE_CLOSE:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,6 +20,8 @@ is" without express or implied warranty.
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
|
|
||||||
|
#include <xcb/xcb_icccm.h>
|
||||||
|
|
||||||
#include "mi/mi_priv.h"
|
#include "mi/mi_priv.h"
|
||||||
|
|
||||||
#include "scrnintstr.h"
|
#include "scrnintstr.h"
|
||||||
|
@ -29,7 +31,7 @@ is" without express or implied warranty.
|
||||||
#include "colormapst.h"
|
#include "colormapst.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
@ -39,7 +41,6 @@ is" without express or implied warranty.
|
||||||
#include "XNFont.h"
|
#include "XNFont.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include "XNCursor.h"
|
#include "XNCursor.h"
|
||||||
#include "Visual.h"
|
|
||||||
#include "Events.h"
|
#include "Events.h"
|
||||||
#include "Init.h"
|
#include "Init.h"
|
||||||
#include "mipointer.h"
|
#include "mipointer.h"
|
||||||
|
@ -78,31 +79,36 @@ static Bool
|
||||||
xnestSaveScreen(ScreenPtr pScreen, int what)
|
xnestSaveScreen(ScreenPtr pScreen, int what)
|
||||||
{
|
{
|
||||||
if (xnestSoftwareScreenSaver)
|
if (xnestSoftwareScreenSaver)
|
||||||
return False;
|
return FALSE;
|
||||||
else {
|
else {
|
||||||
switch (what) {
|
switch (what) {
|
||||||
case SCREEN_SAVER_ON:
|
case SCREEN_SAVER_ON:
|
||||||
XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
|
xcb_map_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
|
||||||
|
uint32_t value = XCB_STACK_MODE_ABOVE;
|
||||||
|
xcb_configure_window(xnestUpstreamInfo.conn,
|
||||||
|
xnestScreenSaverWindows[pScreen->myNum],
|
||||||
|
XCB_CONFIG_WINDOW_STACK_MODE,
|
||||||
|
&value);
|
||||||
xnestSetScreenSaverColormapWindow(pScreen);
|
xnestSetScreenSaverColormapWindow(pScreen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCREEN_SAVER_OFF:
|
case SCREEN_SAVER_OFF:
|
||||||
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
|
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
|
||||||
xnestSetInstalledColormapWindows(pScreen);
|
xnestSetInstalledColormapWindows(pScreen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCREEN_SAVER_FORCER:
|
case SCREEN_SAVER_FORCER:
|
||||||
lastEventTime = GetTimeInMillis();
|
lastEventTime = GetTimeInMillis();
|
||||||
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
|
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
|
||||||
xnestSetInstalledColormapWindows(pScreen);
|
xnestSetInstalledColormapWindows(pScreen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCREEN_SAVER_CYCLE:
|
case SCREEN_SAVER_CYCLE:
|
||||||
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
|
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
|
||||||
xnestSetInstalledColormapWindows(pScreen);
|
xnestSetInstalledColormapWindows(pScreen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,17 +138,39 @@ static miPointerSpriteFuncRec xnestPointerSpriteFuncs = {
|
||||||
xnestDeviceCursorCleanup
|
xnestDeviceCursorCleanup
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int addDepthVisual(DepthPtr depths, int numDepths, int nplanes, VisualID vid)
|
||||||
|
{
|
||||||
|
DepthPtr walk = NULL;
|
||||||
|
|
||||||
|
for (int j = 0; j < numDepths; j++)
|
||||||
|
if (depths[j].depth == nplanes) {
|
||||||
|
walk = &depths[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!walk) {
|
||||||
|
walk = &depths[numDepths++];
|
||||||
|
walk->depth = nplanes;
|
||||||
|
walk->numVids = 0;
|
||||||
|
walk->vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
|
||||||
|
}
|
||||||
|
if (walk->numVids >= MAXVISUALSPERDEPTH) {
|
||||||
|
FatalError("Visual table overflow");
|
||||||
|
}
|
||||||
|
walk->vids[walk->numVids] = vid;
|
||||||
|
walk->numVids++;
|
||||||
|
|
||||||
|
return numDepths;
|
||||||
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
VisualPtr visuals;
|
VisualPtr visuals;
|
||||||
DepthPtr depths;
|
DepthPtr depths;
|
||||||
int numVisuals, numDepths;
|
int numVisuals, numDepths;
|
||||||
int i, j, depthIndex;
|
int j;
|
||||||
unsigned long valuemask;
|
unsigned long valuemask;
|
||||||
XSetWindowAttributes attributes;
|
|
||||||
XWindowAttributes gattributes;
|
|
||||||
XSizeHints sizeHints;
|
|
||||||
VisualID defaultVisual;
|
VisualID defaultVisual;
|
||||||
int rootDepth;
|
int rootDepth;
|
||||||
miPointerScreenPtr PointPriv;
|
miPointerScreenPtr PointPriv;
|
||||||
|
@ -167,96 +195,128 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
||||||
PRIVATE_CURSOR, 0))
|
PRIVATE_CURSOR, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
visuals = xallocarray(xnestNumVisuals, sizeof(VisualRec));
|
visuals = xallocarray(1, sizeof(VisualRec));
|
||||||
numVisuals = 0;
|
numVisuals = 0;
|
||||||
|
|
||||||
|
if (!xnestVisualMap)
|
||||||
|
xnestVisualMap = calloc(1, sizeof(XnestVisualRec));
|
||||||
|
else
|
||||||
|
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(XnestVisualRec));
|
||||||
|
|
||||||
depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
|
depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
|
||||||
depths[0].depth = 1;
|
depths[0].depth = 1;
|
||||||
depths[0].numVids = 0;
|
depths[0].numVids = 0;
|
||||||
depths[0].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
|
depths[0].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
|
||||||
numDepths = 1;
|
numDepths = 1;
|
||||||
|
|
||||||
for (i = 0; i < xnestNumVisuals; i++) {
|
int found_default_visual = 0;
|
||||||
visuals[numVisuals].class = xnestVisuals[i].class;
|
xcb_depth_iterator_t depth_iter;
|
||||||
visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
|
for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
|
||||||
visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
|
depth_iter.rem;
|
||||||
visuals[numVisuals].nplanes = xnestVisuals[i].depth;
|
xcb_depth_next(&depth_iter))
|
||||||
visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
|
{
|
||||||
visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
|
int vlen = xcb_depth_visuals_length (depth_iter.data);
|
||||||
visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
|
xcb_visualtype_t *vts = xcb_depth_visuals (depth_iter.data);
|
||||||
visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
|
for (int x=0; x<vlen; x++) {
|
||||||
visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
|
for (j = 0; j < numVisuals; j++) {
|
||||||
visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
|
if (vts[x]._class == visuals[j].class &&
|
||||||
|
vts[x].bits_per_rgb_value == visuals[j].bitsPerRGBValue &&
|
||||||
/* Check for and remove duplicates. */
|
vts[x].colormap_entries == visuals[j].ColormapEntries &&
|
||||||
for (j = 0; j < numVisuals; j++) {
|
depth_iter.data->depth == visuals[j].nplanes &&
|
||||||
if (visuals[numVisuals].class == visuals[j].class &&
|
vts[x].red_mask == visuals[j].redMask &&
|
||||||
visuals[numVisuals].bitsPerRGBValue ==
|
vts[x].green_mask == visuals[j].greenMask &&
|
||||||
visuals[j].bitsPerRGBValue &&
|
vts[x].blue_mask == visuals[j].blueMask &&
|
||||||
visuals[numVisuals].ColormapEntries ==
|
offset(vts[x].red_mask) == visuals[j].offsetRed &&
|
||||||
visuals[j].ColormapEntries &&
|
offset(vts[x].green_mask) == visuals[j].offsetGreen &&
|
||||||
visuals[numVisuals].nplanes == visuals[j].nplanes &&
|
offset(vts[x].blue_mask) == visuals[j].offsetBlue)
|
||||||
visuals[numVisuals].redMask == visuals[j].redMask &&
|
goto breakout;
|
||||||
visuals[numVisuals].greenMask == visuals[j].greenMask &&
|
|
||||||
visuals[numVisuals].blueMask == visuals[j].blueMask &&
|
|
||||||
visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
|
|
||||||
visuals[numVisuals].offsetGreen == visuals[j].offsetGreen &&
|
|
||||||
visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (j < numVisuals)
|
|
||||||
break;
|
|
||||||
|
|
||||||
visuals[numVisuals].vid = FakeClientID(0);
|
|
||||||
|
|
||||||
depthIndex = UNDEFINED;
|
|
||||||
for (j = 0; j < numDepths; j++)
|
|
||||||
if (depths[j].depth == xnestVisuals[i].depth) {
|
|
||||||
depthIndex = j;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depthIndex == UNDEFINED) {
|
visuals[numVisuals] = (VisualRec) {
|
||||||
depthIndex = numDepths;
|
.class = vts[x]._class,
|
||||||
depths[depthIndex].depth = xnestVisuals[i].depth;
|
.bitsPerRGBValue = vts[x].bits_per_rgb_value,
|
||||||
depths[depthIndex].numVids = 0;
|
.ColormapEntries = vts[x].colormap_entries,
|
||||||
depths[depthIndex].vids =
|
.nplanes = depth_iter.data->depth,
|
||||||
(VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
|
.redMask = vts[x].red_mask,
|
||||||
numDepths++;
|
.greenMask = vts[x].green_mask,
|
||||||
}
|
.blueMask = vts[x].blue_mask,
|
||||||
if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
|
.offsetRed = offset(vts[x].red_mask),
|
||||||
FatalError("Visual table overflow");
|
.offsetGreen = offset(vts[x].green_mask),
|
||||||
}
|
.offsetBlue = offset(vts[x].blue_mask),
|
||||||
depths[depthIndex].vids[depths[depthIndex].numVids] =
|
.vid = FakeClientID(0),
|
||||||
visuals[numVisuals].vid;
|
};
|
||||||
depths[depthIndex].numVids++;
|
|
||||||
|
|
||||||
numVisuals++;
|
xnestVisualMap[xnestNumVisualMap] = (XnestVisualRec) {
|
||||||
|
.ourXID = visuals[numVisuals].vid,
|
||||||
|
.ourVisual = &visuals[numVisuals],
|
||||||
|
.upstreamDepth = depth_iter.data,
|
||||||
|
.upstreamVisual = &vts[x],
|
||||||
|
.upstreamCMap = xcb_generate_id(xnestUpstreamInfo.conn),
|
||||||
|
};
|
||||||
|
|
||||||
|
xcb_create_colormap(xnestUpstreamInfo.conn,
|
||||||
|
XCB_COLORMAP_ALLOC_NONE,
|
||||||
|
xnestVisualMap[xnestNumVisualMap].upstreamCMap,
|
||||||
|
xnestUpstreamInfo.screenInfo->root,
|
||||||
|
xnestVisualMap[xnestNumVisualMap].upstreamVisual->visual_id);
|
||||||
|
|
||||||
|
numDepths = addDepthVisual(depths, numDepths, visuals[numVisuals].nplanes, visuals[numVisuals].vid);
|
||||||
|
|
||||||
|
if (xnestUserDefaultClass || xnestUserDefaultDepth) {
|
||||||
|
if ((!xnestDefaultClass || visuals[numVisuals].class == xnestDefaultClass) &&
|
||||||
|
(!xnestDefaultDepth || visuals[numVisuals].nplanes == xnestDefaultDepth))
|
||||||
|
{
|
||||||
|
defaultVisual = visuals[numVisuals].vid;
|
||||||
|
rootDepth = visuals[numVisuals].nplanes;
|
||||||
|
found_default_visual = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VisualID visual_id = xnestUpstreamInfo.screenInfo->root_visual;
|
||||||
|
if (visual_id == vts[x].visual_id) {
|
||||||
|
defaultVisual = visuals[numVisuals].vid;
|
||||||
|
rootDepth = visuals[numVisuals].nplanes;
|
||||||
|
found_default_visual = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
numVisuals++;
|
||||||
|
xnestNumVisualMap++;
|
||||||
|
visuals = reallocarray(visuals, numVisuals+1, sizeof(VisualRec));
|
||||||
|
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(XnestVisualRec));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
breakout:
|
||||||
visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
|
visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
|
||||||
|
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap, sizeof(XnestVisualRec));
|
||||||
|
|
||||||
defaultVisual = visuals[xnestDefaultVisualIndex].vid;
|
if (!found_default_visual) {
|
||||||
rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
|
ErrorF("Xnest: can't find matching visual for user specified depth %d\n", xnestDefaultDepth);
|
||||||
|
defaultVisual = visuals[0].vid;
|
||||||
|
rootDepth = visuals[0].nplanes;
|
||||||
|
}
|
||||||
|
|
||||||
if (xnestParentWindow != 0) {
|
if (xnestParentWindow != 0) {
|
||||||
XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
|
xRectangle r = xnestGetGeometry(xnestUpstreamInfo.conn, xnestParentWindow);
|
||||||
xnestWidth = gattributes.width;
|
xnestGeometry.width = r.width;
|
||||||
xnestHeight = gattributes.height;
|
xnestGeometry.height = r.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* myNum */
|
/* myNum */
|
||||||
/* id */
|
/* id */
|
||||||
if (!miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth, rootDepth, numDepths, depths, defaultVisual, /* root visual */
|
if (!miScreenInit(pScreen, NULL, xnestGeometry.width, xnestGeometry.height,
|
||||||
|
1, 1, xnestGeometry.width, rootDepth, numDepths, depths, defaultVisual, /* root visual */
|
||||||
numVisuals, visuals))
|
numVisuals, visuals))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pScreen->defColormap = (Colormap) FakeClientID(0);
|
pScreen->defColormap = (Colormap) FakeClientID(0);
|
||||||
pScreen->minInstalledCmaps = MINCMAPS;
|
pScreen->minInstalledCmaps = MINCMAPS;
|
||||||
pScreen->maxInstalledCmaps = MAXCMAPS;
|
pScreen->maxInstalledCmaps = MAXCMAPS;
|
||||||
pScreen->backingStoreSupport = NotUseful;
|
pScreen->backingStoreSupport = XCB_BACKING_STORE_NOT_USEFUL;
|
||||||
pScreen->saveUnderSupport = NotUseful;
|
pScreen->saveUnderSupport = XCB_BACKING_STORE_NOT_USEFUL;
|
||||||
pScreen->whitePixel = xnestWhitePixel;
|
pScreen->whitePixel = xnestUpstreamInfo.screenInfo->white_pixel;
|
||||||
pScreen->blackPixel = xnestBlackPixel;
|
pScreen->blackPixel = xnestUpstreamInfo.screenInfo->black_pixel;
|
||||||
/* GCperDepth */
|
/* GCperDepth */
|
||||||
/* defaultStipple */
|
/* defaultStipple */
|
||||||
/* WindowPrivateLen */
|
/* WindowPrivateLen */
|
||||||
|
@ -282,9 +342,10 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
||||||
pScreen->RealizeWindow = xnestRealizeWindow;
|
pScreen->RealizeWindow = xnestRealizeWindow;
|
||||||
pScreen->UnrealizeWindow = xnestUnrealizeWindow;
|
pScreen->UnrealizeWindow = xnestUnrealizeWindow;
|
||||||
pScreen->PostValidateTree = NULL;
|
pScreen->PostValidateTree = NULL;
|
||||||
pScreen->WindowExposures = xnestWindowExposures;
|
pScreen->WindowExposures = miWindowExposures;
|
||||||
pScreen->CopyWindow = xnestCopyWindow;
|
pScreen->CopyWindow = xnestCopyWindow;
|
||||||
pScreen->ClipNotify = xnestClipNotify;
|
pScreen->ClipNotify = xnestClipNotify;
|
||||||
|
pScreen->ClearToBackground = xnestClearToBackground;
|
||||||
|
|
||||||
/* Pixmap procedures */
|
/* Pixmap procedures */
|
||||||
|
|
||||||
|
@ -325,13 +386,12 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
||||||
&xnestCursorFuncs);
|
&xnestCursorFuncs);
|
||||||
PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
|
PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
|
||||||
|
|
||||||
pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
|
pScreen->mmWidth =
|
||||||
DefaultScreen(xnestDisplay))
|
xnestGeometry.width * xnestUpstreamInfo.screenInfo->width_in_millimeters /
|
||||||
/ DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay));
|
xnestUpstreamInfo.screenInfo->width_in_pixels;
|
||||||
pScreen->mmHeight =
|
pScreen->mmHeight =
|
||||||
xnestHeight * DisplayHeightMM(xnestDisplay,
|
xnestGeometry.height * xnestUpstreamInfo.screenInfo->height_in_millimeters /
|
||||||
DefaultScreen(xnestDisplay)) /
|
xnestUpstreamInfo.screenInfo->height_in_pixels;
|
||||||
DisplayHeight(xnestDisplay, DefaultScreen(xnestDisplay));
|
|
||||||
|
|
||||||
/* overwrite miCloseScreen with our own */
|
/* overwrite miCloseScreen with our own */
|
||||||
pScreen->CloseScreen = xnestCloseScreen;
|
pScreen->CloseScreen = xnestCloseScreen;
|
||||||
|
@ -341,74 +401,123 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
||||||
|
|
||||||
/* devPrivates */
|
/* devPrivates */
|
||||||
|
|
||||||
#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
|
#define POSITION_OFFSET (pScreen->myNum * (xnestGeometry.width + xnestGeometry.height) / 32)
|
||||||
|
|
||||||
if (xnestDoFullGeneration) {
|
if (xnestDoFullGeneration) {
|
||||||
|
|
||||||
valuemask = CWBackPixel | CWEventMask | CWColormap;
|
XnSetWindowAttr attributes = {
|
||||||
attributes.background_pixel = xnestWhitePixel;
|
.background_pixel = xnestUpstreamInfo.screenInfo->white_pixel,
|
||||||
attributes.event_mask = xnestEventMask;
|
.event_mask = xnestEventMask,
|
||||||
attributes.colormap =
|
.colormap = xnestVisualToHostCmap(pScreen->rootVisual),
|
||||||
xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
|
};
|
||||||
|
|
||||||
|
valuemask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
|
||||||
|
|
||||||
if (xnestParentWindow != 0) {
|
if (xnestParentWindow != 0) {
|
||||||
xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
|
xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
|
||||||
XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
xnestEventMask);
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
XCB_CW_EVENT_MASK,
|
||||||
|
&xnestEventMask);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
xnestDefaultWindows[pScreen->myNum] =
|
uint32_t values[32] = { 0 };
|
||||||
XCreateWindow(xnestDisplay,
|
xnest_encode_window_attr(attributes, valuemask, values);
|
||||||
DefaultRootWindow(xnestDisplay),
|
|
||||||
xnestX + POSITION_OFFSET,
|
xnestDefaultWindows[pScreen->myNum] = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
xnestY + POSITION_OFFSET,
|
xcb_create_window(xnestUpstreamInfo.conn,
|
||||||
xnestWidth, xnestHeight,
|
|
||||||
xnestBorderWidth,
|
|
||||||
pScreen->rootDepth,
|
pScreen->rootDepth,
|
||||||
InputOutput,
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
xnestDefaultVisual(pScreen),
|
xnestUpstreamInfo.screenInfo->root,
|
||||||
valuemask, &attributes);
|
xnestGeometry.x + POSITION_OFFSET,
|
||||||
|
xnestGeometry.y + POSITION_OFFSET,
|
||||||
|
xnestGeometry.width,
|
||||||
|
xnestGeometry.height,
|
||||||
|
xnestBorderWidth,
|
||||||
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||||
|
xnest_visual_map_to_host(pScreen->rootVisual),
|
||||||
|
valuemask,
|
||||||
|
values);
|
||||||
|
}
|
||||||
|
|
||||||
if (!xnestWindowName)
|
if (!xnestWindowName)
|
||||||
xnestWindowName = argv[0];
|
xnestWindowName = argv[0];
|
||||||
|
|
||||||
sizeHints.flags = PPosition | PSize | PMaxSize;
|
xcb_size_hints_t sizeHints = {
|
||||||
sizeHints.x = xnestX + POSITION_OFFSET;
|
.flags = XCB_ICCCM_SIZE_HINT_P_POSITION | XCB_ICCCM_SIZE_HINT_P_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE,
|
||||||
sizeHints.y = xnestY + POSITION_OFFSET;
|
.x = xnestGeometry.x + POSITION_OFFSET,
|
||||||
sizeHints.width = sizeHints.max_width = xnestWidth;
|
.y = xnestGeometry.y + POSITION_OFFSET,
|
||||||
sizeHints.height = sizeHints.max_height = xnestHeight;
|
.width = xnestGeometry.width,
|
||||||
if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
|
.height = xnestGeometry.height,
|
||||||
sizeHints.flags |= USPosition;
|
.max_width = xnestGeometry.width,
|
||||||
if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
|
.max_height = xnestGeometry.height,
|
||||||
sizeHints.flags |= USSize;
|
};
|
||||||
XSetStandardProperties(xnestDisplay,
|
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
|
||||||
xnestWindowName,
|
|
||||||
xnestWindowName,
|
|
||||||
xnestIconBitmap, argv, argc, &sizeHints);
|
|
||||||
|
|
||||||
XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
|
if (xnestUserGeometry & XCB_CONFIG_WINDOW_X ||
|
||||||
|
xnestUserGeometry & XCB_CONFIG_WINDOW_Y)
|
||||||
|
sizeHints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION;
|
||||||
|
if (xnestUserGeometry & XCB_CONFIG_WINDOW_WIDTH ||
|
||||||
|
xnestUserGeometry & XCB_CONFIG_WINDOW_HEIGHT)
|
||||||
|
sizeHints.flags |= XCB_ICCCM_SIZE_HINT_US_SIZE;
|
||||||
|
|
||||||
valuemask = CWBackPixmap | CWColormap;
|
const size_t windowNameLen = strlen(xnestWindowName);
|
||||||
|
|
||||||
|
xcb_icccm_set_wm_name_checked(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
XCB_ATOM_STRING,
|
||||||
|
8,
|
||||||
|
windowNameLen,
|
||||||
|
xnestWindowName);
|
||||||
|
|
||||||
|
xcb_icccm_set_wm_icon_name_checked(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
XCB_ATOM_STRING,
|
||||||
|
8,
|
||||||
|
windowNameLen,
|
||||||
|
xnestWindowName);
|
||||||
|
|
||||||
|
xnestSetCommand(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
argv, argc);
|
||||||
|
|
||||||
|
xcb_icccm_wm_hints_t wmhints = {
|
||||||
|
.icon_pixmap = xnestIconBitmap,
|
||||||
|
.flags = XCB_ICCCM_WM_HINT_ICON_PIXMAP,
|
||||||
|
};
|
||||||
|
|
||||||
|
xcb_icccm_set_wm_hints_checked(xnestUpstreamInfo.conn,
|
||||||
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
|
&wmhints);
|
||||||
|
|
||||||
|
xcb_map_window(xnestUpstreamInfo.conn, xnestDefaultWindows[pScreen->myNum]);
|
||||||
|
|
||||||
|
valuemask = XCB_CW_BACK_PIXMAP | XCB_CW_COLORMAP;
|
||||||
attributes.background_pixmap = xnestScreenSaverPixmap;
|
attributes.background_pixmap = xnestScreenSaverPixmap;
|
||||||
attributes.colormap =
|
attributes.colormap = xnestUpstreamInfo.screenInfo->default_colormap;
|
||||||
DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
|
|
||||||
xnestScreenSaverWindows[pScreen->myNum] =
|
uint32_t values[32] = { 0 };
|
||||||
XCreateWindow(xnestDisplay,
|
xnest_encode_window_attr(attributes, valuemask, values);
|
||||||
|
|
||||||
|
xnestScreenSaverWindows[pScreen->myNum] = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_create_window(xnestUpstreamInfo.conn,
|
||||||
|
xnestUpstreamInfo.screenInfo->root_depth,
|
||||||
|
xnestScreenSaverWindows[pScreen->myNum],
|
||||||
xnestDefaultWindows[pScreen->myNum],
|
xnestDefaultWindows[pScreen->myNum],
|
||||||
0, 0, xnestWidth, xnestHeight, 0,
|
0,
|
||||||
DefaultDepth(xnestDisplay,
|
0,
|
||||||
DefaultScreen(xnestDisplay)),
|
xnestGeometry.width,
|
||||||
InputOutput, DefaultVisual(xnestDisplay,
|
xnestGeometry.height,
|
||||||
DefaultScreen
|
0,
|
||||||
(xnestDisplay)), valuemask,
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||||
&attributes);
|
xnestUpstreamInfo.screenInfo->root_visual,
|
||||||
|
valuemask,
|
||||||
|
values);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!xnestCreateDefaultColormap(pScreen))
|
if (!xnestCreateDefaultColormap(pScreen))
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
@ -427,5 +536,5 @@ xnestCloseScreen(ScreenPtr pScreen)
|
||||||
the display connection. There is no need to generate extra protocol.
|
the display connection. There is no need to generate extra protocol.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Copyright 1993 by Davor Matic
|
|
||||||
|
|
||||||
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. Davor Matic makes no representations about
|
|
||||||
the suitability of this software for any purpose. It is provided "as
|
|
||||||
is" without express or implied warranty.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_XNEST_CONFIG_H
|
|
||||||
#include <xnest-config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <X11/X.h>
|
|
||||||
#include <X11/Xproto.h>
|
|
||||||
#include "scrnintstr.h"
|
|
||||||
#include "dix.h"
|
|
||||||
#include "mi.h"
|
|
||||||
#include "Xnest.h"
|
|
||||||
|
|
||||||
#include "Display.h"
|
|
||||||
#include "Visual.h"
|
|
||||||
|
|
||||||
Visual *
|
|
||||||
xnestVisual(VisualPtr pVisual)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < xnestNumVisuals; i++)
|
|
||||||
if (pVisual->class == xnestVisuals[i].class &&
|
|
||||||
pVisual->bitsPerRGBValue == xnestVisuals[i].bits_per_rgb &&
|
|
||||||
pVisual->ColormapEntries == xnestVisuals[i].colormap_size &&
|
|
||||||
pVisual->nplanes == xnestVisuals[i].depth &&
|
|
||||||
pVisual->redMask == xnestVisuals[i].red_mask &&
|
|
||||||
pVisual->greenMask == xnestVisuals[i].green_mask &&
|
|
||||||
pVisual->blueMask == xnestVisuals[i].blue_mask)
|
|
||||||
return xnestVisuals[i].visual;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Visual *
|
|
||||||
xnestVisualFromID(ScreenPtr pScreen, VisualID visual)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < pScreen->numVisuals; i++)
|
|
||||||
if (pScreen->visuals[i].vid == visual)
|
|
||||||
return xnestVisual(&pScreen->visuals[i]);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Colormap
|
|
||||||
xnestDefaultVisualColormap(Visual * visual)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < xnestNumVisuals; i++)
|
|
||||||
if (xnestVisuals[i].visual == visual)
|
|
||||||
return xnestDefaultColormaps[i];
|
|
||||||
|
|
||||||
return None;
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Copyright 1993 by Davor Matic
|
|
||||||
|
|
||||||
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. Davor Matic makes no representations about
|
|
||||||
the suitability of this software for any purpose. It is provided "as
|
|
||||||
is" without express or implied warranty.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XNESTVISUAL_H
|
|
||||||
#define XNESTVISUAL_H
|
|
||||||
|
|
||||||
#include <X11/X.h>
|
|
||||||
|
|
||||||
Visual *xnestVisual(VisualPtr pVisual);
|
|
||||||
Visual *xnestVisualFromID(ScreenPtr pScreen, VisualID visual);
|
|
||||||
Colormap xnestDefaultVisualColormap(Visual * visual);
|
|
||||||
|
|
||||||
#define xnestDefaultVisual(pScreen) \
|
|
||||||
xnestVisualFromID((pScreen), (pScreen)->rootVisual)
|
|
||||||
|
|
||||||
#endif /* XNESTVISUAL_H */
|
|
|
@ -16,6 +16,9 @@ is" without express or implied warranty.
|
||||||
#include <xnest-config.h>
|
#include <xnest-config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/shape.h>
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
|
@ -30,14 +33,13 @@ is" without express or implied warranty.
|
||||||
|
|
||||||
#include "mi.h"
|
#include "mi.h"
|
||||||
|
|
||||||
#include "Xnest.h"
|
#include "xnest-xcb.h"
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "XNGC.h"
|
#include "XNGC.h"
|
||||||
#include "Drawable.h"
|
#include "Drawable.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include "Visual.h"
|
|
||||||
#include "Events.h"
|
#include "Events.h"
|
||||||
#include "Args.h"
|
#include "Args.h"
|
||||||
|
|
||||||
|
@ -78,25 +80,25 @@ Bool
|
||||||
xnestCreateWindow(WindowPtr pWin)
|
xnestCreateWindow(WindowPtr pWin)
|
||||||
{
|
{
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
XSetWindowAttributes attributes;
|
XnSetWindowAttr attributes = { 0 };
|
||||||
Visual *visual;
|
uint32_t visual = CopyFromParent; /* 0L */
|
||||||
ColormapPtr pCmap;
|
ColormapPtr pCmap;
|
||||||
|
uint32_t params[32] = { 0 };
|
||||||
|
|
||||||
if (pWin->drawable.class == InputOnly) {
|
if (pWin->drawable.class == InputOnly) {
|
||||||
mask = 0L;
|
mask = 0L;
|
||||||
visual = CopyFromParent;
|
visual = CopyFromParent;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mask = CWEventMask | CWBackingStore;
|
mask = XCB_CW_EVENT_MASK | XCB_CW_BACKING_STORE;
|
||||||
attributes.event_mask = ExposureMask;
|
attributes.event_mask = XCB_EVENT_MASK_EXPOSURE;
|
||||||
attributes.backing_store = NotUseful;
|
attributes.backing_store = XCB_BACKING_STORE_NOT_USEFUL;
|
||||||
|
|
||||||
if (pWin->parent) {
|
if (pWin->parent) {
|
||||||
if (pWin->optional &&
|
if (pWin->optional &&
|
||||||
pWin->optional->visual != wVisual(pWin->parent)) {
|
pWin->optional->visual != wVisual(pWin->parent)) {
|
||||||
visual =
|
visual = xnest_visual_map_to_host(wVisual(pWin));
|
||||||
xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
|
mask |= XCB_CW_COLORMAP;
|
||||||
mask |= CWColormap;
|
|
||||||
if (pWin->optional->colormap) {
|
if (pWin->optional->colormap) {
|
||||||
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
||||||
X11_RESTYPE_COLORMAP, serverClient,
|
X11_RESTYPE_COLORMAP, serverClient,
|
||||||
|
@ -104,39 +106,43 @@ xnestCreateWindow(WindowPtr pWin)
|
||||||
attributes.colormap = xnestColormap(pCmap);
|
attributes.colormap = xnestColormap(pCmap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
attributes.colormap = xnestDefaultVisualColormap(visual);
|
attributes.colormap = xnestHostVisualToHostCmap(visual);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
visual = CopyFromParent;
|
visual = CopyFromParent;
|
||||||
}
|
}
|
||||||
else { /* root windows have their own colormaps at creation time */
|
else { /* root windows have their own colormaps at creation time */
|
||||||
visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
|
visual = xnest_visual_map_to_host(wVisual(pWin));
|
||||||
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
||||||
X11_RESTYPE_COLORMAP, serverClient, DixUseAccess);
|
X11_RESTYPE_COLORMAP, serverClient, DixUseAccess);
|
||||||
mask |= CWColormap;
|
mask |= XCB_CW_COLORMAP;
|
||||||
attributes.colormap = xnestColormap(pCmap);
|
attributes.colormap = xnestColormap(pCmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xnestWindowPriv(pWin)->window = XCreateWindow(xnestDisplay,
|
xnestWindowPriv(pWin)->window = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
xnestWindowParent(pWin),
|
xnest_encode_window_attr(attributes, mask, params);
|
||||||
pWin->origin.x -
|
xcb_create_window(xnestUpstreamInfo.conn,
|
||||||
wBorderWidth(pWin),
|
pWin->drawable.depth,
|
||||||
pWin->origin.y -
|
xnestWindowPriv(pWin)->window,
|
||||||
wBorderWidth(pWin),
|
xnestWindowParent(pWin),
|
||||||
pWin->drawable.width,
|
pWin->origin.x - wBorderWidth(pWin),
|
||||||
pWin->drawable.height,
|
pWin->origin.y - wBorderWidth(pWin),
|
||||||
pWin->borderWidth,
|
pWin->drawable.width,
|
||||||
pWin->drawable.depth,
|
pWin->drawable.height,
|
||||||
pWin->drawable.class,
|
pWin->borderWidth,
|
||||||
visual, mask, &attributes);
|
pWin->drawable.class,
|
||||||
|
visual,
|
||||||
|
mask,
|
||||||
|
¶ms);
|
||||||
|
|
||||||
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
|
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
|
||||||
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
|
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
|
||||||
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
||||||
xnestWindowPriv(pWin)->width = pWin->drawable.width;
|
xnestWindowPriv(pWin)->width = pWin->drawable.width;
|
||||||
xnestWindowPriv(pWin)->height = pWin->drawable.height;
|
xnestWindowPriv(pWin)->height = pWin->drawable.height;
|
||||||
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
|
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
|
||||||
xnestWindowPriv(pWin)->sibling_above = None;
|
xnestWindowPriv(pWin)->sibling_above = XCB_WINDOW_NONE;
|
||||||
if (pWin->nextSib)
|
if (pWin->nextSib)
|
||||||
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
|
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
|
||||||
xnestWindowPriv(pWin)->bounding_shape = RegionCreate(NULL, 1);
|
xnestWindowPriv(pWin)->bounding_shape = RegionCreate(NULL, 1);
|
||||||
|
@ -145,7 +151,7 @@ xnestCreateWindow(WindowPtr pWin)
|
||||||
if (!pWin->parent) /* only the root window will have the right colormap */
|
if (!pWin->parent) /* only the root window will have the right colormap */
|
||||||
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
@ -156,83 +162,90 @@ xnestDestroyWindow(WindowPtr pWin)
|
||||||
xnestWindowPriv(pWin)->sibling_above;
|
xnestWindowPriv(pWin)->sibling_above;
|
||||||
RegionDestroy(xnestWindowPriv(pWin)->bounding_shape);
|
RegionDestroy(xnestWindowPriv(pWin)->bounding_shape);
|
||||||
RegionDestroy(xnestWindowPriv(pWin)->clip_shape);
|
RegionDestroy(xnestWindowPriv(pWin)->clip_shape);
|
||||||
XDestroyWindow(xnestDisplay, xnestWindow(pWin));
|
xcb_destroy_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
|
||||||
xnestWindowPriv(pWin)->window = None;
|
xnestWindowPriv(pWin)->window = XCB_WINDOW_NONE;
|
||||||
|
|
||||||
if (pWin->optional && pWin->optional->colormap && pWin->parent)
|
if (pWin->optional && pWin->optional->colormap && pWin->parent)
|
||||||
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xnestPositionWindow(WindowPtr pWin, int x, int y)
|
xnestPositionWindow(WindowPtr pWin, int x, int y)
|
||||||
{
|
{
|
||||||
xnestConfigureWindow(pWin,
|
xnestConfigureWindow(pWin,
|
||||||
CWParent |
|
XCB_CONFIG_WINDOW_SIBLING | \
|
||||||
CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
|
XCB_CONFIG_WINDOW_X | \
|
||||||
|
XCB_CONFIG_WINDOW_Y | \
|
||||||
|
XCB_CONFIG_WINDOW_WIDTH | \
|
||||||
|
XCB_CONFIG_WINDOW_HEIGHT | \
|
||||||
|
XCB_CONFIG_WINDOW_BORDER_WIDTH);
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
|
xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
|
||||||
{
|
{
|
||||||
unsigned int valuemask;
|
unsigned int valuemask;
|
||||||
XWindowChanges values;
|
XnWindowChanges values;
|
||||||
|
|
||||||
if (mask & CWParent &&
|
if (mask & XCB_CONFIG_WINDOW_SIBLING &&
|
||||||
xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) {
|
xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) {
|
||||||
XReparentWindow(xnestDisplay, xnestWindow(pWin),
|
|
||||||
xnestWindowParent(pWin),
|
xcb_reparent_window(
|
||||||
pWin->origin.x - wBorderWidth(pWin),
|
xnestUpstreamInfo.conn,
|
||||||
pWin->origin.y - wBorderWidth(pWin));
|
xnestWindow(pWin),
|
||||||
|
xnestWindowParent(pWin),
|
||||||
|
pWin->origin.x - wBorderWidth(pWin),
|
||||||
|
pWin->origin.y - wBorderWidth(pWin));
|
||||||
|
|
||||||
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
|
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
|
||||||
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
|
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
|
||||||
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
||||||
xnestWindowPriv(pWin)->sibling_above = None;
|
xnestWindowPriv(pWin)->sibling_above = XCB_WINDOW_NONE;
|
||||||
if (pWin->nextSib)
|
if (pWin->nextSib)
|
||||||
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
|
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
valuemask = 0;
|
valuemask = 0;
|
||||||
|
|
||||||
if (mask & CWX &&
|
if (mask & XCB_CONFIG_WINDOW_X &&
|
||||||
xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) {
|
xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) {
|
||||||
valuemask |= CWX;
|
valuemask |= XCB_CONFIG_WINDOW_X;
|
||||||
values.x =
|
values.x =
|
||||||
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
|
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWY &&
|
if (mask & XCB_CONFIG_WINDOW_Y &&
|
||||||
xnestWindowPriv(pWin)->y != pWin->origin.y - wBorderWidth(pWin)) {
|
xnestWindowPriv(pWin)->y != pWin->origin.y - wBorderWidth(pWin)) {
|
||||||
valuemask |= CWY;
|
valuemask |= XCB_CONFIG_WINDOW_Y;
|
||||||
values.y =
|
values.y =
|
||||||
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWWidth && xnestWindowPriv(pWin)->width != pWin->drawable.width) {
|
if (mask & XCB_CONFIG_WINDOW_WIDTH && xnestWindowPriv(pWin)->width != pWin->drawable.width) {
|
||||||
valuemask |= CWWidth;
|
valuemask |= XCB_CONFIG_WINDOW_WIDTH;
|
||||||
values.width = xnestWindowPriv(pWin)->width = pWin->drawable.width;
|
values.width = xnestWindowPriv(pWin)->width = pWin->drawable.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWHeight &&
|
if (mask & XCB_CONFIG_WINDOW_HEIGHT &&
|
||||||
xnestWindowPriv(pWin)->height != pWin->drawable.height) {
|
xnestWindowPriv(pWin)->height != pWin->drawable.height) {
|
||||||
valuemask |= CWHeight;
|
valuemask |= XCB_CONFIG_WINDOW_HEIGHT;
|
||||||
values.height = xnestWindowPriv(pWin)->height = pWin->drawable.height;
|
values.height = xnestWindowPriv(pWin)->height = pWin->drawable.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWBorderWidth &&
|
if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH &&
|
||||||
xnestWindowPriv(pWin)->border_width != pWin->borderWidth) {
|
xnestWindowPriv(pWin)->border_width != pWin->borderWidth) {
|
||||||
valuemask |= CWBorderWidth;
|
valuemask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
|
||||||
values.border_width =
|
values.border_width =
|
||||||
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
|
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valuemask)
|
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pWin), valuemask, values);
|
||||||
XConfigureWindow(xnestDisplay, xnestWindow(pWin), valuemask, &values);
|
|
||||||
|
|
||||||
if (mask & CWStackingOrder &&
|
if (mask & XCB_CONFIG_WINDOW_SIBLING &&
|
||||||
xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) {
|
xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) {
|
||||||
WindowPtr pSib;
|
WindowPtr pSib;
|
||||||
|
|
||||||
|
@ -240,18 +253,18 @@ xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
|
||||||
for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
|
for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
|
||||||
|
|
||||||
/* the top sibling */
|
/* the top sibling */
|
||||||
valuemask = CWStackMode;
|
valuemask = XCB_CONFIG_WINDOW_STACK_MODE;
|
||||||
values.stack_mode = Above;
|
values.stack_mode = Above;
|
||||||
XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values);
|
|
||||||
xnestWindowPriv(pSib)->sibling_above = None;
|
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pSib), valuemask, values);
|
||||||
|
xnestWindowPriv(pSib)->sibling_above = XCB_WINDOW_NONE;
|
||||||
|
|
||||||
/* the rest of siblings */
|
/* the rest of siblings */
|
||||||
for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) {
|
for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) {
|
||||||
valuemask = CWSibling | CWStackMode;
|
valuemask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
|
||||||
values.sibling = xnestWindowSiblingAbove(pSib);
|
values.sibling = xnestWindowSiblingAbove(pSib);
|
||||||
values.stack_mode = Below;
|
values.stack_mode = Below;
|
||||||
XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask,
|
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pSib), valuemask, values);
|
||||||
&values);
|
|
||||||
xnestWindowPriv(pSib)->sibling_above =
|
xnestWindowPriv(pSib)->sibling_above =
|
||||||
xnestWindowSiblingAbove(pSib);
|
xnestWindowSiblingAbove(pSib);
|
||||||
}
|
}
|
||||||
|
@ -261,15 +274,15 @@ xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
|
||||||
Bool
|
Bool
|
||||||
xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||||
{
|
{
|
||||||
XSetWindowAttributes attributes;
|
XnSetWindowAttr attributes;
|
||||||
|
|
||||||
if (mask & CWBackPixmap)
|
if (mask & XCB_CW_BACK_PIXMAP)
|
||||||
switch (pWin->backgroundState) {
|
switch (pWin->backgroundState) {
|
||||||
case None:
|
case XCB_BACK_PIXMAP_NONE:
|
||||||
attributes.background_pixmap = None;
|
attributes.background_pixmap = XCB_PIXMAP_NONE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ParentRelative:
|
case XCB_BACK_PIXMAP_PARENT_RELATIVE:
|
||||||
attributes.background_pixmap = ParentRelative;
|
attributes.background_pixmap = ParentRelative;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -278,59 +291,59 @@ xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BackgroundPixel:
|
case BackgroundPixel:
|
||||||
mask &= ~CWBackPixmap;
|
mask &= ~XCB_CW_BACK_PIXMAP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWBackPixel) {
|
if (mask & XCB_CW_BACK_PIXEL) {
|
||||||
if (pWin->backgroundState == BackgroundPixel)
|
if (pWin->backgroundState == BackgroundPixel)
|
||||||
attributes.background_pixel = xnestPixel(pWin->background.pixel);
|
attributes.background_pixel = xnestPixel(pWin->background.pixel);
|
||||||
else
|
else
|
||||||
mask &= ~CWBackPixel;
|
mask &= ~XCB_CW_BACK_PIXEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWBorderPixmap) {
|
if (mask & XCB_CW_BORDER_PIXMAP) {
|
||||||
if (pWin->borderIsPixel)
|
if (pWin->borderIsPixel)
|
||||||
mask &= ~CWBorderPixmap;
|
mask &= ~XCB_CW_BORDER_PIXMAP;
|
||||||
else
|
else
|
||||||
attributes.border_pixmap = xnestPixmap(pWin->border.pixmap);
|
attributes.border_pixmap = xnestPixmap(pWin->border.pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWBorderPixel) {
|
if (mask & XCB_CW_BORDER_PIXEL) {
|
||||||
if (pWin->borderIsPixel)
|
if (pWin->borderIsPixel)
|
||||||
attributes.border_pixel = xnestPixel(pWin->border.pixel);
|
attributes.border_pixel = xnestPixel(pWin->border.pixel);
|
||||||
else
|
else
|
||||||
mask &= ~CWBorderPixel;
|
mask &= ~XCB_CW_BORDER_PIXEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWBitGravity)
|
if (mask & XCB_CW_BIT_GRAVITY)
|
||||||
attributes.bit_gravity = pWin->bitGravity;
|
attributes.bit_gravity = pWin->bitGravity;
|
||||||
|
|
||||||
if (mask & CWWinGravity) /* dix does this for us */
|
if (mask & XCB_CW_WIN_GRAVITY) /* dix does this for us */
|
||||||
mask &= ~CWWinGravity;
|
mask &= ~XCB_CW_WIN_GRAVITY;
|
||||||
|
|
||||||
if (mask & CWBackingStore) /* this is really not useful */
|
if (mask & XCB_CW_BACKING_STORE) /* this is really not useful */
|
||||||
mask &= ~CWBackingStore;
|
mask &= ~XCB_CW_BACKING_STORE;
|
||||||
|
|
||||||
if (mask & CWBackingPlanes) /* this is really not useful */
|
if (mask & XCB_CW_BACKING_PLANES) /* this is really not useful */
|
||||||
mask &= ~CWBackingPlanes;
|
mask &= ~XCB_CW_BACKING_PLANES;
|
||||||
|
|
||||||
if (mask & CWBackingPixel) /* this is really not useful */
|
if (mask & XCB_CW_BACKING_PIXEL) /* this is really not useful */
|
||||||
mask &= ~CWBackingPixel;
|
mask &= ~XCB_CW_BACKING_PIXEL;
|
||||||
|
|
||||||
if (mask & CWOverrideRedirect)
|
if (mask & XCB_CW_OVERRIDE_REDIRECT)
|
||||||
attributes.override_redirect = pWin->overrideRedirect;
|
attributes.override_redirect = pWin->overrideRedirect;
|
||||||
|
|
||||||
if (mask & CWSaveUnder) /* this is really not useful */
|
if (mask & XCB_CW_SAVE_UNDER) /* this is really not useful */
|
||||||
mask &= ~CWSaveUnder;
|
mask &= ~XCB_CW_SAVE_UNDER;
|
||||||
|
|
||||||
if (mask & CWEventMask) /* events are handled elsewhere */
|
if (mask & XCB_CW_EVENT_MASK) /* events are handled elsewhere */
|
||||||
mask &= ~CWEventMask;
|
mask &= ~XCB_CW_EVENT_MASK;
|
||||||
|
|
||||||
if (mask & CWDontPropagate) /* events are handled elsewhere */
|
if (mask & XCB_CW_DONT_PROPAGATE) /* events are handled elsewhere */
|
||||||
mask &= ~CWDontPropagate;
|
mask &= ~XCB_CW_DONT_PROPAGATE;
|
||||||
|
|
||||||
if (mask & CWColormap) {
|
if (mask & XCB_CW_COLORMAP) {
|
||||||
ColormapPtr pCmap;
|
ColormapPtr pCmap;
|
||||||
|
|
||||||
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
||||||
|
@ -341,32 +354,35 @@ xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||||
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & CWCursor) /* this is handled in cursor code */
|
if (mask & XCB_CW_CURSOR) /* this is handled in cursor code */
|
||||||
mask &= ~CWCursor;
|
mask &= ~XCB_CW_CURSOR;
|
||||||
|
|
||||||
if (mask)
|
if (mask) {
|
||||||
XChangeWindowAttributes(xnestDisplay, xnestWindow(pWin),
|
uint32_t values[32];
|
||||||
mask, &attributes);
|
xnest_encode_window_attr(attributes, mask, values);
|
||||||
|
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||||
return True;
|
xnestWindow(pWin),
|
||||||
|
mask,
|
||||||
|
values);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xnestRealizeWindow(WindowPtr pWin)
|
xnestRealizeWindow(WindowPtr pWin)
|
||||||
{
|
{
|
||||||
xnestConfigureWindow(pWin, CWStackingOrder);
|
xnestConfigureWindow(pWin, XCB_CONFIG_WINDOW_SIBLING);
|
||||||
xnestShapeWindow(pWin);
|
xnestShapeWindow(pWin);
|
||||||
XMapWindow(xnestDisplay, xnestWindow(pWin));
|
xcb_map_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
xnestUnrealizeWindow(WindowPtr pWin)
|
xnestUnrealizeWindow(WindowPtr pWin)
|
||||||
{
|
{
|
||||||
XUnmapWindow(xnestDisplay, xnestWindow(pWin));
|
xcb_unmap_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
|
||||||
|
return TRUE;
|
||||||
return True;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -377,44 +393,10 @@ xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion)
|
||||||
void
|
void
|
||||||
xnestClipNotify(WindowPtr pWin, int dx, int dy)
|
xnestClipNotify(WindowPtr pWin, int dx, int dy)
|
||||||
{
|
{
|
||||||
xnestConfigureWindow(pWin, CWStackingOrder);
|
xnestConfigureWindow(pWin, XCB_CONFIG_WINDOW_SIBLING);
|
||||||
xnestShapeWindow(pWin);
|
xnestShapeWindow(pWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
|
||||||
xnestWindowExposurePredicate(Display * dpy, XEvent * event, XPointer ptr)
|
|
||||||
{
|
|
||||||
return (event->type == Expose && event->xexpose.window == *(Window *) ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn)
|
|
||||||
{
|
|
||||||
XEvent event;
|
|
||||||
Window window;
|
|
||||||
BoxRec Box;
|
|
||||||
|
|
||||||
XSync(xnestDisplay, False);
|
|
||||||
|
|
||||||
window = xnestWindow(pWin);
|
|
||||||
|
|
||||||
while (XCheckIfEvent(xnestDisplay, &event,
|
|
||||||
xnestWindowExposurePredicate, (char *) &window)) {
|
|
||||||
|
|
||||||
Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + event.xexpose.x;
|
|
||||||
Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + event.xexpose.y;
|
|
||||||
Box.x2 = Box.x1 + event.xexpose.width;
|
|
||||||
Box.y2 = Box.y1 + event.xexpose.height;
|
|
||||||
|
|
||||||
event.xexpose.type = ProcessedExpose;
|
|
||||||
|
|
||||||
if (RegionContainsRect(pRgn, &Box) != rgnIN)
|
|
||||||
XPutBackEvent(xnestDisplay, &event);
|
|
||||||
}
|
|
||||||
|
|
||||||
miWindowExposures(pWin, pRgn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestSetShape(WindowPtr pWin, int kind)
|
xnestSetShape(WindowPtr pWin, int kind)
|
||||||
{
|
{
|
||||||
|
@ -429,10 +411,10 @@ xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
|
||||||
unsigned int n1, n2;
|
unsigned int n1, n2;
|
||||||
|
|
||||||
if (pReg1 == pReg2)
|
if (pReg1 == pReg2)
|
||||||
return True;
|
return TRUE;
|
||||||
|
|
||||||
if (pReg1 == NullRegion || pReg2 == NullRegion)
|
if (pReg1 == NullRegion || pReg2 == NullRegion)
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
pBox1 = RegionRects(pReg1);
|
pBox1 = RegionRects(pReg1);
|
||||||
n1 = RegionNumRects(pReg1);
|
n1 = RegionNumRects(pReg1);
|
||||||
|
@ -441,25 +423,20 @@ xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
|
||||||
n2 = RegionNumRects(pReg2);
|
n2 = RegionNumRects(pReg2);
|
||||||
|
|
||||||
if (n1 != n2)
|
if (n1 != n2)
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
if (pBox1 == pBox2)
|
if (pBox1 == pBox2)
|
||||||
return True;
|
return TRUE;
|
||||||
|
|
||||||
if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec)))
|
if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec)))
|
||||||
return False;
|
return FALSE;
|
||||||
|
|
||||||
return True;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xnestShapeWindow(WindowPtr pWin)
|
xnestShapeWindow(WindowPtr pWin)
|
||||||
{
|
{
|
||||||
Region reg;
|
|
||||||
BoxPtr pBox;
|
|
||||||
XRectangle rect;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape,
|
if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape,
|
||||||
wBoundingShape(pWin))) {
|
wBoundingShape(pWin))) {
|
||||||
|
|
||||||
|
@ -467,26 +444,27 @@ xnestShapeWindow(WindowPtr pWin)
|
||||||
RegionCopy(xnestWindowPriv(pWin)->bounding_shape,
|
RegionCopy(xnestWindowPriv(pWin)->bounding_shape,
|
||||||
wBoundingShape(pWin));
|
wBoundingShape(pWin));
|
||||||
|
|
||||||
reg = XCreateRegion();
|
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||||
pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
|
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||||
for (i = 0;
|
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
|
||||||
i < RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
|
|
||||||
i++) {
|
for (int i = 0; i < num_rects; i++) {
|
||||||
rect.x = pBox[i].x1;
|
rects[i].x = pBox[i].x1;
|
||||||
rect.y = pBox[i].y1;
|
rects[i].y = pBox[i].y1;
|
||||||
rect.width = pBox[i].x2 - pBox[i].x1;
|
rects[i].width = pBox[i].x2 - pBox[i].x1;
|
||||||
rect.height = pBox[i].y2 - pBox[i].y1;
|
rects[i].height = pBox[i].y2 - pBox[i].y1;
|
||||||
XUnionRectWithRegion(&rect, reg, reg);
|
|
||||||
}
|
}
|
||||||
XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
|
|
||||||
ShapeBounding, 0, 0, reg, ShapeSet);
|
xcb_shape_rectangles(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||||
XDestroyRegion(reg);
|
XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_YX_BANDED,
|
||||||
|
xnestWindow(pWin), 0, 0, num_rects, rects);
|
||||||
|
free(rects);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RegionEmpty(xnestWindowPriv(pWin)->bounding_shape);
|
RegionEmpty(xnestWindowPriv(pWin)->bounding_shape);
|
||||||
|
xcb_shape_mask(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||||
XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
|
XCB_SHAPE_SK_BOUNDING, xnestWindow(pWin),
|
||||||
ShapeBounding, 0, 0, None, ShapeSet);
|
0, 0, XCB_PIXMAP_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,25 +473,34 @@ xnestShapeWindow(WindowPtr pWin)
|
||||||
if (wClipShape(pWin)) {
|
if (wClipShape(pWin)) {
|
||||||
RegionCopy(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin));
|
RegionCopy(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin));
|
||||||
|
|
||||||
reg = XCreateRegion();
|
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->clip_shape);
|
||||||
pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
|
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
|
||||||
for (i = 0;
|
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
|
||||||
i < RegionNumRects(xnestWindowPriv(pWin)->clip_shape); i++) {
|
|
||||||
rect.x = pBox[i].x1;
|
for (int i = 0; i < num_rects; i++) {
|
||||||
rect.y = pBox[i].y1;
|
rects[i].x = pBox[i].x1;
|
||||||
rect.width = pBox[i].x2 - pBox[i].x1;
|
rects[i].y = pBox[i].y1;
|
||||||
rect.height = pBox[i].y2 - pBox[i].y1;
|
rects[i].width = pBox[i].x2 - pBox[i].x1;
|
||||||
XUnionRectWithRegion(&rect, reg, reg);
|
rects[i].height = pBox[i].y2 - pBox[i].y1;
|
||||||
}
|
}
|
||||||
XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
|
|
||||||
ShapeClip, 0, 0, reg, ShapeSet);
|
xcb_shape_rectangles(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||||
XDestroyRegion(reg);
|
XCB_SHAPE_SK_CLIP, XCB_CLIP_ORDERING_YX_BANDED,
|
||||||
|
xnestWindow(pWin), 0, 0, num_rects, rects);
|
||||||
|
free(rects);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RegionEmpty(xnestWindowPriv(pWin)->clip_shape);
|
RegionEmpty(xnestWindowPriv(pWin)->clip_shape);
|
||||||
|
xcb_shape_mask(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||||
XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
|
XCB_SHAPE_SK_CLIP, xnestWindow(pWin), 0, 0, XCB_PIXMAP_NONE);
|
||||||
ShapeClip, 0, 0, None, ShapeSet);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xnestClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures)
|
||||||
|
{
|
||||||
|
xcb_clear_area(xnestUpstreamInfo.conn,
|
||||||
|
generateExposures,
|
||||||
|
xnestWindow(pWin),
|
||||||
|
x, y, w, h);
|
||||||
|
}
|
||||||
|
|
|
@ -17,19 +17,13 @@ is" without express or implied warranty.
|
||||||
|
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
|
|
||||||
typedef struct {
|
#include <xcb/xcb.h>
|
||||||
XFontStruct *font_struct;
|
|
||||||
} xnestPrivFont;
|
|
||||||
|
|
||||||
extern int xnestFontPrivateIndex;
|
extern int xnestFontPrivateIndex;
|
||||||
|
|
||||||
#define xnestFontPriv(pFont) \
|
#define xnestFontPriv(pFont) \
|
||||||
((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex))
|
((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex))
|
||||||
|
|
||||||
#define xnestFontStruct(pFont) (xnestFontPriv(pFont)->font_struct)
|
|
||||||
|
|
||||||
#define xnestFont(pFont) (xnestFontStruct(pFont)->fid)
|
|
||||||
|
|
||||||
Bool xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
Bool xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
||||||
Bool xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
Bool xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,11 @@ is" without express or implied warranty.
|
||||||
|
|
||||||
#include <X11/Xdefs.h>
|
#include <X11/Xdefs.h>
|
||||||
|
|
||||||
/* This file uses the GC definition form Xlib.h as XlibGC. */
|
#include "include/gcstruct.h"
|
||||||
|
#include "include/privates.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
XlibGC gc;
|
uint32_t gc;
|
||||||
} xnestPrivGC;
|
} xnestPrivGC;
|
||||||
|
|
||||||
extern DevPrivateKeyRec xnestGCPrivateKeyRec;
|
extern DevPrivateKeyRec xnestGCPrivateKeyRec;
|
||||||
|
|
|
@ -50,13 +50,10 @@ extern DevPrivateKeyRec xnestWindowPrivateKeyRec;
|
||||||
xnestDefaultWindows[pWin->drawable.pScreen->myNum])
|
xnestDefaultWindows[pWin->drawable.pScreen->myNum])
|
||||||
|
|
||||||
#define xnestWindowSiblingAbove(pWin) \
|
#define xnestWindowSiblingAbove(pWin) \
|
||||||
((pWin)->prevSib ? xnestWindow((pWin)->prevSib) : None)
|
((pWin)->prevSib ? xnestWindow((pWin)->prevSib) : XCB_WINDOW_NONE)
|
||||||
|
|
||||||
#define xnestWindowSiblingBelow(pWin) \
|
#define xnestWindowSiblingBelow(pWin) \
|
||||||
((pWin)->nextSib ? xnestWindow((pWin)->nextSib) : None)
|
((pWin)->nextSib ? xnestWindow((pWin)->nextSib) : XCB_WINDOW_NONE)
|
||||||
|
|
||||||
#define CWParent CWSibling
|
|
||||||
#define CWStackingOrder CWStackMode
|
|
||||||
|
|
||||||
WindowPtr xnestWindowPtr(Window window);
|
WindowPtr xnestWindowPtr(Window window);
|
||||||
Bool xnestCreateWindow(WindowPtr pWin);
|
Bool xnestCreateWindow(WindowPtr pWin);
|
||||||
|
@ -68,8 +65,8 @@ Bool xnestRealizeWindow(WindowPtr pWin);
|
||||||
Bool xnestUnrealizeWindow(WindowPtr pWin);
|
Bool xnestUnrealizeWindow(WindowPtr pWin);
|
||||||
void xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion);
|
void xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion);
|
||||||
void xnestClipNotify(WindowPtr pWin, int dx, int dy);
|
void xnestClipNotify(WindowPtr pWin, int dx, int dy);
|
||||||
void xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn);
|
|
||||||
void xnestSetShape(WindowPtr pWin, int kind);
|
void xnestSetShape(WindowPtr pWin, int kind);
|
||||||
void xnestShapeWindow(WindowPtr pWin);
|
void xnestShapeWindow(WindowPtr pWin);
|
||||||
|
void xnestClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures);
|
||||||
|
|
||||||
#endif /* XNESTWINDOW_H */
|
#endif /* XNESTWINDOW_H */
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 1995 X Consortium
|
|
||||||
|
|
||||||
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 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 X CONSORTIUM 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.
|
|
||||||
|
|
||||||
Except as contained in this notice, the name of the X Consortium shall
|
|
||||||
not be used in advertising or otherwise to promote the sale, use or
|
|
||||||
other dealings in this Software without prior written authorization
|
|
||||||
from the X Consortium.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Machines with a 64 bit library interface and a 32 bit server require
|
|
||||||
** name changes to protect the guilty.
|
|
||||||
*/
|
|
||||||
#ifdef _XSERVER64
|
|
||||||
#define _XSERVER64_tmp
|
|
||||||
#undef _XSERVER64
|
|
||||||
typedef unsigned long XID64;
|
|
||||||
typedef unsigned long Mask64;
|
|
||||||
typedef unsigned long Atom64;
|
|
||||||
typedef unsigned long VisualID64;
|
|
||||||
typedef unsigned long Time64;
|
|
||||||
|
|
||||||
#define XID XID64
|
|
||||||
#define Mask Mask64
|
|
||||||
#define Atom Atom64
|
|
||||||
#define VisualID VisualID64
|
|
||||||
#define Time Time64
|
|
||||||
typedef XID Window64;
|
|
||||||
typedef XID Drawable64;
|
|
||||||
typedef XID Font64;
|
|
||||||
typedef XID Pixmap64;
|
|
||||||
typedef XID Cursor64;
|
|
||||||
typedef XID Colormap64;
|
|
||||||
typedef XID GContext64;
|
|
||||||
typedef XID KeySym64;
|
|
||||||
|
|
||||||
#define Window Window64
|
|
||||||
#define Drawable Drawable64
|
|
||||||
#define Font Font64
|
|
||||||
#define Pixmap Pixmap64
|
|
||||||
#define Cursor Cursor64
|
|
||||||
#define Colormap Colormap64
|
|
||||||
#define GContext GContext64
|
|
||||||
#define KeySym KeySym64
|
|
||||||
#endif /*_XSERVER64*/
|
|
||||||
|
|
||||||
#define GC XlibGC
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
#include <X11/extensions/shape.h>
|
|
||||||
#undef GC
|
|
||||||
|
|
||||||
#ifdef _XSERVER64_tmp
|
|
||||||
#define _XSERVER64
|
|
||||||
#undef _XSERVER64_tmp
|
|
||||||
#undef XID
|
|
||||||
#undef Mask
|
|
||||||
#undef Atom
|
|
||||||
#undef VisualID
|
|
||||||
#undef Time
|
|
||||||
#undef Window
|
|
||||||
#undef Drawable
|
|
||||||
#undef Font
|
|
||||||
#undef Pixmap
|
|
||||||
#undef Cursor
|
|
||||||
#undef Colormap
|
|
||||||
#undef GContext
|
|
||||||
#undef KeySym
|
|
||||||
#endif /*_XSERVER64_tmp*/
|
|
|
@ -13,19 +13,28 @@ srcs = [
|
||||||
'Pixmap.c',
|
'Pixmap.c',
|
||||||
'Pointer.c',
|
'Pointer.c',
|
||||||
'Screen.c',
|
'Screen.c',
|
||||||
'Visual.c',
|
|
||||||
'Window.c',
|
'Window.c',
|
||||||
'../../mi/miinitext.c',
|
'../../mi/miinitext.c',
|
||||||
'../../mi/miinitext.h',
|
'../../mi/miinitext.h',
|
||||||
|
'xcb.c',
|
||||||
|
'xkb.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
xcb_dep = dependency('xcb', required: true)
|
||||||
|
xcb_shape_dep = dependency('xcb-shape', required: true)
|
||||||
|
xcb_icccm_dep = dependency('xcb-icccm', required: true)
|
||||||
|
xcb_xkb_dep = dependency('xcb-xkb', required: true)
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'Xnest',
|
'Xnest',
|
||||||
srcs,
|
srcs,
|
||||||
include_directories: inc,
|
include_directories: inc,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
common_dep,
|
common_dep,
|
||||||
xnest_dep,
|
xcb_dep,
|
||||||
|
xcb_shape_dep,
|
||||||
|
xcb_icccm_dep,
|
||||||
|
xcb_xkb_dep,
|
||||||
],
|
],
|
||||||
link_with: [
|
link_with: [
|
||||||
libxserver_main,
|
libxserver_main,
|
||||||
|
|
|
@ -0,0 +1,676 @@
|
||||||
|
/* SPDX-License-Identifier: MIT OR X11
|
||||||
|
*
|
||||||
|
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
|
||||||
|
*/
|
||||||
|
#include <dix-config.h>
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_icccm.h>
|
||||||
|
|
||||||
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xdefs.h>
|
||||||
|
#include <X11/Xproto.h>
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
|
||||||
|
#include "include/gc.h"
|
||||||
|
#include "include/servermd.h"
|
||||||
|
|
||||||
|
#include "xnest-xcb.h"
|
||||||
|
#include "xnest-xkb.h"
|
||||||
|
#include "XNGC.h"
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
xnestUpstreamInfoRec xnestUpstreamInfo = { 0 };
|
||||||
|
XnestVisualRec *xnestVisualMap;
|
||||||
|
int xnestNumVisualMap;
|
||||||
|
|
||||||
|
Bool xnest_upstream_setup(const char* displayName)
|
||||||
|
{
|
||||||
|
xnestUpstreamInfo.conn = xcb_connect(displayName, &xnestUpstreamInfo.screenId);
|
||||||
|
if (!xnestUpstreamInfo.conn)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* retrieve setup data for our screen */
|
||||||
|
xnestUpstreamInfo.setup = xcb_get_setup(xnestUpstreamInfo.conn);
|
||||||
|
xcb_screen_iterator_t iter = xcb_setup_roots_iterator (xnestUpstreamInfo.setup);
|
||||||
|
|
||||||
|
for (int i = 0; i < xnestUpstreamInfo.screenId; ++i)
|
||||||
|
xcb_screen_next (&iter);
|
||||||
|
xnestUpstreamInfo.screenInfo = iter.data;
|
||||||
|
|
||||||
|
xorg_list_init(&xnestUpstreamInfo.eventQueue.entry);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* retrieve upstream GC XID for our xserver GC */
|
||||||
|
uint32_t xnestUpstreamGC(GCPtr pGC) {
|
||||||
|
if (pGC == NULL) return 0;
|
||||||
|
|
||||||
|
xnestPrivGC *priv = dixLookupPrivate(&(pGC)->devPrivates, xnestGCPrivateKey);
|
||||||
|
if (priv == NULL) return 0;
|
||||||
|
|
||||||
|
return priv->gc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xnest_encode_window_attr(XnSetWindowAttr attr, uint32_t mask, uint32_t *values)
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
#define EXTRA_VALUE(flag,val) if (mask & flag) { values[idx++] = attr.val; }
|
||||||
|
EXTRA_VALUE(XCB_CW_BACK_PIXMAP, background_pixmap);
|
||||||
|
EXTRA_VALUE(XCB_CW_BACK_PIXEL, background_pixel)
|
||||||
|
EXTRA_VALUE(XCB_CW_BORDER_PIXMAP, border_pixmap)
|
||||||
|
EXTRA_VALUE(XCB_CW_BORDER_PIXEL, border_pixel)
|
||||||
|
EXTRA_VALUE(XCB_CW_BIT_GRAVITY, bit_gravity)
|
||||||
|
EXTRA_VALUE(XCB_CW_WIN_GRAVITY, win_gravity);
|
||||||
|
EXTRA_VALUE(XCB_CW_BACKING_STORE, backing_store);
|
||||||
|
EXTRA_VALUE(XCB_CW_BACKING_PLANES, backing_planes);
|
||||||
|
EXTRA_VALUE(XCB_CW_BACKING_PIXEL, backing_pixel);
|
||||||
|
EXTRA_VALUE(XCB_CW_OVERRIDE_REDIRECT, override_redirect);
|
||||||
|
EXTRA_VALUE(XCB_CW_SAVE_UNDER, save_under);
|
||||||
|
EXTRA_VALUE(XCB_CW_EVENT_MASK, event_mask);
|
||||||
|
EXTRA_VALUE(XCB_CW_DONT_PROPAGATE, do_not_propagate_mask);
|
||||||
|
EXTRA_VALUE(XCB_CW_COLORMAP, colormap);
|
||||||
|
EXTRA_VALUE(XCB_CW_CURSOR, cursor);
|
||||||
|
#undef EXTRA_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
void xnest_configure_window(xcb_connection_t *conn, uint32_t window,
|
||||||
|
uint32_t mask, XnWindowChanges values)
|
||||||
|
{
|
||||||
|
if (mask) {
|
||||||
|
uint32_t value_list[16] = { 0 };
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
#define EXTRA_VALUE(flag,val) if (mask & flag) { value_list[idx++] = values.val; }
|
||||||
|
EXTRA_VALUE(XCB_CONFIG_WINDOW_X, x);
|
||||||
|
EXTRA_VALUE(XCB_CONFIG_WINDOW_Y, y);
|
||||||
|
EXTRA_VALUE(XCB_CONFIG_WINDOW_WIDTH, width);
|
||||||
|
EXTRA_VALUE(XCB_CONFIG_WINDOW_HEIGHT, height);
|
||||||
|
EXTRA_VALUE(XCB_CONFIG_WINDOW_BORDER_WIDTH, border_width);
|
||||||
|
EXTRA_VALUE(XCB_CONFIG_WINDOW_SIBLING, sibling);
|
||||||
|
EXTRA_VALUE(XCB_CONFIG_WINDOW_STACK_MODE, stack_mode);
|
||||||
|
#undef EXTRA_VALUE
|
||||||
|
|
||||||
|
xcb_configure_window(conn, window, mask, value_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xnestEncodeKeyboardControl(XnKeyboardControl ctrl, long mask, uint32_t *value)
|
||||||
|
{
|
||||||
|
if (mask & KBKeyClickPercent)
|
||||||
|
*value++ = ctrl.key_click_percent;
|
||||||
|
|
||||||
|
if (mask & KBBellPercent)
|
||||||
|
*value++ = ctrl.bell_percent;
|
||||||
|
|
||||||
|
if (mask & KBBellPitch)
|
||||||
|
*value++ = ctrl.bell_pitch;
|
||||||
|
|
||||||
|
if (mask & KBBellDuration)
|
||||||
|
*value++ = ctrl.bell_duration;
|
||||||
|
|
||||||
|
if (mask & KBLed)
|
||||||
|
*value++ = ctrl.led;
|
||||||
|
|
||||||
|
if (mask & KBLedMode)
|
||||||
|
*value++ = ctrl.led_mode;
|
||||||
|
|
||||||
|
if (mask & KBKey)
|
||||||
|
*value++ = ctrl.key;
|
||||||
|
|
||||||
|
if (mask & KBAutoRepeatMode)
|
||||||
|
*value++ = ctrl.auto_repeat_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xnChangeGC(xcb_connection_t *conn, uint32_t gc, XnGCValues gcval, uint32_t mask)
|
||||||
|
{
|
||||||
|
char value_list[128] = { 0 };
|
||||||
|
char *walk = value_list;
|
||||||
|
|
||||||
|
#define EXTRA_VALUE(flag,val) if (mask & flag) { *((uint32_t*)walk) = gcval.val; walk+=4; }
|
||||||
|
EXTRA_VALUE(GCFunction, function);
|
||||||
|
EXTRA_VALUE(GCPlaneMask, plane_mask);
|
||||||
|
EXTRA_VALUE(GCForeground, foreground);
|
||||||
|
EXTRA_VALUE(GCBackground, background);
|
||||||
|
EXTRA_VALUE(GCLineWidth, line_width);
|
||||||
|
EXTRA_VALUE(GCLineStyle, line_style);
|
||||||
|
EXTRA_VALUE(GCCapStyle, cap_style);
|
||||||
|
EXTRA_VALUE(GCJoinStyle, join_style);
|
||||||
|
EXTRA_VALUE(GCFillStyle, fill_style);
|
||||||
|
EXTRA_VALUE(GCFillRule, fill_rule);
|
||||||
|
EXTRA_VALUE(GCTile, tile);
|
||||||
|
EXTRA_VALUE(GCStipple, stipple);
|
||||||
|
EXTRA_VALUE(GCTileStipXOrigin, ts_x_origin);
|
||||||
|
EXTRA_VALUE(GCTileStipYOrigin, ts_y_origin);
|
||||||
|
EXTRA_VALUE(GCFont, font);
|
||||||
|
EXTRA_VALUE(GCSubwindowMode, subwindow_mode);
|
||||||
|
EXTRA_VALUE(GCGraphicsExposures, graphics_exposures);
|
||||||
|
EXTRA_VALUE(GCClipXOrigin, clip_x_origin);
|
||||||
|
EXTRA_VALUE(GCClipYOrigin, clip_y_origin);
|
||||||
|
EXTRA_VALUE(GCClipMask, clip_mask);
|
||||||
|
EXTRA_VALUE(GCDashOffset, dash_offset);
|
||||||
|
EXTRA_VALUE(GCDashList, dashes);
|
||||||
|
EXTRA_VALUE(GCArcMode, arc_mode);
|
||||||
|
#undef EXTRA_VALUE
|
||||||
|
|
||||||
|
xcb_change_gc(conn, gc, mask, value_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char WM_COLORMAP_WINDOWS[] = "WM_COLORMAP_WINDOWS";
|
||||||
|
|
||||||
|
void xnestWMColormapWindows(xcb_connection_t *conn, xcb_window_t w, xcb_window_t *windows, int count)
|
||||||
|
{
|
||||||
|
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(
|
||||||
|
conn,
|
||||||
|
xcb_intern_atom(
|
||||||
|
conn, 0,
|
||||||
|
sizeof(WM_COLORMAP_WINDOWS)-1,
|
||||||
|
WM_COLORMAP_WINDOWS),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!reply)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xcb_icccm_set_wm_colormap_windows_checked(
|
||||||
|
conn,
|
||||||
|
w,
|
||||||
|
reply->atom,
|
||||||
|
count,
|
||||||
|
(xcb_window_t*)windows);
|
||||||
|
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t xnestCreateBitmapFromData(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
uint32_t drawable,
|
||||||
|
const char *data,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height)
|
||||||
|
{
|
||||||
|
uint32_t pix = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_create_pixmap(conn, 1, pix, drawable, width, height);
|
||||||
|
|
||||||
|
uint32_t gc = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_create_gc(conn, gc, pix, 0, NULL);
|
||||||
|
|
||||||
|
const int leftPad = 0;
|
||||||
|
|
||||||
|
xcb_put_image(conn,
|
||||||
|
XYPixmap,
|
||||||
|
pix,
|
||||||
|
gc,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0 /* dst_x */,
|
||||||
|
0 /* dst_y */,
|
||||||
|
leftPad,
|
||||||
|
1 /* depth */,
|
||||||
|
BitmapBytePad(width + leftPad) * height,
|
||||||
|
(uint8_t*)data);
|
||||||
|
|
||||||
|
xcb_free_gc(conn, gc);
|
||||||
|
return pix;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t xnestCreatePixmapFromBitmapData(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
uint32_t drawable,
|
||||||
|
const char *data,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t fg,
|
||||||
|
uint32_t bg,
|
||||||
|
uint16_t depth)
|
||||||
|
{
|
||||||
|
uint32_t pix = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_create_pixmap(conn, depth, pix, drawable, width, height);
|
||||||
|
|
||||||
|
uint32_t gc = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||||
|
xcb_create_gc(conn, gc, pix, 0, NULL);
|
||||||
|
|
||||||
|
XnGCValues gcv = {
|
||||||
|
.foreground = fg,
|
||||||
|
.background = bg
|
||||||
|
};
|
||||||
|
|
||||||
|
xnChangeGC(conn, gc, gcv, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND);
|
||||||
|
|
||||||
|
const int leftPad = 0;
|
||||||
|
xcb_put_image(conn,
|
||||||
|
XYBitmap,
|
||||||
|
pix,
|
||||||
|
gc,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0 /* dst_x */,
|
||||||
|
0 /* dst_y */,
|
||||||
|
leftPad,
|
||||||
|
1 /* depth */,
|
||||||
|
BitmapBytePad(width + leftPad) * height,
|
||||||
|
(uint8_t*)data);
|
||||||
|
|
||||||
|
xcb_free_gc(conn, gc);
|
||||||
|
return pix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xnestSetCommand(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
xcb_window_t window,
|
||||||
|
char **argv,
|
||||||
|
int argc)
|
||||||
|
{
|
||||||
|
int i = 0, nbytes = 0;
|
||||||
|
|
||||||
|
for (i = 0, nbytes = 0; i < argc; i++)
|
||||||
|
nbytes += strlen(argv[i]) + 1;
|
||||||
|
|
||||||
|
if (nbytes >= (2^16) - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char buf[nbytes+1];
|
||||||
|
char *bp = buf;
|
||||||
|
|
||||||
|
/* copy arguments into single buffer */
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
strcpy(bp, argv[i]);
|
||||||
|
bp += strlen(argv[i]) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_change_property(conn,
|
||||||
|
XCB_PROP_MODE_REPLACE,
|
||||||
|
window,
|
||||||
|
XCB_ATOM_WM_COMMAND,
|
||||||
|
XCB_ATOM_STRING,
|
||||||
|
8,
|
||||||
|
nbytes,
|
||||||
|
buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xnestXkbInit(xcb_connection_t *conn)
|
||||||
|
{
|
||||||
|
xcb_generic_error_t *err = NULL;
|
||||||
|
xcb_xkb_use_extension_reply_t *reply = xcb_xkb_use_extension_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_xkb_use_extension(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
XCB_XKB_MAJOR_VERSION,
|
||||||
|
XCB_XKB_MINOR_VERSION),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ErrorF("failed query xkb extension: %d\n", err->error_code);
|
||||||
|
free(err);
|
||||||
|
} else {
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define XkbGBN_AllComponentsMask_2 ( \
|
||||||
|
XCB_XKB_GBN_DETAIL_TYPES | \
|
||||||
|
XCB_XKB_GBN_DETAIL_COMPAT_MAP | \
|
||||||
|
XCB_XKB_GBN_DETAIL_CLIENT_SYMBOLS | \
|
||||||
|
XCB_XKB_GBN_DETAIL_SERVER_SYMBOLS | \
|
||||||
|
XCB_XKB_GBN_DETAIL_INDICATOR_MAPS | \
|
||||||
|
XCB_XKB_GBN_DETAIL_KEY_NAMES | \
|
||||||
|
XCB_XKB_GBN_DETAIL_GEOMETRY | \
|
||||||
|
XCB_XKB_GBN_DETAIL_OTHER_NAMES)
|
||||||
|
|
||||||
|
int xnestXkbDeviceId(xcb_connection_t *conn)
|
||||||
|
{
|
||||||
|
int device_id = -1;
|
||||||
|
uint8_t xlen[6] = { 0 };
|
||||||
|
xcb_generic_error_t *err = NULL;
|
||||||
|
|
||||||
|
xcb_xkb_get_kbd_by_name_reply_t *reply = xcb_xkb_get_kbd_by_name_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_xkb_get_kbd_by_name_2(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
XCB_XKB_ID_USE_CORE_KBD,
|
||||||
|
XkbGBN_AllComponentsMask_2,
|
||||||
|
XkbGBN_AllComponentsMask_2,
|
||||||
|
0,
|
||||||
|
sizeof(xlen),
|
||||||
|
xlen),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ErrorF("failed retrieving core keyboard: %d\n", err->error_code);
|
||||||
|
free(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reply) {
|
||||||
|
ErrorF("failed retrieving core keyboard: no reply");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_id = reply->deviceID;
|
||||||
|
free(reply);
|
||||||
|
return device_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_get_keyboard_mapping_reply_t *xnestGetKeyboardMapping(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
int min_keycode,
|
||||||
|
int count
|
||||||
|
) {
|
||||||
|
xcb_generic_error_t *err= NULL;
|
||||||
|
xcb_get_keyboard_mapping_reply_t * reply = xcb_get_keyboard_mapping_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_keyboard_mapping(conn, min_keycode, count),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ErrorF("Couldn't get keyboard mapping: %d\n", err->error_code);
|
||||||
|
free(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xnestGetPointerControl(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
int *acc_num,
|
||||||
|
int *acc_den,
|
||||||
|
int *threshold)
|
||||||
|
{
|
||||||
|
xcb_generic_error_t *err = NULL;
|
||||||
|
xcb_get_pointer_control_reply_t *reply = xcb_get_pointer_control_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_pointer_control(xnestUpstreamInfo.conn),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ErrorF("error retrieving pointer control data: %d\n", err->error_code);
|
||||||
|
free(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reply) {
|
||||||
|
ErrorF("error retrieving pointer control data: no reply\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*acc_num = reply->acceleration_numerator;
|
||||||
|
*acc_den = reply->acceleration_denominator;
|
||||||
|
*threshold = reply->threshold;
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
xRectangle xnestGetGeometry(xcb_connection_t *conn, uint32_t window)
|
||||||
|
{
|
||||||
|
xcb_generic_error_t *err = NULL;
|
||||||
|
xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(
|
||||||
|
xnestUpstreamInfo.conn,
|
||||||
|
xcb_get_geometry(xnestUpstreamInfo.conn, window),
|
||||||
|
&err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
ErrorF("failed getting window attributes for %d: %d\n", window, err->error_code);
|
||||||
|
free(err);
|
||||||
|
return (xRectangle) { 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!reply) {
|
||||||
|
ErrorF("failed getting window attributes for %d: no reply\n", window);
|
||||||
|
return (xRectangle) { 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
return (xRectangle) {
|
||||||
|
.x = reply->x,
|
||||||
|
.y = reply->y,
|
||||||
|
.width = reply->width,
|
||||||
|
.height = reply->height };
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __readint(const char *str, const char **next)
|
||||||
|
{
|
||||||
|
int res = 0, sign = 1;
|
||||||
|
|
||||||
|
if (*str=='+')
|
||||||
|
str++;
|
||||||
|
else if (*str=='-') {
|
||||||
|
str++;
|
||||||
|
sign = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; (*str>='0') && (*str<='9'); str++)
|
||||||
|
res = (res * 10) + (*str-'0');
|
||||||
|
|
||||||
|
*next = str;
|
||||||
|
return sign * res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xnestParseGeometry(const char *string, xRectangle *geometry)
|
||||||
|
{
|
||||||
|
int mask = 0;
|
||||||
|
const char *next;
|
||||||
|
xRectangle temp = { 0 };
|
||||||
|
|
||||||
|
if ((string == NULL) || (*string == '\0')) return 0;
|
||||||
|
|
||||||
|
if (*string == '=')
|
||||||
|
string++; /* ignore possible '=' at beg of geometry spec */
|
||||||
|
|
||||||
|
if (*string != '+' && *string != '-' && *string != 'x') {
|
||||||
|
temp.width = __readint(string, &next);
|
||||||
|
if (string == next)
|
||||||
|
return 0;
|
||||||
|
string = next;
|
||||||
|
mask |= XCB_CONFIG_WINDOW_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*string == 'x' || *string == 'X') {
|
||||||
|
string++;
|
||||||
|
temp.height = __readint(string, &next);
|
||||||
|
if (string == next)
|
||||||
|
return 0;
|
||||||
|
string = next;
|
||||||
|
mask |= XCB_CONFIG_WINDOW_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*string == '+') || (*string== '-')) {
|
||||||
|
if (*string== '-') {
|
||||||
|
string++;
|
||||||
|
temp.x = -__readint(string, &next);
|
||||||
|
if (string == next)
|
||||||
|
return 0;
|
||||||
|
string = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string++;
|
||||||
|
temp.x = __readint(string, &next);
|
||||||
|
if (string == next)
|
||||||
|
return 0;
|
||||||
|
string = next;
|
||||||
|
}
|
||||||
|
mask |= XCB_CONFIG_WINDOW_X;
|
||||||
|
if ((*string == '+') || (*string== '-')) {
|
||||||
|
if (*string== '-') {
|
||||||
|
string++;
|
||||||
|
temp.y = -__readint(string, &next);
|
||||||
|
if (string == next)
|
||||||
|
return 0;
|
||||||
|
string = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string++;
|
||||||
|
temp.y = __readint(string, &next);
|
||||||
|
if (string == next)
|
||||||
|
return 0;
|
||||||
|
string = next;
|
||||||
|
}
|
||||||
|
mask |= XCB_CONFIG_WINDOW_Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*string != '\0') return 0;
|
||||||
|
|
||||||
|
if (mask & XCB_CONFIG_WINDOW_X)
|
||||||
|
geometry->x = temp.x;
|
||||||
|
if (mask & XCB_CONFIG_WINDOW_Y)
|
||||||
|
geometry->y = temp.y;
|
||||||
|
if (mask & XCB_CONFIG_WINDOW_WIDTH)
|
||||||
|
geometry->width = temp.width;
|
||||||
|
if (mask & XCB_CONFIG_WINDOW_HEIGHT)
|
||||||
|
geometry->height = temp.height;
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t xnest_visual_map_to_host(VisualID visual)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < xnestNumVisualMap; i++) {
|
||||||
|
if (xnestVisualMap[i].ourXID == visual) {
|
||||||
|
return xnestVisualMap[i].upstreamVisual->visual_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return XCB_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t xnestHostVisualToHostCmap(uint32_t upstreamVisual)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < xnestNumVisualMap; i++) {
|
||||||
|
if (xnestVisualMap[i].upstreamVisual->visual_id == upstreamVisual) {
|
||||||
|
return xnestVisualMap[i].upstreamCMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return XCB_COLORMAP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t xnestVisualToHostCmap(uint32_t visual)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < xnestNumVisualMap; i++) {
|
||||||
|
if (xnestVisualMap[i].ourXID == visual) {
|
||||||
|
return xnestVisualMap[i].upstreamCMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return XCB_COLORMAP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char XN_CI_NONEXISTCHAR(xcb_charinfo_t *cs)
|
||||||
|
{
|
||||||
|
return ((cs->character_width == 0) && \
|
||||||
|
((cs->right_side_bearing | cs->left_side_bearing | cs->ascent | cs->descent) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define XN_CI_GET_CHAR_INFO_1D(font,col,def,cs) \
|
||||||
|
do { \
|
||||||
|
cs = def; \
|
||||||
|
if (col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \
|
||||||
|
if (font->chars == NULL) { \
|
||||||
|
cs = &font->font_reply->min_bounds; \
|
||||||
|
} else { \
|
||||||
|
cs = (xcb_charinfo_t *)&font->chars[(col - font->font_reply->min_char_or_byte2)]; \
|
||||||
|
if (XN_CI_NONEXISTCHAR(cs)) cs = def; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XN_CI_GET_CHAR_INFO_2D(font,row,col,def,cs) \
|
||||||
|
do { \
|
||||||
|
cs = def; \
|
||||||
|
if (row >= font->font_reply->min_byte1 && row <= font->font_reply->max_byte1 && \
|
||||||
|
col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \
|
||||||
|
if (font->chars == NULL) { \
|
||||||
|
cs = &font->font_reply->min_bounds; \
|
||||||
|
} else { \
|
||||||
|
cs = (xcb_charinfo_t*)&font->chars[((row - font->font_reply->min_byte1) * \
|
||||||
|
(font->font_reply->max_char_or_byte2 - \
|
||||||
|
font->font_reply->min_char_or_byte2 + 1)) + \
|
||||||
|
(col - font->font_reply->min_char_or_byte2)]; \
|
||||||
|
if (XN_CI_NONEXISTCHAR(cs)) cs = def; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XN_CI_GET_DEFAULT_INFO_2D(font,cs) \
|
||||||
|
do { \
|
||||||
|
unsigned int r = (font->font_reply->default_char >> 8); \
|
||||||
|
unsigned int c = (font->font_reply->default_char & 0xff); \
|
||||||
|
XN_CI_GET_CHAR_INFO_2D (font, r, c, NULL, cs); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define XN_CI_GET_ROWZERO_CHAR_INFO_2D(font,col,def,cs) \
|
||||||
|
do { \
|
||||||
|
cs = def; \
|
||||||
|
if (font->font_reply->min_byte1 == 0 && \
|
||||||
|
col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \
|
||||||
|
if (font->chars == NULL) { \
|
||||||
|
cs = &font->font_reply->min_bounds; \
|
||||||
|
} else { \
|
||||||
|
cs = (xcb_charinfo_t*)&font->chars[(col - font->font_reply->min_char_or_byte2)]; \
|
||||||
|
if (XN_CI_NONEXISTCHAR(cs)) cs = def; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int
|
||||||
|
xnestTextWidth (
|
||||||
|
xnestPrivFont *font,
|
||||||
|
const char *string,
|
||||||
|
int count)
|
||||||
|
{
|
||||||
|
xcb_charinfo_t *def;
|
||||||
|
|
||||||
|
if (font->font_reply->max_byte1 == 0)
|
||||||
|
XN_CI_GET_CHAR_INFO_1D (font, font->font_reply->default_char, NULL, def);
|
||||||
|
else
|
||||||
|
XN_CI_GET_DEFAULT_INFO_2D (font, def);
|
||||||
|
|
||||||
|
if (def && font->font_reply->min_bounds.character_width == font->font_reply->max_bounds.character_width)
|
||||||
|
return (font->font_reply->min_bounds.character_width * count);
|
||||||
|
|
||||||
|
int width = 0, i = 0;
|
||||||
|
unsigned char *us;
|
||||||
|
for (i = 0, us = (unsigned char *) string; i < count; i++, us++) {
|
||||||
|
unsigned uc = (unsigned) *us;
|
||||||
|
xcb_charinfo_t *cs;
|
||||||
|
|
||||||
|
if (font->font_reply->max_byte1 == 0) {
|
||||||
|
XN_CI_GET_CHAR_INFO_1D (font, uc, def, cs);
|
||||||
|
} else {
|
||||||
|
XN_CI_GET_ROWZERO_CHAR_INFO_2D (font, uc, def, cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs) width += cs->character_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xnestTextWidth16 (xnestPrivFont *font, const uint16_t* str, int count)
|
||||||
|
{
|
||||||
|
xcb_charinfo_t *def;
|
||||||
|
xcb_char2b_t *string = (xcb_char2b_t*)str;
|
||||||
|
|
||||||
|
if (font->font_reply->max_byte1 == 0)
|
||||||
|
XN_CI_GET_CHAR_INFO_1D (font, font->font_reply->default_char, NULL, def);
|
||||||
|
else
|
||||||
|
XN_CI_GET_DEFAULT_INFO_2D (font, def);
|
||||||
|
|
||||||
|
if (def && font->font_reply->min_bounds.character_width == font->font_reply->max_bounds.character_width)
|
||||||
|
return (font->font_reply->min_bounds.character_width * count);
|
||||||
|
|
||||||
|
int width = 0;
|
||||||
|
for (int i = 0; i < count; i++, string++) {
|
||||||
|
xcb_charinfo_t *cs;
|
||||||
|
unsigned int r = (unsigned int) string->byte1;
|
||||||
|
unsigned int c = (unsigned int) string->byte2;
|
||||||
|
|
||||||
|
if (font->font_reply->max_byte1 == 0) {
|
||||||
|
unsigned int ind = ((r << 8) | c);
|
||||||
|
XN_CI_GET_CHAR_INFO_1D (font, ind, def, cs);
|
||||||
|
} else {
|
||||||
|
XN_CI_GET_CHAR_INFO_2D (font, r, c, def, cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs) width += cs->character_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h> /* for offsetof() */
|
||||||
|
|
||||||
|
#include <xcb/xcbext.h>
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
|
#include "xnest-xkb.h"
|
||||||
|
|
||||||
|
xcb_xkb_get_kbd_by_name_cookie_t
|
||||||
|
xcb_xkb_get_kbd_by_name_2 (xcb_connection_t *c,
|
||||||
|
xcb_xkb_device_spec_t deviceSpec,
|
||||||
|
uint16_t need,
|
||||||
|
uint16_t want,
|
||||||
|
uint8_t load,
|
||||||
|
uint32_t data_len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
static const xcb_protocol_request_t xcb_req = {
|
||||||
|
.count = 4,
|
||||||
|
.ext = &xcb_xkb_id,
|
||||||
|
.opcode = XCB_XKB_GET_KBD_BY_NAME,
|
||||||
|
.isvoid = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iovec xcb_parts[6];
|
||||||
|
xcb_xkb_get_kbd_by_name_cookie_t xcb_ret;
|
||||||
|
xcb_xkb_get_kbd_by_name_request_t xcb_out;
|
||||||
|
|
||||||
|
xcb_out.deviceSpec = deviceSpec;
|
||||||
|
xcb_out.need = need;
|
||||||
|
xcb_out.want = want;
|
||||||
|
xcb_out.load = load;
|
||||||
|
xcb_out.pad0 = 0;
|
||||||
|
|
||||||
|
xcb_parts[2].iov_base = (char *) &xcb_out;
|
||||||
|
xcb_parts[2].iov_len = sizeof(xcb_out);
|
||||||
|
xcb_parts[3].iov_base = 0;
|
||||||
|
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
|
||||||
|
/* uint8_t data */
|
||||||
|
xcb_parts[4].iov_base = (char *) data;
|
||||||
|
xcb_parts[4].iov_len = data_len * sizeof(uint8_t);
|
||||||
|
xcb_parts[5].iov_base = 0;
|
||||||
|
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
|
||||||
|
|
||||||
|
xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req);
|
||||||
|
return xcb_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_xkb_get_kbd_by_name_cookie_t
|
||||||
|
xcb_xkb_get_kbd_by_name_2_unchecked (xcb_connection_t *c,
|
||||||
|
xcb_xkb_device_spec_t deviceSpec,
|
||||||
|
uint16_t need,
|
||||||
|
uint16_t want,
|
||||||
|
uint8_t load,
|
||||||
|
uint32_t data_len,
|
||||||
|
const uint8_t *data)
|
||||||
|
{
|
||||||
|
static const xcb_protocol_request_t xcb_req = {
|
||||||
|
.count = 4,
|
||||||
|
.ext = &xcb_xkb_id,
|
||||||
|
.opcode = XCB_XKB_GET_KBD_BY_NAME,
|
||||||
|
.isvoid = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iovec xcb_parts[6];
|
||||||
|
xcb_xkb_get_kbd_by_name_cookie_t xcb_ret;
|
||||||
|
xcb_xkb_get_kbd_by_name_request_t xcb_out;
|
||||||
|
|
||||||
|
xcb_out.deviceSpec = deviceSpec;
|
||||||
|
xcb_out.need = need;
|
||||||
|
xcb_out.want = want;
|
||||||
|
xcb_out.load = load;
|
||||||
|
xcb_out.pad0 = 0;
|
||||||
|
|
||||||
|
xcb_parts[2].iov_base = (char *) &xcb_out;
|
||||||
|
xcb_parts[2].iov_len = sizeof(xcb_out);
|
||||||
|
xcb_parts[3].iov_base = 0;
|
||||||
|
xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;
|
||||||
|
/* uint8_t data */
|
||||||
|
xcb_parts[4].iov_base = (char *) data;
|
||||||
|
xcb_parts[4].iov_len = data_len * sizeof(uint8_t);
|
||||||
|
xcb_parts[5].iov_base = 0;
|
||||||
|
xcb_parts[5].iov_len = -xcb_parts[4].iov_len & 3;
|
||||||
|
|
||||||
|
xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req);
|
||||||
|
return xcb_ret;
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
/* SPDX-License-Identifier: MIT OR X11
|
||||||
|
*
|
||||||
|
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
|
||||||
|
*/
|
||||||
|
#ifndef __XNEST__XCB_H
|
||||||
|
#define __XNEST__XCB_H
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
#include "include/list.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct xorg_list entry;
|
||||||
|
xcb_generic_event_t *event;
|
||||||
|
} xnestEventQueue;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
xcb_connection_t *conn;
|
||||||
|
int screenId;
|
||||||
|
const xcb_screen_t *screenInfo;
|
||||||
|
const xcb_setup_t *setup;
|
||||||
|
xnestEventQueue eventQueue;
|
||||||
|
} xnestUpstreamInfoRec;
|
||||||
|
|
||||||
|
extern xnestUpstreamInfoRec xnestUpstreamInfo;
|
||||||
|
|
||||||
|
/* connect to upstream X server */
|
||||||
|
Bool xnest_upstream_setup(const char* displayName);
|
||||||
|
|
||||||
|
/* retrieve upstream GC XID for our xserver GC */
|
||||||
|
uint32_t xnestUpstreamGC(GCPtr pGC);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t background_pixmap;
|
||||||
|
uint32_t background_pixel;
|
||||||
|
uint32_t border_pixmap;
|
||||||
|
uint32_t border_pixel;
|
||||||
|
uint16_t bit_gravity;
|
||||||
|
uint16_t win_gravity;
|
||||||
|
uint16_t backing_store;
|
||||||
|
uint32_t backing_planes;
|
||||||
|
uint32_t backing_pixel;
|
||||||
|
Bool save_under;
|
||||||
|
uint32_t event_mask;
|
||||||
|
uint32_t do_not_propagate_mask;
|
||||||
|
Bool override_redirect;
|
||||||
|
uint32_t colormap;
|
||||||
|
uint32_t cursor;
|
||||||
|
} XnSetWindowAttr;
|
||||||
|
|
||||||
|
void xnest_encode_window_attr(XnSetWindowAttr attr, uint32_t mask, uint32_t *values);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x, y;
|
||||||
|
int width, height;
|
||||||
|
int border_width;
|
||||||
|
uint32_t sibling;
|
||||||
|
int stack_mode;
|
||||||
|
} XnWindowChanges;
|
||||||
|
|
||||||
|
void xnest_configure_window(xcb_connection_t *conn, uint32_t window, uint32_t mask, XnWindowChanges values);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int key_click_percent;
|
||||||
|
int bell_percent;
|
||||||
|
int bell_pitch;
|
||||||
|
int bell_duration;
|
||||||
|
int led;
|
||||||
|
int led_mode;
|
||||||
|
int key;
|
||||||
|
int auto_repeat_mode;
|
||||||
|
} XnKeyboardControl;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
xcb_visualtype_t *upstreamVisual;
|
||||||
|
xcb_depth_t *upstreamDepth;
|
||||||
|
xcb_colormap_t upstreamCMap;
|
||||||
|
uint32_t ourXID;
|
||||||
|
VisualPtr ourVisual;
|
||||||
|
} XnestVisualRec;
|
||||||
|
|
||||||
|
extern XnestVisualRec *xnestVisualMap;
|
||||||
|
extern int xnestNumVisualMap;
|
||||||
|
|
||||||
|
void xnestEncodeKeyboardControl(XnKeyboardControl ctrl, long mask, uint32_t *value);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int function; /* logical operation */
|
||||||
|
unsigned long plane_mask;/* plane mask */
|
||||||
|
unsigned long foreground;/* foreground pixel */
|
||||||
|
unsigned long background;/* background pixel */
|
||||||
|
int line_width; /* line width */
|
||||||
|
int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */
|
||||||
|
int cap_style; /* CapNotLast, CapButt,
|
||||||
|
CapRound, CapProjecting */
|
||||||
|
int join_style; /* JoinMiter, JoinRound, JoinBevel */
|
||||||
|
int fill_style; /* FillSolid, FillTiled,
|
||||||
|
FillStippled, FillOpaqueStippled */
|
||||||
|
int fill_rule; /* EvenOddRule, WindingRule */
|
||||||
|
int arc_mode; /* ArcChord, ArcPieSlice */
|
||||||
|
xcb_pixmap_t tile; /* tile pixmap for tiling operations */
|
||||||
|
xcb_pixmap_t stipple; /* stipple 1 plane pixmap for stippling */
|
||||||
|
int ts_x_origin; /* offset for tile or stipple operations */
|
||||||
|
int ts_y_origin;
|
||||||
|
xcb_font_t font; /* default text font for text operations */
|
||||||
|
int subwindow_mode; /* ClipByChildren, IncludeInferiors */
|
||||||
|
Bool graphics_exposures;/* boolean, should exposures be generated */
|
||||||
|
int clip_x_origin; /* origin for clipping */
|
||||||
|
int clip_y_origin;
|
||||||
|
xcb_pixmap_t clip_mask; /* bitmap clipping; other calls for rects */
|
||||||
|
int dash_offset; /* patterned/dashed line information */
|
||||||
|
char dashes;
|
||||||
|
} XnGCValues;
|
||||||
|
|
||||||
|
void xnChangeGC(xcb_connection_t *conn, uint32_t gc, XnGCValues gcval, uint32_t mask);
|
||||||
|
|
||||||
|
void xnestWMColormapWindows(xcb_connection_t *conn, xcb_window_t w, xcb_window_t *windows, int count);
|
||||||
|
|
||||||
|
uint32_t xnestCreateBitmapFromData(xcb_connection_t *conn, uint32_t drawable,
|
||||||
|
const char *data, uint32_t width, uint32_t height);
|
||||||
|
|
||||||
|
uint32_t xnestCreatePixmapFromBitmapData(xcb_connection_t *conn, uint32_t drawable,
|
||||||
|
const char *data, uint32_t width, uint32_t height,
|
||||||
|
uint32_t fg, uint32_t bg, uint16_t depth);
|
||||||
|
|
||||||
|
void xnestSetCommand(xcb_connection_t *conn, xcb_window_t window, char ** argv, int argc);
|
||||||
|
|
||||||
|
void xnestXkbInit(xcb_connection_t *conn);
|
||||||
|
int xnestXkbDeviceId(xcb_connection_t *conn);
|
||||||
|
|
||||||
|
xcb_get_keyboard_mapping_reply_t *xnestGetKeyboardMapping(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
int min_keycode,
|
||||||
|
int count
|
||||||
|
);
|
||||||
|
|
||||||
|
void xnestGetPointerControl(xcb_connection_t *conn, int *acc_num, int *acc_den, int *threshold);
|
||||||
|
|
||||||
|
xRectangle xnestGetGeometry(xcb_connection_t *conn, uint32_t window);
|
||||||
|
|
||||||
|
int xnestParseGeometry(const char *string, xRectangle *geometry);
|
||||||
|
|
||||||
|
uint32_t xnest_visual_map_to_host(VisualID visual);
|
||||||
|
uint32_t xnestHostVisualToHostCmap(uint32_t visual);
|
||||||
|
uint32_t xnestVisualToHostCmap(uint32_t visual);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
xcb_query_font_reply_t *font_reply;
|
||||||
|
xcb_font_t font_id;
|
||||||
|
xcb_charinfo_t *chars;
|
||||||
|
uint16_t chars_len;
|
||||||
|
} xnestPrivFont;
|
||||||
|
|
||||||
|
int xnestTextWidth (xnestPrivFont *font, const char *string, int count);
|
||||||
|
int xnestTextWidth16 (xnestPrivFont *font, const uint16_t *string, int count);
|
||||||
|
|
||||||
|
#endif /* __XNEST__XCB_H */
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* SPDX-License-Identifier: MIT OR X11
|
||||||
|
*
|
||||||
|
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
|
||||||
|
*/
|
||||||
|
#ifndef __XNEST__XKB_H
|
||||||
|
#define __XNEST__XKB_H
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
|
||||||
|
xcb_xkb_get_kbd_by_name_cookie_t
|
||||||
|
xcb_xkb_get_kbd_by_name_2 (xcb_connection_t *c,
|
||||||
|
xcb_xkb_device_spec_t deviceSpec,
|
||||||
|
uint16_t need,
|
||||||
|
uint16_t want,
|
||||||
|
uint8_t load,
|
||||||
|
uint32_t data_len,
|
||||||
|
const uint8_t *data);
|
||||||
|
|
||||||
|
xcb_xkb_get_kbd_by_name_cookie_t
|
||||||
|
xcb_xkb_get_kbd_by_name_2_unchecked (xcb_connection_t *c,
|
||||||
|
xcb_xkb_device_spec_t deviceSpec,
|
||||||
|
uint16_t need,
|
||||||
|
uint16_t want,
|
||||||
|
uint8_t load,
|
||||||
|
uint32_t data_len,
|
||||||
|
const uint8_t *data);
|
||||||
|
|
||||||
|
#endif /* __XNEST__XKB_H */
|
14
meson.build
14
meson.build
|
@ -245,20 +245,6 @@ endif
|
||||||
|
|
||||||
## configure Xnest - nesting X server
|
## configure Xnest - nesting X server
|
||||||
build_xnest = get_option('xnest') != 'false'
|
build_xnest = get_option('xnest') != 'false'
|
||||||
xnest_required = get_option('xnest') == 'true'
|
|
||||||
xnest_dep = [
|
|
||||||
dependency('xext', version: xext_req, required: xnest_required),
|
|
||||||
dependency('x11', required: xnest_required),
|
|
||||||
dependency('xau', required: xnest_required),
|
|
||||||
]
|
|
||||||
if get_option('xnest') == 'auto'
|
|
||||||
# check for all the deps being found, to handle 'auto' mode.
|
|
||||||
foreach d: xnest_dep
|
|
||||||
if not d.found()
|
|
||||||
build_xnest = false
|
|
||||||
endif
|
|
||||||
endforeach
|
|
||||||
endif
|
|
||||||
|
|
||||||
build_xwin = false
|
build_xwin = false
|
||||||
if get_option('xwin') == 'auto'
|
if get_option('xwin') == 'auto'
|
||||||
|
|
Loading…
Reference in New Issue