summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-08-10 23:38:28 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-08-10 23:38:28 +0000
commit47ee068d2c202c4006d5a916fb2cfa4d4071230d (patch)
treeca18f62ea3a5300b4e94f757208abf47fecad42f
parentdb9d51186b28bc2252032458b433ba5f8d1972bc (diff)
downloadtdelibs-47ee068d2c202c4006d5a916fb2cfa4d4071230d.tar.gz
tdelibs-47ee068d2c202c4006d5a916fb2cfa4d4071230d.zip
Add composition manager detection and support to Trinity
This adds the methods required to make transparent widgets via alpha blending a reality An additional widget class may be coming shortly git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1246265 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
-rw-r--r--CMakeLists.txt6
-rw-r--r--config.h.cmake3
-rw-r--r--kdecore/CMakeLists.txt10
-rw-r--r--kdecore/kapplication.cpp215
-rw-r--r--kdecore/kapplication.h89
5 files changed, 316 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3fd7da01c..941411514 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -548,6 +548,12 @@ if( XRENDER_FOUND )
set( HAVE_XRENDER 1 )
endif( XRENDER_FOUND )
+##### check for xcomposite #########################
+
+pkg_search_module( XCOMPOSITE xcomposite )
+if( XCOMPOSITE_FOUND )
+ set( HAVE_XCOMPOSITE 1 )
+endif( XCOMPOSITE_FOUND )
##### check for libxml-2.0 ######################
diff --git a/config.h.cmake b/config.h.cmake
index 719e324df..99562b3a6 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -665,6 +665,9 @@
/* Defined if your system has XRender support */
#cmakedefine HAVE_XRENDER 1
+/* Defined if your system has XComposite support */
+#cmakedefine HAVE_XCOMPOSITE 1
+
/* Define to 1 if you have the `_getpty' function. */
#cmakedefine HAVE__GETPTY 1
diff --git a/kdecore/CMakeLists.txt b/kdecore/CMakeLists.txt
index 3e37ed20c..efe2c8f3c 100644
--- a/kdecore/CMakeLists.txt
+++ b/kdecore/CMakeLists.txt
@@ -129,7 +129,7 @@ tde_add_library( ${target} SHARED AUTOMOC
SOURCES ${${target}_SRCS}
VERSION 4.2.0
EMBED kdecorenetwork-static
- LINK ltdlc-static ${KDESVGICONS} DCOP-shared kdefx-shared ${ZLIB_LIBRARIES} ${LIBIDN_LIBRARIES} ICE SM
+ LINK ltdlc-static ${KDESVGICONS} DCOP-shared kdefx-shared ${ZLIB_LIBRARIES} ${LIBIDN_LIBRARIES} ${XCOMPOSITE_LIBRARIES} ICE SM
DEPENDENCIES dcopidl dcopidl2cpp
DESTINATION ${LIB_INSTALL_DIR}
)
@@ -199,3 +199,11 @@ tde_add_executable(kgrantpty SETUID
SOURCES kgrantpty.c
DESTINATION ${BIN_INSTALL_DIR}
)
+
+##### kdetcompmgr #################################
+
+tde_add_executable( kdetcompmgr
+ SOURCES kdetcompmgr.cpp
+ LINK kdecore-shared
+ DESTINATION ${BIN_INSTALL_DIR}
+)
diff --git a/kdecore/kapplication.cpp b/kdecore/kapplication.cpp
index 292105835..7986079f4 100644
--- a/kdecore/kapplication.cpp
+++ b/kdecore/kapplication.cpp
@@ -125,6 +125,11 @@
#ifdef Q_WS_X11
#include <X11/Xlib.h>
+#ifdef COMPOSITE
+#include <X11/extensions/Xrender.h>
+#include <X11/extensions/Xcomposite.h>
+#include <dlfcn.h>
+#endif
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/SM/SMlib.h>
@@ -175,6 +180,18 @@ static Atom atom_NetSupported;
static Atom kde_xdnd_drop;
#endif
+#ifdef Q_WS_X11
+static int composite_event, composite_error, composite_opcode;
+static bool x11_composite_error_generated;
+static int x11_error(Display *dpy, XErrorEvent *ev) {
+ if (ev->request_code == composite_opcode && ev->minor_code == X_CompositeRedirectSubwindows)
+ {
+ x11_composite_error_generated = true;
+ return 0;
+ }
+}
+#endif
+
// duplicated from patched Qt, so that there won't be unresolved symbols if Qt gets
// replaced by unpatched one
KDECORE_EXPORT bool qt_qclipboard_bailout_hack = false;
@@ -602,6 +619,7 @@ KApplication::KApplication( int& argc, char** argv, const TQCString& rAppName,
TQApplication( argc, argv, GUIenabled ), KInstance(rAppName),
#ifdef Q_WS_X11
display(0L),
+ argb_visual(false),
#endif
d (new KApplicationPrivate())
{
@@ -622,11 +640,11 @@ KApplication::KApplication( int& argc, char** argv, const TQCString& rAppName,
}
KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
- TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
- TRUE ), // Qt4 requires that there always be a GUI
+ TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), TRUE ), // Qt4 requires that there always be a GUI
KInstance( KCmdLineArgs::about),
#ifdef Q_WS_X11
display(0L),
+ argb_visual(false),
#endif
d (new KApplicationPrivate)
{
@@ -648,9 +666,11 @@ KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
bool allowStyles ) :
TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
- visual, colormap ),
+ visual?visual:getX11RGBAVisual(dpy), colormap?colormap:getX11RGBAColormap(dpy) ),
KInstance( KCmdLineArgs::about), display(0L), d (new KApplicationPrivate)
{
+ if ((visual) && (colormap))
+ getX11RGBAInformation(dpy);
aIconPixmap.pm.icon = 0L;
aIconPixmap.pm.miniIcon = 0L;
read_app_startup_id();
@@ -665,9 +685,11 @@ KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap
KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
bool allowStyles, KInstance * _instance ) :
TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
- visual, colormap ),
+ visual?visual:getX11RGBAVisual(dpy), colormap?colormap:getX11RGBAColormap(dpy) ),
KInstance( _instance ), display(0L), d (new KApplicationPrivate)
{
+ if ((visual) && (colormap))
+ getX11RGBAInformation(dpy);
aIconPixmap.pm.icon = 0L;
aIconPixmap.pm.miniIcon = 0L;
read_app_startup_id();
@@ -684,6 +706,7 @@ KApplication::KApplication( bool allowStyles, bool GUIenabled, KInstance* _insta
TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
GUIenabled ),
KInstance( _instance ),
+ argb_visual(false),
#ifdef Q_WS_X11
display(0L),
#endif
@@ -708,6 +731,7 @@ KApplication::KApplication(Display *display, int& argc, char** argv, const TQCSt
bool allowStyles, bool GUIenabled ) :
TQApplication( display ), KInstance(rAppName),
display(0L),
+ argb_visual(false),
d (new KApplicationPrivate())
{
aIconPixmap.pm.icon = 0L;
@@ -1718,7 +1742,190 @@ public:
};
#endif
+#if defined(Q_WS_X11) && defined(COMPOSITE)
+bool KApplication::isCompositionManagerAvailable() {
+ KConfigGroup pConfig (KGlobal::config(), "General");
+ return pConfig.readBoolEntry("compositingManagerAvailable", false);
+
+return false;
+}
+
+bool KApplication::detectCompositionManagerAvailable(bool force_available) {
+ bool compositing_manager_available;
+ if (force_available) {
+ compositing_manager_available = true;
+ }
+ else {
+ // See if compositing has been enabled
+ KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
+ char *displayname = 0;
+ if ( qtargs->isSet("display"))
+ displayname = qtargs->getOption( "display" ).data();
+
+ Display *dpy = XOpenDisplay( displayname );
+
+ x11_composite_error_generated = false;
+ compositing_manager_available = false;
+ XSetErrorHandler(x11_error);
+ if (!XQueryExtension (dpy, COMPOSITE_NAME, &composite_opcode, &composite_event, &composite_error)) {
+ XSetErrorHandler(NULL);
+ compositing_manager_available = false;
+ }
+ else {
+ Window root_window = XDefaultRootWindow(dpy);
+ XCompositeRedirectSubwindows(dpy, root_window, CompositeRedirectManual);
+ XSync(dpy, false);
+ if (x11_composite_error_generated == true) {
+ compositing_manager_available = true;
+ }
+ else {
+ XCompositeUnredirectSubwindows(dpy, root_window, CompositeRedirectManual);
+ compositing_manager_available = false;
+ }
+ XSetErrorHandler(NULL);
+ XCloseDisplay(dpy);
+ }
+ }
+
+ KConfigGroup pConfig (KGlobal::config(), "General");
+ bool cmanager_enabled = pConfig.readBoolEntry("compositingManagerAvailable", false);
+ if (cmanager_enabled != compositing_manager_available) {
+ pConfig.writeEntry("compositingManagerAvailable", compositing_manager_available, true, true);
+ }
+ pConfig.sync();
+
+ return compositing_manager_available;
+}
+
+Display* KApplication::openX11RGBADisplay() {
+ KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
+ char *displayname = 0;
+ if ( qtargs->isSet("display"))
+ displayname = qtargs->getOption( "display" ).data();
+
+ Display *dpy = XOpenDisplay( displayname );
+ return dpy;
+}
+
+Qt::HANDLE KApplication::getX11RGBAVisual(Display *dpy) {
+ getX11RGBAInformation(dpy);
+ return argb_x11_visual;
+}
+
+Qt::HANDLE KApplication::getX11RGBAColormap(Display *dpy) {
+ getX11RGBAInformation(dpy);
+ return argb_x11_colormap;
+}
+
+bool KApplication::isX11CompositionAvailable() {
+ return argb_visual & isCompositionManagerAvailable();
+}
+
+void KApplication::getX11RGBAInformation(Display *dpy) {
+ if ( !dpy ) {
+ argb_visual = false;
+ return;
+ }
+
+ int screen = DefaultScreen( dpy );
+ Colormap colormap = 0;
+ Visual *visual = 0;
+ int event_base, error_base;
+
+ if ( XRenderQueryExtension( dpy, &event_base, &error_base ) ) {
+ int nvi;
+ XVisualInfo templ;
+ templ.screen = screen;
+ templ.depth = 32;
+ templ.c_class = TrueColor;
+ XVisualInfo *xvi = XGetVisualInfo( dpy, VisualScreenMask | VisualDepthMask
+ | VisualClassMask, &templ, &nvi );
+
+ for ( int i = 0; i < nvi; i++ ) {
+ XRenderPictFormat *format = XRenderFindVisualFormat( dpy, xvi[i].visual );
+ if ( format->type == PictTypeDirect && format->direct.alphaMask ) {
+ visual = xvi[i].visual;
+ colormap = XCreateColormap( dpy, RootWindow( dpy, screen ), visual, AllocNone );
+ kdDebug() << "found visual with alpha support" << endl;
+ argb_visual = true;
+ break;
+ }
+ }
+ }
+
+ if( argb_visual ) {
+ argb_x11_visual = Qt::HANDLE( visual );
+ argb_x11_colormap = Qt::HANDLE( colormap );
+ argb_visual = true;
+ return;
+ }
+ argb_visual = false;
+ return;
+}
+
+KApplication KApplication::KARGBApplicationObject( bool allowStyles ) {
+ KCmdLineArgs *qtargs = KCmdLineArgs::parsedArgs("qt");
+ bool argb_visual_available = false;
+ char *display = 0;
+ if ( qtargs->isSet("display"))
+ display = qtargs->getOption( "display" ).data();
+
+ Display *dpy = XOpenDisplay( display );
+ if ( !dpy ) {
+ kdError() << "cannot connect to X server " << display << endl;
+ exit( 1 );
+ }
+
+ int screen = DefaultScreen( dpy );
+ Colormap colormap = 0;
+ Visual *visual = 0;
+ int event_base, error_base;
+
+ if ( XRenderQueryExtension( dpy, &event_base, &error_base ) ) {
+ int nvi;
+ XVisualInfo templ;
+ templ.screen = screen;
+ templ.depth = 32;
+ templ.c_class = TrueColor;
+ XVisualInfo *xvi = XGetVisualInfo( dpy, VisualScreenMask | VisualDepthMask
+ | VisualClassMask, &templ, &nvi );
+
+ for ( int i = 0; i < nvi; i++ ) {
+ XRenderPictFormat *format = XRenderFindVisualFormat( dpy, xvi[i].visual );
+ if ( format->type == PictTypeDirect && format->direct.alphaMask ) {
+ visual = xvi[i].visual;
+ colormap = XCreateColormap( dpy, RootWindow( dpy, screen ), visual, AllocNone );
+ kdDebug() << "found visual with alpha support" << endl;
+ argb_visual_available = true;
+ break;
+ }
+ }
+ }
+
+ if( argb_visual_available ) {
+ return KApplication( dpy, Qt::HANDLE( visual ), Qt::HANDLE( colormap ), allowStyles );
+ }
+ else {
+ return KApplication(allowStyles, true);
+ }
+}
+#else
+Qt::HANDLE KApplication::getX11RGBAVisual(char *display) {
+ return 0;
+}
+
+Qt::HANDLE KApplication::getX11RGBAColormap(char *display) {
+ return 0;
+}
+bool KApplication::isX11CompositionAvailable() {
+ return false;
+}
+
+KApplication KApplication::KARGBApplication( bool allowStyles ) {
+ return KApplication::KApplication(allowStyles, true);
+}
+#endif
static bool kapp_block_user_input = false;
diff --git a/kdecore/kapplication.h b/kdecore/kapplication.h
index 93820b68d..00a6429da 100644
--- a/kdecore/kapplication.h
+++ b/kdecore/kapplication.h
@@ -48,6 +48,8 @@ class KSessionManaged;
class KStyle;
class KURL;
+#define COMPOSITE // [FIXME] Autodetect composition support
+
#define kapp KApplication::kApplication()
class KApplicationPrivate;
@@ -113,6 +115,10 @@ public:
* This constructor takes aboutData and command line
* arguments from KCmdLineArgs.
*
+ * If ARGB (transparent) widgets are to be used in your application,
+ * please use KARGBApplication(new object name) or
+ * KARGBApplication(new object name, allow_styles) instead of KApplication(...).
+ *
* @param allowStyles Set to false to disable the loading on plugin based
* styles. This is only useful to applications that do not display a GUI
* normally. If you do create an application with @p allowStyles set to false
@@ -860,15 +866,88 @@ public:
*/
TQString checkRecoverFile( const TQString& pFilename, bool& bRecover ) const;
-#ifdef Q_WS_X11
+#if defined(Q_WS_X11) && defined(COMPOSITE)
/**
+ * @internal
* Get the X11 display
* @return the X11 Display
*/
- Display *getDisplay() { return display; }
+ Display *getDisplay() { return display; }
+
+ /**
+ * @internal
+ * Gets X11 composition information
+ */
+ void getX11RGBAInformation(Display *dpy);
+
+ /**
+ * Gets the availability of a composition manager such as kompmgr
+ * Note that at least one application must have called detectCompositionManagerAvailable
+ * while the current X display was active in order for this method to return valid results.
+ * @see detectCompositionManagerAvailable()
+ * @return whether the composition manager is enabled
+ */
+ static bool isCompositionManagerAvailable();
+
+ /**
+ * Detects the availability of a composition manager such as kompmgr
+ * Note that calling this method will probably cause the screen to flicker.
+ * @see isCompositionManagerAvailable()
+ * @param force_available If set, force TDE to assume a composition manager is available
+ * @return whether the composition manager is enabled
+ */
+ bool detectCompositionManagerAvailable(bool force_available=false);
+
+ /**
+ * @internal
+ * Opens an X11 display and returns the handle to it
+ * @return the X11 display handle
+ */
+ Display *openX11RGBADisplay();
#endif
/**
+ * @internal
+ * Creates a default KApplication with transparency support
+ * (if available)
+ */
+ static KApplication KARGBApplicationObject( bool allowStyles=true );
+
+ #define KARGBApplication(objectname, ...) const KApplication &__kapplication_internal_app = KApplication::KARGBApplicationObject(__VA_ARGS__); KApplication &objectname = const_cast<KApplication&>(__kapplication_internal_app);
+
+ /**
+ * Returns the X11 display visual
+ *
+ * @return A pointer to the X11 display visual
+ */
+ Qt::HANDLE getX11RGBAVisual(Display *dpy);
+
+ /**
+ * Returns the X11 display colormap
+ *
+ * @return An X11 display colormap object
+ */
+ Qt::HANDLE getX11RGBAColormap(Display *dpy);
+
+ /**
+ * Returns whether or not X11 composition is available
+ *
+ * You must first call getX11RGBAInformation()
+ *
+ * Note that getX11RGBAInformation() has already
+ * been called if you used the default KApplication
+ * constructor.
+ *
+ * Additionally, at least one application must have called
+ * detectCompositionManagerAvailable while the current X
+ * display was active in order for this method to return
+ * valid results.
+ *
+ * @return true if composition is available
+ */
+ bool isX11CompositionAvailable();
+
+ /**
* Enables style plugins.
*
* This is useful only to applications that normally
@@ -1201,6 +1280,12 @@ private:
void dcopClientPostInit();
void initUrlActionRestrictions();
+ bool argb_visual;
+#if defined(Q_WS_X11) && defined(COMPOSITE)
+ Qt::HANDLE argb_x11_visual;
+ Qt::HANDLE argb_x11_colormap;
+#endif
+
public:
/**
* @internal