00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "utils.h"
00029
00030 #include <unistd.h>
00031
00032 #ifndef KCMRULES
00033
00034 #include <kxerrorhandler.h>
00035 #include <assert.h>
00036 #include <kdebug.h>
00037 #include <kshortcut.h>
00038 #include <kkeyserver.h>
00039
00040 #include <X11/Xlib.h>
00041 #include <X11/extensions/shape.h>
00042 #include <X11/Xatom.h>
00043 #include <QX11Info>
00044
00045 #include <stdio.h>
00046
00047 #include "atoms.h"
00048 #include "notifications.h"
00049 #include "workspace.h"
00050
00051 #endif
00052
00053 namespace KWin
00054 {
00055
00056 #ifndef KCMRULES
00057
00058 void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
00059 bool& minimize, bool& maximize, bool& close )
00060 {
00061 Atom type;
00062 int format;
00063 unsigned long length, after;
00064 unsigned char* data;
00065 MwmHints* hints = 0;
00066 if ( XGetWindowProperty( display(), w, atoms->motif_wm_hints, 0, 5,
00067 false, atoms->motif_wm_hints, &type, &format,
00068 &length, &after, &data ) == Success )
00069 {
00070 if ( data )
00071 hints = (MwmHints*) data;
00072 }
00073 noborder = false;
00074 resize = true;
00075 move = true;
00076 minimize = true;
00077 maximize = true;
00078 close = true;
00079 if ( hints )
00080 {
00081
00082 if ( hints->flags & MWM_HINTS_FUNCTIONS )
00083 {
00084
00085 bool set_value = (( hints->functions & MWM_FUNC_ALL ) == 0 );
00086 resize = move = minimize = maximize = close = !set_value;
00087 if( hints->functions & MWM_FUNC_RESIZE )
00088 resize = set_value;
00089 if( hints->functions & MWM_FUNC_MOVE )
00090 move = set_value;
00091 if( hints->functions & MWM_FUNC_MINIMIZE )
00092 minimize = set_value;
00093 if( hints->functions & MWM_FUNC_MAXIMIZE )
00094 maximize = set_value;
00095 if( hints->functions & MWM_FUNC_CLOSE )
00096 close = set_value;
00097 }
00098 if ( hints->flags & MWM_HINTS_DECORATIONS )
00099 {
00100 if ( hints->decorations == 0 )
00101 noborder = true;
00102 }
00103 XFree( data );
00104 }
00105 }
00106
00107
00108
00109
00110
00111 KWinSelectionOwner::KWinSelectionOwner( int screen_P )
00112 : KSelectionOwner( make_selection_atom( screen_P ), screen_P )
00113 {
00114 }
00115
00116 Atom KWinSelectionOwner::make_selection_atom( int screen_P )
00117 {
00118 if( screen_P < 0 )
00119 screen_P = DefaultScreen( display());
00120 char tmp[ 30 ];
00121 sprintf( tmp, "WM_S%d", screen_P );
00122 return XInternAtom( display(), tmp, False );
00123 }
00124
00125 void KWinSelectionOwner::getAtoms()
00126 {
00127 KSelectionOwner::getAtoms();
00128 if( xa_version == None )
00129 {
00130 Atom atoms[ 1 ];
00131 const char* const names[] =
00132 { "VERSION" };
00133 XInternAtoms( display(), const_cast< char** >( names ), 1, False, atoms );
00134 xa_version = atoms[ 0 ];
00135 }
00136 }
00137
00138 void KWinSelectionOwner::replyTargets( Atom property_P, Window requestor_P )
00139 {
00140 KSelectionOwner::replyTargets( property_P, requestor_P );
00141 Atom atoms[ 1 ] = { xa_version };
00142
00143 XChangeProperty( display(), requestor_P, property_P, XA_ATOM, 32, PropModeAppend,
00144 reinterpret_cast< unsigned char* >( atoms ), 1 );
00145 }
00146
00147 bool KWinSelectionOwner::genericReply( Atom target_P, Atom property_P, Window requestor_P )
00148 {
00149 if( target_P == xa_version )
00150 {
00151 long version[] = { 2, 0 };
00152 XChangeProperty( display(), requestor_P, property_P, XA_INTEGER, 32,
00153 PropModeReplace, reinterpret_cast< unsigned char* >( &version ), 2 );
00154 }
00155 else
00156 return KSelectionOwner::genericReply( target_P, property_P, requestor_P );
00157 return true;
00158 }
00159
00160 Atom KWinSelectionOwner::xa_version = None;
00161
00162
00163 QByteArray getStringProperty(WId w, Atom prop, char separator)
00164 {
00165 Atom type;
00166 int format, status;
00167 unsigned long nitems = 0;
00168 unsigned long extra = 0;
00169 unsigned char *data = 0;
00170 QByteArray result = "";
00171 KXErrorHandler handler;
00172 status = XGetWindowProperty( display(), w, prop, 0, 10000,
00173 false, XA_STRING, &type, &format,
00174 &nitems, &extra, &data );
00175 if ( status == Success)
00176 {
00177 if (data && separator)
00178 {
00179 for (int i=0; i<(int)nitems; i++)
00180 if (!data[i] && i+1<(int)nitems)
00181 data[i] = separator;
00182 }
00183 if (data)
00184 result = (const char*) data;
00185 XFree(data);
00186 }
00187 return result;
00188 }
00189
00190 static Time next_x_time;
00191 static Bool update_x_time_predicate( Display*, XEvent* event, XPointer )
00192 {
00193 if( next_x_time != CurrentTime )
00194 return False;
00195
00196 switch ( event->type ) {
00197 case ButtonPress:
00198
00199 case ButtonRelease:
00200 next_x_time = event->xbutton.time;
00201 break;
00202 case MotionNotify:
00203 next_x_time = event->xmotion.time;
00204 break;
00205 case KeyPress:
00206
00207 case KeyRelease:
00208 next_x_time = event->xkey.time;
00209 break;
00210 case PropertyNotify:
00211 next_x_time = event->xproperty.time;
00212 break;
00213 case EnterNotify:
00214 case LeaveNotify:
00215 next_x_time = event->xcrossing.time;
00216 break;
00217 case SelectionClear:
00218 next_x_time = event->xselectionclear.time;
00219 break;
00220 default:
00221 break;
00222 }
00223 return False;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 void updateXTime()
00235 {
00236 static QWidget* w = 0;
00237 if ( !w )
00238 w = new QWidget;
00239 long data = 1;
00240 XChangeProperty(display(), w->winId(), atoms->kwin_running, atoms->kwin_running, 32,
00241 PropModeAppend, (unsigned char*) &data, 1);
00242 next_x_time = CurrentTime;
00243 XEvent dummy;
00244 XCheckIfEvent( display(), &dummy, update_x_time_predicate, NULL );
00245 if( next_x_time == CurrentTime )
00246 {
00247 XSync( display(), False );
00248 XCheckIfEvent( display(), &dummy, update_x_time_predicate, NULL );
00249 }
00250 assert( next_x_time != CurrentTime );
00251 QX11Info::setAppTime( next_x_time );
00252 XEvent ev;
00253 XWindowEvent( display(), w->winId(), PropertyChangeMask, &ev );
00254 }
00255
00256 static int server_grab_count = 0;
00257
00258 void grabXServer()
00259 {
00260 if( ++server_grab_count == 1 )
00261 XGrabServer( display());
00262 }
00263
00264 void ungrabXServer()
00265 {
00266 assert( server_grab_count > 0 );
00267 if( --server_grab_count == 0 )
00268 {
00269 XUngrabServer( display());
00270 XFlush( display());
00271 Notify::sendPendingEvents();
00272 }
00273 }
00274
00275 bool grabbedXServer()
00276 {
00277 return server_grab_count > 0;
00278 }
00279
00280 static bool keyboard_grabbed = false;
00281
00282 bool grabXKeyboard( Window w )
00283 {
00284 if( QWidget::keyboardGrabber() != NULL )
00285 return false;
00286 if( keyboard_grabbed )
00287 return false;
00288 if( qApp->activePopupWidget() != NULL )
00289 return false;
00290 if( w == None )
00291 w = rootWindow();
00292 if( XGrabKeyboard( display(), w, False,
00293 GrabModeAsync, GrabModeAsync, xTime()) != GrabSuccess )
00294 return false;
00295 keyboard_grabbed = true;
00296 return true;
00297 }
00298
00299 void ungrabXKeyboard()
00300 {
00301 if( !keyboard_grabbed )
00302 {
00303 kDebug() << "ungrabXKeyboard() called but keyboard not grabbed!";
00304 }
00305 keyboard_grabbed = false;
00306 XUngrabKeyboard( display(), xTime());
00307 }
00308
00309 QPoint cursorPos()
00310 {
00311 return Workspace::self()->cursorPos();
00312 }
00313
00314
00315
00316 int qtToX11Button( Qt::MouseButton button )
00317 {
00318 if( button == Qt::LeftButton )
00319 return Button1;
00320 else if( button == Qt::MidButton )
00321 return Button2;
00322 else if( button == Qt::RightButton )
00323 return Button3;
00324 return AnyButton;
00325 }
00326
00327 Qt::MouseButton x11ToQtMouseButton( int button )
00328 {
00329 if( button == Button1 )
00330 return Qt::LeftButton;
00331 if( button == Button2 )
00332 return Qt::MidButton;
00333 if( button == Button3 )
00334 return Qt::RightButton;
00335 return Qt::NoButton;
00336 }
00337
00338 int qtToX11State( Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers )
00339 {
00340 int ret = 0;
00341 if( buttons & Qt::LeftButton )
00342 ret |= Button1Mask;
00343 if( buttons & Qt::MidButton )
00344 ret |= Button2Mask;
00345 if( buttons & Qt::RightButton )
00346 ret |= Button3Mask;
00347 if( modifiers & Qt::ShiftModifier )
00348 ret |= ShiftMask;
00349 if( modifiers & Qt::ControlModifier )
00350 ret |= ControlMask;
00351 if( modifiers & Qt::AltModifier )
00352 ret |= KKeyServer::modXAlt();
00353 if( modifiers & Qt::MetaModifier )
00354 ret |= KKeyServer::modXMeta();
00355 return ret;
00356 }
00357
00358 Qt::MouseButtons x11ToQtMouseButtons( int state )
00359 {
00360 Qt::MouseButtons ret = 0;
00361 if( state & Button1Mask )
00362 ret |= Qt::LeftButton;
00363 if( state & Button2Mask )
00364 ret |= Qt::MidButton;
00365 if( state & Button3Mask )
00366 ret |= Qt::RightButton;
00367 return ret;
00368 }
00369
00370 Qt::KeyboardModifiers x11ToQtKeyboardModifiers( int state )
00371 {
00372 Qt::KeyboardModifiers ret = 0;
00373 if( state & ShiftMask )
00374 ret |= Qt::ShiftModifier;
00375 if( state & ControlMask )
00376 ret |= Qt::ControlModifier;
00377 if( state & KKeyServer::modXAlt())
00378 ret |= Qt::AltModifier;
00379 if( state & KKeyServer::modXMeta())
00380 ret |= Qt::MetaModifier;
00381 return ret;
00382 }
00383
00384 #endif
00385
00386 bool isLocalMachine( const QByteArray& host )
00387 {
00388 #ifdef HOST_NAME_MAX
00389 char hostnamebuf[HOST_NAME_MAX];
00390 #else
00391 char hostnamebuf[256];
00392 #endif
00393 if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0)
00394 {
00395 hostnamebuf[sizeof(hostnamebuf)-1] = 0;
00396 if (host == hostnamebuf)
00397 return true;
00398 if( char *dot = strchr(hostnamebuf, '.'))
00399 {
00400 *dot = '\0';
00401 if( host == hostnamebuf )
00402 return true;
00403 }
00404 }
00405 return false;
00406 }
00407
00408 #ifndef KCMRULES
00409 ShortcutDialog::ShortcutDialog( const QKeySequence& cut )
00410 : widget( new KKeySequenceWidget( this ))
00411 {
00412 widget->setKeySequence( cut );
00413
00414 XSetWindowAttributes attrs;
00415 attrs.override_redirect = True;
00416 XChangeWindowAttributes( display(), winId(), CWOverrideRedirect, &attrs );
00417 setWindowFlags( Qt::Popup );
00418 }
00419
00420 void ShortcutDialog::accept()
00421 {
00422 QKeySequence seq = shortcut();
00423 if( !seq.isEmpty())
00424 {
00425 if( seq[0] == Qt::Key_Escape )
00426 {
00427 reject();
00428 return;
00429 }
00430 if( seq[0] == Qt::Key_Space
00431 || (seq[0] & Qt::KeyboardModifierMask) == 0 )
00432 {
00433 widget->clearKeySequence();
00434 KDialog::accept();
00435 return;
00436 }
00437 }
00438 KDialog::accept();
00439 }
00440
00441 void ShortcutDialog::done( int r )
00442 {
00443 KDialog::done( r );
00444 emit dialogDone( r == Accepted );
00445 }
00446
00447 QKeySequence ShortcutDialog::shortcut() const
00448 {
00449 return widget->keySequence();
00450 }
00451
00452 #endif //KCMRULES
00453 }
00454
00455 #ifndef KCMRULES
00456 #include "utils.moc"
00457 #endif