You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kompose/src/komposeglobal.cpp

376 lines
11 KiB

//
// C++ Implementation: komposeglobal
//
// Description:
//
//
// Author: Hans Oischinger <hans.oischinger@kde-mail.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "komposeglobal.h"
#include "komposetaskmanager.h"
#include "komposeviewmanager.h"
#include "komposesettings.h"
#include "komposesystray.h"
#include <tqtimer.h>
#include <tdeapplication.h>
#include <tdepopupmenu.h>
#include <tdeaction.h>
#include <tdeactioncollection.h>
#include <tdelocale.h>
#include <kiconloader.h>
#include <tdeaccel.h>
#include <kkeydialog.h>
#include <tdeaboutapplication.h>
#include <ksharedpixmap.h>
#include <twinmodule.h>
#include <kdebug.h>
#include <dcopclient.h>
#include <dcopref.h>
#include <dcopclient.h>
// #include those AFTER TQt-includes!
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <Imlib2.h>
#ifdef COMPOSITE
#include <X11/Xatom.h>
#include <X11/extensions/Xcomposite.h>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xrender.h>
#endif
static KomposeGlobal* globalInstance = 0;
Display *disp;
static TQString wallpaperForDesktop(int desktop)
{
return DCOPRef("kdesktop", "KBackgroundIface").call("currentWallpaper", desktop);
}
/**
* KomposeSettings is a singleton
*/
KomposeGlobal* KomposeGlobal::instance()
{
if ( !globalInstance )
{
kdDebug() << "KomposeSettings::instance() - Creating Singleton instance" << endl;
KomposeGlobal *settiglobalInstance = new KomposeGlobal();
}
return globalInstance;
}
KomposeGlobal::KomposeGlobal(TQObject *parent, const char *name)
: TQObject(parent, name),
aboutDialogOpen(0),
hideSystray( false ),
singleShot( false ),
xcomposite(0),
damageEvent(0)
{
globalInstance = this;
twin_module = new KWinModule(); //FIXME: only needed for sharedpixmap :(
currentDesktop = twin_module->currentDesktop();
desktopBgPixmap = new TDESharedPixmap;
connect(desktopBgPixmap, SIGNAL(done(bool)), SLOT(slotDone(bool)));
initSharedPixmaps();
initCompositeExt();
initImlib();
connect( KomposeSettings::instance(), SIGNAL(settingsChanged()), this, SLOT(slotConfigChanged()) );
}
KomposeGlobal::~KomposeGlobal()
{
delete systray;
delete actionCollection;
delete actConfigGlobalShortcuts;
delete actPreferencesDialog;
delete actShowVirtualDesktopView;
delete actShowCurrentDesktopView;
delete actShowWorldView;
delete actAboutDlg;
delete actQuit;
delete desktopBgPixmap;
}
void KomposeGlobal::slotConfigChanged( )
{
initCompositeExt();
}
/**
* Gives us control about when the GUI should appear. Called from outside
* Called from outside as KomposeGlobal is a singleton that can be instantiated at any time
*/
void KomposeGlobal::initGui()
{
// Initialise the Singleton instances
KomposeSettings::instance();
KomposeViewManager::instance();
KomposeTaskManager::instance();
// Create DCop Client
kapp->dcopClient()->setDefaultObject( "KomposeTaskMgrDcopIface" );
initActions();
if ( !hideSystray && !singleShot )
{
// Create systray
systray = new KomposeSysTray();
kapp->setMainWidget( systray );
systray->currentDesktopChanged( currentDesktop );
actionCollection->setWidget( systray );
systray->show();
}
else
kdDebug() << "KomposeGlobal::initGui() - Hiding systray icon" << endl;
if ( singleShot )
{
kdDebug() << "KomposeGlobal::initGui() - SingleShot has been selected" << endl;
KomposeViewManager::instance()->createView();
}
}
/**
* Initialise Kompose's global actions. Retrieve these via the getters in KomposeGlobal
*/
void KomposeGlobal::initActions()
{
actionCollection = new TDEActionCollection( (TQWidget*)0 );
// Actions
actQuit = KStdAction::quit( kapp, SLOT(quit()), actionCollection );
actShowWorldView = new TDEAction(i18n("Komposé (ungrouped)"), "kompose_ungrouped",
0,
KomposeViewManager::instance(), SLOT(createWorldView()),
actionCollection, "showWorldView");
actShowVirtualDesktopView = new TDEAction(i18n("Komposé (grouped by virtual desktops)"), "kompose_grouped_by_virtual_desktop",
0,
KomposeViewManager::instance(), SLOT(createVirtualDesktopView()),
actionCollection, "showVirtualDesktopView");
actShowCurrentDesktopView = new TDEAction(i18n("Komposé (current virtual desktop)"), "kompose_current_virtual_desktop",
0,
KomposeViewManager::instance(), SLOT(createCurrentDesktopView()),
actionCollection, "showCurrentDesktopView");
actPreferencesDialog = KStdAction::preferences( KomposeSettings::instance(), SLOT(showPreferencesDlg()), actionCollection );
actConfigGlobalShortcuts = KStdAction::keyBindings(this, SLOT(showGlobalShortcutsSettingsDialog()),
actionCollection, "options_configure_global_keybinding");
actConfigGlobalShortcuts->setText(i18n("Configure &Global Shortcuts..."));
actAboutDlg = new TDEAction(i18n("About Komposé"), "kompose",
0,
this, SLOT(showAboutDlg()),
actionCollection, "showAboutDlg");
}
void KomposeGlobal::initSharedPixmaps()
{
// Whenever the background pixmap changes we'll have to reload it:
//connect(twin_module, SIGNAL(windowChanged(WId, unsigned int)), SLOT(desktopChanged(WId, unsigned int)));
connect(twin_module, SIGNAL(currentDesktopChanged(int)), SLOT(slotDesktopChanged(int)));
connect(kapp, SIGNAL(backgroundChanged(int)), SLOT(slotBackgroundChanged(int)));
enablePixmapExports();
// When Kompose is started by session management the bg shared pixmap may not be available yet
if (!desktopBgPixmap->isAvailable( pixmapName(1) ))
{
tqWarning("KomposeGlobal::initSharedPixmaps() - Pixmap not available");
//enablePixmapExports();
TQTimer::singleShot( 1000, this, SLOT( initSharedPixmaps() ) );
//initSharedPixmaps();
//return;
}
kdDebug() << "KomposeGlobal::initSharedPixmaps()" << endl;
refreshSharedPixmaps();
}
void KomposeGlobal::slotDesktopChanged(int desktop)
{
systray->currentDesktopChanged( desktop );
if (desktop != -2)
{
// -2 is for manual loading, everything else enables the following checks:
if (wallpaperForDesktop(currentDesktop) == wallpaperForDesktop(desktop) &&
!wallpaperForDesktop(currentDesktop).isNull())
return;
if ( !(pixmapName(currentDesktop) != pixmapName(desktop)) )
return;
}
currentDesktop = twin_module->currentDesktop();
refreshSharedPixmaps();
}
void KomposeGlobal::slotBackgroundChanged(int)
{
refreshSharedPixmaps();
}
void KomposeGlobal::refreshSharedPixmaps()
{
desktopBgPixmap->loadFromShared( pixmapName(currentDesktop) );
}
TQString KomposeGlobal::pixmapName(int desk)
{
// To simplify things we take the background of the first desktop
TQString pattern = TQString("DESKTOP%1");
int screen_number = DefaultScreen(tqt_xdisplay());
if (screen_number)
{
pattern = TQString("SCREEN%1-DESKTOP").arg(screen_number) + "%1";
}
return pattern.arg( desk );
}
void KomposeGlobal::slotDone(bool success)
{
if (!success)
{
kdDebug() << "KomposeGlobal::slotDone() - loading of desktop background failed.\n" << endl;
//TQTimer::singleShot( 1000, this, SLOT( initSharedPixmaps() ) );
}
}
void KomposeGlobal::enablePixmapExports()
{
#ifdef Q_WS_X11
kdDebug() << "KomposeGlobal::enablePixmapExports()" << endl;
DCOPClient *client = kapp->dcopClient();
if (!client->isAttached())
client->attach();
TQByteArray data;
TQDataStream args( data, IO_WriteOnly );
args << 1;
TQCString appname( "kdesktop" );
int screen_number = DefaultScreen(tqt_xdisplay());
if ( screen_number )
appname.sprintf("kdesktop-screen-%d", screen_number );
client->send( appname, "KBackgroundIface", "setExport(int)", data );
#endif
}
/**
* Show Global Shortcuts Dialog for Kompose
*/
void KomposeGlobal::showGlobalShortcutsSettingsDialog()
{
KKeyDialog::configure( KomposeSettings::instance()->getGlobalAccel() );
KomposeSettings::instance()->writeConfig();
}
/**
* Show About Dialog for Kompose
*/
void KomposeGlobal::showAboutDlg()
{
aboutDialogOpen = true;
TDEAboutApplication* kabout = new TDEAboutApplication();
kabout->exec();
delete kabout;
aboutDialogOpen = false;
}
/**
* Initialise Imlib2.
* Should only be called by the KomposeGlobal constructor
*/
void KomposeGlobal::initImlib()
{
Display *disp;
Visual *vis;
Colormap cm;
//int screen;
disp = TQPaintDevice::x11AppDisplay();
vis = DefaultVisual(disp, DefaultScreen(disp));
cm = DefaultColormap(disp, DefaultScreen(disp));
// context = imlib_context_new();
// imlib_context_push(d->context);
imlib_set_cache_size(0);
imlib_set_color_usage(128);
imlib_context_set_dither(1);
imlib_context_set_display(disp);
imlib_context_set_visual(vis);
imlib_context_set_colormap(cm);
kdDebug() << "KomposeGlobal::initImlib() - Imlib2 support enabled." << endl;
}
/**
* Detect and initialise the XComposite extension.
* Should only be called by the KomposeGlobal constructor
*/
void KomposeGlobal::initCompositeExt()
{
if ( !(!xcomposite && KomposeSettings::instance()->getUseComposite()) )
return;
xcomposite = false;
#ifdef COMPOSITE
// Check for XComposite
Display *dpy = TQPaintDevice::x11AppDisplay();
int event_base, error_base;
if ( XCompositeQueryExtension( dpy, &event_base, &error_base ) )
{
// If we get here the server supports the extension
xcomposite = true;
// XComposite version check
int major = 1, minor = 1; // The highest version we support
XCompositeQueryVersion( dpy, &major, &minor );
// major and minor will now contain the version the server supports.
if (!(major > 0 || minor >= 2))
{
kdDebug() << "KomposeGlobal::initCompositeExt() - XComposite doesn't allow NamePixmap requests! - Disabling XComposite support" << endl;
// TODO: create a namewindowpixbool to make it work with composite 0.1
xcomposite = false;
}
// XRender version check
int renderEvent, renderError;
if (!XRenderQueryExtension (dpy, &renderEvent, &renderError))
{
kdDebug() << "KomposeGlobal::initCompositeExt() - XRender not available! - Disabling XComposite support" << endl;
}
//XDamage version check
//int damageEvent, damageError; // The event base is important here
if (!XDamageQueryExtension( dpy, &damageEvent, &damageError ))
{
kdDebug() << "KomposeGlobal::initCompositeExt() - XDamage is not available! - Disabling XComposite support" << endl;
xcomposite = false;
}
}
else
xcomposite = false;
#endif
if ( xcomposite )
kdDebug() << "KomposeGlobal::initCompositeExt() - XComposite extension found and enabled." << endl;
}
#include "komposeglobal.moc"