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
v3.5.13-sru
tpearson 13 years ago
parent db9d51186b
commit 47ee068d2c

@ -548,6 +548,12 @@ if( XRENDER_FOUND )
set( HAVE_XRENDER 1 ) set( HAVE_XRENDER 1 )
endif( XRENDER_FOUND ) 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 ###################### ##### check for libxml-2.0 ######################

@ -665,6 +665,9 @@
/* Defined if your system has XRender support */ /* Defined if your system has XRender support */
#cmakedefine HAVE_XRENDER 1 #cmakedefine HAVE_XRENDER 1
/* Defined if your system has XComposite support */
#cmakedefine HAVE_XCOMPOSITE 1
/* Define to 1 if you have the `_getpty' function. */ /* Define to 1 if you have the `_getpty' function. */
#cmakedefine HAVE__GETPTY 1 #cmakedefine HAVE__GETPTY 1

@ -129,7 +129,7 @@ tde_add_library( ${target} SHARED AUTOMOC
SOURCES ${${target}_SRCS} SOURCES ${${target}_SRCS}
VERSION 4.2.0 VERSION 4.2.0
EMBED kdecorenetwork-static 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 DEPENDENCIES dcopidl dcopidl2cpp
DESTINATION ${LIB_INSTALL_DIR} DESTINATION ${LIB_INSTALL_DIR}
) )
@ -199,3 +199,11 @@ tde_add_executable(kgrantpty SETUID
SOURCES kgrantpty.c SOURCES kgrantpty.c
DESTINATION ${BIN_INSTALL_DIR} DESTINATION ${BIN_INSTALL_DIR}
) )
##### kdetcompmgr #################################
tde_add_executable( kdetcompmgr
SOURCES kdetcompmgr.cpp
LINK kdecore-shared
DESTINATION ${BIN_INSTALL_DIR}
)

@ -125,6 +125,11 @@
#ifdef Q_WS_X11 #ifdef Q_WS_X11
#include <X11/Xlib.h> #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/Xutil.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/SM/SMlib.h> #include <X11/SM/SMlib.h>
@ -175,6 +180,18 @@ static Atom atom_NetSupported;
static Atom kde_xdnd_drop; static Atom kde_xdnd_drop;
#endif #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 // duplicated from patched Qt, so that there won't be unresolved symbols if Qt gets
// replaced by unpatched one // replaced by unpatched one
KDECORE_EXPORT bool qt_qclipboard_bailout_hack = false; 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), TQApplication( argc, argv, GUIenabled ), KInstance(rAppName),
#ifdef Q_WS_X11 #ifdef Q_WS_X11
display(0L), display(0L),
argb_visual(false),
#endif #endif
d (new KApplicationPrivate()) d (new KApplicationPrivate())
{ {
@ -622,11 +640,11 @@ KApplication::KApplication( int& argc, char** argv, const TQCString& rAppName,
} }
KApplication::KApplication( bool allowStyles, bool GUIenabled ) : KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), TRUE ), // Qt4 requires that there always be a GUI
TRUE ), // Qt4 requires that there always be a GUI
KInstance( KCmdLineArgs::about), KInstance( KCmdLineArgs::about),
#ifdef Q_WS_X11 #ifdef Q_WS_X11
display(0L), display(0L),
argb_visual(false),
#endif #endif
d (new KApplicationPrivate) d (new KApplicationPrivate)
{ {
@ -648,9 +666,11 @@ KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap, KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
bool allowStyles ) : bool allowStyles ) :
TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), 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) KInstance( KCmdLineArgs::about), display(0L), d (new KApplicationPrivate)
{ {
if ((visual) && (colormap))
getX11RGBAInformation(dpy);
aIconPixmap.pm.icon = 0L; aIconPixmap.pm.icon = 0L;
aIconPixmap.pm.miniIcon = 0L; aIconPixmap.pm.miniIcon = 0L;
read_app_startup_id(); 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, KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
bool allowStyles, KInstance * _instance ) : bool allowStyles, KInstance * _instance ) :
TQApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), 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) KInstance( _instance ), display(0L), d (new KApplicationPrivate)
{ {
if ((visual) && (colormap))
getX11RGBAInformation(dpy);
aIconPixmap.pm.icon = 0L; aIconPixmap.pm.icon = 0L;
aIconPixmap.pm.miniIcon = 0L; aIconPixmap.pm.miniIcon = 0L;
read_app_startup_id(); read_app_startup_id();
@ -684,6 +706,7 @@ KApplication::KApplication( bool allowStyles, bool GUIenabled, KInstance* _insta
TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(), TQApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
GUIenabled ), GUIenabled ),
KInstance( _instance ), KInstance( _instance ),
argb_visual(false),
#ifdef Q_WS_X11 #ifdef Q_WS_X11
display(0L), display(0L),
#endif #endif
@ -708,6 +731,7 @@ KApplication::KApplication(Display *display, int& argc, char** argv, const TQCSt
bool allowStyles, bool GUIenabled ) : bool allowStyles, bool GUIenabled ) :
TQApplication( display ), KInstance(rAppName), TQApplication( display ), KInstance(rAppName),
display(0L), display(0L),
argb_visual(false),
d (new KApplicationPrivate()) d (new KApplicationPrivate())
{ {
aIconPixmap.pm.icon = 0L; aIconPixmap.pm.icon = 0L;
@ -1718,7 +1742,190 @@ public:
}; };
#endif #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; static bool kapp_block_user_input = false;

@ -48,6 +48,8 @@ class KSessionManaged;
class KStyle; class KStyle;
class KURL; class KURL;
#define COMPOSITE // [FIXME] Autodetect composition support
#define kapp KApplication::kApplication() #define kapp KApplication::kApplication()
class KApplicationPrivate; class KApplicationPrivate;
@ -113,6 +115,10 @@ public:
* This constructor takes aboutData and command line * This constructor takes aboutData and command line
* arguments from KCmdLineArgs. * 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 * @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 * 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 * normally. If you do create an application with @p allowStyles set to false
@ -860,14 +866,87 @@ public:
*/ */
TQString checkRecoverFile( const TQString& pFilename, bool& bRecover ) const; TQString checkRecoverFile( const TQString& pFilename, bool& bRecover ) const;
#ifdef Q_WS_X11 #if defined(Q_WS_X11) && defined(COMPOSITE)
/** /**
* @internal
* Get the X11 display * Get the X11 display
* @return 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 #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. * Enables style plugins.
* *
@ -1201,6 +1280,12 @@ private:
void dcopClientPostInit(); void dcopClientPostInit();
void initUrlActionRestrictions(); void initUrlActionRestrictions();
bool argb_visual;
#if defined(Q_WS_X11) && defined(COMPOSITE)
Qt::HANDLE argb_x11_visual;
Qt::HANDLE argb_x11_colormap;
#endif
public: public:
/** /**
* @internal * @internal

Loading…
Cancel
Save