New upstream version 3.5.99.27
This commit is contained in:
21
nxcompshad/.gitignore
vendored
Normal file
21
nxcompshad/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
build-aux/compile
|
||||
build-aux/config.guess
|
||||
build-aux/config.sub
|
||||
build-aux/depcomp
|
||||
build-aux/install-sh
|
||||
build-aux/ltmain.sh
|
||||
build-aux/missing
|
||||
config.h
|
||||
config.h.in
|
||||
libtool
|
||||
m4/libtool.m4
|
||||
m4/ltoptions.m4
|
||||
m4/ltsugar.m4
|
||||
m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
nxcompshad.pc
|
||||
src/Makefile
|
||||
src/Makefile.in
|
||||
23
nxcompshad/Makefile.am
Normal file
23
nxcompshad/Makefile.am
Normal file
@@ -0,0 +1,23 @@
|
||||
SUBDIRS = src
|
||||
|
||||
pkgconfig_DATA = nxcompshad.pc
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/autom4te.cache/* \
|
||||
$(srcdir)/build-aux/* \
|
||||
$(srcdir)/Makefile.in \
|
||||
$(srcdir)/src/Makefile.in \
|
||||
$(srcdir)/aclocal.m4 \
|
||||
$(srcdir)/config.h.in \
|
||||
$(srcdir)/config.h.in~ \
|
||||
$(srcdir)/configure \
|
||||
$(srcdir)/m4/libtool.m4 \
|
||||
$(srcdir)/m4/lt~obsolete.m4 \
|
||||
$(srcdir)/m4/ltoptions.m4 \
|
||||
$(srcdir)/m4/ltsugar.m4 \
|
||||
$(srcdir)/m4/ltversion.m4 \
|
||||
$(NULL)
|
||||
|
||||
DISTCLEANFILES=$(MAINTAINERCLEANFILES)
|
||||
1
nxcompshad/VERSION
Symbolic link
1
nxcompshad/VERSION
Symbolic link
@@ -0,0 +1 @@
|
||||
../VERSION
|
||||
71
nxcompshad/configure.ac
Normal file
71
nxcompshad/configure.ac
Normal file
@@ -0,0 +1,71 @@
|
||||
dnl ***************************************************************************
|
||||
dnl *** configure.ac for nxcompshad ***
|
||||
dnl ***************************************************************************
|
||||
|
||||
m4_define([nxcompshad_version], m4_esyscmd([tr -d '\n' < VERSION]))
|
||||
|
||||
# Initialize Autoconf
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
AC_INIT([libXcompshad], [nxcompshad_version], [https://github.com/ArcticaProject/nx-libs/issues])
|
||||
AC_PROG_CXX
|
||||
AC_CONFIG_SRCDIR([Makefile.am])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-bzip2])
|
||||
|
||||
# Initialize libtool
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# enable this to add the variable to the Makefiles
|
||||
#AC_ARG_VAR(NX_VERSION_CUSTOM, [custom version string])
|
||||
|
||||
if test "x$NX_VERSION_CUSTOM" != x; then
|
||||
AC_DEFINE_UNQUOTED([NX_VERSION_CUSTOM], ["${NX_VERSION_CUSTOM}"], [user provided custom version string])
|
||||
fi
|
||||
|
||||
COMPSHAD_VERSION=nxcompshad_version
|
||||
AC_SUBST([COMPSHAD_VERSION])
|
||||
|
||||
LT_COMPSHAD_VERSION=["$(printf '%s\n' "${COMPSHAD_VERSION}" | awk -F '.' '/^[0-9]+\.[0-9]+\.[0-9]+.*$/ { print $1 ":" $2 ":" $3; }')"]
|
||||
AC_SUBST([LT_COMPSHAD_VERSION])
|
||||
|
||||
# Silence warning: ar: 'u' modifier ignored since 'D' is the default
|
||||
AC_SUBST(AR_FLAGS, [cr])
|
||||
|
||||
PKG_CHECK_MODULES(Xext, xext)
|
||||
PKG_CHECK_MODULES(Xdamage, xdamage)
|
||||
PKG_CHECK_MODULES(Xrandr, xrandr)
|
||||
PKG_CHECK_MODULES(Xtst, xtst)
|
||||
|
||||
# Upstream's pkg.m4 (since 0.27) offers this now, but define our own
|
||||
# compatible version in case the local version of pkgconfig isn't new enough.
|
||||
# https://bugs.freedesktop.org/show_bug.cgi?id=48743
|
||||
m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR],
|
||||
[AC_ARG_WITH([pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-pkgconfigdir],
|
||||
[install directory for nxcompshad.pc pkg-config file])],
|
||||
[],[with_pkgconfigdir='$(libdir)/pkgconfig'])
|
||||
AC_SUBST([pkgconfigdir], [${with_pkgconfigdir}])])
|
||||
|
||||
AC_LANG([C++])
|
||||
NX_COMPILER_BRAND
|
||||
NX_DEFAULT_OPTIONS
|
||||
|
||||
NX_TARGET_USE_ELF
|
||||
|
||||
AC_ARG_ENABLE([cxx11],
|
||||
[AS_HELP_STRING([--enable-cxx11],
|
||||
[enable optional features requiring C++11 support (disabled by default)])],
|
||||
[AS_IF([test x$enableval = xyes],
|
||||
[AX_CXX_COMPILE_STDCXX_11([], [mandatory])])])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
nxcompshad.pc
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
111
nxcompshad/include/Shadow.h
Normal file
111
nxcompshad/include/Shadow.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Shadow_H
|
||||
#define Shadow_H
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
|
||||
#define NXShadowCorrectColor(length, buffer) \
|
||||
\
|
||||
{ \
|
||||
unsigned short a; \
|
||||
unsigned short b; \
|
||||
unsigned short *shorts; \
|
||||
int i; \
|
||||
\
|
||||
length >>= 1; \
|
||||
shorts = (unsigned short *)buffer; \
|
||||
for (i = 0; i < length ; i++) \
|
||||
{ \
|
||||
a = shorts[i]; \
|
||||
\
|
||||
b = a & 63; \
|
||||
a <<= 1; \
|
||||
a = (a & ~127) | b; \
|
||||
\
|
||||
shorts[i] = a; \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef char* UpdaterHandle;
|
||||
|
||||
typedef struct _ShadowOptions
|
||||
{
|
||||
char optionShmExtension;
|
||||
char optionDamageExtension;
|
||||
int optionShadowDisplayUid;
|
||||
} ShadowOptions;
|
||||
|
||||
extern ShadowOptions NXShadowOptions;
|
||||
|
||||
extern void NXShadowResetOptions();
|
||||
|
||||
extern int NXShadowCreate(void *, char *, char *, void **);
|
||||
extern void NXShadowDestroy(void);
|
||||
|
||||
/*
|
||||
* Use an already opened Display connection.
|
||||
* We use <void *> instead of <Display *> to avoid
|
||||
* useless dependences from Xlib headers.
|
||||
*/
|
||||
|
||||
extern int NXShadowAddUpdaterDisplay(void *display, int *width, int *height,
|
||||
unsigned char *depth);
|
||||
extern UpdaterHandle NXShadowAddUpdater(char *displayName);
|
||||
extern int NXShadowRemoveUpdater(UpdaterHandle handle);
|
||||
extern int NXShadowRemoveAllUpdaters(void);
|
||||
|
||||
extern void NXShadowHandleInput(void);
|
||||
extern int NXShadowHasChanged(int (*)(void *), void *, int *);
|
||||
extern void NXShadowExportChanges(long *, char **);
|
||||
extern int NXShadowHasUpdaters(void);
|
||||
extern int NXShadowCaptureCursor(unsigned int wnd, void *vis);
|
||||
extern void NXShadowColorCorrect(int, int, unsigned int, unsigned int, char *);
|
||||
extern void NXShadowUpdateBuffer(void **);
|
||||
|
||||
extern void NXShadowEvent(Display *, XEvent);
|
||||
extern void NXShadowWebKeyEvent(KeySym keysym, Bool isKeyPress);
|
||||
|
||||
extern void NXShadowSetDisplayUid(int uid);
|
||||
|
||||
extern void NXShadowDisableShm(void);
|
||||
extern void NXShadowDisableDamage(void);
|
||||
|
||||
extern void NXShadowGetScreenSize(int *width, int *height);
|
||||
extern void NXShadowSetScreenSize(int *width, int *height);
|
||||
|
||||
extern void NXShadowInitKeymap(void *keysyms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Shadow_H */
|
||||
|
||||
1
nxcompshad/m4/ax_cxx_compile_stdcxx.m4
Symbolic link
1
nxcompshad/m4/ax_cxx_compile_stdcxx.m4
Symbolic link
@@ -0,0 +1 @@
|
||||
../../m4/ax_cxx_compile_stdcxx.m4
|
||||
1
nxcompshad/m4/ax_cxx_compile_stdcxx_11.m4
Symbolic link
1
nxcompshad/m4/ax_cxx_compile_stdcxx_11.m4
Symbolic link
@@ -0,0 +1 @@
|
||||
../../m4/ax_cxx_compile_stdcxx_11.m4
|
||||
1
nxcompshad/m4/nx-macros.m4
Symbolic link
1
nxcompshad/m4/nx-macros.m4
Symbolic link
@@ -0,0 +1 @@
|
||||
../../m4/nx-macros.m4
|
||||
13
nxcompshad/nxcompshad.pc.in
Normal file
13
nxcompshad/nxcompshad.pc.in
Normal file
@@ -0,0 +1,13 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: nxcompshad
|
||||
Description: Shadow Session Support for NX Compression Library
|
||||
Version: @COMPSHAD_VERSION@
|
||||
Requires: nxcomp
|
||||
Requires.private: x11
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lXcompshad
|
||||
|
||||
626
nxcompshad/src/Core.cpp
Normal file
626
nxcompshad/src/Core.cpp
Normal file
@@ -0,0 +1,626 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#include "Core.h"
|
||||
#include "Logger.h"
|
||||
|
||||
const int CorePoller::maxSliceHeight_ = 20;
|
||||
const int CorePoller::minSliceHeight_ = 3;
|
||||
|
||||
const char CorePoller::interlace_[] =
|
||||
{
|
||||
0, 16,
|
||||
8, 24,
|
||||
4, 20, 12, 28,
|
||||
2, 18, 10, 26, 6, 22, 14, 30,
|
||||
1, 17,
|
||||
9, 25,
|
||||
5, 21, 13, 29,
|
||||
3, 19, 11, 27, 7, 23, 15, 31
|
||||
};
|
||||
|
||||
CorePoller::CorePoller(Input *input, Display *display) : input_(input)
|
||||
{
|
||||
logTrace("CorePoller::CorePoller");
|
||||
|
||||
buffer_ = NULL;
|
||||
lastUpdatedRegion_ = NULL;
|
||||
lineStatus_ = NULL;
|
||||
linePriority_ = NULL;
|
||||
lefts_ = NULL;
|
||||
rights_ = NULL;
|
||||
}
|
||||
|
||||
CorePoller::~CorePoller()
|
||||
{
|
||||
logTrace("CorePoller::~CorePoller");
|
||||
|
||||
if (buffer_ != NULL)
|
||||
{
|
||||
delete [] buffer_;
|
||||
|
||||
buffer_ = NULL;
|
||||
}
|
||||
|
||||
if (lastUpdatedRegion_ != NULL)
|
||||
{
|
||||
XDestroyRegion(lastUpdatedRegion_);
|
||||
|
||||
lastUpdatedRegion_ = NULL;
|
||||
}
|
||||
|
||||
if (lineStatus_ != NULL)
|
||||
{
|
||||
delete [] lineStatus_;
|
||||
|
||||
lineStatus_ = NULL;
|
||||
}
|
||||
|
||||
if (linePriority_ != NULL)
|
||||
{
|
||||
delete [] linePriority_;
|
||||
|
||||
linePriority_ = NULL;
|
||||
}
|
||||
|
||||
if (lefts_ != NULL)
|
||||
{
|
||||
delete [] lefts_;
|
||||
|
||||
lefts_ = NULL;
|
||||
}
|
||||
|
||||
if (rights_ != NULL)
|
||||
{
|
||||
delete [] rights_;
|
||||
|
||||
rights_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int CorePoller::init()
|
||||
{
|
||||
logTrace("CorePoller::init");
|
||||
|
||||
createFrameBuffer();
|
||||
|
||||
if (buffer_ == NULL)
|
||||
{
|
||||
logError("CorePoller::init", ESET(ENOMEM));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
logTest("CorePoller::init", "Allocated frame buffer at [%p] for [%d] bytes.",
|
||||
buffer_, bpl_ * height_);
|
||||
|
||||
if (lastUpdatedRegion_ != NULL)
|
||||
{
|
||||
XDestroyRegion(lastUpdatedRegion_);
|
||||
|
||||
lastUpdatedRegion_ = NULL;
|
||||
}
|
||||
|
||||
lastUpdatedRegion_ = XCreateRegion();
|
||||
|
||||
if (lineStatus_ != NULL)
|
||||
{
|
||||
delete[] lineStatus_;
|
||||
}
|
||||
|
||||
lineStatus_ = new LineStatus[height_ + 1];
|
||||
|
||||
if (lineStatus_ == NULL)
|
||||
{
|
||||
logError("CorePoller::init", ESET(ENOMEM));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// We need this boundary element to
|
||||
// speed up the algo.
|
||||
//
|
||||
|
||||
if (linePriority_ != NULL)
|
||||
{
|
||||
delete[] linePriority_;
|
||||
}
|
||||
|
||||
linePriority_ = new int [height_ + 1];
|
||||
|
||||
if (linePriority_ == NULL)
|
||||
{
|
||||
logError("CorePoller::init", ESET(ENOMEM));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < height_; i++)
|
||||
{
|
||||
linePriority_[i] = HIGHEST_PRIORITY;
|
||||
}
|
||||
|
||||
if (lefts_ != NULL)
|
||||
{
|
||||
delete[] lefts_;
|
||||
}
|
||||
|
||||
lefts_ = new int [height_];
|
||||
|
||||
if (rights_ != NULL)
|
||||
{
|
||||
delete[] rights_;
|
||||
}
|
||||
|
||||
rights_ = new int [height_];
|
||||
|
||||
for (unsigned int i = 0; i < height_; i++)
|
||||
{
|
||||
rights_[i] = lefts_[i] = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CorePoller::isChanged(int (*checkIfInputCallback)(void *), void *arg, int *suspended)
|
||||
{
|
||||
logTrace("CorePoller::isChanged");
|
||||
|
||||
if (mirror_ == 1)
|
||||
{
|
||||
int result = mirrorChanges_;
|
||||
|
||||
mirrorChanges_ = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
logDebug("CorePoller:isChanged", "Going to use default polling algorithm.\n");
|
||||
|
||||
//
|
||||
// In order to allow this function to
|
||||
// be suspended and resumed later, we
|
||||
// need to save these two status vars.
|
||||
//
|
||||
|
||||
static int idxIlace = 0;
|
||||
static int curLine = 0;
|
||||
|
||||
|
||||
const long timeout = 50;
|
||||
long oldTime;
|
||||
long newTime;
|
||||
struct timeval ts;
|
||||
|
||||
gettimeofday(&ts, NULL);
|
||||
|
||||
oldTime = ts.tv_sec * 1000 + ts.tv_usec / 1000;
|
||||
|
||||
if (curLine == 0) // && idxIlace == 0 ?
|
||||
{
|
||||
for (unsigned int i = 0; i < height_; i++)
|
||||
{
|
||||
lineStatus_[i] = LINE_NOT_CHECKED;
|
||||
}
|
||||
}
|
||||
|
||||
int foundChanges = 0;
|
||||
|
||||
foundChanges = 0;
|
||||
|
||||
int curIlace = interlace_[idxIlace];
|
||||
|
||||
bool moveBackward = false;
|
||||
|
||||
logDebug("CorePoller::isChanged", "Interlace index [%d] interlace [%d].", idxIlace, curIlace);
|
||||
|
||||
for (; curLine < (int) height_; curLine++)
|
||||
{
|
||||
logDebug("CorePoller::isChanged", "Analyzing line [%d] move backward [%d] status [%d] priority [%d].",
|
||||
curLine, moveBackward, lineStatus_[curIlace], linePriority_[curLine]);
|
||||
|
||||
//
|
||||
// Ask the caller if the polling have to be suspended.
|
||||
//
|
||||
|
||||
if ((*checkIfInputCallback)(arg) == 1)
|
||||
{
|
||||
*suspended = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Suspend if too much time is elapsed.
|
||||
//
|
||||
|
||||
gettimeofday(&ts, NULL);
|
||||
|
||||
newTime = ts.tv_sec * 1000 + ts.tv_usec / 1000;
|
||||
|
||||
if (newTime - oldTime >= timeout)
|
||||
{
|
||||
*suspended = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
oldTime = newTime;
|
||||
|
||||
if (lineStatus_[curLine] != LINE_NOT_CHECKED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (moveBackward)
|
||||
{
|
||||
moveBackward = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (linePriority_[curLine])
|
||||
{
|
||||
case 1:
|
||||
case 29:
|
||||
{
|
||||
//
|
||||
// It was a priority,
|
||||
// but now it may not be.
|
||||
//
|
||||
}
|
||||
case 31:
|
||||
{
|
||||
//
|
||||
// Not a priority, still isn't.
|
||||
//
|
||||
|
||||
linePriority_[curLine] = NOT_PRIORITY;
|
||||
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
//
|
||||
// Make it a priority.
|
||||
//
|
||||
|
||||
linePriority_[curLine] = PRIORITY;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
linePriority_[curLine]--;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((linePriority_[curLine] > PRIORITY) && ((curLine & 31) != curIlace))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
XRectangle rect = {0,
|
||||
static_cast<short>(curLine),
|
||||
static_cast<unsigned short>(width_),
|
||||
1};
|
||||
|
||||
char *buffer;
|
||||
|
||||
logDebug("CorePoller::isChanged", "Checking line [%d].", curLine);
|
||||
|
||||
if ((buffer = getRect(rect)) == NULL)
|
||||
{
|
||||
logDebug("CorePoller::isChanged", "Failed to retrieve line [%d].", curLine);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(buffer, buffer_ + curLine * bpl_, bpl_) == 0 || differ(buffer, rect) == 0)
|
||||
{
|
||||
logDebug("CorePoller::isChanged", "Data buffer didn't change.");
|
||||
|
||||
lineStatus_[curLine] = LINE_NOT_CHANGED;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
rect.x = lefts_[rect.y];
|
||||
rect.width = rights_[rect.y] - lefts_[rect.y] + 1;
|
||||
|
||||
update(buffer + rect.x * bpp_, rect);
|
||||
|
||||
foundChanges = 1;
|
||||
|
||||
lineStatus_[curLine] = LINE_HAS_CHANGED;
|
||||
|
||||
//
|
||||
// Wake up the next line.
|
||||
//
|
||||
|
||||
if (linePriority_[curLine + 1] > PRIORITY)
|
||||
{
|
||||
linePriority_[curLine + 1] = HIGHEST_PRIORITY;
|
||||
}
|
||||
|
||||
//
|
||||
// Give this line priority.
|
||||
//
|
||||
|
||||
linePriority_[curLine] = HIGHEST_PRIORITY;
|
||||
|
||||
//
|
||||
// Wake up previous line.
|
||||
//
|
||||
|
||||
if (curLine > 0 && lineStatus_[curLine - 1] == LINE_NOT_CHECKED)
|
||||
{
|
||||
moveBackward = true;
|
||||
curLine -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Execution reached the end of loop.
|
||||
//
|
||||
|
||||
if (curLine == (int) height_)
|
||||
{
|
||||
idxIlace = (idxIlace + 1) % 32;
|
||||
|
||||
curLine = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the region of changed pixels.
|
||||
//
|
||||
|
||||
if (foundChanges)
|
||||
{
|
||||
int start, last, curWorkLine, left, right;
|
||||
|
||||
for (curWorkLine = 0; curWorkLine < (int) height_; curWorkLine++)
|
||||
{
|
||||
if (lineStatus_[curWorkLine] == LINE_HAS_CHANGED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
start = curWorkLine;
|
||||
last = curWorkLine;
|
||||
|
||||
left = lefts_[curWorkLine];
|
||||
right = rights_[curWorkLine];
|
||||
curWorkLine++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
for (; curWorkLine < (int) height_; curWorkLine++)
|
||||
{
|
||||
if (lineStatus_[curWorkLine] == LINE_HAS_CHANGED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (curWorkLine == (int) height_)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ((curWorkLine - last > minSliceHeight_) ||
|
||||
(last - start > maxSliceHeight_))
|
||||
{
|
||||
XRectangle rect = {static_cast<short>(left),
|
||||
static_cast<short>(start),
|
||||
static_cast<unsigned short>(right - left + 1),
|
||||
static_cast<unsigned short>(last - start + 1)};
|
||||
|
||||
XUnionRectWithRegion(&rect, lastUpdatedRegion_, lastUpdatedRegion_);
|
||||
|
||||
start = curWorkLine;
|
||||
left = lefts_[curWorkLine];
|
||||
right = rights_[curWorkLine];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lefts_[curWorkLine] < left)
|
||||
{
|
||||
left = lefts_[curWorkLine];
|
||||
}
|
||||
|
||||
if (rights_[curWorkLine] > right)
|
||||
{
|
||||
right = rights_[curWorkLine];
|
||||
}
|
||||
}
|
||||
|
||||
last = curWorkLine;
|
||||
|
||||
curWorkLine++;
|
||||
}
|
||||
|
||||
//
|
||||
// Send last block.
|
||||
//
|
||||
|
||||
if (last >= start)
|
||||
{
|
||||
XRectangle rect = {static_cast<short>(left),
|
||||
static_cast<short>(start),
|
||||
static_cast<unsigned short>(right - left + 1),
|
||||
static_cast<unsigned short>(last - start + 1)};
|
||||
|
||||
XUnionRectWithRegion(&rect, lastUpdatedRegion_, lastUpdatedRegion_);
|
||||
}
|
||||
}
|
||||
|
||||
return foundChanges;
|
||||
}
|
||||
|
||||
int CorePoller::differ(char *buffer, XRectangle r)
|
||||
{
|
||||
logTrace("CorePoller::differ");
|
||||
|
||||
int bpl = bpp_ * r.width;
|
||||
int i;
|
||||
char *pBuf;
|
||||
char *pFb;
|
||||
|
||||
pBuf = (buffer);
|
||||
pFb = (buffer_ + r.x + r.y * bpl_);
|
||||
|
||||
for (i = 0; i < bpl; i++)
|
||||
{
|
||||
if (*pFb++ != *pBuf++)
|
||||
{
|
||||
lefts_[r.y] = i / bpp_;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == bpl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pBuf = (buffer) + bpl - 1;
|
||||
pFb = (buffer_ + r.x + r.y * bpl_) + bpl - 1;
|
||||
|
||||
int j = i - 1;
|
||||
|
||||
for (i = bpl - 1; i > j; i--)
|
||||
{
|
||||
if (*pFb-- != *pBuf--)
|
||||
{
|
||||
rights_[r.y] = i / bpp_;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CorePoller::update(char *src, XRectangle r)
|
||||
{
|
||||
logTrace("CorePoller::update");
|
||||
|
||||
char *dst = buffer_ + r.x * bpp_ + r.y * bpl_;
|
||||
int bpl = bpp_ * r.width;
|
||||
|
||||
for (unsigned int i = 0; i < r.height; i++)
|
||||
{
|
||||
if(((r.x * bpp_ + r.y * bpl_) + bpl) > (bpl_ * height_))
|
||||
{
|
||||
//
|
||||
// Out of bounds. Maybe a resize is going on.
|
||||
//
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(dst, src, bpl);
|
||||
|
||||
src += bpl;
|
||||
|
||||
dst += bpl_;
|
||||
}
|
||||
}
|
||||
|
||||
void CorePoller::handleEvent(Display *display, XEvent *event)
|
||||
{
|
||||
logTrace("CorePoller::handleEvent");
|
||||
|
||||
switch (event -> type)
|
||||
{
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
{
|
||||
handleKeyboardEvent(display, event);
|
||||
break;
|
||||
}
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
case MotionNotify:
|
||||
{
|
||||
handleMouseEvent(display, event);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
logTest("CorePoller::handleEvent", "Handling unexpected event [%d] from display [%p].",
|
||||
event -> type, display);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CorePoller::handleWebKeyEvent(KeySym keysym, Bool isKeyPress)
|
||||
{
|
||||
logTrace("CorePoller::handleWebKeyEvent");
|
||||
|
||||
handleWebKeyboardEvent(keysym, isKeyPress);
|
||||
}
|
||||
|
||||
void CorePoller::handleInput()
|
||||
{
|
||||
while (input_ -> checkIfEvent())
|
||||
{
|
||||
Display *display = input_ -> currentDisplay();
|
||||
XEvent *event = input_ -> popEvent();
|
||||
|
||||
handleEvent(display, event);
|
||||
|
||||
delete event;
|
||||
}
|
||||
}
|
||||
|
||||
void CorePoller::createFrameBuffer()
|
||||
{
|
||||
logTrace("CorePoller::createFrameBuffer");
|
||||
|
||||
if (buffer_ == NULL)
|
||||
{
|
||||
buffer_ = new char[bpl_ * height_];
|
||||
}
|
||||
}
|
||||
208
nxcompshad/src/Core.h
Normal file
208
nxcompshad/src/Core.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CorePoller_H
|
||||
#define CorePoller_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Logger.h"
|
||||
#include "Regions.h"
|
||||
#include "Input.h"
|
||||
|
||||
typedef enum{
|
||||
LINE_HAS_CHANGED,
|
||||
LINE_NOT_CHECKED,
|
||||
LINE_NOT_CHANGED
|
||||
} LineStatus;
|
||||
|
||||
typedef enum{
|
||||
HIGHEST_PRIORITY = 0,
|
||||
PRIORITY = 30,
|
||||
NOT_PRIORITY = 90
|
||||
} LinePriority;
|
||||
|
||||
class CorePoller
|
||||
{
|
||||
public:
|
||||
|
||||
CorePoller(Input*, Display*);
|
||||
|
||||
virtual ~CorePoller();
|
||||
|
||||
virtual int init();
|
||||
|
||||
unsigned int width() const;
|
||||
|
||||
unsigned int height() const;
|
||||
|
||||
unsigned char depth() const;
|
||||
|
||||
int isChanged(int (*)(void*), void *, int *);
|
||||
|
||||
char *getFrameBuffer() const;
|
||||
|
||||
void destroyFrameBuffer();
|
||||
|
||||
void createFrameBuffer();
|
||||
|
||||
Region lastUpdatedRegion();
|
||||
|
||||
Region getLastUpdatedRegion();
|
||||
|
||||
void handleInput();
|
||||
|
||||
void handleEvent(Display *, XEvent *);
|
||||
|
||||
void handleWebKeyEvent(KeySym keysym, Bool isKeyPress);
|
||||
|
||||
Display *getShadowDisplay();
|
||||
|
||||
void setShadowDisplay(Display *shadowDisplay);
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int bpp_;
|
||||
|
||||
unsigned int bpl_;
|
||||
|
||||
unsigned int width_;
|
||||
|
||||
unsigned int height_;
|
||||
|
||||
int depth_;
|
||||
|
||||
char *buffer_;
|
||||
|
||||
unsigned long redMask_;
|
||||
unsigned long greenMask_;
|
||||
unsigned long blueMask_;
|
||||
unsigned long colorMask_[3];
|
||||
|
||||
char mirror_;
|
||||
|
||||
char mirrorChanges_;
|
||||
|
||||
virtual int updateShadowFrameBuffer(void) = 0;
|
||||
|
||||
virtual char *getRect(XRectangle r) = 0;
|
||||
|
||||
int imageByteOrder_;
|
||||
|
||||
Display *shadowDisplay_;
|
||||
|
||||
void update(char *src, XRectangle r);
|
||||
|
||||
Region lastUpdatedRegion_;
|
||||
|
||||
private:
|
||||
|
||||
virtual void handleKeyboardEvent(Display *, XEvent *) = 0;
|
||||
|
||||
virtual void handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress) = 0;
|
||||
|
||||
virtual void handleMouseEvent(Display *, XEvent *) = 0;
|
||||
|
||||
Input *input_;
|
||||
|
||||
static const int maxSliceHeight_;
|
||||
static const int minSliceHeight_;
|
||||
|
||||
LineStatus *lineStatus_;
|
||||
int *linePriority_;
|
||||
|
||||
static const char interlace_[];
|
||||
|
||||
int *lefts_;
|
||||
int *rights_;
|
||||
|
||||
// FIXME: Make them friend.
|
||||
|
||||
int differ(char *src, XRectangle r);
|
||||
};
|
||||
|
||||
inline unsigned int CorePoller::width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
inline unsigned int CorePoller::height() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
inline unsigned char CorePoller::depth() const
|
||||
{
|
||||
return depth_;
|
||||
}
|
||||
|
||||
inline char *CorePoller::getFrameBuffer() const
|
||||
{
|
||||
return buffer_;
|
||||
}
|
||||
|
||||
inline void CorePoller::destroyFrameBuffer()
|
||||
{
|
||||
if (buffer_ != NULL)
|
||||
{
|
||||
delete[] buffer_;
|
||||
buffer_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline Region CorePoller::lastUpdatedRegion()
|
||||
{
|
||||
Region region = lastUpdatedRegion_;
|
||||
|
||||
lastUpdatedRegion_ = XCreateRegion();
|
||||
|
||||
if (lastUpdatedRegion_ == NULL)
|
||||
{
|
||||
logError("CorePoller::lastUpdatedRegion", ESET(ENOMEM));
|
||||
|
||||
lastUpdatedRegion_ = region;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
inline Region CorePoller::getLastUpdatedRegion()
|
||||
{
|
||||
return lastUpdatedRegion_;
|
||||
}
|
||||
|
||||
inline Display *CorePoller::getShadowDisplay()
|
||||
{
|
||||
return shadowDisplay_ ;
|
||||
}
|
||||
|
||||
inline void CorePoller::setShadowDisplay(Display *shadowDisplay)
|
||||
{
|
||||
shadowDisplay_ = shadowDisplay;
|
||||
}
|
||||
|
||||
#endif /* CorePoller_H */
|
||||
179
nxcompshad/src/Input.cpp
Normal file
179
nxcompshad/src/Input.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#include "Input.h"
|
||||
#include "Logger.h"
|
||||
|
||||
Input::Input()
|
||||
{
|
||||
logTrace("Input::Input");
|
||||
|
||||
eventsHead_ = NULL;
|
||||
eventsTail_ = NULL;
|
||||
keymap_ = NULL;
|
||||
}
|
||||
|
||||
Input::~Input()
|
||||
{
|
||||
logTrace("Input::~Input");
|
||||
|
||||
Event *head = eventsHead_;
|
||||
|
||||
while (head)
|
||||
{
|
||||
Event *next = head -> next;
|
||||
|
||||
delete head -> event;
|
||||
delete head;
|
||||
|
||||
head = next;
|
||||
}
|
||||
|
||||
if (keymap_ != NULL)
|
||||
{
|
||||
logDebug("Input::~Input", "Delete keymap_ [%p].", keymap_);
|
||||
|
||||
delete [] keymap_;
|
||||
}
|
||||
}
|
||||
|
||||
void Input::pushEvent(Display *display, XEvent *event)
|
||||
{
|
||||
Event *tail = new Event;
|
||||
|
||||
if (tail == NULL)
|
||||
{
|
||||
logError("Input::pushEvent", ESET(ENOMEM));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
tail -> next = NULL;
|
||||
tail -> display = display;
|
||||
tail -> event = event;
|
||||
|
||||
if (eventsHead_ == NULL)
|
||||
{
|
||||
eventsHead_ = tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
eventsTail_ -> next = tail;
|
||||
}
|
||||
|
||||
eventsTail_ = tail;
|
||||
}
|
||||
|
||||
XEvent *Input::popEvent()
|
||||
{
|
||||
Event *head = eventsHead_;
|
||||
|
||||
if (head == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEvent *event = head -> event;
|
||||
|
||||
eventsHead_ = head -> next;
|
||||
|
||||
delete head;
|
||||
|
||||
if (eventsHead_ == NULL)
|
||||
{
|
||||
eventsTail_ = NULL;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
int Input::removeAllEvents(Display *display)
|
||||
{
|
||||
logTrace("Input::removeAllEvents");
|
||||
|
||||
int nRemoved = 0;
|
||||
|
||||
Event *current = eventsHead_;
|
||||
|
||||
while (current)
|
||||
{
|
||||
if (display == current -> display)
|
||||
{
|
||||
//
|
||||
// Update head of list.
|
||||
//
|
||||
|
||||
if (current == eventsHead_)
|
||||
{
|
||||
eventsHead_ = current -> next;
|
||||
}
|
||||
|
||||
//
|
||||
// Update tail of list.
|
||||
//
|
||||
|
||||
if (current == eventsTail_)
|
||||
{
|
||||
eventsTail_ = eventsHead_;
|
||||
|
||||
while (eventsTail_ && eventsTail_ -> next)
|
||||
{
|
||||
eventsTail_ = eventsTail_ -> next;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Remove event.
|
||||
//
|
||||
|
||||
Event *next = current -> next;
|
||||
|
||||
delete current -> event;
|
||||
delete current;
|
||||
|
||||
current = next;
|
||||
|
||||
nRemoved++;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = current -> next;
|
||||
}
|
||||
}
|
||||
|
||||
return nRemoved;
|
||||
}
|
||||
|
||||
99
nxcompshad/src/Input.h
Normal file
99
nxcompshad/src/Input.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Input_H
|
||||
#define Input_H
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
|
||||
typedef struct Event
|
||||
{
|
||||
struct Event *next;
|
||||
Display *display;
|
||||
XEvent *event;
|
||||
} Event;
|
||||
|
||||
class Input
|
||||
{
|
||||
public:
|
||||
|
||||
Input();
|
||||
|
||||
~Input();
|
||||
|
||||
int checkIfEvent();
|
||||
|
||||
void pushEvent(Display *, XEvent *);
|
||||
|
||||
XEvent *popEvent();
|
||||
Display *currentDisplay();
|
||||
|
||||
int removeAllEvents(Display *);
|
||||
|
||||
void setKeymap(char *keymap);
|
||||
char *getKeymap();
|
||||
|
||||
void setShadowDisplayName(char *shadowDisplayName);
|
||||
char *getShadowDisplayName();
|
||||
|
||||
private:
|
||||
|
||||
Event *eventsHead_;
|
||||
Event *eventsTail_;
|
||||
char *keymap_;
|
||||
char *shadowDisplayName_;
|
||||
};
|
||||
|
||||
inline Display *Input::currentDisplay()
|
||||
{
|
||||
return eventsHead_ ? eventsHead_ -> display : NULL;
|
||||
}
|
||||
|
||||
inline int Input::checkIfEvent()
|
||||
{
|
||||
return (eventsHead_ != NULL);
|
||||
}
|
||||
|
||||
inline void Input::setKeymap(char *keymap)
|
||||
{
|
||||
keymap_ = keymap;
|
||||
}
|
||||
|
||||
inline char *Input::getKeymap()
|
||||
{
|
||||
return keymap_;
|
||||
}
|
||||
|
||||
inline void Input::setShadowDisplayName(char *shadowDisplayName)
|
||||
{
|
||||
shadowDisplayName_ = shadowDisplayName;
|
||||
}
|
||||
|
||||
inline char *Input::getShadowDisplayName()
|
||||
{
|
||||
return shadowDisplayName_;
|
||||
}
|
||||
|
||||
#endif /* Input_H */
|
||||
128
nxcompshad/src/Logger.cpp
Normal file
128
nxcompshad/src/Logger.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#define DEBUG
|
||||
|
||||
#include "Misc.h"
|
||||
#include "Logger.h"
|
||||
|
||||
Logger logger;
|
||||
|
||||
void Logger::user(const char *format, va_list arguments)
|
||||
{
|
||||
char string[1024];
|
||||
|
||||
vsnprintf(string, 1024, format, arguments);
|
||||
|
||||
fprintf(stderr, "%s\n", string);
|
||||
}
|
||||
|
||||
void Logger::error(const char *name, int error)
|
||||
{
|
||||
fprintf(stderr, "PANIC! %s: Failed with code %d: %s\n",
|
||||
name, error, strerror(error));
|
||||
}
|
||||
|
||||
void Logger::warning(const char *name, const char *format, va_list arguments)
|
||||
{
|
||||
char string[1024];
|
||||
|
||||
vsnprintf(string, 1024, format, arguments);
|
||||
|
||||
fprintf(stderr, "%s: WARNING! %s\n", name, string);
|
||||
}
|
||||
|
||||
void Logger::test(const char *name, const char *format, va_list arguments)
|
||||
{
|
||||
char string[1024];
|
||||
|
||||
vsnprintf(string, 1024, format, arguments);
|
||||
|
||||
fprintf(stderr, "%s: %s\n", name, string);
|
||||
}
|
||||
|
||||
void Logger::trace(const char *name)
|
||||
{
|
||||
fprintf(stderr, "%s\n", name);
|
||||
}
|
||||
|
||||
void Logger::debug(const char *name, const char *format, va_list arguments)
|
||||
{
|
||||
char string[1024];
|
||||
|
||||
vsnprintf(string, 1024, format, arguments);
|
||||
|
||||
fprintf(stderr, "%s: %s\n", name, string);
|
||||
}
|
||||
|
||||
void Logger::dump(const char *name, const char *data, int size)
|
||||
{
|
||||
fprintf(stderr, "%s: Dumping %d bytes of data at %p\n",
|
||||
name, size, data);
|
||||
|
||||
for (int i = 0; i < size;)
|
||||
{
|
||||
fprintf(stderr, "[%d]\t", i);
|
||||
|
||||
int t = i;
|
||||
|
||||
for (unsigned int ii = 0; i < size && ii < 8; i++, ii++)
|
||||
{
|
||||
fprintf(stderr, "%02x/%d\t", data[i] & 0xff, data[i]);
|
||||
}
|
||||
|
||||
for (unsigned int ii = i % 8; ii > 0 && ii < 8; ii++)
|
||||
{
|
||||
fprintf(stderr, "\t");
|
||||
}
|
||||
|
||||
i = t;
|
||||
|
||||
for (unsigned int ii = 0; i < size && ii < 8; i++, ii++)
|
||||
{
|
||||
if (isprint(data[i]))
|
||||
{
|
||||
fprintf(stderr, "%c", data[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, ".");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
167
nxcompshad/src/Logger.h
Normal file
167
nxcompshad/src/Logger.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Logger_H
|
||||
#define Logger_H
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdarg>
|
||||
|
||||
//
|
||||
// Error handling macros.
|
||||
//
|
||||
|
||||
#define ESET(e) (errno = (e))
|
||||
#define EGET() (errno)
|
||||
#define ESTR() strerror(errno)
|
||||
|
||||
extern class Logger logger;
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
|
||||
void user(const char *format, va_list arguments) __attribute__((format(printf, 2, 0)));
|
||||
|
||||
void error(const char *name, int error);
|
||||
|
||||
void warning(const char *name, const char *format, va_list arguments) __attribute__((format(printf, 3, 0)));
|
||||
|
||||
void test(const char *name, const char *format, va_list arguments) __attribute__((format(printf, 3, 0)));
|
||||
|
||||
void trace(const char *name);
|
||||
|
||||
void debug(const char *name, const char *format, va_list arguments) __attribute__((format(printf, 3, 0)));
|
||||
|
||||
void dump(const char *name, const char *data, int size);
|
||||
};
|
||||
|
||||
static inline void logUser(const char *format, ...) \
|
||||
__attribute__((format(printf, 1, 2))) __attribute__((__unused__));
|
||||
|
||||
static inline void logError(const char *name, int error) \
|
||||
__attribute__((__unused__));
|
||||
|
||||
static inline void logWarning(const char *name, const char *format, ...) \
|
||||
__attribute__((format(printf, 2, 3))) __attribute__((__unused__));
|
||||
|
||||
static inline void logTest(const char *name, const char *format, ...) \
|
||||
__attribute__((format(printf, 2, 3))) __attribute__((__unused__));
|
||||
|
||||
static inline void logTrace(const char *name) \
|
||||
__attribute__((__unused__));
|
||||
|
||||
static inline void logDebug(const char *name, const char *format, ...) \
|
||||
__attribute__((format(printf, 2, 3))) __attribute__((__unused__));
|
||||
|
||||
static inline void logDump(const char *name, const char *data, int size) \
|
||||
__attribute__((__unused__));
|
||||
|
||||
static inline void logUser(const char *format, ...)
|
||||
{
|
||||
va_list arguments;
|
||||
|
||||
va_start(arguments, format);
|
||||
|
||||
logger.user(format, arguments);
|
||||
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
static inline void logError(const char *name, int error)
|
||||
{
|
||||
#if defined(DEBUG) || defined(TEST) || \
|
||||
defined(WARNING) || defined(PANIC)
|
||||
|
||||
logger.error(name, error);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void logWarning(const char *name, const char *format, ...)
|
||||
{
|
||||
#if defined(DEBUG) || defined(TEST) || \
|
||||
defined(WARNING)
|
||||
|
||||
va_list arguments;
|
||||
|
||||
va_start(arguments, format);
|
||||
|
||||
logger.warning(name, format, arguments);
|
||||
|
||||
va_end(arguments);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void logTest(const char *name, const char *format, ...)
|
||||
{
|
||||
#if defined(TEST)
|
||||
|
||||
va_list arguments;
|
||||
|
||||
va_start(arguments, format);
|
||||
|
||||
logger.test(name, format, arguments);
|
||||
|
||||
va_end(arguments);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void logTrace(const char *name)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
|
||||
logger.trace(name);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void logDebug(const char *name, const char *format, ...)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
|
||||
va_list arguments;
|
||||
|
||||
va_start(arguments, format);
|
||||
|
||||
logger.debug(name, format, arguments);
|
||||
|
||||
va_end(arguments);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void logDump(const char *name, const char *data, int size)
|
||||
{
|
||||
#if defined(TEST)
|
||||
|
||||
logger.dump(name, data, size);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* Logger_H */
|
||||
54
nxcompshad/src/Makefile.am
Normal file
54
nxcompshad/src/Makefile.am
Normal file
@@ -0,0 +1,54 @@
|
||||
NULL =
|
||||
|
||||
lib_LTLIBRARIES = libXcompshad.la
|
||||
|
||||
libXcompshad_la_SOURCES = \
|
||||
Core.cpp \
|
||||
Input.cpp \
|
||||
Logger.cpp \
|
||||
Manager.cpp \
|
||||
Shadow.cpp \
|
||||
Updater.cpp \
|
||||
X11.cpp \
|
||||
$(NULL)
|
||||
|
||||
libXcompshad_la_LIBADD = \
|
||||
-lX11 \
|
||||
@Xext_LIBS@ \
|
||||
@Xdamage_LIBS@ \
|
||||
@Xrandr_LIBS@ \
|
||||
@Xtst_LIBS@ \
|
||||
-L$(top_srcdir)/../nx-X11/lib/src/.libs -lNX_X11 \
|
||||
$(NULL)
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(Xext_CFLAGS) \
|
||||
$(Xdamage_CFLAGS) \
|
||||
$(Xrandr_CFLAGS) \
|
||||
$(Xtst_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_CXXFLAGS = \
|
||||
$(BASE_CXXFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/../nx-X11/exports/include \
|
||||
$(NULL)
|
||||
|
||||
libXcompshad_la_LDFLAGS = \
|
||||
-version-number @LT_COMPSHAD_VERSION@ -no-undefined \
|
||||
-R '$(libdir)/nx/X11' \
|
||||
$(NULL)
|
||||
|
||||
if TARGET_ELF
|
||||
libXcompshad_la_LDFLAGS += \
|
||||
-Wl,--enable-new-dtags \
|
||||
$(NULL)
|
||||
endif TARGET_ELF
|
||||
|
||||
libXcompshadincludedir = $(includedir)/nx
|
||||
libXcompshadinclude_HEADERS = \
|
||||
$(top_srcdir)/include/Shadow.h \
|
||||
$(NULL)
|
||||
264
nxcompshad/src/Manager.cpp
Normal file
264
nxcompshad/src/Manager.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
#include <nx-X11/Xutil.h>
|
||||
#include <nx-X11/keysym.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#include "Manager.h"
|
||||
#include "Logger.h"
|
||||
|
||||
UpdateManager::UpdateManager(int w, int h, char *f, Input *i)
|
||||
: width_(w), height_(h), frameBuffer_(f), input_(i)
|
||||
{
|
||||
logTrace("UpdateManager::UpdateManager");
|
||||
|
||||
nUpdater = 0;
|
||||
updaterVector = NULL;
|
||||
updateManagerRegion_ = NULL;
|
||||
}
|
||||
|
||||
UpdateManager::~UpdateManager()
|
||||
{
|
||||
logTrace("UpdateManager::~UpdateManager");
|
||||
|
||||
for (int i = 0; i < nUpdater; i++)
|
||||
{
|
||||
delete updaterVector[i];
|
||||
}
|
||||
|
||||
delete [] updaterVector;
|
||||
}
|
||||
|
||||
Updater *UpdateManager::createUpdater(char *displayName, Display *display)
|
||||
{
|
||||
Updater *updater = new Updater(displayName, display);
|
||||
|
||||
if (updater == NULL)
|
||||
{
|
||||
logError("UpdateManager::createUpdater", ESET(ENOMEM));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (updater -> init(width_, height_, frameBuffer_, input_) == -1)
|
||||
{
|
||||
logError("UpdateManager::createUpdater", EGET());
|
||||
|
||||
delete updater;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return updater;
|
||||
}
|
||||
|
||||
UpdaterHandle UpdateManager::addUpdater(char *displayName, Display *display)
|
||||
{
|
||||
Updater *newUpdater = createUpdater(displayName, display);
|
||||
|
||||
if (newUpdater == NULL)
|
||||
{
|
||||
logError("UpdateManager::addUpdater", EGET());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Updater **newUpdaterVector = new Updater*[nUpdater + 1];
|
||||
|
||||
if (newUpdaterVector == NULL)
|
||||
{
|
||||
logError("UpdateManager::addUpdater", ESET(ENOMEM));
|
||||
|
||||
delete newUpdater;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nUpdater; i++)
|
||||
{
|
||||
newUpdaterVector[i] = updaterVector[i];
|
||||
}
|
||||
|
||||
newUpdaterVector[nUpdater] = newUpdater;
|
||||
|
||||
delete [] updaterVector;
|
||||
|
||||
updaterVector = newUpdaterVector;
|
||||
|
||||
nUpdater++;
|
||||
|
||||
logTest("UpdateManager::AddUpdater", "Number of updaters [%d].", nUpdater);
|
||||
|
||||
return reinterpret_cast<UpdaterHandle>(newUpdater);
|
||||
}
|
||||
|
||||
int UpdateManager::removeAllUpdaters()
|
||||
{
|
||||
logTest("UpdateManager::removeAllUpdaters", "Number of updaters [%d].", nUpdater);
|
||||
|
||||
int nullUpdaters = 0;
|
||||
|
||||
for (int i = nUpdater; i > 0; i--)
|
||||
{
|
||||
if (removeUpdater(reinterpret_cast<UpdaterHandle>(updaterVector[i - 1])) == 0)
|
||||
{
|
||||
nullUpdaters++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nUpdater == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (nUpdater == nullUpdaters)
|
||||
{
|
||||
logTest("UpdateManager::removeAllUpdaters", "Ignored null records in Updater vector.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
logTest("UpdateManager::removeAllUpdaters", "Failed to remove some updaters.");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int UpdateManager::removeUpdater(UpdaterHandle handle)
|
||||
{
|
||||
Updater * const updater = (Updater*) handle;
|
||||
|
||||
logTest("UpdateManager::removeUpdater", "Removing Updater [%p].", updater);
|
||||
|
||||
if (updater == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < nUpdater; i++)
|
||||
{
|
||||
if (updater == updaterVector[i])
|
||||
{
|
||||
updaterVector[i] = updaterVector[nUpdater - 1];
|
||||
|
||||
nUpdater--;
|
||||
|
||||
delete updater;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
logTest("UpdateManager::removeUpdater", "Couldn't find Updater [%p].", updater);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void UpdateManager::addRegion(Region region)
|
||||
{
|
||||
logTrace("UpdateManager::addRegion");
|
||||
|
||||
for (int i = 0; i < nUpdater; i++)
|
||||
{
|
||||
updaterVector[i] -> addRegion(region);
|
||||
}
|
||||
|
||||
XDestroyRegion(region);
|
||||
}
|
||||
|
||||
void UpdateManager::update()
|
||||
{
|
||||
logTrace("UpdateManager::update");
|
||||
|
||||
for (int i = 0; i < nUpdater; i++)
|
||||
{
|
||||
/*updaterVector[i] -> update();*/
|
||||
if (updaterVector[i] -> getUpdateRegion())
|
||||
{
|
||||
logDebug("UpdateManager::update", "pRegion [%p] rect[%ld].",
|
||||
updaterVector[i] -> getUpdateRegion(), (updaterVector[i] -> getUpdateRegion()) -> numRects);
|
||||
|
||||
updateManagerRegion_ = updaterVector[i] -> getUpdateRegion();
|
||||
//
|
||||
// FIXME: Remove me.
|
||||
//
|
||||
for (int j = 0; j < updateManagerRegion_ -> numRects; j++)
|
||||
{
|
||||
int x = updateManagerRegion_ -> rects[j].x1;
|
||||
int y = updateManagerRegion_ -> rects[j].y1;
|
||||
unsigned int width = updateManagerRegion_ -> rects[j].x2 - updateManagerRegion_ -> rects[j].x1;
|
||||
unsigned int height = updateManagerRegion_ -> rects[j].y2 - updateManagerRegion_ -> rects[j].y1;
|
||||
logDebug("UpdateManager::update", "x[%d]y[%d]width[%u]height[%u], updateManagerRegion_[%p]",
|
||||
x, y, width, height, updateManagerRegion_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateManager::handleInput()
|
||||
{
|
||||
logTrace("UpdateManager::handleInput");
|
||||
|
||||
for (int i = 0; i < nUpdater; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
updaterVector[i] -> handleInput();
|
||||
}
|
||||
catch (UpdaterClosing u)
|
||||
{
|
||||
logTest("UpdateManager::handleInput", "Caught exception UpdaterClosing().");
|
||||
|
||||
removeUpdater((UpdaterHandle)updaterVector[i]);
|
||||
|
||||
//
|
||||
// Now the i-element of the updaterVector
|
||||
// is changed. We don't want to skip it.
|
||||
//
|
||||
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateManager::newRegion()
|
||||
{
|
||||
logTrace("UpdateManager::newRegion");
|
||||
|
||||
for (int i = 0; i < nUpdater; i++)
|
||||
{
|
||||
updaterVector[i] -> newRegion();
|
||||
}
|
||||
}
|
||||
123
nxcompshad/src/Manager.h
Normal file
123
nxcompshad/src/Manager.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef UpdateManager_H
|
||||
#define UpdateManager_H
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
|
||||
#include "Updater.h"
|
||||
#include "Regions.h"
|
||||
#include "Input.h"
|
||||
|
||||
typedef char* UpdaterHandle;
|
||||
|
||||
class UpdateManager
|
||||
{
|
||||
public:
|
||||
|
||||
UpdateManager(int, int, char *, Input *);
|
||||
|
||||
~UpdateManager();
|
||||
|
||||
void handleInput();
|
||||
|
||||
void addRegion(Region);
|
||||
|
||||
void update();
|
||||
|
||||
UpdaterHandle addUpdater(char *displayName, Display *display);
|
||||
|
||||
int removeUpdater(UpdaterHandle);
|
||||
|
||||
int removeAllUpdaters();
|
||||
|
||||
int numberOfUpdaters();
|
||||
|
||||
int getWidth();
|
||||
|
||||
int getHeight();
|
||||
|
||||
char *getBuffer();
|
||||
|
||||
Region getUpdateManagerRegion();
|
||||
|
||||
void destroyUpdateManagerRegion();
|
||||
|
||||
void newRegion();
|
||||
|
||||
private:
|
||||
|
||||
Updater *createUpdater(char *displayName, Display *display);
|
||||
|
||||
int width_;
|
||||
int height_;
|
||||
char *frameBuffer_;
|
||||
Input *input_;
|
||||
|
||||
int nUpdater;
|
||||
|
||||
Updater **updaterVector;
|
||||
|
||||
Region updateManagerRegion_;
|
||||
|
||||
};
|
||||
|
||||
inline int UpdateManager::numberOfUpdaters()
|
||||
{
|
||||
return nUpdater;
|
||||
}
|
||||
|
||||
inline int UpdateManager::getWidth()
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
inline int UpdateManager::getHeight()
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
inline char *UpdateManager::getBuffer()
|
||||
{
|
||||
return frameBuffer_;
|
||||
}
|
||||
|
||||
inline Region UpdateManager::getUpdateManagerRegion()
|
||||
{
|
||||
return updateManagerRegion_;
|
||||
}
|
||||
|
||||
inline void UpdateManager::destroyUpdateManagerRegion()
|
||||
{
|
||||
if (updateManagerRegion_ != NULL)
|
||||
{
|
||||
XDestroyRegion(updateManagerRegion_);
|
||||
|
||||
updateManagerRegion_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* UpdateManager_H */
|
||||
50
nxcompshad/src/Misc.h
Normal file
50
nxcompshad/src/Misc.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Misc_H
|
||||
#define Misc_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// Error handling macros.
|
||||
//
|
||||
|
||||
#define ESET(e) (errno = (e))
|
||||
#define EGET() (errno)
|
||||
#define ESTR() strerror(errno)
|
||||
|
||||
//
|
||||
// Log file.
|
||||
//
|
||||
|
||||
extern ostream *logofs;
|
||||
|
||||
#endif /* Misc_H */
|
||||
31
nxcompshad/src/Poller.h
Normal file
31
nxcompshad/src/Poller.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Poller_H
|
||||
#define Poller_H
|
||||
|
||||
#include "X11.h"
|
||||
|
||||
#endif /* Poller_H */
|
||||
43
nxcompshad/src/Regions.h
Normal file
43
nxcompshad/src/Regions.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Region_H
|
||||
#define Region_H
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
#include <nx-X11/Xutil.h>
|
||||
|
||||
typedef struct {
|
||||
short x1, x2, y1, y2;
|
||||
} Box, BOX, BoxRec, *BoxPtr;
|
||||
|
||||
struct _XRegion {
|
||||
long size;
|
||||
long numRects;
|
||||
BOX *rects;
|
||||
BOX extents;
|
||||
};
|
||||
|
||||
#endif /* Region_H */
|
||||
458
nxcompshad/src/Shadow.cpp
Normal file
458
nxcompshad/src/Shadow.cpp
Normal file
@@ -0,0 +1,458 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
|
||||
#include "Logger.h"
|
||||
#include "Shadow.h"
|
||||
#include "Poller.h"
|
||||
#include "Manager.h"
|
||||
|
||||
typedef struct {
|
||||
KeySym *map;
|
||||
KeyCode minKeyCode,
|
||||
maxKeyCode;
|
||||
int mapWidth;
|
||||
} KeySymsRec, *KeySymsPtr;
|
||||
|
||||
KeySymsPtr NXShadowKeymap = NULL;
|
||||
|
||||
ShadowOptions NXShadowOptions = {1, 1, -1};
|
||||
|
||||
static int mirrorException = 0;
|
||||
|
||||
static UpdateManager *updateManager;
|
||||
static Poller *poller;
|
||||
static Input *input;
|
||||
|
||||
inline bool NXShadowNotInitialized()
|
||||
{
|
||||
//
|
||||
// updateManager depends on input and poller.
|
||||
// So this test seem redundant.
|
||||
//
|
||||
// return (input == NULL) || (poller == NULL) || (updateManager == NULL);
|
||||
//
|
||||
|
||||
return (updateManager == NULL);
|
||||
}
|
||||
|
||||
#ifdef NEED_SIGNAL_HANDLER
|
||||
static void NXSignalHandler(int signal)
|
||||
{
|
||||
logTest("NXSignalHandler", "Got signal [%d]", signal);
|
||||
|
||||
if (signal == SIGINT)
|
||||
{
|
||||
mirrorException = 1;
|
||||
}
|
||||
else if (signal == SIGTERM)
|
||||
{
|
||||
mirrorException = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int NXInitSignal()
|
||||
{
|
||||
logTrace("NXInitSignal");
|
||||
|
||||
struct sigaction sa;
|
||||
|
||||
sa.sa_handler = NXSignalHandler;
|
||||
sigfillset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
|
||||
int res;
|
||||
|
||||
while ((res = sigaction(SIGINT, &sa, NULL)) == -1 &&
|
||||
errno == EINTR);
|
||||
|
||||
if (res == -1)
|
||||
{
|
||||
logError("NXInitSignal", EGET());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void NXHandleException()
|
||||
{
|
||||
if (mirrorException)
|
||||
{
|
||||
mirrorException = 0;
|
||||
|
||||
NXShadowRemoveAllUpdaters();
|
||||
}
|
||||
}
|
||||
|
||||
static int NXCreateInput(char *keymap, char *shadowDisplayName)
|
||||
{
|
||||
logTrace("NXCreateInput");
|
||||
|
||||
input = new Input;
|
||||
|
||||
if (input == NULL)
|
||||
{
|
||||
logError("NXCreateInput", ESET(ENOMEM));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
input -> setKeymap(keymap);
|
||||
|
||||
input -> setShadowDisplayName(shadowDisplayName);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int NXCreatePoller(Display *display, Display **shadowDisplay)
|
||||
{
|
||||
logTrace("NXCreatePoller");
|
||||
|
||||
if (input == NULL)
|
||||
{
|
||||
logError("NXCreatePoller", ESET(EBADF));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
poller = new Poller(input,display);
|
||||
|
||||
if (poller == NULL)
|
||||
{
|
||||
logError("NXCreatePoller", ESET(ENOMEM));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (poller -> init() == -1)
|
||||
{
|
||||
logWarning("NXCreatePoller", "Failed to initialize poller.");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
*shadowDisplay = poller -> getShadowDisplay();
|
||||
|
||||
logTest("NXCreatePoller", "Poller geometry [%d, %d], ShadowDisplay[%p].", poller -> width(),
|
||||
poller -> height(), (Display *) *shadowDisplay);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int NXCreateUpdateManager()
|
||||
{
|
||||
logTrace("NXCreateUpdateManager");
|
||||
|
||||
if (input == NULL || poller == NULL)
|
||||
{
|
||||
logError("NXCreateUpdateManager", ESET(EBADF));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
updateManager = new UpdateManager(poller -> width(), poller -> height(),
|
||||
poller -> getFrameBuffer(), input);
|
||||
|
||||
if (updateManager == NULL)
|
||||
{
|
||||
logError("NXCreateUpdateManager", ESET(ENOMEM));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NXShadowResetOptions()
|
||||
{
|
||||
NXShadowOptions.optionShmExtension = 1;
|
||||
NXShadowOptions.optionDamageExtension = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Exported functions.
|
||||
//
|
||||
|
||||
int NXShadowHasUpdaters()
|
||||
{
|
||||
logTrace("NXShadowHasUpdaters");
|
||||
|
||||
return (updateManager && updateManager -> numberOfUpdaters()) ? 1 : 0;
|
||||
}
|
||||
|
||||
int NXShadowRemoveAllUpdaters()
|
||||
{
|
||||
logTrace("NXShadowRemoveAllUpdaters");
|
||||
|
||||
return updateManager ? updateManager -> removeAllUpdaters() : 0;
|
||||
}
|
||||
|
||||
int NXShadowRemoveUpdater(UpdaterHandle handle)
|
||||
{
|
||||
logTrace("NXShadowRemoveUpdater");
|
||||
|
||||
return updateManager ? updateManager -> removeUpdater(handle) : 0;
|
||||
}
|
||||
|
||||
UpdaterHandle NXShadowAddUpdater(char *displayName)
|
||||
{
|
||||
logTrace("NXShadowAddUpdater");
|
||||
|
||||
return updateManager ? updateManager -> addUpdater(displayName, NULL) : NULL;
|
||||
}
|
||||
|
||||
int NXShadowAddUpdaterDisplay(void *dpy, int *w, int *h, unsigned char *d)
|
||||
{
|
||||
Display *display = reinterpret_cast<Display*>(dpy);
|
||||
|
||||
logTrace("NXShadowAddUpdaterDisplay");
|
||||
|
||||
if ((updateManager ? updateManager -> addUpdater(NULL, display) : NULL) == NULL)
|
||||
{
|
||||
logTest("NXShadowAddUpdaterDisplay", "Error");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
*w = updateManager -> getWidth();
|
||||
*h = updateManager -> getHeight();
|
||||
*d = poller -> depth();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int NXShadowCreate(void *dpy, char *keymap, char* shadowDisplayName, void **shadowDpy)
|
||||
{
|
||||
logTrace("NXShadowCreate");
|
||||
|
||||
Display *display = reinterpret_cast<Display*>(dpy);
|
||||
Display **shadowDisplay = reinterpret_cast<Display**>(shadowDpy);
|
||||
|
||||
/* if (NXInitSignal() != 1)
|
||||
{
|
||||
logError("NXShadowCreate", EGET());
|
||||
|
||||
return -1;
|
||||
}*/
|
||||
|
||||
if (NXCreateInput(keymap, shadowDisplayName) != 1)
|
||||
{
|
||||
logError("NXShadowCreate", EGET());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NXCreatePoller(display, shadowDisplay) != 1)
|
||||
{
|
||||
logWarning("NXShadowCreate", "NXCreatePoller failed.");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NXCreateUpdateManager() != 1)
|
||||
{
|
||||
logError("NXShadowCreate", EGET());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NXShadowSetDisplayUid(int uid)
|
||||
{
|
||||
NXShadowOptions.optionShadowDisplayUid = uid;
|
||||
}
|
||||
|
||||
void NXShadowDisableShm(void)
|
||||
{
|
||||
logUser("NXShadowDisableShm: Disabling SHM.\n");
|
||||
|
||||
NXShadowOptions.optionShmExtension = 0;
|
||||
}
|
||||
|
||||
void NXShadowDisableDamage(void)
|
||||
{
|
||||
NXShadowOptions.optionDamageExtension = 0;
|
||||
}
|
||||
|
||||
void NXShadowGetScreenSize(int *w, int *h)
|
||||
{
|
||||
poller -> getScreenSize(w, h);
|
||||
}
|
||||
|
||||
void NXShadowSetScreenSize(int *w, int *h)
|
||||
{
|
||||
poller -> setScreenSize(w, h);
|
||||
}
|
||||
|
||||
void NXShadowDestroy()
|
||||
{
|
||||
if (poller)
|
||||
{
|
||||
delete poller;
|
||||
|
||||
poller = NULL;
|
||||
}
|
||||
|
||||
if (updateManager)
|
||||
{
|
||||
delete updateManager;
|
||||
|
||||
updateManager = NULL;
|
||||
}
|
||||
|
||||
if (input)
|
||||
{
|
||||
delete input;
|
||||
|
||||
input = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void NXShadowHandleInput()
|
||||
{
|
||||
logTrace("NXShadowHandleInput");
|
||||
|
||||
if (NXShadowNotInitialized())
|
||||
{
|
||||
logError("NXShadowHandleInput - NXShadow not properly initialized.", ESET(EBADF));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NXHandleException();
|
||||
|
||||
updateManager -> handleInput();
|
||||
|
||||
poller -> handleInput();
|
||||
}
|
||||
|
||||
int NXShadowHasChanged(int (*callback)(void *), void *arg, int *suspended)
|
||||
{
|
||||
int result;
|
||||
|
||||
logTrace("NXShadowHasChanged");
|
||||
|
||||
if (NXShadowNotInitialized())
|
||||
{
|
||||
logError("NXShadowHasChanged - NXShadow not properly initialized.", ESET(EBADF));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME
|
||||
//updateManager -> destroyUpdateManagerRegion();
|
||||
//
|
||||
|
||||
updateManager -> newRegion();
|
||||
|
||||
poller -> getEvents();
|
||||
|
||||
result = poller -> isChanged(callback, arg, suspended);
|
||||
|
||||
if (result == 1)
|
||||
{
|
||||
updateManager -> addRegion(poller -> lastUpdatedRegion());
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (result == -1)
|
||||
{
|
||||
logTest("NXShadowHasChanged", "Scanline error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NXShadowExportChanges(long *numRects, char **pBox)
|
||||
{
|
||||
Region pReg;
|
||||
|
||||
logTrace("NXShadowExportChanges");
|
||||
|
||||
if (NXShadowNotInitialized())
|
||||
{
|
||||
logError("NXShadowExportChanges - NXShadow not properly initialized.", ESET(EBADF));
|
||||
}
|
||||
|
||||
updateManager -> update();
|
||||
pReg = updateManager -> getUpdateManagerRegion();
|
||||
*numRects = pReg -> numRects;
|
||||
*pBox = (char *)pReg -> rects;
|
||||
|
||||
logTest("NXShadowExportChanges", "numRects [%ld] pBox[%p], pReg->numRects[%ld], rects[%p], size[%lu]",
|
||||
*numRects, *pBox, pReg -> numRects, &(pReg -> rects -> x2),
|
||||
(unsigned long) sizeof(pReg -> rects -> x2));
|
||||
}
|
||||
|
||||
void NXShadowEvent(Display *display, XEvent event)
|
||||
{
|
||||
poller -> handleEvent(display, &event);
|
||||
}
|
||||
|
||||
void NXShadowWebKeyEvent(KeySym keysym, Bool isKeyPress)
|
||||
{
|
||||
poller -> handleWebKeyEvent(keysym, isKeyPress);
|
||||
}
|
||||
|
||||
void NXShadowUpdateBuffer(void **buffer)
|
||||
{
|
||||
char **fBuffer = reinterpret_cast<char **>(buffer);
|
||||
|
||||
if (*fBuffer != NULL)
|
||||
{
|
||||
poller -> destroyFrameBuffer();
|
||||
|
||||
poller -> init();
|
||||
}
|
||||
|
||||
*fBuffer = poller -> getFrameBuffer();
|
||||
|
||||
logTest("NXShadowUpdateBuffer","New frame buffer [0x%p]", (void *)*fBuffer);
|
||||
}
|
||||
|
||||
void NXShadowInitKeymap(void *keysyms)
|
||||
{
|
||||
NXShadowKeymap = (KeySymsPtr) keysyms;
|
||||
|
||||
logTest("NXShadowInitKeymap","KeySyms pointer [0x%p]", (void *)NXShadowKeymap);
|
||||
}
|
||||
395
nxcompshad/src/Updater.cpp
Normal file
395
nxcompshad/src/Updater.cpp
Normal file
@@ -0,0 +1,395 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
#include <nx-X11/Xutil.h>
|
||||
#include <nx-X11/keysym.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PANIC
|
||||
#define WARNING
|
||||
#undef TEST
|
||||
#undef DEBUG
|
||||
//
|
||||
#include <stdio.h>
|
||||
//
|
||||
#include "Updater.h"
|
||||
#include "Logger.h"
|
||||
|
||||
Updater::Updater(char *displayName, Display *display)
|
||||
{
|
||||
logTrace("Updater::Updater");
|
||||
|
||||
displayName_ = displayName;
|
||||
display_ = display;
|
||||
closeDisplay_ = false;
|
||||
image_ = NULL;
|
||||
updateRegion_ = NULL;
|
||||
buffer_ = NULL;
|
||||
}
|
||||
|
||||
Updater::~Updater()
|
||||
{
|
||||
logTrace("Updater::~Updater");
|
||||
|
||||
if (input_)
|
||||
{
|
||||
int removedEvents = input_ -> removeAllEvents(display_);
|
||||
|
||||
logTest("Updater::~Updater", "Removed events in input queue is [%d].", removedEvents);
|
||||
}
|
||||
|
||||
if (display_)
|
||||
{
|
||||
XDestroyWindow(display_, window_);
|
||||
XFreePixmap(display_, pixmap_);
|
||||
|
||||
if (closeDisplay_)
|
||||
{
|
||||
XCloseDisplay(display_);
|
||||
}
|
||||
}
|
||||
|
||||
if (image_)
|
||||
{
|
||||
image_ -> data = NULL;
|
||||
|
||||
XDestroyImage(image_);
|
||||
}
|
||||
|
||||
if (updateRegion_)
|
||||
{
|
||||
XDestroyRegion(updateRegion_);
|
||||
}
|
||||
}
|
||||
|
||||
int Updater::init(int width, int height, char *fb, Input *input)
|
||||
{
|
||||
logTrace("Updater::init");
|
||||
|
||||
if (fb == NULL || input == NULL || width <= 0 || height <= 0)
|
||||
{
|
||||
logError("Updater::init", ESET(EINVAL));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
buffer_ = fb;
|
||||
input_ = input;
|
||||
/*
|
||||
if (display_ == NULL)
|
||||
{
|
||||
display_ = XOpenDisplay(displayName_);
|
||||
|
||||
closeDisplay_ = true;
|
||||
|
||||
if (display_ == NULL)
|
||||
{
|
||||
logError("Updater::init", ESET(ENOMSG));
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
depth_ = DefaultDepth(display_, DefaultScreen(display_));
|
||||
|
||||
if (depth_ == 8) bpl_ = width_;
|
||||
else if (depth_ == 16) bpl_ = width_ * 2;
|
||||
else bpl_ = width_ * 4;
|
||||
|
||||
logTest("Updater::init", "Server geometry [%d, %d] depth [%d] bpl [%d].", width_, height_, depth_, bpl_);
|
||||
|
||||
/* int bitmap_pad = 8;
|
||||
|
||||
image_ = XCreateImage(display_, DefaultVisual(display_, DefaultScreen(display_)), depth_, ZPixmap, 0,
|
||||
buffer_, width_, height_, bitmap_pad, 0);
|
||||
|
||||
if (image_ == NULL)
|
||||
{
|
||||
logError("Updater::init", ESET(ENOMSG));
|
||||
|
||||
logTest("Updater::init", "Failed to create default image.");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pixmap_ = XCreatePixmap(display_, DefaultRootWindow(display_), width_, height_, depth_);
|
||||
|
||||
unsigned int mask = CWBackPixmap | CWBorderPixel | CWEventMask;
|
||||
|
||||
XSetWindowAttributes attributes;
|
||||
|
||||
attributes.background_pixmap = pixmap_;
|
||||
attributes.border_pixel = WhitePixel(display_, DefaultScreen(display_));
|
||||
attributes.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
|
||||
|
||||
window_ = XCreateWindow(display_, DefaultRootWindow(display_),
|
||||
0, 0, width_, height_, 0, depth_, InputOutput,
|
||||
DefaultVisual(display_, DefaultScreen(display_)), mask, &attributes);
|
||||
|
||||
if (window_ == None)
|
||||
{
|
||||
logError("Updater::init", ESET(ENOMSG));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
XSizeHints *size_hints;
|
||||
|
||||
if ((size_hints = XAllocSizeHints()) == NULL)
|
||||
{
|
||||
logError("Updater::init", ESET(ENOMEM));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_hints -> flags = PMinSize | PMaxSize;
|
||||
size_hints -> min_width = width_;
|
||||
size_hints -> max_width = width_;
|
||||
size_hints -> min_height = height_;
|
||||
size_hints -> max_height = height_;
|
||||
|
||||
XSetWMNormalHints(display_, window_, size_hints);
|
||||
|
||||
XFree(size_hints);
|
||||
|
||||
Atom deleteWMatom = XInternAtom(display_, "WM_DELETE_WINDOW", 1);
|
||||
|
||||
XSetWMProtocols(display_, window_, &deleteWMatom, 1);
|
||||
|
||||
XMapWindow(display_, window_);*/
|
||||
|
||||
updateRegion_ = XCreateRegion();
|
||||
|
||||
logTest("Updater::init", "updateRegion_[%p]", updateRegion_);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Updater::addRegion(Region region)
|
||||
{
|
||||
//
|
||||
// FIXME: Is this too paranoid ?
|
||||
//
|
||||
|
||||
if (updateRegion_ == NULL)
|
||||
{
|
||||
logError("Updater::addRegion", ESET(EINVAL));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
XUnionRegion(region, updateRegion_, updateRegion_);
|
||||
}
|
||||
|
||||
void Updater::update()
|
||||
{
|
||||
logTrace("Updater::update");
|
||||
|
||||
if (updateRegion_ == NULL)
|
||||
{
|
||||
logError("Updater::update", ESET(EINVAL));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
logTest("Updater::update", "Number of rectangles [%ld].", updateRegion_ -> numRects);
|
||||
|
||||
/* for (; updateRegion_ -> numRects > 0; updateRegion_ -> numRects--)
|
||||
{
|
||||
int n = updateRegion_ -> numRects - 1;
|
||||
|
||||
int x = updateRegion_ -> rects[n].x1;
|
||||
int y = updateRegion_ -> rects[n].y1;
|
||||
unsigned int width = updateRegion_ -> rects[n].x2 - updateRegion_ -> rects[n].x1;
|
||||
unsigned int height = updateRegion_ -> rects[n].y2 - updateRegion_ -> rects[n].y1;
|
||||
|
||||
logDebug("Updater::update", "Sending rectangle: [%d, %d, %d, %d].", x, y, width, height);
|
||||
|
||||
//
|
||||
// We need to update the extents.
|
||||
//
|
||||
|
||||
int bitmap_pad;
|
||||
|
||||
if (depth_ == 32 || depth_ == 24)
|
||||
{
|
||||
bitmap_pad = 32;
|
||||
}
|
||||
else if (depth_ == 16)
|
||||
{
|
||||
if ((width & 1) == 0)
|
||||
{
|
||||
bitmap_pad = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap_pad = 16;
|
||||
}
|
||||
}
|
||||
else if ((width & 3) == 0)
|
||||
{
|
||||
bitmap_pad = 32;
|
||||
}
|
||||
else if ((width & 1) == 0)
|
||||
{
|
||||
bitmap_pad = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap_pad = 8;
|
||||
}*/
|
||||
|
||||
/* image_ -> bitmap_pad = bitmap_pad;*/
|
||||
|
||||
/* NXShadowCorrectColor(x, y, width, height);*/
|
||||
|
||||
/* XPutImage(display_, pixmap_, DefaultGC(display_, DefaultScreen(display_)),
|
||||
image_, x, y, x, y, width, height);
|
||||
|
||||
XClearArea(display_, window_, x, y, width, height, 0);
|
||||
}*/
|
||||
|
||||
//
|
||||
// Should we reduces the box vector ?
|
||||
//
|
||||
// BOX *box = Xrealloc(updateRegion_ -> rects,
|
||||
// updateRegion_ -> numRects == 0 ? sizeof(BOX) :
|
||||
// updateRegion_ -> numRects * sizeof(BOX));
|
||||
//
|
||||
// if (box)
|
||||
// {
|
||||
// updateRegion_ -> rects = box;
|
||||
// updateRegion_ -> size = 1;
|
||||
// }
|
||||
//
|
||||
|
||||
if (updateRegion_ -> numRects == 0)
|
||||
{
|
||||
updateRegion_ -> extents.x1 = 0;
|
||||
updateRegion_ -> extents.y1 = 0;
|
||||
updateRegion_ -> extents.x2 = 0;
|
||||
updateRegion_ -> extents.y2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// FIXME: We have to update the region extents.
|
||||
//
|
||||
|
||||
logTest("Updater::update", "Region extents has not been updated.");
|
||||
}
|
||||
}
|
||||
|
||||
void Updater::handleInput()
|
||||
{
|
||||
logTrace("Updater::handleInput");
|
||||
|
||||
XEvent *event = new XEvent;
|
||||
|
||||
if (event == NULL)
|
||||
{
|
||||
logError("Updater::handleInput", ESET(ENOMEM));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (XCheckIfEvent(display_, event, anyEventPredicate, NULL))
|
||||
{
|
||||
switch (event -> type)
|
||||
{
|
||||
/* case ClientMessage:
|
||||
{
|
||||
Atom wmProtocols = XInternAtom(display_, "WM_PROTOCOLS", 0);
|
||||
Atom wmDeleteWindow = XInternAtom(display_, "WM_DELETE_WINDOW", 0);
|
||||
|
||||
if (event -> xclient.message_type == wmProtocols &&
|
||||
(Atom)event -> xclient.data.l[0] == wmDeleteWindow)
|
||||
{
|
||||
logTest("Updater::handleInput", "Got client message of type WM_PROTOCOLS and value WM_DELETE_WINDOW,"
|
||||
" throwing exception UpdaterClosing.");
|
||||
|
||||
delete event;
|
||||
|
||||
throw UpdaterClosing();
|
||||
}
|
||||
else
|
||||
{
|
||||
logTest("Updater::handleInput", "Unexpected client message type [%ld] format [%d] first value [%ld]",
|
||||
event -> xclient.message_type, event -> xclient.format, event -> xclient.data.l[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
}*/
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
case MotionNotify:
|
||||
{
|
||||
input_ -> pushEvent(display_, event);
|
||||
|
||||
event = new XEvent;
|
||||
|
||||
if (event == NULL)
|
||||
{
|
||||
logError("Updater::handleInput", ESET(ENOMEM));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
logTest("Updater::handleInput", "Handling unexpected event [%d].", event -> type);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete event;
|
||||
}
|
||||
|
||||
void Updater::newRegion()
|
||||
{
|
||||
if (updateRegion_ != NULL)
|
||||
{
|
||||
XDestroyRegion(updateRegion_);
|
||||
}
|
||||
|
||||
updateRegion_ = XCreateRegion();
|
||||
|
||||
logTest("Updater::newRegion", "updateRegion_ [%p].", updateRegion_);
|
||||
}
|
||||
//
|
||||
// Private functions.
|
||||
//
|
||||
103
nxcompshad/src/Updater.h
Normal file
103
nxcompshad/src/Updater.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef Updater_H
|
||||
#define Updater_H
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
|
||||
#include "Regions.h"
|
||||
#include "Input.h"
|
||||
|
||||
class UpdaterClosing {};
|
||||
|
||||
class Updater
|
||||
{
|
||||
public:
|
||||
|
||||
Updater(char *displayName, Display *display);
|
||||
|
||||
~Updater();
|
||||
|
||||
int init(int, int, char *, Input*);
|
||||
|
||||
void addRegion(Region r);
|
||||
|
||||
void update();
|
||||
|
||||
void handleInput();
|
||||
|
||||
XImage *getImage();
|
||||
|
||||
Region getUpdateRegion();
|
||||
|
||||
void newRegion();
|
||||
|
||||
private:
|
||||
|
||||
Input *input_;
|
||||
|
||||
static inline Bool anyEventPredicate(Display*, XEvent*, XPointer);
|
||||
|
||||
void handleKeyboardEvent(XEvent &event);
|
||||
|
||||
char *displayName_;
|
||||
|
||||
char *buffer_;
|
||||
|
||||
bool closeDisplay_;
|
||||
|
||||
Display *display_;
|
||||
|
||||
int depth_;
|
||||
|
||||
int width_;
|
||||
int height_;
|
||||
|
||||
int bpl_;
|
||||
|
||||
Window window_;
|
||||
XImage *image_;
|
||||
|
||||
Pixmap pixmap_;
|
||||
|
||||
Region updateRegion_;
|
||||
|
||||
};
|
||||
|
||||
Bool Updater::anyEventPredicate(Display*, XEvent*, XPointer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline XImage* Updater::getImage()
|
||||
{
|
||||
return image_;
|
||||
}
|
||||
inline Region Updater::getUpdateRegion()
|
||||
{
|
||||
return updateRegion_;
|
||||
}
|
||||
#endif /* Updater_H */
|
||||
1594
nxcompshad/src/X11.cpp
Normal file
1594
nxcompshad/src/X11.cpp
Normal file
File diff suppressed because it is too large
Load Diff
135
nxcompshad/src/X11.h
Normal file
135
nxcompshad/src/X11.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
|
||||
/* Copyright (c) 2008-2017 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
|
||||
/* Copyright (c) 2014-2022 Ulrich Sibiller <uli42@gmx.de> */
|
||||
/* Copyright (c) 2014-2019 Mihai Moldovan <ionic@ionic.de> */
|
||||
/* Copyright (c) 2011-2022 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
|
||||
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
|
||||
/* */
|
||||
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
|
||||
/* are copyright of the aforementioned persons and companies. */
|
||||
/* */
|
||||
/* Redistribution and use of the present software is allowed according */
|
||||
/* to terms specified in the file LICENSE which comes in the source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
/* NOTE: This software has received contributions from various other */
|
||||
/* contributors, only the core maintainers and supporters are listed as */
|
||||
/* copyright holders. Please contact us, if you feel you should be listed */
|
||||
/* as copyright holder, as well. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef X11Poller_H
|
||||
#define X11Poller_H
|
||||
|
||||
#include <nx-X11/Xlib.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include "X11/include/Xdamage_nxcompshad.h"
|
||||
#include "X11/include/Xrandr_nxcompshad.h"
|
||||
|
||||
#include "Core.h"
|
||||
|
||||
class Poller : public CorePoller
|
||||
{
|
||||
public:
|
||||
|
||||
Poller(Input *, Display *display, int = 0);
|
||||
|
||||
~Poller();
|
||||
|
||||
int init();
|
||||
|
||||
void setRootSize();
|
||||
|
||||
void destroyShmImage();
|
||||
|
||||
void getEvents(void);
|
||||
|
||||
void getScreenSize(int *width, int *height);
|
||||
|
||||
void setScreenSize(int *width, int *height);
|
||||
|
||||
private:
|
||||
|
||||
Display *display_;
|
||||
|
||||
char *shadowDisplayName_;
|
||||
|
||||
int shadowDisplayUid_;
|
||||
|
||||
char *tmpBuffer_;
|
||||
|
||||
char xtestExtension_;
|
||||
|
||||
char shmExtension_;
|
||||
|
||||
char randrExtension_;
|
||||
|
||||
int randrEventBase_;
|
||||
|
||||
char damageExtension_;
|
||||
|
||||
int damageEventBase_;
|
||||
|
||||
Damage damage_;
|
||||
|
||||
XShmSegmentInfo *shminfo_;
|
||||
|
||||
XImage *image_;
|
||||
|
||||
int updateShadowFrameBuffer(void);
|
||||
|
||||
char *getRect(XRectangle);
|
||||
|
||||
void keymapShadowInit(Display *display);
|
||||
|
||||
void keymapMasterInit();
|
||||
|
||||
KeySym keymapKeycodeToKeysym(KeyCode keycode, KeySym *keysyms,
|
||||
int minKey, int per, int col);
|
||||
|
||||
KeyCode keymapKeysymToKeycode(KeySym keysym, KeySym *keysyms,
|
||||
int minKey, int maxKey, int per, int *col);
|
||||
|
||||
KeyCode translateKeysymToKeycode(KeySym keysym, int *col);
|
||||
|
||||
Bool checkModifierKeys(KeySym keysym, Bool isKeyPress);
|
||||
|
||||
void sendFakeModifierEvents(int pos, Bool skip);
|
||||
|
||||
void cancelFakeModifierEvents();
|
||||
|
||||
Bool keyIsDown(KeyCode keycode);
|
||||
|
||||
void addKeyPressed(KeyCode received, KeyCode sent);
|
||||
|
||||
KeyCode getKeyPressed(KeyCode received);
|
||||
|
||||
void handleKeyboardEvent(Display *display, XEvent *);
|
||||
|
||||
void handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress);
|
||||
|
||||
void handleMouseEvent(Display *, XEvent *);
|
||||
|
||||
void xtestInit(void);
|
||||
|
||||
void shmInit(void);
|
||||
|
||||
void randrInit(void);
|
||||
|
||||
void damageInit(void);
|
||||
|
||||
void handleRRScreenChangeNotify(XEvent *);
|
||||
|
||||
void handleDamageNotify(XEvent *);
|
||||
|
||||
void updateDamagedAreas(void);
|
||||
};
|
||||
|
||||
int anyEventPredicate(Display *display, XEvent *event, XPointer parameter);
|
||||
|
||||
#endif /* X11Poller_H */
|
||||
71
nxcompshad/src/X11/include/XTest_nxcompshad.h
Normal file
71
nxcompshad/src/X11/include/XTest_nxcompshad.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Copyright 1992, 1998 The Open Group
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
OPEN GROUP 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 Open Group 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 Open Group.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _XTEST_H_
|
||||
#define _XTEST_H_
|
||||
|
||||
#include <nx-X11/Xfuncproto.h>
|
||||
|
||||
_XFUNCPROTOBEGIN
|
||||
|
||||
Bool XTestQueryExtension(
|
||||
Display* /* dpy */,
|
||||
int* /* event_basep */,
|
||||
int* /* error_basep */,
|
||||
int* /* majorp */,
|
||||
int* /* minorp */
|
||||
);
|
||||
|
||||
extern int XTestFakeKeyEvent(
|
||||
Display* /* dpy */,
|
||||
unsigned int /* keycode */,
|
||||
Bool /* is_press */,
|
||||
unsigned long /* delay */
|
||||
);
|
||||
|
||||
extern int XTestFakeButtonEvent(
|
||||
Display* /* dpy */,
|
||||
unsigned int /* button */,
|
||||
Bool /* is_press */,
|
||||
unsigned long /* delay */
|
||||
);
|
||||
|
||||
extern int XTestFakeMotionEvent(
|
||||
Display* /* dpy */,
|
||||
int /* screen */,
|
||||
int /* x */,
|
||||
int /* y */,
|
||||
unsigned long /* delay */
|
||||
);
|
||||
|
||||
extern int XTestGrabControl(
|
||||
Display* /* dpy */,
|
||||
Bool /* impervious */
|
||||
);
|
||||
|
||||
_XFUNCPROTOEND
|
||||
|
||||
#endif
|
||||
92
nxcompshad/src/X11/include/Xdamage_nxcompshad.h
Normal file
92
nxcompshad/src/X11/include/Xdamage_nxcompshad.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is a reduced version of the header file of
|
||||
* <X11/extensions/Xdamaga.h>
|
||||
*
|
||||
* This copy of code has been introduced to allow a clear namespace
|
||||
* separation between <X11/...> and <nx-X11/...> header files.
|
||||
*
|
||||
* This version of the Xdamage library header file only contains symbols
|
||||
* required by nxcompshad and strictly avoids indirectly including
|
||||
* from an X11 library that is also shipped in nx-X11/lib/.
|
||||
*
|
||||
* When using <X11/extensions/Xdamage.h> instead for inclusion in
|
||||
* nxcompshad, it will attempt pulling in the <X11/extensions/Xfixes.h>
|
||||
* header which in turn will include <X11/Xlib.h>. However, the headers of
|
||||
* the same name from <nx-X11/...> should be used instead.
|
||||
*
|
||||
* FIXME: Once the nxagent Xserver starts using libX11 from X.Org, this
|
||||
* hack can be removed.
|
||||
*
|
||||
* 2015/06/26, Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _XDAMAGE_H_
|
||||
#define _XDAMAGE_H_
|
||||
|
||||
#include <X11/extensions/damagewire.h>
|
||||
#include <nx-X11/Xfuncproto.h>
|
||||
|
||||
/* from <X11/extensions/Xfixes.h> */
|
||||
typedef XID XserverRegion;
|
||||
|
||||
#define XDAMAGE_1_1_INTERFACE
|
||||
|
||||
typedef XID Damage;
|
||||
|
||||
typedef struct {
|
||||
int type; /* event base */
|
||||
unsigned long serial;
|
||||
Bool send_event;
|
||||
Display *display;
|
||||
Drawable drawable;
|
||||
Damage damage;
|
||||
int level;
|
||||
Bool more; /* more events will be delivered immediately */
|
||||
Time timestamp;
|
||||
XRectangle area;
|
||||
XRectangle geometry;
|
||||
} XDamageNotifyEvent;
|
||||
|
||||
_XFUNCPROTOBEGIN
|
||||
|
||||
Bool XDamageQueryExtension (Display *dpy,
|
||||
int *event_base_return,
|
||||
int *error_base_return);
|
||||
|
||||
Status XDamageQueryVersion (Display *dpy,
|
||||
int *major_version_return,
|
||||
int *minor_version_return);
|
||||
|
||||
Damage
|
||||
XDamageCreate (Display *dpy, Drawable drawable, int level);
|
||||
|
||||
void
|
||||
XDamageSubtract (Display *dpy, Damage damage,
|
||||
XserverRegion repair, XserverRegion parts);
|
||||
|
||||
_XFUNCPROTOEND
|
||||
|
||||
#endif /* _XDAMAGE_H_ */
|
||||
80
nxcompshad/src/X11/include/Xrandr_nxcompshad.h
Normal file
80
nxcompshad/src/X11/include/Xrandr_nxcompshad.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright © 2000 Compaq Computer Corporation, Inc.
|
||||
* Copyright © 2002 Hewlett-Packard Company, Inc.
|
||||
* Copyright © 2006 Intel Corporation
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
|
||||
* Keith Packard, Intel Corporation
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is a reduced version of the header file of
|
||||
* <X11/extensions/Xrandr.h>
|
||||
*
|
||||
* This copy of code has been introduced to allow a clear namespace
|
||||
* separation between <X11/...> and <nx-X11/...> header files.
|
||||
*
|
||||
* This version of the Xrandr library header file only contains symbols
|
||||
* required by nxcompshad and strictly avoids indirectly including
|
||||
* from an X11 library that is also shipped in nx-X11/lib/.
|
||||
*
|
||||
* When using <X11/extensions/Xrandr.h> instead for inclusion in
|
||||
* nxcompshad, it will attempt pulling in the <X11/extensions/Xrender.h>
|
||||
* header which in turn will include <X11/Xlib.h>. However, the headers of
|
||||
* the same name from <nx-X11/...> should be used instead.
|
||||
*
|
||||
* FIXME: Once the nxagent Xserver starts using libXrender from X.Org, this
|
||||
* hack can be removed.
|
||||
*
|
||||
* 2015/06/26, Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
|
||||
*/
|
||||
|
||||
#ifndef _XRANDR_H_
|
||||
#define _XRANDR_H_
|
||||
|
||||
/* from <X11/extensions/randr.h> */
|
||||
#define RRScreenChangeNotify 0
|
||||
#define RRScreenChangeNotifyMask (1L << 0)
|
||||
|
||||
#include <X11/Xfuncproto.h>
|
||||
|
||||
_XFUNCPROTOBEGIN
|
||||
|
||||
/* internal representation is private to the library */
|
||||
typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
|
||||
|
||||
Bool XRRQueryExtension (Display *dpy,
|
||||
int *event_base_return,
|
||||
int *error_base_return);
|
||||
|
||||
void XRRSelectInput(Display *dpy, Window window, int mask);
|
||||
|
||||
|
||||
/*
|
||||
* intended to take RRScreenChangeNotify, or
|
||||
* ConfigureNotify (on the root window)
|
||||
* returns 1 if it is an event type it understands, 0 if not
|
||||
*/
|
||||
int XRRUpdateConfiguration(XEvent *event);
|
||||
_XFUNCPROTOEND
|
||||
|
||||
#endif /* _XRANDR_H_ */
|
||||
Reference in New Issue
Block a user