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 "servermd.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Args.h"
|
||||
|
||||
char *xnestDisplayName = NULL;
|
||||
Bool xnestSynchronize = False;
|
||||
Bool xnestFullGeneration = False;
|
||||
Bool xnestFullGeneration = FALSE;
|
||||
int xnestDefaultClass;
|
||||
Bool xnestUserDefaultClass = False;
|
||||
Bool xnestUserDefaultClass = FALSE;
|
||||
int xnestDefaultDepth;
|
||||
Bool xnestUserDefaultDepth = False;
|
||||
Bool xnestSoftwareScreenSaver = False;
|
||||
int xnestX;
|
||||
int xnestY;
|
||||
unsigned int xnestWidth;
|
||||
unsigned int xnestHeight;
|
||||
Bool xnestUserDefaultDepth = FALSE;
|
||||
Bool xnestSoftwareScreenSaver = FALSE;
|
||||
xRectangle xnestGeometry = { 0 };
|
||||
int xnestUserGeometry = 0;
|
||||
int xnestBorderWidth;
|
||||
Bool xnestUserBorderWidth = False;
|
||||
Bool xnestUserBorderWidth = FALSE;
|
||||
char *xnestWindowName = NULL;
|
||||
int xnestNumScreens = 0;
|
||||
Bool xnestDoDirectColormaps = False;
|
||||
Bool xnestDoDirectColormaps = FALSE;
|
||||
Window xnestParentWindow = 0;
|
||||
|
||||
int
|
||||
|
@ -63,44 +59,40 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[i], "-sync")) {
|
||||
xnestSynchronize = True;
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(argv[i], "-full")) {
|
||||
xnestFullGeneration = True;
|
||||
xnestFullGeneration = TRUE;
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(argv[i], "-class")) {
|
||||
if (++i < argc) {
|
||||
if (!strcmp(argv[i], "StaticGray")) {
|
||||
xnestDefaultClass = StaticGray;
|
||||
xnestUserDefaultClass = True;
|
||||
xnestUserDefaultClass = TRUE;
|
||||
return 2;
|
||||
}
|
||||
else if (!strcmp(argv[i], "GrayScale")) {
|
||||
xnestDefaultClass = GrayScale;
|
||||
xnestUserDefaultClass = True;
|
||||
xnestUserDefaultClass = TRUE;
|
||||
return 2;
|
||||
}
|
||||
else if (!strcmp(argv[i], "StaticColor")) {
|
||||
xnestDefaultClass = StaticColor;
|
||||
xnestUserDefaultClass = True;
|
||||
xnestUserDefaultClass = TRUE;
|
||||
return 2;
|
||||
}
|
||||
else if (!strcmp(argv[i], "PseudoColor")) {
|
||||
xnestDefaultClass = PseudoColor;
|
||||
xnestUserDefaultClass = True;
|
||||
xnestUserDefaultClass = TRUE;
|
||||
return 2;
|
||||
}
|
||||
else if (!strcmp(argv[i], "TrueColor")) {
|
||||
xnestDefaultClass = TrueColor;
|
||||
xnestUserDefaultClass = True;
|
||||
xnestUserDefaultClass = TRUE;
|
||||
return 2;
|
||||
}
|
||||
else if (!strcmp(argv[i], "DirectColor")) {
|
||||
xnestDefaultClass = DirectColor;
|
||||
xnestUserDefaultClass = True;
|
||||
xnestUserDefaultClass = TRUE;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +101,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||
if (!strcmp(argv[i], "-cc")) {
|
||||
if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultClass) == 1) {
|
||||
if (xnestDefaultClass >= 0 && xnestDefaultClass <= 5) {
|
||||
xnestUserDefaultClass = True;
|
||||
xnestUserDefaultClass = TRUE;
|
||||
/* 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 (++i < argc && sscanf(argv[i], "%i", &xnestDefaultDepth) == 1) {
|
||||
if (xnestDefaultDepth > 0) {
|
||||
xnestUserDefaultDepth = True;
|
||||
xnestUserDefaultDepth = TRUE;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[i], "-sss")) {
|
||||
xnestSoftwareScreenSaver = True;
|
||||
xnestSoftwareScreenSaver = TRUE;
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(argv[i], "-geometry")) {
|
||||
if (++i < argc) {
|
||||
xnestUserGeometry = XParseGeometry(argv[i],
|
||||
&xnestX, &xnestY,
|
||||
&xnestWidth, &xnestHeight);
|
||||
if (xnestUserGeometry)
|
||||
if (xnestParseGeometry(argv[i], &xnestGeometry))
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
@ -141,7 +130,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||
if (!strcmp(argv[i], "-bw")) {
|
||||
if (++i < argc && sscanf(argv[i], "%i", &xnestBorderWidth) == 1) {
|
||||
if (xnestBorderWidth >= 0) {
|
||||
xnestUserBorderWidth = True;
|
||||
xnestUserBorderWidth = TRUE;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +156,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||
return 0;
|
||||
}
|
||||
if (!strcmp(argv[i], "-install")) {
|
||||
xnestDoDirectColormaps = True;
|
||||
xnestDoDirectColormaps = TRUE;
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(argv[i], "-parent")) {
|
||||
|
@ -183,7 +172,6 @@ void
|
|||
ddxUseMsg(void)
|
||||
{
|
||||
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("-class string default visual class\n");
|
||||
ErrorF("-depth int default depth\n");
|
||||
|
|
|
@ -19,17 +19,13 @@ is" without express or implied warranty.
|
|||
#include <X11/Xdefs.h>
|
||||
|
||||
extern char *xnestDisplayName;
|
||||
extern Bool xnestSynchronize;
|
||||
extern Bool xnestFullGeneration;
|
||||
extern int xnestDefaultClass;
|
||||
extern Bool xnestUserDefaultClass;
|
||||
extern int xnestDefaultDepth;
|
||||
extern Bool xnestUserDefaultDepth;
|
||||
extern Bool xnestSoftwareScreenSaver;
|
||||
extern int xnestX;
|
||||
extern int xnestY;
|
||||
extern unsigned int xnestWidth;
|
||||
extern unsigned int xnestHeight;
|
||||
extern xRectangle xnestGeometry;
|
||||
extern int xnestUserGeometry;
|
||||
extern int xnestBorderWidth;
|
||||
extern Bool xnestUserBorderWidth;
|
||||
|
|
209
hw/xnest/Color.c
209
hw/xnest/Color.c
|
@ -26,15 +26,16 @@ is" without express or implied warranty.
|
|||
#include "colormapst.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
#include "Color.h"
|
||||
#include "Visual.h"
|
||||
#include "XNWindow.h"
|
||||
#include "Args.h"
|
||||
|
||||
#include <xcb/xcb_icccm.h>
|
||||
|
||||
DevPrivateKeyRec xnestColormapPrivateKeyRec;
|
||||
|
||||
static DevPrivateKeyRec cmapScrPrivateKeyRec;
|
||||
|
@ -44,59 +45,79 @@ static DevPrivateKeyRec cmapScrPrivateKeyRec;
|
|||
#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
|
||||
#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
|
||||
xnestCreateColormap(ColormapPtr pCmap)
|
||||
{
|
||||
VisualPtr pVisual;
|
||||
XColor *colors;
|
||||
int i, ncolors;
|
||||
Pixel red, green, blue;
|
||||
Pixel redInc, greenInc, blueInc;
|
||||
VisualPtr pVisual = pCmap->pVisual;
|
||||
int ncolors = pVisual->ColormapEntries;
|
||||
|
||||
pVisual = pCmap->pVisual;
|
||||
ncolors = pVisual->ColormapEntries;
|
||||
uint32_t const cmap = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xnestColormapPriv(pCmap)->colormap = cmap;
|
||||
|
||||
xnestColormapPriv(pCmap)->colormap =
|
||||
XCreateColormap(xnestDisplay,
|
||||
xcb_create_colormap(xnestUpstreamInfo.conn,
|
||||
(pVisual->class & DynamicClass) ? XCB_COLORMAP_ALLOC_ALL : XCB_COLORMAP_ALLOC_NONE,
|
||||
cmap,
|
||||
xnestDefaultWindows[pCmap->pScreen->myNum],
|
||||
xnestVisual(pVisual),
|
||||
(pVisual->class & DynamicClass) ? AllocAll : AllocNone);
|
||||
xnest_visual_map_to_host(pVisual->vid));
|
||||
|
||||
switch (pVisual->class) {
|
||||
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 */
|
||||
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].green;
|
||||
pCmap->red[i].co.local.blue = colors[i].blue;
|
||||
{
|
||||
uint32_t *colors = malloc(ncolors * sizeof(uint32_t));
|
||||
for (int i = 0; i < ncolors; i++)
|
||||
colors[i] = i;
|
||||
return loadColormap(pCmap, ncolors, colors);
|
||||
}
|
||||
free(colors);
|
||||
break;
|
||||
|
||||
case TrueColor: /* read only */
|
||||
colors = xallocarray(ncolors, sizeof(XColor));
|
||||
red = green = blue = 0L;
|
||||
redInc = lowbit(pVisual->redMask);
|
||||
greenInc = lowbit(pVisual->greenMask);
|
||||
blueInc = lowbit(pVisual->blueMask);
|
||||
for (i = 0; i < ncolors; i++) {
|
||||
colors[i].pixel = red | green | blue;
|
||||
{
|
||||
uint32_t *colors = malloc(ncolors * sizeof(uint32_t));
|
||||
Pixel red = 0, redInc = lowbit(pVisual->redMask);
|
||||
Pixel green = 0, greenInc = lowbit(pVisual->greenMask);
|
||||
Pixel blue = 0, blueInc = lowbit(pVisual->blueMask);
|
||||
|
||||
for (int i = 0; i < ncolors; i++) {
|
||||
colors[i] = red | green | blue;
|
||||
red += redInc;
|
||||
if (red > pVisual->redMask)
|
||||
red = 0L;
|
||||
|
@ -107,13 +128,8 @@ xnestCreateColormap(ColormapPtr pCmap)
|
|||
if (blue > pVisual->blueMask)
|
||||
blue = 0L;
|
||||
}
|
||||
XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
|
||||
for (i = 0; i < ncolors; i++) {
|
||||
pCmap->red[i].co.local.red = colors[i].red;
|
||||
pCmap->green[i].co.local.green = colors[i].green;
|
||||
pCmap->blue[i].co.local.blue = colors[i].blue;
|
||||
return loadColormap(pCmap, ncolors, colors);
|
||||
}
|
||||
free(colors);
|
||||
break;
|
||||
|
||||
case GrayScale: /* read and write */
|
||||
|
@ -126,17 +142,17 @@ xnestCreateColormap(ColormapPtr pCmap)
|
|||
break;
|
||||
}
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
xnestDestroyColormap(ColormapPtr pCmap)
|
||||
{
|
||||
XFreeColormap(xnestDisplay, xnestColormap(pCmap));
|
||||
xcb_free_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
|
||||
}
|
||||
|
||||
#define SEARCH_PREDICATE \
|
||||
(xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
|
||||
(xnestWindow(pWin) != XCB_WINDOW_NONE && wColormap(pWin) == icws->cmapIDs[i])
|
||||
|
||||
static int
|
||||
xnestCountInstalledColormapWindows(WindowPtr pWin, void *ptr)
|
||||
|
@ -175,19 +191,19 @@ static Bool
|
|||
xnestSameInstalledColormapWindows(Window *windows, int numWindows)
|
||||
{
|
||||
if (xnestNumOldInstalledColormapWindows != numWindows)
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
if (xnestOldInstalledColormapWindows == windows)
|
||||
return True;
|
||||
return TRUE;
|
||||
|
||||
if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
if (memcmp(xnestOldInstalledColormapWindows, windows,
|
||||
numWindows * sizeof(Window)))
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -217,22 +233,10 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
|
|||
if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
|
||||
free(xnestOldInstalledColormapWindows);
|
||||
|
||||
#ifdef _XSERVER64
|
||||
{
|
||||
int i;
|
||||
Window64 *windows = xallocarray(numWindows, sizeof(Window64));
|
||||
|
||||
for (i = 0; i < numWindows; ++i)
|
||||
windows[i] = icws.windows[i];
|
||||
XSetWMColormapWindows(xnestDisplay,
|
||||
xnestDefaultWindows[pScreen->myNum], windows,
|
||||
xnestWMColormapWindows(xnestUpstreamInfo.conn,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
icws.windows,
|
||||
numWindows);
|
||||
free(windows);
|
||||
}
|
||||
#else
|
||||
XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
|
||||
icws.windows, numWindows);
|
||||
#endif
|
||||
|
||||
xnestOldInstalledColormapWindows = icws.windows;
|
||||
xnestNumOldInstalledColormapWindows = icws.numWindows;
|
||||
|
@ -244,13 +248,12 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
|
|||
*/
|
||||
if (icws.numWindows) {
|
||||
WindowPtr pWin;
|
||||
Visual *visual;
|
||||
ColormapPtr pCmap;
|
||||
|
||||
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),
|
||||
X11_RESTYPE_COLORMAP, serverClient,
|
||||
DixUseAccess);
|
||||
|
@ -259,9 +262,11 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen)
|
|||
pScreen->defColormap, X11_RESTYPE_COLORMAP,
|
||||
serverClient, DixUseAccess);
|
||||
|
||||
XSetWindowColormap(xnestDisplay,
|
||||
uint32_t cmap = xnestColormap(pCmap);
|
||||
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
xnestColormap(pCmap));
|
||||
XCB_CW_COLORMAP,
|
||||
&cmap);
|
||||
}
|
||||
#endif /* DUMB_WINDOW_MANAGERS */
|
||||
}
|
||||
|
@ -274,19 +279,10 @@ xnestSetScreenSaverColormapWindow(ScreenPtr pScreen)
|
|||
{
|
||||
free(xnestOldInstalledColormapWindows);
|
||||
|
||||
#ifdef _XSERVER64
|
||||
{
|
||||
Window64 window;
|
||||
|
||||
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 */
|
||||
xnestWMColormapWindows(xnestUpstreamInfo.conn,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
&xnestScreenSaverWindows[pScreen->myNum],
|
||||
1);
|
||||
|
||||
xnestOldInstalledColormapWindows = NULL;
|
||||
xnestNumOldInstalledColormapWindows = 0;
|
||||
|
@ -311,7 +307,7 @@ xnestDirectInstallColormaps(ScreenPtr pScreen)
|
|||
dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], X11_RESTYPE_COLORMAP,
|
||||
serverClient, DixInstallAccess);
|
||||
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,
|
||||
serverClient, DixUninstallAccess);
|
||||
if (pCmap)
|
||||
XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
|
||||
xcb_uninstall_colormap(xnestUpstreamInfo.conn, xnestColormap(pCmap));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,7 +341,7 @@ xnestInstallColormap(ColormapPtr pCmap)
|
|||
xnestDirectUninstallColormaps(pCmap->pScreen);
|
||||
|
||||
/* Uninstall pInstalledMap. Notify all interested parties. */
|
||||
if (pOldCmap != (ColormapPtr) None)
|
||||
if (pOldCmap != (ColormapPtr) XCB_COLORMAP_NONE)
|
||||
WalkTree(pCmap->pScreen, TellLostMap, (void *) &pOldCmap->mid);
|
||||
|
||||
SetInstalledColormap(pCmap->pScreen, pCmap);
|
||||
|
@ -372,7 +368,7 @@ xnestUninstallColormap(ColormapPtr pCmap)
|
|||
}
|
||||
}
|
||||
|
||||
static Bool xnestInstalledDefaultColormap = False;
|
||||
static Bool xnestInstalledDefaultColormap = FALSE;
|
||||
|
||||
int
|
||||
xnestListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmapIDs)
|
||||
|
@ -389,25 +385,10 @@ void
|
|||
xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem * pColors)
|
||||
{
|
||||
if (pCmap->pVisual->class & DynamicClass)
|
||||
#ifdef _XSERVER64
|
||||
{
|
||||
int i;
|
||||
XColor *pColors64 = xallocarray(nColors, sizeof(XColor));
|
||||
|
||||
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
|
||||
xcb_store_colors(xnestUpstreamInfo.conn,
|
||||
xnestColormap(pCmap),
|
||||
nColors,
|
||||
(xcb_coloritem_t*) pColors);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -474,7 +455,7 @@ xnestCreateDefaultColormap(ScreenPtr pScreen)
|
|||
(pVisual->class & DynamicClass) ? AllocNone : AllocAll,
|
||||
0)
|
||||
!= Success)
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
wp = pScreen->whitePixel;
|
||||
bp = pScreen->blackPixel;
|
||||
|
@ -486,7 +467,7 @@ xnestCreateDefaultColormap(ScreenPtr pScreen)
|
|||
pScreen->blackPixel = bp;
|
||||
(*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 "mipointrst.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
#include "XNCursor.h"
|
||||
#include "Visual.h"
|
||||
#include "Keyboard.h"
|
||||
#include "Args.h"
|
||||
|
||||
|
@ -42,97 +41,87 @@ xnestCursorFuncRec xnestCursorFuncs = { NULL };
|
|||
Bool
|
||||
xnestRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
XImage *ximage;
|
||||
Pixmap source, mask;
|
||||
XColor fg_color, bg_color;
|
||||
unsigned long valuemask;
|
||||
XGCValues values;
|
||||
uint32_t valuemask = XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FOREGROUND
|
||||
| XCB_GC_BACKGROUND | XCB_GC_CLIP_MASK;
|
||||
|
||||
valuemask = GCFunction |
|
||||
GCPlaneMask | GCForeground | GCBackground | GCClipMask;
|
||||
XnGCValues values = {
|
||||
.function = XCB_GX_COPY,
|
||||
.plane_mask = ((unsigned long)~0L),
|
||||
.foreground = 1L,
|
||||
};
|
||||
|
||||
values.function = GXcopy;
|
||||
values.plane_mask = AllPlanes;
|
||||
values.foreground = 1L;
|
||||
values.background = 0L;
|
||||
values.clip_mask = None;
|
||||
xnChangeGC(xnestUpstreamInfo.conn, xnestBitmapGC, values, valuemask);
|
||||
|
||||
XChangeGC(xnestDisplay, xnestBitmapGC, valuemask, &values);
|
||||
uint32_t const winId = xnestDefaultWindows[pScreen->myNum];
|
||||
|
||||
source = XCreatePixmap(xnestDisplay,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
pCursor->bits->width, pCursor->bits->height, 1);
|
||||
Pixmap const source = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xcb_create_pixmap(xnestUpstreamInfo.conn, 1, source, winId, pCursor->bits->width, pCursor->bits->height);
|
||||
|
||||
mask = XCreatePixmap(xnestDisplay,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
pCursor->bits->width, pCursor->bits->height, 1);
|
||||
Pixmap const mask = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xcb_create_pixmap(xnestUpstreamInfo.conn, 1, mask, winId, pCursor->bits->width, pCursor->bits->height);
|
||||
|
||||
ximage = XCreateImage(xnestDisplay,
|
||||
xnestDefaultVisual(pScreen),
|
||||
1, XYBitmap, 0,
|
||||
(char *) pCursor->bits->source,
|
||||
int const pixmap_len = BitmapBytePad(pCursor->bits->width) * pCursor->bits->height;
|
||||
|
||||
xcb_put_image(xnestUpstreamInfo.conn,
|
||||
XCB_IMAGE_FORMAT_XY_BITMAP,
|
||||
source,
|
||||
xnestBitmapGC,
|
||||
pCursor->bits->width,
|
||||
pCursor->bits->height, BitmapPad(xnestDisplay), 0);
|
||||
pCursor->bits->height,
|
||||
0, // x
|
||||
0, // y
|
||||
0, // left_pad
|
||||
1, // depth
|
||||
pixmap_len,
|
||||
(uint8_t*) pCursor->bits->source);
|
||||
|
||||
XPutImage(xnestDisplay, source, xnestBitmapGC, ximage,
|
||||
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
|
||||
|
||||
XFree(ximage);
|
||||
|
||||
ximage = XCreateImage(xnestDisplay,
|
||||
xnestDefaultVisual(pScreen),
|
||||
1, XYBitmap, 0,
|
||||
(char *) pCursor->bits->mask,
|
||||
xcb_put_image(xnestUpstreamInfo.conn,
|
||||
XCB_IMAGE_FORMAT_XY_BITMAP,
|
||||
mask,
|
||||
xnestBitmapGC,
|
||||
pCursor->bits->width,
|
||||
pCursor->bits->height, BitmapPad(xnestDisplay), 0);
|
||||
|
||||
XPutImage(xnestDisplay, mask, xnestBitmapGC, ximage,
|
||||
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
|
||||
|
||||
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;
|
||||
pCursor->bits->height,
|
||||
0, // x
|
||||
0, // y
|
||||
0, // left_pad
|
||||
1, // depth
|
||||
pixmap_len,
|
||||
(uint8_t*) pCursor->bits->mask);
|
||||
|
||||
xnestSetCursorPriv(pCursor, pScreen, calloc(1, sizeof(xnestPrivCursor)));
|
||||
xnestCursor(pCursor, pScreen) =
|
||||
XCreatePixmapCursor(xnestDisplay, source, mask, &fg_color, &bg_color,
|
||||
uint32_t cursor = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xcb_create_cursor(xnestUpstreamInfo.conn, cursor, source, mask,
|
||||
pCursor->foreRed, pCursor->foreGreen, pCursor->foreBlue,
|
||||
pCursor->backRed, pCursor->backGreen, pCursor->backBlue,
|
||||
pCursor->bits->xhot, pCursor->bits->yhot);
|
||||
|
||||
XFreePixmap(xnestDisplay, source);
|
||||
XFreePixmap(xnestDisplay, mask);
|
||||
xnestCursor(pCursor, pScreen) = cursor;
|
||||
|
||||
return True;
|
||||
xcb_free_pixmap(xnestUpstreamInfo.conn, source);
|
||||
xcb_free_pixmap(xnestUpstreamInfo.conn, mask);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xnestUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
|
||||
{
|
||||
XFreeCursor(xnestDisplay, xnestCursor(pCursor, pScreen));
|
||||
xcb_free_cursor(xnestUpstreamInfo.conn, xnestCursor(pCursor, pScreen));
|
||||
free(xnestGetCursorPriv(pCursor, pScreen));
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
xnestRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
|
||||
{
|
||||
XColor fg_color, bg_color;
|
||||
|
||||
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;
|
||||
|
||||
XRecolorCursor(xnestDisplay,
|
||||
xnestCursor(pCursor, pScreen), &fg_color, &bg_color);
|
||||
xcb_recolor_cursor(xnestUpstreamInfo.conn,
|
||||
xnestCursor(pCursor, pScreen),
|
||||
pCursor->foreRed,
|
||||
pCursor->foreGreen,
|
||||
pCursor->foreBlue,
|
||||
pCursor->backRed,
|
||||
pCursor->backGreen,
|
||||
pCursor->backBlue);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -140,9 +129,12 @@ xnestSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x,
|
|||
int y)
|
||||
{
|
||||
if (pCursor) {
|
||||
XDefineCursor(xnestDisplay,
|
||||
uint32_t cursor = xnestCursor(pCursor, pScreen);
|
||||
|
||||
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
xnestCursor(pCursor, pScreen));
|
||||
XCB_CW_CURSOR,
|
||||
&cursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ is" without express or implied warranty.
|
|||
#include "scrnintstr.h"
|
||||
#include "servermd.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Init.h"
|
||||
|
@ -39,173 +39,111 @@ is" without express or implied warranty.
|
|||
#include "icon"
|
||||
#include "screensaver"
|
||||
|
||||
Display *xnestDisplay = NULL;
|
||||
XVisualInfo *xnestVisuals;
|
||||
int xnestNumVisuals;
|
||||
int xnestDefaultVisualIndex;
|
||||
Colormap *xnestDefaultColormaps;
|
||||
static uint16_t xnestNumDefaultColormaps;
|
||||
int *xnestDepths;
|
||||
int xnestNumDepths;
|
||||
XPixmapFormatValues *xnestPixmapFormats;
|
||||
int xnestNumPixmapFormats;
|
||||
Pixel xnestBlackPixel;
|
||||
Pixel xnestWhitePixel;
|
||||
Drawable xnestDefaultDrawables[MAXDEPTH + 1];
|
||||
Pixmap xnestIconBitmap;
|
||||
Pixmap xnestScreenSaverPixmap;
|
||||
XlibGC xnestBitmapGC;
|
||||
unsigned long 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);
|
||||
}
|
||||
uint32_t xnestBitmapGC;
|
||||
uint32_t xnestEventMask;
|
||||
|
||||
void
|
||||
xnestOpenDisplay(int argc, char *argv[])
|
||||
{
|
||||
XVisualInfo vi;
|
||||
long mask;
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
if (!xnestDoFullGeneration)
|
||||
return;
|
||||
|
||||
XSetIOErrorHandler(x_io_error_handler);
|
||||
|
||||
xnestCloseDisplay();
|
||||
|
||||
xnestDisplay = XOpenDisplay(xnestDisplayName);
|
||||
if (xnestDisplay == NULL)
|
||||
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 (!xnest_upstream_setup(xnestDisplayName))
|
||||
FatalError("Unable to open display \"%s\".\n", xnestDisplayName);
|
||||
|
||||
if (xnestParentWindow != (Window) 0)
|
||||
xnestEventMask = StructureNotifyMask;
|
||||
xnestEventMask = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||
else
|
||||
xnestEventMask = 0L;
|
||||
|
||||
for (i = 0; i <= MAXDEPTH; i++)
|
||||
xnestDefaultDrawables[i] = None;
|
||||
xnestDefaultDrawables[i] = XCB_WINDOW_NONE;
|
||||
|
||||
for (i = 0; i < xnestNumPixmapFormats; i++)
|
||||
for (j = 0; j < xnestNumDepths; j++)
|
||||
if (xnestPixmapFormats[i].depth == 1 ||
|
||||
xnestPixmapFormats[i].depth == xnestDepths[j]) {
|
||||
xnestDefaultDrawables[xnestPixmapFormats[i].depth] =
|
||||
XCreatePixmap(xnestDisplay, DefaultRootWindow(xnestDisplay),
|
||||
1, 1, xnestPixmapFormats[i].depth);
|
||||
xcb_format_t *fmt = xcb_setup_pixmap_formats(xnestUpstreamInfo.setup);
|
||||
const xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(xnestUpstreamInfo.setup);
|
||||
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) {
|
||||
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))
|
||||
xnestX = 0;
|
||||
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_X))
|
||||
xnestGeometry.x = 0;
|
||||
|
||||
if (!(xnestUserGeometry & YValue))
|
||||
xnestY = 0;
|
||||
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_Y))
|
||||
xnestGeometry.y = 0;
|
||||
|
||||
if (xnestParentWindow == 0) {
|
||||
if (!(xnestUserGeometry & WidthValue))
|
||||
xnestWidth = 3 * DisplayWidth(xnestDisplay,
|
||||
DefaultScreen(xnestDisplay)) / 4;
|
||||
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_WIDTH))
|
||||
xnestGeometry.width = 3 * xnestUpstreamInfo.screenInfo->width_in_pixels / 4;
|
||||
|
||||
if (!(xnestUserGeometry & HeightValue))
|
||||
xnestHeight = 3 * DisplayHeight(xnestDisplay,
|
||||
DefaultScreen(xnestDisplay)) / 4;
|
||||
if (!(xnestUserGeometry & XCB_CONFIG_WINDOW_HEIGHT))
|
||||
xnestGeometry.height = 3 * xnestUpstreamInfo.screenInfo->height_in_pixels / 4;
|
||||
}
|
||||
|
||||
if (!xnestUserBorderWidth)
|
||||
xnestBorderWidth = 1;
|
||||
|
||||
xnestIconBitmap =
|
||||
XCreateBitmapFromData(xnestDisplay,
|
||||
DefaultRootWindow(xnestDisplay),
|
||||
xnestCreateBitmapFromData(xnestUpstreamInfo.conn,
|
||||
xnestUpstreamInfo.screenInfo->root,
|
||||
(char *) icon_bits, icon_width, icon_height);
|
||||
|
||||
xnestScreenSaverPixmap =
|
||||
XCreatePixmapFromBitmapData(xnestDisplay,
|
||||
DefaultRootWindow(xnestDisplay),
|
||||
xnestCreatePixmapFromBitmapData(xnestUpstreamInfo.conn,
|
||||
xnestUpstreamInfo.screenInfo->root,
|
||||
(char *) screensaver_bits,
|
||||
screensaver_width,
|
||||
screensaver_height,
|
||||
xnestWhitePixel,
|
||||
xnestBlackPixel,
|
||||
DefaultDepth(xnestDisplay,
|
||||
DefaultScreen(xnestDisplay)));
|
||||
xnestUpstreamInfo.screenInfo->white_pixel,
|
||||
xnestUpstreamInfo.screenInfo->black_pixel,
|
||||
xnestUpstreamInfo.screenInfo->root_depth);
|
||||
}
|
||||
|
||||
void
|
||||
xnestCloseDisplay(void)
|
||||
{
|
||||
if (!xnestDoFullGeneration || !xnestDisplay)
|
||||
if (!xnestDoFullGeneration || !xnestUpstreamInfo.conn)
|
||||
return;
|
||||
|
||||
/*
|
||||
If xnestDoFullGeneration all x resources will be destroyed upon closing
|
||||
the display connection. There is no need to generate extra protocol.
|
||||
*/
|
||||
free(xnestVisualMap);
|
||||
xnestVisualMap = NULL;
|
||||
xnestNumVisualMap = 0;
|
||||
|
||||
free(xnestDefaultColormaps);
|
||||
XFree(xnestVisuals);
|
||||
XFree(xnestDepths);
|
||||
XFree(xnestPixmapFormats);
|
||||
XCloseDisplay(xnestDisplay);
|
||||
xcb_disconnect(xnestUpstreamInfo.conn);
|
||||
xnestUpstreamInfo.conn = NULL;
|
||||
xnestUpstreamInfo.screenInfo = NULL;
|
||||
xnestUpstreamInfo.setup = NULL;
|
||||
}
|
||||
|
|
|
@ -15,28 +15,19 @@ is" without express or implied warranty.
|
|||
#ifndef XNESTCOMMON_H
|
||||
#define XNESTCOMMON_H
|
||||
|
||||
#include "colormap.h"
|
||||
|
||||
#define UNDEFINED -1
|
||||
|
||||
#define MAXDEPTH 32
|
||||
#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 Pixel xnestBlackPixel;
|
||||
extern Pixel xnestWhitePixel;
|
||||
extern Drawable xnestDefaultDrawables[MAXDEPTH + 1];
|
||||
extern Pixmap xnestIconBitmap;
|
||||
extern Pixmap xnestScreenSaverPixmap;
|
||||
extern XlibGC xnestBitmapGC;
|
||||
extern unsigned long xnestEventMask;
|
||||
extern uint32_t xnestBitmapGC;
|
||||
extern uint32_t xnestEventMask;
|
||||
|
||||
void xnestOpenDisplay(int argc, char *argv[]);
|
||||
void xnestCloseDisplay(void);
|
||||
|
|
|
@ -31,7 +31,7 @@ is" without express or implied warranty.
|
|||
|
||||
#include "mi.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Args.h"
|
||||
#include "Color.h"
|
||||
|
@ -65,42 +65,6 @@ SetTimeSinceLastInputEvent(void)
|
|||
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
|
||||
xnestQueueKeyEvent(int type, unsigned int keycode)
|
||||
{
|
||||
|
@ -108,78 +72,106 @@ xnestQueueKeyEvent(int type, unsigned int keycode)
|
|||
QueueKeyboardEvents(xnestKeyboardDevice, type, keycode);
|
||||
}
|
||||
|
||||
void
|
||||
xnestCollectEvents(void)
|
||||
{
|
||||
XEvent X;
|
||||
int valuators[2];
|
||||
ValuatorMask mask;
|
||||
ScreenPtr pScreen;
|
||||
#define EVTYPE(tname) tname *ev = (tname*)event
|
||||
|
||||
while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
|
||||
switch (X.type) {
|
||||
static void
|
||||
xnest_handle_event(xcb_generic_event_t *event)
|
||||
{
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
switch (event->response_type & ~0x80) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
case ButtonPress:
|
||||
{
|
||||
ValuatorMask mask;
|
||||
EVTYPE(xcb_button_press_event_t);
|
||||
valuator_mask_set_range(&mask, 0, 0, NULL);
|
||||
xnestUpdateModifierState(X.xkey.state);
|
||||
xnestUpdateModifierState(ev->state);
|
||||
lastEventTime = GetTimeInMillis();
|
||||
QueuePointerEvents(xnestPointerDevice, ButtonPress,
|
||||
X.xbutton.button, POINTER_RELATIVE, &mask);
|
||||
ev->detail, POINTER_RELATIVE, &mask);
|
||||
break;
|
||||
}
|
||||
|
||||
case ButtonRelease:
|
||||
{
|
||||
ValuatorMask mask;
|
||||
EVTYPE(xcb_button_release_event_t);
|
||||
valuator_mask_set_range(&mask, 0, 0, NULL);
|
||||
xnestUpdateModifierState(X.xkey.state);
|
||||
xnestUpdateModifierState(ev->state);
|
||||
lastEventTime = GetTimeInMillis();
|
||||
QueuePointerEvents(xnestPointerDevice, ButtonRelease,
|
||||
X.xbutton.button, POINTER_RELATIVE, &mask);
|
||||
ev->detail, POINTER_RELATIVE, &mask);
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
lastEventTime = GetTimeInMillis();
|
||||
QueuePointerEvents(xnestPointerDevice, MotionNotify,
|
||||
0, POINTER_ABSOLUTE, &mask);
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
xnestDirectInstallColormaps(pScreen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
xnestDirectUninstallColormaps(pScreen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case KeymapNotify:
|
||||
break;
|
||||
|
||||
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) {
|
||||
NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x,
|
||||
X.xcrossing.y);
|
||||
valuators[0] = X.xcrossing.x;
|
||||
valuators[1] = X.xcrossing.y;
|
||||
ValuatorMask mask;
|
||||
int valuators[2];
|
||||
NewCurrentScreen(inputInfo.pointer, pScreen,
|
||||
ev->event_x, ev->event_y);
|
||||
valuators[0] = ev->event_x;
|
||||
valuators[1] = ev->event_y;
|
||||
valuator_mask_set_range(&mask, 0, 2, valuators);
|
||||
lastEventTime = GetTimeInMillis();
|
||||
QueuePointerEvents(xnestPointerDevice, MotionNotify,
|
||||
|
@ -188,21 +180,28 @@ xnestCollectEvents(void)
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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) {
|
||||
xnestDirectUninstallColormaps(pScreen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
case CirculateNotify:
|
||||
case ConfigureNotify:
|
||||
|
@ -210,12 +209,65 @@ xnestCollectEvents(void)
|
|||
case MapNotify:
|
||||
case ReparentNotify:
|
||||
case UnmapNotify:
|
||||
break;
|
||||
|
||||
case Expose:
|
||||
{
|
||||
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", X.type);
|
||||
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>
|
||||
|
||||
#define ProcessedExpose (LASTEvent + 1)
|
||||
|
||||
extern CARD32 lastEventTime;
|
||||
|
||||
void SetTimeSinceLastInputEvent(void);
|
||||
void xnestCollectExposures(void);
|
||||
void xnestCollectEvents(void);
|
||||
void xnestQueueKeyEvent(int type, unsigned int keycode);
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ is" without express or implied warranty.
|
|||
#include "dixfontstr.h"
|
||||
#include "scrnintstr.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "XNFont.h"
|
||||
|
@ -38,7 +38,7 @@ int xnestFontPrivateIndex;
|
|||
Bool
|
||||
xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
void *priv;
|
||||
xnestPrivFont *priv;
|
||||
Atom name_atom, value_atom;
|
||||
int nprops;
|
||||
FontPropPtr props;
|
||||
|
@ -47,7 +47,7 @@ xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
|||
|
||||
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
|
||||
|
||||
name_atom = MakeAtom("FONT", 4, True);
|
||||
name_atom = MakeAtom("FONT", 4, TRUE);
|
||||
value_atom = 0L;
|
||||
|
||||
nprops = pFont->info.nprops;
|
||||
|
@ -60,32 +60,46 @@ xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
|||
}
|
||||
|
||||
if (!value_atom)
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
name = NameForAtom(value_atom);
|
||||
|
||||
if (!name)
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
priv = (void *) malloc(sizeof(xnestPrivFont));
|
||||
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))
|
||||
return False;
|
||||
xcb_generic_error_t *err = NULL;
|
||||
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
|
||||
xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
|
||||
{
|
||||
if (xnestFontPriv(pFont)) {
|
||||
if (xnestFontStruct(pFont))
|
||||
XFreeFont(xnestDisplay, xnestFontStruct(pFont));
|
||||
xcb_close_font(xnestUpstreamInfo.conn, xnestFontPriv(pFont)->font_id);
|
||||
free(xnestFontPriv(pFont));
|
||||
xfont2_font_set_private(pFont, xnestFontPrivateIndex, NULL);
|
||||
}
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
134
hw/xnest/GC.c
134
hw/xnest/GC.c
|
@ -28,7 +28,7 @@ is" without express or implied warranty.
|
|||
#include "mistruct.h"
|
||||
#include "region.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "XNGC.h"
|
||||
|
@ -80,11 +80,14 @@ xnestCreateGC(GCPtr pGC)
|
|||
|
||||
pGC->miTranslate = 1;
|
||||
|
||||
xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
|
||||
xnestGCPriv(pGC)->gc = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xcb_create_gc(xnestUpstreamInfo.conn,
|
||||
xnestGCPriv(pGC)->gc,
|
||||
xnestDefaultDrawables[pGC->depth],
|
||||
0L, NULL);
|
||||
0,
|
||||
NULL);
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -95,7 +98,7 @@ xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
|||
void
|
||||
xnestChangeGC(GCPtr pGC, unsigned long mask)
|
||||
{
|
||||
XGCValues values;
|
||||
XnGCValues values;
|
||||
|
||||
if (mask & GCFunction)
|
||||
values.function = pGC->alu;
|
||||
|
@ -144,7 +147,7 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
|
|||
values.ts_y_origin = pGC->patOrg.y;
|
||||
|
||||
if (mask & GCFont)
|
||||
values.font = xnestFont(pGC->font);
|
||||
values.font = xnestFontPriv(pGC->font)->font_id;
|
||||
|
||||
if (mask & GCSubwindowMode)
|
||||
values.subwindow_mode = pGC->subWindowMode;
|
||||
|
@ -166,62 +169,89 @@ xnestChangeGC(GCPtr pGC, unsigned long mask)
|
|||
|
||||
if (mask & GCDashList) {
|
||||
mask &= ~GCDashList;
|
||||
XSetDashes(xnestDisplay, xnestGC(pGC),
|
||||
pGC->dashOffset, (char *) pGC->dash, pGC->numInDashList);
|
||||
xcb_set_dashes(xnestUpstreamInfo.conn,
|
||||
xnestUpstreamGC(pGC),
|
||||
pGC->dashOffset,
|
||||
pGC->numInDashList,
|
||||
(uint8_t*) pGC->dash);
|
||||
}
|
||||
|
||||
if (mask & GCArcMode)
|
||||
values.arc_mode = pGC->arcMode;
|
||||
|
||||
if (mask)
|
||||
XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
|
||||
xnChangeGC(xnestUpstreamInfo.conn, xnestUpstreamGC(pGC), values, mask);
|
||||
}
|
||||
|
||||
void
|
||||
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
|
||||
xnestDestroyGC(GCPtr pGC)
|
||||
{
|
||||
XFreeGC(xnestDisplay, xnestGC(pGC));
|
||||
xcb_free_gc(xnestUpstreamInfo.conn, xnestGC(pGC));
|
||||
}
|
||||
|
||||
void
|
||||
xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
|
||||
{
|
||||
int i;
|
||||
BoxPtr pBox;
|
||||
XRectangle *pRects;
|
||||
|
||||
xnestDestroyClip(pGC);
|
||||
|
||||
switch (type) {
|
||||
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;
|
||||
break;
|
||||
|
||||
case CT_REGION:
|
||||
{
|
||||
nRects = RegionNumRects((RegionPtr) pValue);
|
||||
pRects = xallocarray(nRects, sizeof(*pRects));
|
||||
pBox = RegionRects((RegionPtr) pValue);
|
||||
for (i = nRects; i-- > 0;) {
|
||||
pRects[i].x = pBox[i].x1;
|
||||
pRects[i].y = pBox[i].y1;
|
||||
pRects[i].width = pBox[i].x2 - pBox[i].x1;
|
||||
pRects[i].height = pBox[i].y2 - pBox[i].y1;
|
||||
xcb_rectangle_t *rects= calloc(nRects, sizeof(xcb_rectangle_t));
|
||||
if (rects == NULL) {
|
||||
ErrorF("xnestChangeClip: memory alloc failure");
|
||||
return;
|
||||
}
|
||||
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;
|
||||
|
||||
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
|
||||
* current pixmap contents.
|
||||
|
@ -232,27 +262,47 @@ xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects)
|
|||
break;
|
||||
|
||||
case CT_UNSORTED:
|
||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
||||
xcb_set_clip_rectangles(
|
||||
xnestUpstreamInfo.conn,
|
||||
XCB_CLIP_ORDERING_UNSORTED,
|
||||
xnestUpstreamGC(pGC),
|
||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
||||
(XRectangle *) pValue, nRects, Unsorted);
|
||||
nRects,
|
||||
(xcb_rectangle_t*)pValue);
|
||||
break;
|
||||
|
||||
case CT_YSORTED:
|
||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
||||
(XRectangle *) pValue, nRects, YSorted);
|
||||
xcb_set_clip_rectangles(
|
||||
xnestUpstreamInfo.conn,
|
||||
XCB_CLIP_ORDERING_Y_SORTED,
|
||||
xnestUpstreamGC(pGC),
|
||||
pGC->clipOrg.x,
|
||||
pGC->clipOrg.y,
|
||||
nRects,
|
||||
(xcb_rectangle_t*)pValue);
|
||||
break;
|
||||
|
||||
case CT_YXSORTED:
|
||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
||||
(XRectangle *) pValue, nRects, YXSorted);
|
||||
xcb_set_clip_rectangles(
|
||||
xnestUpstreamInfo.conn,
|
||||
XCB_CLIP_ORDERING_YX_SORTED,
|
||||
xnestUpstreamGC(pGC),
|
||||
pGC->clipOrg.x,
|
||||
pGC->clipOrg.y,
|
||||
nRects,
|
||||
(xcb_rectangle_t*)pValue);
|
||||
|
||||
break;
|
||||
|
||||
case CT_YXBANDED:
|
||||
XSetClipRectangles(xnestDisplay, xnestGC(pGC),
|
||||
pGC->clipOrg.x, pGC->clipOrg.y,
|
||||
(XRectangle *) pValue, nRects, YXBanded);
|
||||
xcb_set_clip_rectangles(
|
||||
xnestUpstreamInfo.conn,
|
||||
XCB_CLIP_ORDERING_YX_BANDED,
|
||||
xnestUpstreamGC(pGC),
|
||||
pGC->clipOrg.x,
|
||||
pGC->clipOrg.y,
|
||||
nRects,
|
||||
(xcb_rectangle_t*)pValue);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -279,7 +329,11 @@ xnestDestroyClip(GCPtr pGC)
|
|||
{
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
|
|
342
hw/xnest/GCOps.c
342
hw/xnest/GCOps.c
|
@ -29,7 +29,7 @@ is" without express or implied warranty.
|
|||
#include "region.h"
|
||||
#include "servermd.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
|
@ -37,7 +37,6 @@ is" without express or implied warranty.
|
|||
#include "XNFont.h"
|
||||
#include "GCOps.h"
|
||||
#include "Drawable.h"
|
||||
#include "Visual.h"
|
||||
|
||||
void
|
||||
xnestFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, xPoint * pPoints,
|
||||
|
@ -64,74 +63,81 @@ void
|
|||
xnestQueryBestSize(int class, unsigned short *pWidth, unsigned short *pHeight,
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
unsigned int width, height;
|
||||
|
||||
width = *pWidth;
|
||||
height = *pHeight;
|
||||
|
||||
XQueryBestSize(xnestDisplay, class,
|
||||
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],
|
||||
width, height, &width, &height);
|
||||
*pWidth,
|
||||
*pHeight),
|
||||
&err);
|
||||
|
||||
*pWidth = width;
|
||||
*pHeight = height;
|
||||
if (err) {
|
||||
ErrorF("QueryBestSize request failed: %d\n", err->error_code);
|
||||
free(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!reply) {
|
||||
ErrorF("QueryBestSize request failed: no reply\n");
|
||||
return;
|
||||
}
|
||||
|
||||
*pWidth = reply->width;
|
||||
*pHeight = reply->height;
|
||||
free(reply);
|
||||
}
|
||||
|
||||
void
|
||||
xnestPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
||||
int w, int h, int leftPad, int format, char *pImage)
|
||||
{
|
||||
XImage *ximage;
|
||||
|
||||
ximage = XCreateImage(xnestDisplay, xnestDefaultVisual(pDrawable->pScreen),
|
||||
depth, format, leftPad, (char *) pImage,
|
||||
w, h, BitmapPad(xnestDisplay),
|
||||
(format == ZPixmap) ?
|
||||
PixmapBytePad(w, depth) : BitmapBytePad(w + leftPad));
|
||||
|
||||
if (ximage) {
|
||||
XPutImage(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
ximage, 0, 0, x, y, w, h);
|
||||
XFree(ximage);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
xnestIgnoreErrorHandler (Display *dpy,
|
||||
XErrorEvent *event)
|
||||
{
|
||||
return False; /* return value is ignored */
|
||||
xcb_put_image(xnestUpstreamInfo.conn,
|
||||
format,
|
||||
xnestDrawable(pDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
w,
|
||||
h,
|
||||
x,
|
||||
y,
|
||||
leftPad,
|
||||
depth,
|
||||
(format == XCB_IMAGE_FORMAT_Z_PIXMAP ? PixmapBytePad(w, depth)
|
||||
: BitmapBytePad(w + leftPad)) * h,
|
||||
(uint8_t*)pImage);
|
||||
}
|
||||
|
||||
void
|
||||
xnestGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
|
||||
unsigned int format, unsigned long planeMask, char *pImage)
|
||||
{
|
||||
XImage *ximage;
|
||||
int length;
|
||||
int (*old_handler)(Display*, XErrorEvent*);
|
||||
xcb_generic_error_t * err = NULL;
|
||||
xcb_get_image_reply_t *reply= xcb_get_image_reply(
|
||||
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 */
|
||||
XSync(xnestDisplay, False);
|
||||
old_handler = XSetErrorHandler (xnestIgnoreErrorHandler);
|
||||
|
||||
ximage = XGetImage(xnestDisplay, xnestDrawable(pDrawable),
|
||||
x, y, w, h, planeMask, format);
|
||||
XSetErrorHandler(old_handler);
|
||||
|
||||
if (ximage) {
|
||||
length = ximage->bytes_per_line * ximage->height;
|
||||
|
||||
memmove(pImage, ximage->data, length);
|
||||
|
||||
XDestroyImage(ximage);
|
||||
}
|
||||
if (err) {
|
||||
// badMatch may happeen if the upstream window is currently minimized
|
||||
if (err->error_code != BadMatch)
|
||||
LogMessage(X_WARNING, "xnestGetImage: received error %d\n", err->error_code);
|
||||
free(err);
|
||||
return;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xnestBitBlitPredicate(Display * dpy, XEvent * event, char *args)
|
||||
{
|
||||
return event->type == GraphicsExpose || event->type == NoExpose;
|
||||
if (!reply) {
|
||||
LogMessage(X_WARNING, "xnestGetImage: received no reply\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(pImage, xcb_get_image_data(reply), xcb_get_image_data_length(reply));
|
||||
free(reply);
|
||||
}
|
||||
|
||||
static RegionPtr
|
||||
|
@ -140,9 +146,7 @@ xnestBitBlitHelper(GCPtr pGC)
|
|||
if (!pGC->graphicsExposures)
|
||||
return NullRegion;
|
||||
else {
|
||||
XEvent event;
|
||||
RegionPtr pReg, pTmpReg;
|
||||
BoxRec Box;
|
||||
Bool pending, overlap;
|
||||
|
||||
pReg = RegionCreate(NULL, 1);
|
||||
|
@ -150,25 +154,44 @@ xnestBitBlitHelper(GCPtr pGC)
|
|||
if (!pReg || !pTmpReg)
|
||||
return NullRegion;
|
||||
|
||||
pending = True;
|
||||
while (pending) {
|
||||
XIfEvent(xnestDisplay, &event, xnestBitBlitPredicate, NULL);
|
||||
xcb_flush(xnestUpstreamInfo.conn);
|
||||
|
||||
switch (event.type) {
|
||||
pending = TRUE;
|
||||
while (pending) {
|
||||
xcb_generic_event_t *event = xcb_wait_for_event(xnestUpstreamInfo.conn);
|
||||
if (!event) {
|
||||
pending = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (event->response_type & ~0x80) {
|
||||
case NoExpose:
|
||||
pending = False;
|
||||
pending = FALSE;
|
||||
free(event);
|
||||
break;
|
||||
|
||||
case GraphicsExpose:
|
||||
Box.x1 = event.xgraphicsexpose.x;
|
||||
Box.y1 = event.xgraphicsexpose.y;
|
||||
Box.x2 = event.xgraphicsexpose.x + event.xgraphicsexpose.width;
|
||||
Box.y2 = event.xgraphicsexpose.y + event.xgraphicsexpose.height;
|
||||
{
|
||||
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 = event.xgraphicsexpose.count;
|
||||
pending = ev->count;
|
||||
free(event);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
xnestEventQueue *q = malloc(sizeof(xnestEventQueue));
|
||||
q->event = event;
|
||||
xorg_list_add(&q->entry, &xnestUpstreamInfo.eventQueue.entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RegionDestroy(pTmpReg);
|
||||
|
@ -182,9 +205,11 @@ xnestCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
|
|||
GCPtr pGC, int srcx, int srcy, int width, int height,
|
||||
int dstx, int dsty)
|
||||
{
|
||||
XCopyArea(xnestDisplay,
|
||||
xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
|
||||
xnestGC(pGC), srcx, srcy, width, height, dstx, dsty);
|
||||
xcb_copy_area(xnestUpstreamInfo.conn,
|
||||
xnestDrawable(pSrcDrawable),
|
||||
xnestDrawable(pDstDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
srcx, srcy, dstx, dsty, width, height);
|
||||
|
||||
return xnestBitBlitHelper(pGC);
|
||||
}
|
||||
|
@ -194,9 +219,11 @@ xnestCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
|
|||
GCPtr pGC, int srcx, int srcy, int width, int height,
|
||||
int dstx, int dsty, unsigned long plane)
|
||||
{
|
||||
XCopyPlane(xnestDisplay,
|
||||
xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
|
||||
xnestGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
|
||||
xcb_copy_plane(xnestUpstreamInfo.conn,
|
||||
xnestDrawable(pSrcDrawable),
|
||||
xnestDrawable(pDstDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
srcx, srcy, dstx, dsty, width, height, plane);
|
||||
|
||||
return xnestBitBlitHelper(pGC);
|
||||
}
|
||||
|
@ -205,106 +232,184 @@ void
|
|||
xnestPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
|
||||
DDXPointPtr pPoints)
|
||||
{
|
||||
XDrawPoints(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XPoint *) pPoints, nPoints, mode);
|
||||
/* xPoint and xcb_segment_t are defined in the same way, both matching
|
||||
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
|
||||
xnestPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int nPoints,
|
||||
DDXPointPtr pPoints)
|
||||
{
|
||||
XDrawLines(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XPoint *) pPoints, nPoints, mode);
|
||||
/* xPoint and xcb_segment_t are defined in the same way, both matching
|
||||
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
|
||||
xnestPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
|
||||
xSegment * pSegments)
|
||||
{
|
||||
XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XSegment *) pSegments, nSegments);
|
||||
/* xSegment and xcb_segment_t are defined in the same way, both matching
|
||||
the protocol layout, so we can directly typecast them */
|
||||
xcb_poly_segment(xnestUpstreamInfo.conn,
|
||||
xnestDrawable(pDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
nSegments,
|
||||
(xcb_segment_t*)pSegments);
|
||||
}
|
||||
|
||||
void
|
||||
xnestPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
|
||||
xRectangle *pRectangles)
|
||||
{
|
||||
XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XRectangle *) pRectangles, nRectangles);
|
||||
/* xRectangle and xcb_rectangle_t are defined in the same way, both matching
|
||||
the protocol layout, so we can directly typecast them */
|
||||
xcb_poly_rectangle(xnestUpstreamInfo.conn,
|
||||
xnestDrawable(pDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
nRectangles,
|
||||
(xcb_rectangle_t*)pRectangles);
|
||||
}
|
||||
|
||||
void
|
||||
xnestPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
|
||||
{
|
||||
XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XArc *) pArcs, nArcs);
|
||||
/* xArc and xcb_arc_t are defined in the same way, both matching
|
||||
the protocol layout, so we can directly typecast them */
|
||||
xcb_poly_arc(xnestUpstreamInfo.conn,
|
||||
xnestDrawable(pDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
nArcs,
|
||||
(xcb_arc_t*)pArcs);
|
||||
}
|
||||
|
||||
void
|
||||
xnestFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode,
|
||||
int nPoints, DDXPointPtr pPoints)
|
||||
{
|
||||
XFillPolygon(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XPoint *) pPoints, nPoints, shape, mode);
|
||||
/* xPoint and xcb_segment_t are defined in the same way, both matching
|
||||
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
|
||||
xnestPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRectangles,
|
||||
xRectangle *pRectangles)
|
||||
{
|
||||
XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XRectangle *) pRectangles, nRectangles);
|
||||
/* xRectangle and xcb_rectangle_t are defined in the same way, both matching
|
||||
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
|
||||
xnestPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, xArc * pArcs)
|
||||
{
|
||||
XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
(XArc *) pArcs, nArcs);
|
||||
/* xArc and xcb_arc_t are defined in the same way, both matching
|
||||
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
|
||||
xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||
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),
|
||||
x, y, string, count);
|
||||
xcb_poly_text_8(xnestUpstreamInfo.conn,
|
||||
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
|
||||
xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||
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),
|
||||
x, y, (XChar2b *) string, count);
|
||||
xcb_poly_text_16(xnestUpstreamInfo.conn,
|
||||
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
|
||||
xnestImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||
char *string)
|
||||
{
|
||||
XDrawImageString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
x, y, string, count);
|
||||
xcb_image_text_8(xnestUpstreamInfo.conn,
|
||||
count,
|
||||
xnestDrawable(pDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
x,
|
||||
y,
|
||||
string);
|
||||
}
|
||||
|
||||
void
|
||||
xnestImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
|
||||
unsigned short *string)
|
||||
{
|
||||
XDrawImageString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
|
||||
x, y, (XChar2b *) string, count);
|
||||
xcb_image_text_16(xnestUpstreamInfo.conn,
|
||||
count,
|
||||
xnestDrawable(pDrawable),
|
||||
xnestUpstreamGC(pGC),
|
||||
x,
|
||||
y,
|
||||
(xcb_char2b_t*)string);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -329,12 +434,35 @@ xnestPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDst,
|
|||
{
|
||||
/* only works for solid bitmaps */
|
||||
if (pGC->fillStyle == FillSolid) {
|
||||
XSetStipple(xnestDisplay, xnestGC(pGC), xnestPixmap(pBitmap));
|
||||
XSetTSOrigin(xnestDisplay, xnestGC(pGC), x, y);
|
||||
XSetFillStyle(xnestDisplay, xnestGC(pGC), FillStippled);
|
||||
XFillRectangle(xnestDisplay, xnestDrawable(pDst),
|
||||
xnestGC(pGC), x, y, width, height);
|
||||
XSetFillStyle(xnestDisplay, xnestGC(pGC), FillSolid);
|
||||
xnChangeGC(xnestUpstreamInfo.conn,
|
||||
xnestUpstreamGC(pGC),
|
||||
(XnGCValues) {
|
||||
.fill_style = XCB_FILL_STYLE_STIPPLED,
|
||||
.ts_x_origin = x,
|
||||
.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
|
||||
ErrorF("xnest warning: function xnestPushPixels not implemented\n");
|
||||
|
|
|
@ -25,8 +25,6 @@ is" without express or implied warranty.
|
|||
#include "windowstr.h"
|
||||
#include "servermd.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Events.h"
|
||||
#include "Handlers.h"
|
||||
|
@ -34,8 +32,7 @@ is" without express or implied warranty.
|
|||
void
|
||||
xnestBlockHandler(void *blockData, void *timeout)
|
||||
{
|
||||
xnestCollectExposures();
|
||||
XFlush(xnestDisplay);
|
||||
xnestCollectEvents();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -34,8 +34,8 @@ is" without express or implied warranty.
|
|||
#include "mi.h"
|
||||
#include "dixfontstr.h"
|
||||
#include "extinit_priv.h"
|
||||
#include "Xnest.h"
|
||||
|
||||
#include "xnest-xcb.h"
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
#include "Pointer.h"
|
||||
|
@ -51,7 +51,7 @@ is" without express or implied warranty.
|
|||
#include "dpmsproc.h"
|
||||
#endif
|
||||
|
||||
Bool xnestDoFullGeneration = True;
|
||||
Bool xnestDoFullGeneration = TRUE;
|
||||
|
||||
#ifdef GLXEXT
|
||||
void
|
||||
|
@ -63,29 +63,37 @@ GlxExtensionInit(void)
|
|||
void
|
||||
InitOutput(ScreenInfo * screen_info, int argc, char *argv[])
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
xnestOpenDisplay(argc, argv);
|
||||
|
||||
screen_info->imageByteOrder = ImageByteOrder(xnestDisplay);
|
||||
screen_info->bitmapScanlineUnit = BitmapUnit(xnestDisplay);
|
||||
screen_info->bitmapScanlinePad = BitmapPad(xnestDisplay);
|
||||
screen_info->bitmapBitOrder = BitmapBitOrder(xnestDisplay);
|
||||
|
||||
screen_info->imageByteOrder = xnestUpstreamInfo.setup->image_byte_order;
|
||||
screen_info->bitmapScanlineUnit = xnestUpstreamInfo.setup->bitmap_format_scanline_unit;
|
||||
screen_info->bitmapScanlinePad = xnestUpstreamInfo.setup->bitmap_format_scanline_pad;
|
||||
screen_info->bitmapBitOrder = xnestUpstreamInfo.setup->bitmap_format_bit_order;
|
||||
screen_info->numPixmapFormats = 0;
|
||||
for (i = 0; i < xnestNumPixmapFormats; i++)
|
||||
for (j = 0; j < xnestNumDepths; j++)
|
||||
if ((xnestPixmapFormats[i].depth == 1) ||
|
||||
(xnestPixmapFormats[i].depth == xnestDepths[j])) {
|
||||
|
||||
xcb_format_t *fmt = xcb_setup_pixmap_formats(xnestUpstreamInfo.setup);
|
||||
const xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(xnestUpstreamInfo.setup);
|
||||
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 =
|
||||
xnestPixmapFormats[i].depth;
|
||||
fmt->depth;
|
||||
screen_info->formats[screen_info->numPixmapFormats].bitsPerPixel =
|
||||
xnestPixmapFormats[i].bits_per_pixel;
|
||||
fmt->bits_per_pixel;
|
||||
screen_info->formats[screen_info->numPixmapFormats].scanlinePad =
|
||||
xnestPixmapFormats[i].scanline_pad;
|
||||
fmt->scanline_pad;
|
||||
screen_info->numPixmapFormats++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xnestFontPrivateIndex = xfont2_allocate_font_private_index();
|
||||
|
||||
|
@ -121,7 +129,10 @@ InitInput(int argc, char *argv[])
|
|||
|
||||
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);
|
||||
}
|
||||
|
@ -135,7 +146,7 @@ CloseInput(void)
|
|||
void
|
||||
ddxGiveUp(enum ExitCode error)
|
||||
{
|
||||
xnestDoFullGeneration = True;
|
||||
xnestDoFullGeneration = TRUE;
|
||||
xnestCloseDisplay();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ is" without express or implied warranty.
|
|||
#include <X11/Xdefs.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <xcb/xkb.h>
|
||||
|
||||
#include "screenint.h"
|
||||
#include "inputstr.h"
|
||||
|
@ -31,7 +32,7 @@ is" without express or implied warranty.
|
|||
#include "scrnintstr.h"
|
||||
#include "servermd.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
|
@ -41,39 +42,19 @@ is" without express or implied warranty.
|
|||
|
||||
#include <X11/extensions/XKB.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;
|
||||
|
||||
void
|
||||
xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls)
|
||||
{
|
||||
XBell(xnestDisplay, volume);
|
||||
xcb_bell(xnestUpstreamInfo.conn, volume);
|
||||
}
|
||||
|
||||
void
|
||||
DDXRingBell(int volume, int pitch, int duration)
|
||||
{
|
||||
XBell(xnestDisplay, volume);
|
||||
xcb_bell(xnestUpstreamInfo.conn, volume);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -81,7 +62,7 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
|||
{
|
||||
#if 0
|
||||
unsigned long value_mask;
|
||||
XKeyboardControl values;
|
||||
XnKeyboardControl values;
|
||||
int i;
|
||||
|
||||
value_mask = KBKeyClickPercent |
|
||||
|
@ -94,7 +75,9 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
|||
values.auto_repeat_mode = ctrl->autoRepeat ?
|
||||
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;
|
||||
|
@ -107,7 +90,9 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
|||
values.led = i;
|
||||
values.led_mode =
|
||||
(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
|
||||
}
|
||||
|
@ -115,73 +100,60 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
|
|||
int
|
||||
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;
|
||||
XKeyboardState values;
|
||||
XkbDescPtr xkb;
|
||||
int op, event, error, major, minor;
|
||||
|
||||
switch (onoff) {
|
||||
case DEVICE_INIT:
|
||||
XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
|
||||
#ifdef _XSERVER64
|
||||
{
|
||||
KeySym64 *keymap64;
|
||||
int len;
|
||||
const int min_keycode = xnestUpstreamInfo.setup->min_keycode;
|
||||
const int max_keycode = xnestUpstreamInfo.setup->max_keycode;
|
||||
const int num_keycode = max_keycode - min_keycode + 1;
|
||||
|
||||
keymap64 = XGetKeyboardMapping(xnestDisplay,
|
||||
xcb_get_keyboard_mapping_reply_t * keymap_reply = xnestGetKeyboardMapping(
|
||||
xnestUpstreamInfo.conn,
|
||||
min_keycode,
|
||||
max_keycode - min_keycode + 1,
|
||||
&mapWidth);
|
||||
len = (max_keycode - min_keycode + 1) * mapWidth;
|
||||
keymap = xallocarray(len, sizeof(KeySym));
|
||||
for (i = 0; i < len; ++i)
|
||||
keymap[i] = keymap64[i];
|
||||
XFree(keymap64);
|
||||
num_keycode);
|
||||
|
||||
if (!keymap_reply) {
|
||||
ErrorF("Couldn't get keyboard mappings: no reply");
|
||||
goto XkbError;
|
||||
}
|
||||
#else
|
||||
keymap = XGetKeyboardMapping(xnestDisplay,
|
||||
min_keycode,
|
||||
max_keycode - min_keycode + 1, &mapWidth);
|
||||
#endif
|
||||
|
||||
memset(modmap, 0, sizeof(modmap));
|
||||
modifier_keymap = XGetModifierMapping(xnestDisplay);
|
||||
KeySymsRec keySyms = {
|
||||
.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 (i = 0; i < modifier_keymap->max_keypermod; i++) {
|
||||
for (i = 0; i < mod_reply->keycodes_per_modifier; i++) {
|
||||
CARD8 keycode;
|
||||
|
||||
if ((keycode =
|
||||
modifier_keymap->modifiermap[j *
|
||||
modifier_keymap->
|
||||
max_keypermod + i]))
|
||||
mod_keycodes[j * mod_reply->keycodes_per_modifier + i]))
|
||||
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,
|
||||
xnestBell, xnestChangeKeyboardControl);
|
||||
|
@ -190,19 +162,80 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
|||
keySyms.maxKeyCode - keySyms.minKeyCode + 1,
|
||||
modmap, serverClient);
|
||||
|
||||
XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
|
||||
XkbFreeKeyboard(xkb, 0, False);
|
||||
free(keymap);
|
||||
free(keymap_reply);
|
||||
|
||||
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;
|
||||
}
|
||||
case DEVICE_ON:
|
||||
xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
|
||||
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;
|
||||
case DEVICE_OFF:
|
||||
xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
|
||||
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;
|
||||
case DEVICE_CLOSE:
|
||||
break;
|
||||
|
@ -210,12 +243,28 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
|
|||
return Success;
|
||||
|
||||
XkbError:
|
||||
XGetKeyboardControl(xnestDisplay, &values);
|
||||
memmove((char *) defaultKeyboardControl.autoRepeats,
|
||||
(char *) values.auto_repeats, sizeof(values.auto_repeats));
|
||||
{
|
||||
xcb_generic_error_t *ctrl_err = NULL;
|
||||
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);
|
||||
free(keymap);
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ is" without express or implied warranty.
|
|||
#define XNESTKEYBOARD_H
|
||||
|
||||
#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;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ is" without express or implied warranty.
|
|||
#include "privates.h"
|
||||
#include "mi.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
|
@ -59,11 +59,12 @@ xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
|
|||
pPixmap->refcnt = 1;
|
||||
pPixmap->devKind = PixmapBytePad(width, depth);
|
||||
pPixmap->usage_hint = usage_hint;
|
||||
if (width && height)
|
||||
xnestPixmapPriv(pPixmap)->pixmap =
|
||||
XCreatePixmap(xnestDisplay,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
width, height, depth);
|
||||
if (width && height) {
|
||||
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xcb_create_pixmap(xnestUpstreamInfo.conn, depth, pixmap,
|
||||
xnestDefaultWindows[pScreen->myNum], width, height);
|
||||
xnestPixmapPriv(pPixmap)->pixmap = pixmap;
|
||||
}
|
||||
else
|
||||
xnestPixmapPriv(pPixmap)->pixmap = 0;
|
||||
|
||||
|
@ -75,7 +76,7 @@ xnestDestroyPixmap(PixmapPtr pPixmap)
|
|||
{
|
||||
if (--pPixmap->refcnt)
|
||||
return TRUE;
|
||||
XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
|
||||
xcb_free_pixmap(xnestUpstreamInfo.conn, xnestPixmap(pPixmap));
|
||||
FreePixmap(pPixmap);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -85,10 +86,11 @@ xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
|
|||
int bitsPerPixel, int devKind, void *pPixData)
|
||||
{
|
||||
if(!xnestPixmapPriv(pPixmap)->pixmap && width > 0 && height > 0) {
|
||||
xnestPixmapPriv(pPixmap)->pixmap =
|
||||
XCreatePixmap(xnestDisplay,
|
||||
uint32_t pixmap = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xcb_create_pixmap(xnestUpstreamInfo.conn, depth, pixmap,
|
||||
xnestDefaultWindows[pPixmap->drawable.pScreen->myNum],
|
||||
width, height, depth);
|
||||
width, height);
|
||||
xnestPixmapPriv(pPixmap)->pixmap = pixmap;
|
||||
}
|
||||
|
||||
return miModifyPixmapHeader(pPixmap, width, height, depth,
|
||||
|
@ -98,30 +100,60 @@ xnestModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
|
|||
RegionPtr
|
||||
xnestPixmapToRegion(PixmapPtr pPixmap)
|
||||
{
|
||||
XImage *ximage;
|
||||
register RegionPtr pReg, pTmpReg;
|
||||
register int x, y;
|
||||
unsigned long previousPixel, currentPixel;
|
||||
BoxRec Box = { 0, 0, 0, 0 };
|
||||
Bool overlap;
|
||||
|
||||
ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0,
|
||||
pPixmap->drawable.width, pPixmap->drawable.height,
|
||||
1, XYPixmap);
|
||||
if (pPixmap->drawable.depth != 1) {
|
||||
LogMessage(X_WARNING, "xnestPixmapToRegion() depth != 1: %d\n", pPixmap->drawable.depth);
|
||||
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);
|
||||
pTmpReg = RegionCreate(NULL, 1);
|
||||
if (!pReg || !pTmpReg) {
|
||||
XDestroyImage(ximage);
|
||||
free(reply);
|
||||
return NullRegion;
|
||||
}
|
||||
|
||||
uint8_t *image_data = xcb_get_image_data(reply);
|
||||
for (y = 0; y < pPixmap->drawable.height; y++) {
|
||||
Box.y1 = y;
|
||||
Box.y2 = y + 1;
|
||||
previousPixel = 0L;
|
||||
const int line_start = BitmapBytePad(pPixmap->drawable.width) * y;
|
||||
|
||||
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 == 0L) {
|
||||
/* left edge */
|
||||
|
@ -145,7 +177,7 @@ xnestPixmapToRegion(PixmapPtr pPixmap)
|
|||
}
|
||||
|
||||
RegionDestroy(pTmpReg);
|
||||
XDestroyImage(ximage);
|
||||
free(reply);
|
||||
|
||||
RegionValidate(pReg, &overlap);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ is" without express or implied warranty.
|
|||
#include "servermd.h"
|
||||
#include "mipointer.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
|
@ -41,25 +41,24 @@ DeviceIntPtr xnestPointerDevice = NULL;
|
|||
void
|
||||
xnestChangePointerControl(DeviceIntPtr pDev, PtrCtrl * ctrl)
|
||||
{
|
||||
XChangePointerControl(xnestDisplay, True, True,
|
||||
ctrl->num, ctrl->den, ctrl->threshold);
|
||||
xcb_change_pointer_control(xnestUpstreamInfo.conn,
|
||||
ctrl->num,
|
||||
ctrl->den,
|
||||
ctrl->threshold,
|
||||
TRUE,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
xnestPointerProc(DeviceIntPtr pDev, int onoff)
|
||||
{
|
||||
CARD8 map[MAXBUTTONS];
|
||||
Atom btn_labels[MAXBUTTONS] = { 0 };
|
||||
Atom axes_labels[2] = { 0 };
|
||||
int nmap;
|
||||
int i;
|
||||
|
||||
switch (onoff) {
|
||||
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[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
|
||||
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[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
|
||||
|
||||
XGetPointerControl(xnestDisplay,
|
||||
xnestGetPointerControl(xnestUpstreamInfo.conn,
|
||||
&defaultPointerControl.num,
|
||||
&defaultPointerControl.den,
|
||||
&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,
|
||||
GetMotionHistorySize(), 2, axes_labels);
|
||||
free(pm_reply);
|
||||
break;
|
||||
}
|
||||
case DEVICE_ON:
|
||||
xnestEventMask |= XNEST_POINTER_EVENT_MASK;
|
||||
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;
|
||||
case DEVICE_OFF:
|
||||
xnestEventMask &= ~XNEST_POINTER_EVENT_MASK;
|
||||
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;
|
||||
case DEVICE_CLOSE:
|
||||
break;
|
||||
|
|
|
@ -20,6 +20,8 @@ is" without express or implied warranty.
|
|||
#include <X11/Xdefs.h>
|
||||
#include <X11/Xproto.h>
|
||||
|
||||
#include <xcb/xcb_icccm.h>
|
||||
|
||||
#include "mi/mi_priv.h"
|
||||
|
||||
#include "scrnintstr.h"
|
||||
|
@ -29,7 +31,7 @@ is" without express or implied warranty.
|
|||
#include "colormapst.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
|
@ -39,7 +41,6 @@ is" without express or implied warranty.
|
|||
#include "XNFont.h"
|
||||
#include "Color.h"
|
||||
#include "XNCursor.h"
|
||||
#include "Visual.h"
|
||||
#include "Events.h"
|
||||
#include "Init.h"
|
||||
#include "mipointer.h"
|
||||
|
@ -78,31 +79,36 @@ static Bool
|
|||
xnestSaveScreen(ScreenPtr pScreen, int what)
|
||||
{
|
||||
if (xnestSoftwareScreenSaver)
|
||||
return False;
|
||||
return FALSE;
|
||||
else {
|
||||
switch (what) {
|
||||
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);
|
||||
break;
|
||||
|
||||
case SCREEN_SAVER_OFF:
|
||||
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
|
||||
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
|
||||
xnestSetInstalledColormapWindows(pScreen);
|
||||
break;
|
||||
|
||||
case SCREEN_SAVER_FORCER:
|
||||
lastEventTime = GetTimeInMillis();
|
||||
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
|
||||
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
|
||||
xnestSetInstalledColormapWindows(pScreen);
|
||||
break;
|
||||
|
||||
case SCREEN_SAVER_CYCLE:
|
||||
XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
|
||||
xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
|
||||
xnestSetInstalledColormapWindows(pScreen);
|
||||
break;
|
||||
}
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,17 +138,39 @@ static miPointerSpriteFuncRec xnestPointerSpriteFuncs = {
|
|||
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
|
||||
xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
||||
{
|
||||
VisualPtr visuals;
|
||||
DepthPtr depths;
|
||||
int numVisuals, numDepths;
|
||||
int i, j, depthIndex;
|
||||
int j;
|
||||
unsigned long valuemask;
|
||||
XSetWindowAttributes attributes;
|
||||
XWindowAttributes gattributes;
|
||||
XSizeHints sizeHints;
|
||||
VisualID defaultVisual;
|
||||
int rootDepth;
|
||||
miPointerScreenPtr PointPriv;
|
||||
|
@ -167,96 +195,128 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
|||
PRIVATE_CURSOR, 0))
|
||||
return FALSE;
|
||||
|
||||
visuals = xallocarray(xnestNumVisuals, sizeof(VisualRec));
|
||||
visuals = xallocarray(1, sizeof(VisualRec));
|
||||
numVisuals = 0;
|
||||
|
||||
if (!xnestVisualMap)
|
||||
xnestVisualMap = calloc(1, sizeof(XnestVisualRec));
|
||||
else
|
||||
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(XnestVisualRec));
|
||||
|
||||
depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
|
||||
depths[0].depth = 1;
|
||||
depths[0].numVids = 0;
|
||||
depths[0].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
|
||||
numDepths = 1;
|
||||
|
||||
for (i = 0; i < xnestNumVisuals; i++) {
|
||||
visuals[numVisuals].class = xnestVisuals[i].class;
|
||||
visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
|
||||
visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
|
||||
visuals[numVisuals].nplanes = xnestVisuals[i].depth;
|
||||
visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
|
||||
visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
|
||||
visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
|
||||
visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
|
||||
visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
|
||||
visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
|
||||
|
||||
/* Check for and remove duplicates. */
|
||||
int found_default_visual = 0;
|
||||
xcb_depth_iterator_t depth_iter;
|
||||
for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
|
||||
depth_iter.rem;
|
||||
xcb_depth_next(&depth_iter))
|
||||
{
|
||||
int vlen = xcb_depth_visuals_length (depth_iter.data);
|
||||
xcb_visualtype_t *vts = xcb_depth_visuals (depth_iter.data);
|
||||
for (int x=0; x<vlen; x++) {
|
||||
for (j = 0; j < numVisuals; j++) {
|
||||
if (visuals[numVisuals].class == visuals[j].class &&
|
||||
visuals[numVisuals].bitsPerRGBValue ==
|
||||
visuals[j].bitsPerRGBValue &&
|
||||
visuals[numVisuals].ColormapEntries ==
|
||||
visuals[j].ColormapEntries &&
|
||||
visuals[numVisuals].nplanes == visuals[j].nplanes &&
|
||||
visuals[numVisuals].redMask == visuals[j].redMask &&
|
||||
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 (vts[x]._class == visuals[j].class &&
|
||||
vts[x].bits_per_rgb_value == visuals[j].bitsPerRGBValue &&
|
||||
vts[x].colormap_entries == visuals[j].ColormapEntries &&
|
||||
depth_iter.data->depth == visuals[j].nplanes &&
|
||||
vts[x].red_mask == visuals[j].redMask &&
|
||||
vts[x].green_mask == visuals[j].greenMask &&
|
||||
vts[x].blue_mask == visuals[j].blueMask &&
|
||||
offset(vts[x].red_mask) == visuals[j].offsetRed &&
|
||||
offset(vts[x].green_mask) == visuals[j].offsetGreen &&
|
||||
offset(vts[x].blue_mask) == visuals[j].offsetBlue)
|
||||
goto breakout;
|
||||
}
|
||||
|
||||
if (depthIndex == UNDEFINED) {
|
||||
depthIndex = numDepths;
|
||||
depths[depthIndex].depth = xnestVisuals[i].depth;
|
||||
depths[depthIndex].numVids = 0;
|
||||
depths[depthIndex].vids =
|
||||
(VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
|
||||
numDepths++;
|
||||
visuals[numVisuals] = (VisualRec) {
|
||||
.class = vts[x]._class,
|
||||
.bitsPerRGBValue = vts[x].bits_per_rgb_value,
|
||||
.ColormapEntries = vts[x].colormap_entries,
|
||||
.nplanes = depth_iter.data->depth,
|
||||
.redMask = vts[x].red_mask,
|
||||
.greenMask = vts[x].green_mask,
|
||||
.blueMask = vts[x].blue_mask,
|
||||
.offsetRed = offset(vts[x].red_mask),
|
||||
.offsetGreen = offset(vts[x].green_mask),
|
||||
.offsetBlue = offset(vts[x].blue_mask),
|
||||
.vid = FakeClientID(0),
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
|
||||
FatalError("Visual table overflow");
|
||||
}
|
||||
depths[depthIndex].vids[depths[depthIndex].numVids] =
|
||||
visuals[numVisuals].vid;
|
||||
depths[depthIndex].numVids++;
|
||||
|
||||
numVisuals++;
|
||||
xnestNumVisualMap++;
|
||||
visuals = reallocarray(visuals, numVisuals+1, sizeof(VisualRec));
|
||||
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(XnestVisualRec));
|
||||
}
|
||||
}
|
||||
breakout:
|
||||
visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
|
||||
xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap, sizeof(XnestVisualRec));
|
||||
|
||||
defaultVisual = visuals[xnestDefaultVisualIndex].vid;
|
||||
rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
|
||||
if (!found_default_visual) {
|
||||
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) {
|
||||
XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
|
||||
xnestWidth = gattributes.width;
|
||||
xnestHeight = gattributes.height;
|
||||
xRectangle r = xnestGetGeometry(xnestUpstreamInfo.conn, xnestParentWindow);
|
||||
xnestGeometry.width = r.width;
|
||||
xnestGeometry.height = r.height;
|
||||
}
|
||||
|
||||
/* myNum */
|
||||
/* 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))
|
||||
return FALSE;
|
||||
|
||||
pScreen->defColormap = (Colormap) FakeClientID(0);
|
||||
pScreen->minInstalledCmaps = MINCMAPS;
|
||||
pScreen->maxInstalledCmaps = MAXCMAPS;
|
||||
pScreen->backingStoreSupport = NotUseful;
|
||||
pScreen->saveUnderSupport = NotUseful;
|
||||
pScreen->whitePixel = xnestWhitePixel;
|
||||
pScreen->blackPixel = xnestBlackPixel;
|
||||
pScreen->backingStoreSupport = XCB_BACKING_STORE_NOT_USEFUL;
|
||||
pScreen->saveUnderSupport = XCB_BACKING_STORE_NOT_USEFUL;
|
||||
pScreen->whitePixel = xnestUpstreamInfo.screenInfo->white_pixel;
|
||||
pScreen->blackPixel = xnestUpstreamInfo.screenInfo->black_pixel;
|
||||
/* GCperDepth */
|
||||
/* defaultStipple */
|
||||
/* WindowPrivateLen */
|
||||
|
@ -282,9 +342,10 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
|||
pScreen->RealizeWindow = xnestRealizeWindow;
|
||||
pScreen->UnrealizeWindow = xnestUnrealizeWindow;
|
||||
pScreen->PostValidateTree = NULL;
|
||||
pScreen->WindowExposures = xnestWindowExposures;
|
||||
pScreen->WindowExposures = miWindowExposures;
|
||||
pScreen->CopyWindow = xnestCopyWindow;
|
||||
pScreen->ClipNotify = xnestClipNotify;
|
||||
pScreen->ClearToBackground = xnestClearToBackground;
|
||||
|
||||
/* Pixmap procedures */
|
||||
|
||||
|
@ -325,13 +386,12 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
|||
&xnestCursorFuncs);
|
||||
PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
|
||||
|
||||
pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
|
||||
DefaultScreen(xnestDisplay))
|
||||
/ DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay));
|
||||
pScreen->mmWidth =
|
||||
xnestGeometry.width * xnestUpstreamInfo.screenInfo->width_in_millimeters /
|
||||
xnestUpstreamInfo.screenInfo->width_in_pixels;
|
||||
pScreen->mmHeight =
|
||||
xnestHeight * DisplayHeightMM(xnestDisplay,
|
||||
DefaultScreen(xnestDisplay)) /
|
||||
DisplayHeight(xnestDisplay, DefaultScreen(xnestDisplay));
|
||||
xnestGeometry.height * xnestUpstreamInfo.screenInfo->height_in_millimeters /
|
||||
xnestUpstreamInfo.screenInfo->height_in_pixels;
|
||||
|
||||
/* overwrite miCloseScreen with our own */
|
||||
pScreen->CloseScreen = xnestCloseScreen;
|
||||
|
@ -341,74 +401,123 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
|
|||
|
||||
/* devPrivates */
|
||||
|
||||
#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
|
||||
#define POSITION_OFFSET (pScreen->myNum * (xnestGeometry.width + xnestGeometry.height) / 32)
|
||||
|
||||
if (xnestDoFullGeneration) {
|
||||
|
||||
valuemask = CWBackPixel | CWEventMask | CWColormap;
|
||||
attributes.background_pixel = xnestWhitePixel;
|
||||
attributes.event_mask = xnestEventMask;
|
||||
attributes.colormap =
|
||||
xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
|
||||
XnSetWindowAttr attributes = {
|
||||
.background_pixel = xnestUpstreamInfo.screenInfo->white_pixel,
|
||||
.event_mask = xnestEventMask,
|
||||
.colormap = xnestVisualToHostCmap(pScreen->rootVisual),
|
||||
};
|
||||
|
||||
valuemask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
|
||||
|
||||
if (xnestParentWindow != 0) {
|
||||
xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
|
||||
XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
|
||||
xnestEventMask);
|
||||
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
XCB_CW_EVENT_MASK,
|
||||
&xnestEventMask);
|
||||
}
|
||||
else
|
||||
xnestDefaultWindows[pScreen->myNum] =
|
||||
XCreateWindow(xnestDisplay,
|
||||
DefaultRootWindow(xnestDisplay),
|
||||
xnestX + POSITION_OFFSET,
|
||||
xnestY + POSITION_OFFSET,
|
||||
xnestWidth, xnestHeight,
|
||||
xnestBorderWidth,
|
||||
else {
|
||||
uint32_t values[32] = { 0 };
|
||||
xnest_encode_window_attr(attributes, valuemask, values);
|
||||
|
||||
xnestDefaultWindows[pScreen->myNum] = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xcb_create_window(xnestUpstreamInfo.conn,
|
||||
pScreen->rootDepth,
|
||||
InputOutput,
|
||||
xnestDefaultVisual(pScreen),
|
||||
valuemask, &attributes);
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
xnestUpstreamInfo.screenInfo->root,
|
||||
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)
|
||||
xnestWindowName = argv[0];
|
||||
|
||||
sizeHints.flags = PPosition | PSize | PMaxSize;
|
||||
sizeHints.x = xnestX + POSITION_OFFSET;
|
||||
sizeHints.y = xnestY + POSITION_OFFSET;
|
||||
sizeHints.width = sizeHints.max_width = xnestWidth;
|
||||
sizeHints.height = sizeHints.max_height = xnestHeight;
|
||||
if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
|
||||
sizeHints.flags |= USPosition;
|
||||
if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
|
||||
sizeHints.flags |= USSize;
|
||||
XSetStandardProperties(xnestDisplay,
|
||||
xcb_size_hints_t sizeHints = {
|
||||
.flags = XCB_ICCCM_SIZE_HINT_P_POSITION | XCB_ICCCM_SIZE_HINT_P_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE,
|
||||
.x = xnestGeometry.x + POSITION_OFFSET,
|
||||
.y = xnestGeometry.y + POSITION_OFFSET,
|
||||
.width = xnestGeometry.width,
|
||||
.height = xnestGeometry.height,
|
||||
.max_width = xnestGeometry.width,
|
||||
.max_height = xnestGeometry.height,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
const size_t windowNameLen = strlen(xnestWindowName);
|
||||
|
||||
xcb_icccm_set_wm_name_checked(xnestUpstreamInfo.conn,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
xnestWindowName,
|
||||
xnestWindowName,
|
||||
xnestIconBitmap, argv, argc, &sizeHints);
|
||||
XCB_ATOM_STRING,
|
||||
8,
|
||||
windowNameLen,
|
||||
xnestWindowName);
|
||||
|
||||
XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
|
||||
xcb_icccm_set_wm_icon_name_checked(xnestUpstreamInfo.conn,
|
||||
xnestDefaultWindows[pScreen->myNum],
|
||||
XCB_ATOM_STRING,
|
||||
8,
|
||||
windowNameLen,
|
||||
xnestWindowName);
|
||||
|
||||
valuemask = CWBackPixmap | CWColormap;
|
||||
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.colormap =
|
||||
DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
|
||||
xnestScreenSaverWindows[pScreen->myNum] =
|
||||
XCreateWindow(xnestDisplay,
|
||||
attributes.colormap = xnestUpstreamInfo.screenInfo->default_colormap;
|
||||
|
||||
uint32_t values[32] = { 0 };
|
||||
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],
|
||||
0, 0, xnestWidth, xnestHeight, 0,
|
||||
DefaultDepth(xnestDisplay,
|
||||
DefaultScreen(xnestDisplay)),
|
||||
InputOutput, DefaultVisual(xnestDisplay,
|
||||
DefaultScreen
|
||||
(xnestDisplay)), valuemask,
|
||||
&attributes);
|
||||
0,
|
||||
0,
|
||||
xnestGeometry.width,
|
||||
xnestGeometry.height,
|
||||
0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||
xnestUpstreamInfo.screenInfo->root_visual,
|
||||
valuemask,
|
||||
values);
|
||||
}
|
||||
|
||||
if (!xnestCreateDefaultColormap(pScreen))
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@ -427,5 +536,5 @@ xnestCloseScreen(ScreenPtr pScreen)
|
|||
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>
|
||||
#endif
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/shape.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xdefs.h>
|
||||
#include <X11/Xproto.h>
|
||||
|
@ -30,14 +33,13 @@ is" without express or implied warranty.
|
|||
|
||||
#include "mi.h"
|
||||
|
||||
#include "Xnest.h"
|
||||
#include "xnest-xcb.h"
|
||||
|
||||
#include "Display.h"
|
||||
#include "Screen.h"
|
||||
#include "XNGC.h"
|
||||
#include "Drawable.h"
|
||||
#include "Color.h"
|
||||
#include "Visual.h"
|
||||
#include "Events.h"
|
||||
#include "Args.h"
|
||||
|
||||
|
@ -78,25 +80,25 @@ Bool
|
|||
xnestCreateWindow(WindowPtr pWin)
|
||||
{
|
||||
unsigned long mask;
|
||||
XSetWindowAttributes attributes;
|
||||
Visual *visual;
|
||||
XnSetWindowAttr attributes = { 0 };
|
||||
uint32_t visual = CopyFromParent; /* 0L */
|
||||
ColormapPtr pCmap;
|
||||
uint32_t params[32] = { 0 };
|
||||
|
||||
if (pWin->drawable.class == InputOnly) {
|
||||
mask = 0L;
|
||||
visual = CopyFromParent;
|
||||
}
|
||||
else {
|
||||
mask = CWEventMask | CWBackingStore;
|
||||
attributes.event_mask = ExposureMask;
|
||||
attributes.backing_store = NotUseful;
|
||||
mask = XCB_CW_EVENT_MASK | XCB_CW_BACKING_STORE;
|
||||
attributes.event_mask = XCB_EVENT_MASK_EXPOSURE;
|
||||
attributes.backing_store = XCB_BACKING_STORE_NOT_USEFUL;
|
||||
|
||||
if (pWin->parent) {
|
||||
if (pWin->optional &&
|
||||
pWin->optional->visual != wVisual(pWin->parent)) {
|
||||
visual =
|
||||
xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
|
||||
mask |= CWColormap;
|
||||
visual = xnest_visual_map_to_host(wVisual(pWin));
|
||||
mask |= XCB_CW_COLORMAP;
|
||||
if (pWin->optional->colormap) {
|
||||
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
||||
X11_RESTYPE_COLORMAP, serverClient,
|
||||
|
@ -104,39 +106,43 @@ xnestCreateWindow(WindowPtr pWin)
|
|||
attributes.colormap = xnestColormap(pCmap);
|
||||
}
|
||||
else
|
||||
attributes.colormap = xnestDefaultVisualColormap(visual);
|
||||
attributes.colormap = xnestHostVisualToHostCmap(visual);
|
||||
}
|
||||
else
|
||||
visual = CopyFromParent;
|
||||
}
|
||||
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),
|
||||
X11_RESTYPE_COLORMAP, serverClient, DixUseAccess);
|
||||
mask |= CWColormap;
|
||||
mask |= XCB_CW_COLORMAP;
|
||||
attributes.colormap = xnestColormap(pCmap);
|
||||
}
|
||||
}
|
||||
|
||||
xnestWindowPriv(pWin)->window = XCreateWindow(xnestDisplay,
|
||||
xnestWindowPriv(pWin)->window = xcb_generate_id(xnestUpstreamInfo.conn);
|
||||
xnest_encode_window_attr(attributes, mask, params);
|
||||
xcb_create_window(xnestUpstreamInfo.conn,
|
||||
pWin->drawable.depth,
|
||||
xnestWindowPriv(pWin)->window,
|
||||
xnestWindowParent(pWin),
|
||||
pWin->origin.x -
|
||||
wBorderWidth(pWin),
|
||||
pWin->origin.y -
|
||||
wBorderWidth(pWin),
|
||||
pWin->origin.x - wBorderWidth(pWin),
|
||||
pWin->origin.y - wBorderWidth(pWin),
|
||||
pWin->drawable.width,
|
||||
pWin->drawable.height,
|
||||
pWin->borderWidth,
|
||||
pWin->drawable.depth,
|
||||
pWin->drawable.class,
|
||||
visual, mask, &attributes);
|
||||
visual,
|
||||
mask,
|
||||
¶ms);
|
||||
|
||||
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
|
||||
xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
|
||||
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
||||
xnestWindowPriv(pWin)->width = pWin->drawable.width;
|
||||
xnestWindowPriv(pWin)->height = pWin->drawable.height;
|
||||
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
|
||||
xnestWindowPriv(pWin)->sibling_above = None;
|
||||
xnestWindowPriv(pWin)->sibling_above = XCB_WINDOW_NONE;
|
||||
if (pWin->nextSib)
|
||||
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
|
||||
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 */
|
||||
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@ -156,83 +162,90 @@ xnestDestroyWindow(WindowPtr pWin)
|
|||
xnestWindowPriv(pWin)->sibling_above;
|
||||
RegionDestroy(xnestWindowPriv(pWin)->bounding_shape);
|
||||
RegionDestroy(xnestWindowPriv(pWin)->clip_shape);
|
||||
XDestroyWindow(xnestDisplay, xnestWindow(pWin));
|
||||
xnestWindowPriv(pWin)->window = None;
|
||||
xcb_destroy_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
|
||||
xnestWindowPriv(pWin)->window = XCB_WINDOW_NONE;
|
||||
|
||||
if (pWin->optional && pWin->optional->colormap && pWin->parent)
|
||||
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xnestPositionWindow(WindowPtr pWin, int x, int y)
|
||||
{
|
||||
xnestConfigureWindow(pWin,
|
||||
CWParent |
|
||||
CWX | CWY | CWWidth | CWHeight | CWBorderWidth);
|
||||
XCB_CONFIG_WINDOW_SIBLING | \
|
||||
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
|
||||
xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
|
||||
{
|
||||
unsigned int valuemask;
|
||||
XWindowChanges values;
|
||||
XnWindowChanges values;
|
||||
|
||||
if (mask & CWParent &&
|
||||
if (mask & XCB_CONFIG_WINDOW_SIBLING &&
|
||||
xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) {
|
||||
XReparentWindow(xnestDisplay, xnestWindow(pWin),
|
||||
|
||||
xcb_reparent_window(
|
||||
xnestUpstreamInfo.conn,
|
||||
xnestWindow(pWin),
|
||||
xnestWindowParent(pWin),
|
||||
pWin->origin.x - wBorderWidth(pWin),
|
||||
pWin->origin.y - wBorderWidth(pWin));
|
||||
|
||||
xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
|
||||
xnestWindowPriv(pWin)->x = pWin->origin.x - 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)
|
||||
xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
|
||||
}
|
||||
|
||||
valuemask = 0;
|
||||
|
||||
if (mask & CWX &&
|
||||
if (mask & XCB_CONFIG_WINDOW_X &&
|
||||
xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) {
|
||||
valuemask |= CWX;
|
||||
valuemask |= XCB_CONFIG_WINDOW_X;
|
||||
values.x =
|
||||
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)) {
|
||||
valuemask |= CWY;
|
||||
valuemask |= XCB_CONFIG_WINDOW_Y;
|
||||
values.y =
|
||||
xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
|
||||
}
|
||||
|
||||
if (mask & CWWidth && xnestWindowPriv(pWin)->width != pWin->drawable.width) {
|
||||
valuemask |= CWWidth;
|
||||
if (mask & XCB_CONFIG_WINDOW_WIDTH && xnestWindowPriv(pWin)->width != pWin->drawable.width) {
|
||||
valuemask |= XCB_CONFIG_WINDOW_WIDTH;
|
||||
values.width = xnestWindowPriv(pWin)->width = pWin->drawable.width;
|
||||
}
|
||||
|
||||
if (mask & CWHeight &&
|
||||
if (mask & XCB_CONFIG_WINDOW_HEIGHT &&
|
||||
xnestWindowPriv(pWin)->height != pWin->drawable.height) {
|
||||
valuemask |= CWHeight;
|
||||
valuemask |= XCB_CONFIG_WINDOW_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) {
|
||||
valuemask |= CWBorderWidth;
|
||||
valuemask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
|
||||
values.border_width =
|
||||
xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
|
||||
}
|
||||
|
||||
if (valuemask)
|
||||
XConfigureWindow(xnestDisplay, xnestWindow(pWin), valuemask, &values);
|
||||
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pWin), valuemask, values);
|
||||
|
||||
if (mask & CWStackingOrder &&
|
||||
if (mask & XCB_CONFIG_WINDOW_SIBLING &&
|
||||
xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) {
|
||||
WindowPtr pSib;
|
||||
|
||||
|
@ -240,18 +253,18 @@ xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
|
|||
for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
|
||||
|
||||
/* the top sibling */
|
||||
valuemask = CWStackMode;
|
||||
valuemask = XCB_CONFIG_WINDOW_STACK_MODE;
|
||||
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 */
|
||||
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.stack_mode = Below;
|
||||
XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask,
|
||||
&values);
|
||||
xnest_configure_window(xnestUpstreamInfo.conn, xnestWindow(pSib), valuemask, values);
|
||||
xnestWindowPriv(pSib)->sibling_above =
|
||||
xnestWindowSiblingAbove(pSib);
|
||||
}
|
||||
|
@ -261,15 +274,15 @@ xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
|
|||
Bool
|
||||
xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||
{
|
||||
XSetWindowAttributes attributes;
|
||||
XnSetWindowAttr attributes;
|
||||
|
||||
if (mask & CWBackPixmap)
|
||||
if (mask & XCB_CW_BACK_PIXMAP)
|
||||
switch (pWin->backgroundState) {
|
||||
case None:
|
||||
attributes.background_pixmap = None;
|
||||
case XCB_BACK_PIXMAP_NONE:
|
||||
attributes.background_pixmap = XCB_PIXMAP_NONE;
|
||||
break;
|
||||
|
||||
case ParentRelative:
|
||||
case XCB_BACK_PIXMAP_PARENT_RELATIVE:
|
||||
attributes.background_pixmap = ParentRelative;
|
||||
break;
|
||||
|
||||
|
@ -278,59 +291,59 @@ xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
|||
break;
|
||||
|
||||
case BackgroundPixel:
|
||||
mask &= ~CWBackPixmap;
|
||||
mask &= ~XCB_CW_BACK_PIXMAP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mask & CWBackPixel) {
|
||||
if (mask & XCB_CW_BACK_PIXEL) {
|
||||
if (pWin->backgroundState == BackgroundPixel)
|
||||
attributes.background_pixel = xnestPixel(pWin->background.pixel);
|
||||
else
|
||||
mask &= ~CWBackPixel;
|
||||
mask &= ~XCB_CW_BACK_PIXEL;
|
||||
}
|
||||
|
||||
if (mask & CWBorderPixmap) {
|
||||
if (mask & XCB_CW_BORDER_PIXMAP) {
|
||||
if (pWin->borderIsPixel)
|
||||
mask &= ~CWBorderPixmap;
|
||||
mask &= ~XCB_CW_BORDER_PIXMAP;
|
||||
else
|
||||
attributes.border_pixmap = xnestPixmap(pWin->border.pixmap);
|
||||
}
|
||||
|
||||
if (mask & CWBorderPixel) {
|
||||
if (mask & XCB_CW_BORDER_PIXEL) {
|
||||
if (pWin->borderIsPixel)
|
||||
attributes.border_pixel = xnestPixel(pWin->border.pixel);
|
||||
else
|
||||
mask &= ~CWBorderPixel;
|
||||
mask &= ~XCB_CW_BORDER_PIXEL;
|
||||
}
|
||||
|
||||
if (mask & CWBitGravity)
|
||||
if (mask & XCB_CW_BIT_GRAVITY)
|
||||
attributes.bit_gravity = pWin->bitGravity;
|
||||
|
||||
if (mask & CWWinGravity) /* dix does this for us */
|
||||
mask &= ~CWWinGravity;
|
||||
if (mask & XCB_CW_WIN_GRAVITY) /* dix does this for us */
|
||||
mask &= ~XCB_CW_WIN_GRAVITY;
|
||||
|
||||
if (mask & CWBackingStore) /* this is really not useful */
|
||||
mask &= ~CWBackingStore;
|
||||
if (mask & XCB_CW_BACKING_STORE) /* this is really not useful */
|
||||
mask &= ~XCB_CW_BACKING_STORE;
|
||||
|
||||
if (mask & CWBackingPlanes) /* this is really not useful */
|
||||
mask &= ~CWBackingPlanes;
|
||||
if (mask & XCB_CW_BACKING_PLANES) /* this is really not useful */
|
||||
mask &= ~XCB_CW_BACKING_PLANES;
|
||||
|
||||
if (mask & CWBackingPixel) /* this is really not useful */
|
||||
mask &= ~CWBackingPixel;
|
||||
if (mask & XCB_CW_BACKING_PIXEL) /* this is really not useful */
|
||||
mask &= ~XCB_CW_BACKING_PIXEL;
|
||||
|
||||
if (mask & CWOverrideRedirect)
|
||||
if (mask & XCB_CW_OVERRIDE_REDIRECT)
|
||||
attributes.override_redirect = pWin->overrideRedirect;
|
||||
|
||||
if (mask & CWSaveUnder) /* this is really not useful */
|
||||
mask &= ~CWSaveUnder;
|
||||
if (mask & XCB_CW_SAVE_UNDER) /* this is really not useful */
|
||||
mask &= ~XCB_CW_SAVE_UNDER;
|
||||
|
||||
if (mask & CWEventMask) /* events are handled elsewhere */
|
||||
mask &= ~CWEventMask;
|
||||
if (mask & XCB_CW_EVENT_MASK) /* events are handled elsewhere */
|
||||
mask &= ~XCB_CW_EVENT_MASK;
|
||||
|
||||
if (mask & CWDontPropagate) /* events are handled elsewhere */
|
||||
mask &= ~CWDontPropagate;
|
||||
if (mask & XCB_CW_DONT_PROPAGATE) /* events are handled elsewhere */
|
||||
mask &= ~XCB_CW_DONT_PROPAGATE;
|
||||
|
||||
if (mask & CWColormap) {
|
||||
if (mask & XCB_CW_COLORMAP) {
|
||||
ColormapPtr pCmap;
|
||||
|
||||
dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
|
||||
|
@ -341,32 +354,35 @@ xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
|||
xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
|
||||
}
|
||||
|
||||
if (mask & CWCursor) /* this is handled in cursor code */
|
||||
mask &= ~CWCursor;
|
||||
if (mask & XCB_CW_CURSOR) /* this is handled in cursor code */
|
||||
mask &= ~XCB_CW_CURSOR;
|
||||
|
||||
if (mask)
|
||||
XChangeWindowAttributes(xnestDisplay, xnestWindow(pWin),
|
||||
mask, &attributes);
|
||||
|
||||
return True;
|
||||
if (mask) {
|
||||
uint32_t values[32];
|
||||
xnest_encode_window_attr(attributes, mask, values);
|
||||
xcb_change_window_attributes(xnestUpstreamInfo.conn,
|
||||
xnestWindow(pWin),
|
||||
mask,
|
||||
values);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xnestRealizeWindow(WindowPtr pWin)
|
||||
{
|
||||
xnestConfigureWindow(pWin, CWStackingOrder);
|
||||
xnestConfigureWindow(pWin, XCB_CONFIG_WINDOW_SIBLING);
|
||||
xnestShapeWindow(pWin);
|
||||
XMapWindow(xnestDisplay, xnestWindow(pWin));
|
||||
xcb_map_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
xnestUnrealizeWindow(WindowPtr pWin)
|
||||
{
|
||||
XUnmapWindow(xnestDisplay, xnestWindow(pWin));
|
||||
|
||||
return True;
|
||||
xcb_unmap_window(xnestUpstreamInfo.conn, xnestWindow(pWin));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -377,44 +393,10 @@ xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion)
|
|||
void
|
||||
xnestClipNotify(WindowPtr pWin, int dx, int dy)
|
||||
{
|
||||
xnestConfigureWindow(pWin, CWStackingOrder);
|
||||
xnestConfigureWindow(pWin, XCB_CONFIG_WINDOW_SIBLING);
|
||||
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
|
||||
xnestSetShape(WindowPtr pWin, int kind)
|
||||
{
|
||||
|
@ -429,10 +411,10 @@ xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
|
|||
unsigned int n1, n2;
|
||||
|
||||
if (pReg1 == pReg2)
|
||||
return True;
|
||||
return TRUE;
|
||||
|
||||
if (pReg1 == NullRegion || pReg2 == NullRegion)
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
pBox1 = RegionRects(pReg1);
|
||||
n1 = RegionNumRects(pReg1);
|
||||
|
@ -441,25 +423,20 @@ xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
|
|||
n2 = RegionNumRects(pReg2);
|
||||
|
||||
if (n1 != n2)
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
if (pBox1 == pBox2)
|
||||
return True;
|
||||
return TRUE;
|
||||
|
||||
if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec)))
|
||||
return False;
|
||||
return FALSE;
|
||||
|
||||
return True;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
xnestShapeWindow(WindowPtr pWin)
|
||||
{
|
||||
Region reg;
|
||||
BoxPtr pBox;
|
||||
XRectangle rect;
|
||||
int i;
|
||||
|
||||
if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape,
|
||||
wBoundingShape(pWin))) {
|
||||
|
||||
|
@ -467,26 +444,27 @@ xnestShapeWindow(WindowPtr pWin)
|
|||
RegionCopy(xnestWindowPriv(pWin)->bounding_shape,
|
||||
wBoundingShape(pWin));
|
||||
|
||||
reg = XCreateRegion();
|
||||
pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||
for (i = 0;
|
||||
i < RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||
i++) {
|
||||
rect.x = pBox[i].x1;
|
||||
rect.y = pBox[i].y1;
|
||||
rect.width = pBox[i].x2 - pBox[i].x1;
|
||||
rect.height = pBox[i].y2 - pBox[i].y1;
|
||||
XUnionRectWithRegion(&rect, reg, reg);
|
||||
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->bounding_shape);
|
||||
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
|
||||
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
rects[i].x = pBox[i].x1;
|
||||
rects[i].y = pBox[i].y1;
|
||||
rects[i].width = pBox[i].x2 - pBox[i].x1;
|
||||
rects[i].height = pBox[i].y2 - pBox[i].y1;
|
||||
}
|
||||
XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
|
||||
ShapeBounding, 0, 0, reg, ShapeSet);
|
||||
XDestroyRegion(reg);
|
||||
|
||||
xcb_shape_rectangles(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||
XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_YX_BANDED,
|
||||
xnestWindow(pWin), 0, 0, num_rects, rects);
|
||||
free(rects);
|
||||
}
|
||||
else {
|
||||
RegionEmpty(xnestWindowPriv(pWin)->bounding_shape);
|
||||
|
||||
XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
|
||||
ShapeBounding, 0, 0, None, ShapeSet);
|
||||
xcb_shape_mask(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||
XCB_SHAPE_SK_BOUNDING, xnestWindow(pWin),
|
||||
0, 0, XCB_PIXMAP_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -495,25 +473,34 @@ xnestShapeWindow(WindowPtr pWin)
|
|||
if (wClipShape(pWin)) {
|
||||
RegionCopy(xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin));
|
||||
|
||||
reg = XCreateRegion();
|
||||
pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
|
||||
for (i = 0;
|
||||
i < RegionNumRects(xnestWindowPriv(pWin)->clip_shape); i++) {
|
||||
rect.x = pBox[i].x1;
|
||||
rect.y = pBox[i].y1;
|
||||
rect.width = pBox[i].x2 - pBox[i].x1;
|
||||
rect.height = pBox[i].y2 - pBox[i].y1;
|
||||
XUnionRectWithRegion(&rect, reg, reg);
|
||||
int const num_rects = RegionNumRects(xnestWindowPriv(pWin)->clip_shape);
|
||||
BoxPtr const pBox = RegionRects(xnestWindowPriv(pWin)->clip_shape);
|
||||
xcb_rectangle_t *rects = calloc(num_rects, sizeof(xcb_rectangle_t));
|
||||
|
||||
for (int i = 0; i < num_rects; i++) {
|
||||
rects[i].x = pBox[i].x1;
|
||||
rects[i].y = pBox[i].y1;
|
||||
rects[i].width = pBox[i].x2 - pBox[i].x1;
|
||||
rects[i].height = pBox[i].y2 - pBox[i].y1;
|
||||
}
|
||||
XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
|
||||
ShapeClip, 0, 0, reg, ShapeSet);
|
||||
XDestroyRegion(reg);
|
||||
|
||||
xcb_shape_rectangles(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||
XCB_SHAPE_SK_CLIP, XCB_CLIP_ORDERING_YX_BANDED,
|
||||
xnestWindow(pWin), 0, 0, num_rects, rects);
|
||||
free(rects);
|
||||
}
|
||||
else {
|
||||
RegionEmpty(xnestWindowPriv(pWin)->clip_shape);
|
||||
xcb_shape_mask(xnestUpstreamInfo.conn, XCB_SHAPE_SO_SET,
|
||||
XCB_SHAPE_SK_CLIP, xnestWindow(pWin), 0, 0, XCB_PIXMAP_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
|
||||
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>
|
||||
|
||||
typedef struct {
|
||||
XFontStruct *font_struct;
|
||||
} xnestPrivFont;
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
extern int xnestFontPrivateIndex;
|
||||
|
||||
#define xnestFontPriv(pFont) \
|
||||
((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex))
|
||||
|
||||
#define xnestFontStruct(pFont) (xnestFontPriv(pFont)->font_struct)
|
||||
|
||||
#define xnestFont(pFont) (xnestFontStruct(pFont)->fid)
|
||||
|
||||
Bool xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
||||
Bool xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
|
||||
|
||||
|
|
|
@ -17,10 +17,11 @@ is" without express or implied warranty.
|
|||
|
||||
#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 {
|
||||
XlibGC gc;
|
||||
uint32_t gc;
|
||||
} xnestPrivGC;
|
||||
|
||||
extern DevPrivateKeyRec xnestGCPrivateKeyRec;
|
||||
|
|
|
@ -50,13 +50,10 @@ extern DevPrivateKeyRec xnestWindowPrivateKeyRec;
|
|||
xnestDefaultWindows[pWin->drawable.pScreen->myNum])
|
||||
|
||||
#define xnestWindowSiblingAbove(pWin) \
|
||||
((pWin)->prevSib ? xnestWindow((pWin)->prevSib) : None)
|
||||
((pWin)->prevSib ? xnestWindow((pWin)->prevSib) : XCB_WINDOW_NONE)
|
||||
|
||||
#define xnestWindowSiblingBelow(pWin) \
|
||||
((pWin)->nextSib ? xnestWindow((pWin)->nextSib) : None)
|
||||
|
||||
#define CWParent CWSibling
|
||||
#define CWStackingOrder CWStackMode
|
||||
((pWin)->nextSib ? xnestWindow((pWin)->nextSib) : XCB_WINDOW_NONE)
|
||||
|
||||
WindowPtr xnestWindowPtr(Window window);
|
||||
Bool xnestCreateWindow(WindowPtr pWin);
|
||||
|
@ -68,8 +65,8 @@ Bool xnestRealizeWindow(WindowPtr pWin);
|
|||
Bool xnestUnrealizeWindow(WindowPtr pWin);
|
||||
void xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion);
|
||||
void xnestClipNotify(WindowPtr pWin, int dx, int dy);
|
||||
void xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn);
|
||||
void xnestSetShape(WindowPtr pWin, int kind);
|
||||
void xnestShapeWindow(WindowPtr pWin);
|
||||
void xnestClearToBackground(WindowPtr pWin, int x, int y, int w, int h, Bool generateExposures);
|
||||
|
||||
#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',
|
||||
'Pointer.c',
|
||||
'Screen.c',
|
||||
'Visual.c',
|
||||
'Window.c',
|
||||
'../../mi/miinitext.c',
|
||||
'../../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(
|
||||
'Xnest',
|
||||
srcs,
|
||||
include_directories: inc,
|
||||
dependencies: [
|
||||
common_dep,
|
||||
xnest_dep,
|
||||
xcb_dep,
|
||||
xcb_shape_dep,
|
||||
xcb_icccm_dep,
|
||||
xcb_xkb_dep,
|
||||
],
|
||||
link_with: [
|
||||
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
|
||||
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
|
||||
if get_option('xwin') == 'auto'
|
||||
|
|
Loading…
Reference in New Issue