summaryrefslogtreecommitdiffstats
path: root/src/screen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen.cpp')
-rw-r--r--src/screen.cpp721
1 files changed, 721 insertions, 0 deletions
diff --git a/src/screen.cpp b/src/screen.cpp
new file mode 100644
index 0000000..0f58d0f
--- /dev/null
+++ b/src/screen.cpp
@@ -0,0 +1,721 @@
+/***************************************************************************
+ * Copyright (C) 2004-2006 by Danny Kukawka *
+ * <dkukawka@suse.de>, <danny.kukawka@web.de> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of version 2 of the GNU General Public License *
+ * as published by the Free Software Foundation. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/*! \file screen.cpp
+ * All here displayed file members of screen.cpp are related to operations with the
+ * XSreensaver/XServer. This functions are basic/low level operations. They are
+ * inspired, partly copied and modified from <a href="http://www.mplayerhq.hu/">MPlayer</a>
+ * code (1.05pre). Thanks for the inspiration. \n \n
+ * All 'higher level' class members of the class screen can be found here: \ref screen
+ * \brief In this file can be found all screensaver related code.
+ * \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de>
+ * \date 2004 - 2006
+ */
+
+ // own headers
+#include "screen.h"
+#include "kpowersave_debug.h"
+
+/* needed for lXext C library linkage */
+extern "C" {
+ #include <X11/Xproto.h>
+ #include <X11/extensions/dpms.h>
+ #include <X11/extensions/XTest.h>
+}
+
+// KDE Headers
+#include <kprocess.h>
+
+/*! The default constructor of the class screen */
+screen::screen() {
+ kdDebugFuncIn(trace);
+
+ xscreensaver_lock = NULL;
+ xscreensaver_reset = NULL;
+ gnomescreensaver_lock = NULL;
+ gnomeScreensaverCheck = NULL;
+ xlock = NULL;
+
+ got_XScreensaver = false;
+ checkDPMSStatus();
+ check_xscreensaver_timer_runs = false;
+
+ SCREENSAVER_STATUS = -1;
+ screen_save_dcop_ref = DCOPRef( "kdesktop", "KScreensaverIface" );
+
+ check_xscreensaver_timer = new QTimer( this );
+ connect( check_xscreensaver_timer, SIGNAL(timeout()), this, SLOT(xscreensaver_ping() ));
+
+ SCREENSAVER_STATUS = checkScreenSaverStatus();
+ kdDebugFuncOut(trace);
+}
+
+/*! The default destructor of the class screen */
+screen::~screen() {
+ kdDebugFuncIn(trace);
+}
+
+/*!
+* To enable/disable the KScreensaver/Xscreensaver.
+* \param enable true: activate/enable screensaver / false: deactivate/disable screensacer
+* \return the result of try to set the screensaver
+* \retval true if screensaver set correct
+* \retval false if there is a error
+*/
+bool screen::setScreenSaver(bool enable){
+ kdDebugFuncIn(trace);
+
+ if(SCREENSAVER_STATUS == -1) SCREENSAVER_STATUS = checkScreenSaverStatus();
+ if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){
+ screen_save_dcop_ref.send( "enable", enable);
+ kdDebugFuncOut(trace);
+ return true;
+ }
+
+ if(SCREENSAVER_STATUS == 11 || SCREENSAVER_STATUS == 10){
+ if(enable) {
+ check_xscreensaver_timer->stop();
+ check_xscreensaver_timer_runs = false;
+ }
+ else {
+ check_xscreensaver_timer->start( xScreenSaver_timer_interval );
+ check_xscreensaver_timer_runs = true;
+ }
+ kdDebugFuncOut(trace);
+ return true;
+ } else {
+ kdDebugFuncOut(trace);
+ return false;
+ }
+}
+
+
+/* * * * *
+ * this inspired, partly copied and modified from MPlayer Code (1.05pre)
+ * START Section
+ */
+//! to handle information about wrong XWindows
+/*!
+* This integer represent information about XWindows.
+* - got_badwindow == True: if the searched Window is wrong or if there is a problem/error
+* - got_badwindow == False: if there is no problem/error
+*/
+static int got_badwindow;
+//! ErrorHandler
+/*! Errorhandler for all X-Server related operations */
+static XErrorHandler defaultHandler;
+
+//! to find/handle bad XWindows / XSetErrorHandler
+/*!
+* This function is involved by the search for the window of the Xscreensaver. By this
+* function we seperate the BadWindow-error and set \ref got_badwindow if we get a BadWindow.
+* For more information take a look at the XServer Documentation!
+* \param dpy pointer to the active X-Display
+* \param error pointer to XErrorEvent
+* \return a info about a window-error
+* \retval 0 if the window is a BadWindow as a integer
+* \retval n the errorID/XErrorHandler if there is a error != BadWindow
+*/
+static int badwindow_handler(Display * dpy, XErrorEvent * error) {
+ if (error->error_code != BadWindow)
+ return (*defaultHandler) (dpy, error);
+ got_badwindow = True;
+ return 0;
+}
+
+//! to find the X-window of XScreensaver
+/*!
+* This function search for the X-Window of the active/activated XScreensaver.
+* \param dpy pointer to the active X-Display
+* \return The WindowID of the active XScreensaver.
+* \retval 0 if no Windows/Xscreensaver was found
+* \retval n ID of the founded XScreensaver window
+*/
+static Window find_xscreensaver_window(Display * dpy) {
+ kdDebugFuncIn(trace);
+
+ Window root = RootWindowOfScreen(DefaultScreenOfDisplay(dpy));
+ Window root2, parent, *kids;
+ Window retval = 0;
+ Atom xs_version;
+ unsigned int i;
+ unsigned int nkids = 0;
+
+ xs_version = XInternAtom(dpy, "_SCREENSAVER_VERSION", True);
+
+ if (!(xs_version != None && XQueryTree(dpy, root, &root2, &parent, &kids, &nkids)
+ && kids && nkids)) {
+ kdDebugFuncOut(trace);
+ return 0;
+ }
+
+ defaultHandler = XSetErrorHandler(badwindow_handler);
+
+ for (i = 0; i < nkids; i++) {
+ Atom type;
+ int format, status;
+ unsigned long nitems, bytesafter;
+ unsigned char *v;
+
+ got_badwindow = False;
+ status = XGetWindowProperty(dpy, kids[i], xs_version, 0, 200, False, XA_STRING, &type, &format,
+ &nitems, &bytesafter, &v);
+ XSync(dpy, False);
+ if (got_badwindow) status = BadWindow;
+
+ if (status == Success && type != None){
+ retval = kids[i];
+ break;
+ }
+ }
+ XFree(kids);
+ XSetErrorHandler(defaultHandler);
+ kdDebugFuncOut(trace);
+ return retval;
+}
+
+/*!
+* This function is used to ping the XScreensaver. There is no direct way to stop
+* the XScreensaver without to kill/stop an restart or modify config-files of the
+* current user. \n \n
+* We ping the xscreensaver as defined in the QTimer-interval \ref xScreenSaver_timer_interval .
+* The value of \ref xScreenSaver_timer_interval is 58 sec at the moment. The intervall must be
+* smaller then 1 minute (this is the smallest interval of Xscreensaver a.t.m.).
+*/
+void screen::xscreensaver_ping(){
+ kdDebugFuncIn(trace);
+
+ if(!got_XScreensaver) {
+ mDisplay = qt_xdisplay();
+ xs_windowid = find_xscreensaver_window(mDisplay);
+
+ Atom deactivate = XInternAtom(mDisplay, "DEACTIVATE", False);
+ Atom screensaver = XInternAtom(mDisplay, "SCREENSAVER", False);
+
+ ev.xany.type = ClientMessage;
+ ev.xclient.display = mDisplay;
+ ev.xclient.window = xs_windowid;
+ ev.xclient.message_type = screensaver;
+ ev.xclient.format = 32;
+ memset(&ev.xclient.data, 0, sizeof(ev.xclient.data));
+ ev.xclient.data.l[0] = (long) deactivate;
+
+ if(xs_windowid != 0) got_XScreensaver = true;
+ }
+ if(got_XScreensaver){
+ if(XSendEvent(mDisplay, xs_windowid, False, 0L, &ev) == 0){
+ if(check_xscreensaver_timer->isActive()) {
+ check_xscreensaver_timer->stop();
+ this->got_XScreensaver = false;
+ }
+ }
+ XSync(mDisplay, False);
+ }
+
+ kdDebugFuncOut(trace);
+}
+/*
+ * END Section
+ * * * * * * */
+
+/*!
+* Checks if KScreenSaver or XscreenSaver is activated
+* \return The result of the check as an integer value.
+* \retval 0 KScreensaver is disabled
+* \retval 1 KScreensaver is activated
+* \retval 10 Xscreensaver is not found or not running
+* \retval 11 Xscreensaver is activated
+* \retval 99 gnome-screensaver check is running
+* \retval -1 else
+*/
+int screen::checkScreenSaverStatus() {
+ kdDebugFuncIn(trace);
+
+ bool get_reply = false;
+ int kScreenSaver_tmp_status = -1;
+ int check = -1;
+
+ // check for KScreenSaver
+ DCOPReply reply = screen_save_dcop_ref.call("isEnabled()");
+ if(reply.isValid()){
+ if(reply.get(get_reply)){
+ if(get_reply) return 1;
+ /* don't return status her because we must also check if
+ * XScreensaver is activated !!!
+ */
+ else kScreenSaver_tmp_status = 0;
+ }
+ }
+ // check for XScreensaver
+ if (got_XScreensaver) return 11;
+ else if(!got_XScreensaver) {
+ Display *dpy = qt_xdisplay();
+ Window windowid = find_xscreensaver_window(dpy);
+ if(windowid == 0) {
+ //Xscreensaver not detected
+ check_xscreensaver_timer->stop();
+ // KScreensaver activ and no XScreensaver found
+ if(kScreenSaver_tmp_status == 0) return 0;
+ // no KScreensaver and no XScreensaver found
+ else check = 10;
+ }
+ else return 11;
+ }
+
+ // check for gnome-screen-saver
+ if (check == 10) {
+ delete gnomeScreensaverCheck;
+
+ gnomeScreensaverCheck = new KProcess;
+ *gnomeScreensaverCheck << "gnome-screensaver-command" << "--query";
+
+ connect( gnomeScreensaverCheck , SIGNAL(processExited(KProcess *)),SLOT(getGSExited(KProcess *)));
+
+ if(!gnomeScreensaverCheck->start(KProcess::NotifyOnExit))
+ {
+ delete gnomeScreensaverCheck;
+ gnomeScreensaverCheck = NULL;
+ return 10;
+ }
+ else return 99;
+ }
+
+ return -1;
+}
+
+/*!
+ * \b SLOT which called if the call of gnomescreensaver-command exited
+ * \param gnomecheckcommand the KPocess which called this SLOT
+ */
+void screen::getGSExited (KProcess *gnomecheckcommand) {
+ kdDebugFuncIn(trace);
+
+ if (gnomecheckcommand->normalExit()){
+ if (gnomecheckcommand->exitStatus() == 1) SCREENSAVER_STATUS = 10;
+ else if (gnomecheckcommand->exitStatus() == 0) SCREENSAVER_STATUS = 20;
+ } else {
+ SCREENSAVER_STATUS = 10;
+ }
+
+ delete gnomeScreensaverCheck;
+ gnomeScreensaverCheck=NULL;
+
+ kdDebugFuncOut(trace);
+ return;
+}
+
+/*!
+* This function check if DMPS is activated on the active X-Server.
+* \return Integer value with the result of the check
+* \retval 1 if DMPS is enabled
+* \retval 0 if DMPS is disabled
+* \retval -1 if there is a error
+*/
+int screen::checkDPMSStatus(){
+ kdDebugFuncIn(trace);
+
+ CARD16 state;
+ BOOL onoff;
+ int dummy;
+
+ Display *dpy = qt_xdisplay();
+
+ if (!DPMSQueryExtension(dpy, &dummy, &dummy) || !DPMSCapable(dpy)){
+ has_DPMS = false;
+ kdDebugFuncOut(trace);
+ return -1;
+ }
+ else
+ has_DPMS = true;
+
+ DPMSInfo(dpy, &state, &onoff);
+ if(onoff) {
+ kdDebugFuncOut(trace);
+ return 1;
+ } else {
+ kdDebugFuncOut(trace);
+ return 0;
+ }
+}
+
+
+/*!
+* To set DPMS on X-Server on/off.
+* \param enable true: activate/enable DMPS / false: deactivate/disable DPMS
+* \return the result of try to set DPMS
+* \retval true if DMPS correct set false
+* \retval false if fail (DPMS not supported)
+* \todo \li check/evaluate for errormessages
+* \li check if DPMS-Settings correct set if DPMSEnable(dpy) used
+*/
+bool screen::setDPMS( bool enable ){
+ kdDebugFuncIn(trace);
+
+ defaultHandler = XSetErrorHandler(badwindow_handler);
+
+ Display *dpy = qt_xdisplay();
+
+ int dummy;
+ if (!DPMSQueryExtension(dpy, &dummy, &dummy) || !DPMSCapable(dpy)){
+ has_DPMS = false;
+ XSetErrorHandler(defaultHandler);
+ kdDebugFuncOut(trace);
+ return false;
+ }
+
+ if(enable) DPMSEnable(dpy);
+ else DPMSDisable(dpy);
+
+ XFlush(dpy);
+ XSetErrorHandler(defaultHandler);
+
+ kdDebugFuncOut(trace);
+ return true;
+}
+
+/*!
+* This function set the Timeouts for DPMS for the X-Server.
+* \param standby_timeout time in seconds to stand-by the display as integer value
+* \param suspend_timeout time in seconds to suspend the display as integer value
+* \param off_timeout time in seconds to switch off the display as integer value
+* \return the result of try to set DPMS-Timeouts
+* \retval true if DMPS correct set false
+* \retval false if fail (DPMS not supported)
+*/
+bool screen::setDPMSTimeouts( int standby_timeout, int suspend_timeout, int off_timeout){
+ kdDebugFuncIn(trace);
+
+ //XErrFunc defaultHandler;
+ defaultHandler = XSetErrorHandler(badwindow_handler);
+
+ Display *dpy = qt_xdisplay();
+
+ int dummy;
+ if (!DPMSQueryExtension(dpy, &dummy, &dummy) || !DPMSCapable(dpy)){
+ has_DPMS = false;
+ XSetErrorHandler(defaultHandler);
+ kdDebugFuncOut(trace);
+ return false;
+ }
+
+ DPMSSetTimeouts(dpy, 60 * standby_timeout, 60 * suspend_timeout, 60 * off_timeout);
+
+ XFlush(dpy);
+ XSetErrorHandler(defaultHandler);
+ kdDebugFuncOut(trace);
+ return true;
+}
+
+/*!
+* Use this function to lock the screen. This function use automatically the right
+* method for KDE or GNOME.
+* \return boolean with the result of the operation
+* \retval true if the requested method worked
+* \retval false if there was a error
+*/
+bool screen::lockScreen(){
+ kdDebugFuncIn(trace);
+
+ // screensaver status known?
+ if(SCREENSAVER_STATUS == -1) SCREENSAVER_STATUS = checkScreenSaverStatus();
+
+ // set lock for KScreensaver
+ if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){
+ DCOPReply reply = screen_save_dcop_ref.call("lock");
+ if ( reply.isValid() ) {
+ return true;
+ } else {
+ kdWarning() << "Could not lock KScreensaver, try XScreensaver as fallback." << endl;
+ goto xscreensaver;
+ }
+ }
+ // set lock for XScreensaver
+ else if(SCREENSAVER_STATUS == 11){
+xscreensaver:
+ delete xscreensaver_lock;
+
+ xscreensaver_lock = new KProcess;
+ *xscreensaver_lock << "xscreensaver-command" << "-lock";
+ connect(xscreensaver_lock, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+
+ bool status = xscreensaver_lock->start(KProcess::DontCare);
+ if(!status)
+ {
+ delete xscreensaver_lock;
+ xscreensaver_lock = NULL;
+ }
+ return status;
+ }
+ // lock with gnome-screen-saver
+ else if(SCREENSAVER_STATUS == 20){
+ delete gnomescreensaver_lock;
+
+ gnomescreensaver_lock = new KProcess;
+ *gnomescreensaver_lock << "gnome-screensaver-command" << "--lock";
+
+ connect(gnomescreensaver_lock, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+ bool status = gnomescreensaver_lock->start(KProcess::DontCare);
+ if(!status)
+ {
+ delete gnomescreensaver_lock;
+ gnomescreensaver_lock=NULL;
+ }
+ return status;
+ }
+ // set lock for xlock --> no kscreensaver, no xscreensaver present and
+ // the check for gnome screensaver is not finished. This should normaly
+ // not happen, but in this case we use xlock
+ else if(SCREENSAVER_STATUS == 10 || SCREENSAVER_STATUS == 99){
+ delete xlock;
+
+ xlock = new KProcess;
+ *xlock << "xlock"; //<< "-mode" << "blank";
+ connect(xlock, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+ bool status = xlock->start(KProcess::DontCare);
+ if(!status)
+ {
+ delete xlock;
+ xlock = NULL;
+ }
+ return status;
+ }
+ else return false;
+}
+
+/*!
+* Use this function to lock the screen with a specified lock method.
+* \param lock_withMethod a QString, which contain the alias for the lock
+* command.
+* \return boolean with the result of the operation
+* \retval true if the requested method worked
+* \retval false if there was a error
+* \todo check if we should also set blank only if the user would like!!!
+*/
+bool screen::lockScreen( QString lock_withMethod ) {
+ kdDebugFuncIn(trace);
+
+ if (lock_withMethod == "automatic") {
+ lockScreen();
+ return true;
+ }
+ else if (lock_withMethod == "xlock") {
+ delete xlock;
+
+ xlock = new KProcess;
+ *xlock << "xlock";
+ connect(xlock, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+
+ bool status = xlock->start(KProcess::DontCare);
+ if(!status)
+ {
+ delete xlock;
+ xlock=NULL;
+ }
+
+ return status;
+ }
+ else if (lock_withMethod == "gnomescreensaver") {
+ gnomescreensaver_lock = new KProcess;
+ *gnomescreensaver_lock << "gnome-screensaver-command" << "--lock";
+ connect(gnomescreensaver_lock, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+
+ bool status = gnomescreensaver_lock->start(KProcess::DontCare);
+ if(!status)
+ {
+ delete gnomescreensaver_lock;
+ gnomescreensaver_lock = NULL;
+ }
+ return status;
+ }
+ else {
+ // screensaver status known?
+ SCREENSAVER_STATUS = checkScreenSaverStatus();
+
+ if (lock_withMethod == "kscreensaver") {
+ if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){
+ DCOPReply reply = screen_save_dcop_ref.call("lock");
+ if ( reply.isValid() ) {
+ return true;
+ } else {
+ kdWarning() << "Could not call lock for KScreensaver, try XScreensaver "
+ << "as fallback." << endl;
+ goto xscreensaver;
+ }
+ }
+ else return false;
+ }
+ else if (lock_withMethod == "xscreensaver") {
+ if(SCREENSAVER_STATUS == 11){
+xscreensaver:
+ delete xscreensaver_lock;
+
+ xscreensaver_lock = new KProcess;
+ *xscreensaver_lock << "xscreensaver-command" << "-lock";
+ connect(xscreensaver_lock, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+
+ bool status = xscreensaver_lock->start(KProcess::DontCare);
+ if(!status)
+ {
+ delete xscreensaver_lock;
+ xscreensaver_lock = NULL;
+ }
+ return status;
+ }
+ else return false;
+ }
+ else return false;
+ }
+ return false;
+}
+
+/*!
+* Use this function to set the screensaver to 'blank only' instead of
+* using the in KDE or GNOME set screensaver.
+* \todo find a way to set the xscreensaver to 'blank only'
+*/
+void screen::blankOnlyScreen( bool blankonly ){
+ kdDebugFuncIn(trace);
+
+ if(SCREENSAVER_STATUS == -1) SCREENSAVER_STATUS = checkScreenSaverStatus();
+ // set KScreensaver
+ if((SCREENSAVER_STATUS == 1) || (SCREENSAVER_STATUS == 0)){
+ screen_save_dcop_ref.send("setBlankOnly", blankonly);
+ }
+ // set XScreensaver
+ else if(SCREENSAVER_STATUS == 11){
+ // implement something !!!
+ }
+
+ kdDebugFuncOut(trace);
+}
+
+/*!
+* Use this function to reset the KDE screensaver/DPMS settings
+* \return boolean with the result of the operation
+* \retval true if the reset was called
+* \retval false if there was a error
+*/
+bool screen::resetKDEScreensaver(){
+ kdDebugFuncIn(trace);
+
+ if(SCREENSAVER_STATUS == -1)
+ SCREENSAVER_STATUS = checkScreenSaverStatus();
+
+ // do this only if the screensaver is not running
+ if(SCREENSAVER_STATUS == 0){
+ DCOPReply reply = screen_save_dcop_ref.call("configure");
+ if ( reply.isValid() ) {
+ kdDebugFuncOut(trace);
+ return true;
+ } else {
+ kdWarning() << "Could not call configure() for the KDE screensaver." << endl;
+ kdDebugFuncOut(trace);
+ return false;
+ }
+ } else {
+ kdDebugFuncOut(trace);
+ return false;
+ }
+}
+
+/*!
+* Use this function to reset the xscreensaver settings
+* \return boolean with the result of the operation
+* \retval true if the reset was called
+* \retval false if there was a error
+*/
+bool screen::resetXScreensaver(){
+ kdDebugFuncIn(trace);
+
+ if(checkScreenSaverStatus() == 11) {
+
+ delete xscreensaver_reset;
+
+ xscreensaver_reset = new KProcess;
+ *xscreensaver_reset << "xscreensaver-command" << "-restart";
+ connect(xscreensaver_reset, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+
+ bool status = xscreensaver_reset->start(KProcess::DontCare);
+ if(!status)
+ {
+ delete xscreensaver_reset;
+ xscreensaver_reset = NULL;
+ }
+ kdDebugFuncOut(trace);
+ return status;
+ } else {
+ kdDebugFuncOut(trace);
+ return false;
+ }
+}
+
+/*!
+* function to call xset commandline tool to force shutdown the display with dpms
+*/
+void screen::forceDPMSOff() {
+ kdDebugFuncIn(trace);
+
+ KProcess *xset = new KProcess;
+ *xset << "xset" << "dpms" << "force" << "off";
+ connect(xset, SIGNAL(processExited(KProcess*)),
+ this, SLOT(cleanProcess(KProcess*)));
+ if(!xset->start())
+ {
+ delete xset;
+ }
+
+ kdDebugFuncOut(trace);
+}
+
+/*!
+ * function to clean KProcess objects
+ */
+void screen::cleanProcess(KProcess* proc)
+{
+ delete proc;
+ proc = NULL;
+}
+
+/*!
+* function to fake a key event for the shift key. Use this to show the login
+* passwd dialog after suspend if we locked the screen.
+*/
+void screen::fakeShiftKeyEvent() {
+ kdDebugFuncIn(trace);
+
+ Display *dpy = qt_xdisplay();
+
+ if (dpy) {
+ XTestFakeKeyEvent(dpy, 62, 1, 0);
+ XTestFakeKeyEvent(dpy, 62, 0, 0);
+
+ XFlush(dpy);
+ }
+
+ kdDebugFuncOut(trace);
+ return;
+}
+
+#include "screen.moc"