00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "utils.h"
00019
00020 #include <unistd.h>
00021 #include <string.h>
00022 #include <netdb.h>
00023
00024 #ifndef KCMRULES
00025
00026 #include <tqapplication.h>
00027 #include <kxerrorhandler.h>
00028 #include <assert.h>
00029 #include <kdebug.h>
00030
00031 #include <X11/Xlib.h>
00032 #include <X11/extensions/shape.h>
00033 #include <X11/Xatom.h>
00034
00035 #include "atoms.h"
00036 #include "notifications.h"
00037
00038 #ifdef USE_QT4
00039 #include <Qt/qx11info_x11.h>
00040 #endif // USE_QT4
00041
00042 #endif
00043
00044 namespace KWinInternal
00045 {
00046
00047 #ifndef KCMRULES
00048
00049
00050
00051
00052 int Shape::kwin_shape_version = 0;
00053 int Shape::kwin_shape_event = 0;
00054
00055
00056 bool Shape::hasShape( WId w)
00057 {
00058 int xws, yws, xbs, ybs;
00059 unsigned int wws, hws, wbs, hbs;
00060 int boundingShaped = 0, clipShaped = 0;
00061 if (!available())
00062 return FALSE;
00063 XShapeQueryExtents(qt_xdisplay(), w,
00064 &boundingShaped, &xws, &yws, &wws, &hws,
00065 &clipShaped, &xbs, &ybs, &wbs, &hbs);
00066 return boundingShaped != 0;
00067 }
00068
00069 int Shape::shapeEvent()
00070 {
00071 return kwin_shape_event;
00072 }
00073
00074 void Shape::init()
00075 {
00076 kwin_shape_version = 0;
00077 int dummy;
00078 if( !XShapeQueryExtension(qt_xdisplay(), &kwin_shape_event, &dummy))
00079 return;
00080 int major, minor;
00081 if( !XShapeQueryVersion( qt_xdisplay(), &major, &minor ))
00082 return;
00083 kwin_shape_version = major * 0x10 + minor;
00084 }
00085
00086 void Motif::readFlags( WId w, bool& noborder, bool& resize, bool& move,
00087 bool& minimize, bool& maximize, bool& close )
00088 {
00089 Atom type;
00090 int format;
00091 unsigned long length, after;
00092 unsigned char* data;
00093 MwmHints* hints = 0;
00094 if ( XGetWindowProperty( qt_xdisplay(), w, atoms->motif_wm_hints, 0, 5,
00095 FALSE, atoms->motif_wm_hints, &type, &format,
00096 &length, &after, &data ) == Success )
00097 {
00098 if ( data )
00099 hints = (MwmHints*) data;
00100 }
00101 noborder = false;
00102 resize = true;
00103 move = true;
00104 minimize = true;
00105 maximize = true;
00106 close = true;
00107 if ( hints )
00108 {
00109
00110 if ( hints->flags & MWM_HINTS_FUNCTIONS )
00111 {
00112
00113 bool set_value = (( hints->functions & MWM_FUNC_ALL ) == 0 );
00114 resize = move = minimize = maximize = close = !set_value;
00115 if( hints->functions & MWM_FUNC_RESIZE )
00116 resize = set_value;
00117 if( hints->functions & MWM_FUNC_MOVE )
00118 move = set_value;
00119 if( hints->functions & MWM_FUNC_MINIMIZE )
00120 minimize = set_value;
00121 if( hints->functions & MWM_FUNC_MAXIMIZE )
00122 maximize = set_value;
00123 if( hints->functions & MWM_FUNC_CLOSE )
00124 close = set_value;
00125 }
00126 if ( hints->flags & MWM_HINTS_DECORATIONS )
00127 {
00128 if ( hints->decorations == 0 )
00129 noborder = true;
00130 }
00131 XFree( data );
00132 }
00133 }
00134
00135
00136
00137
00138
00139 KWinSelectionOwner::KWinSelectionOwner( int screen_P )
00140 : KSelectionOwner( make_selection_atom( screen_P ), screen_P )
00141 {
00142 }
00143
00144 Atom KWinSelectionOwner::make_selection_atom( int screen_P )
00145 {
00146 if( screen_P < 0 )
00147 screen_P = DefaultScreen( qt_xdisplay());
00148 char tmp[ 30 ];
00149 sprintf( tmp, "WM_S%d", screen_P );
00150 return XInternAtom( qt_xdisplay(), tmp, False );
00151 }
00152
00153 void KWinSelectionOwner::getAtoms()
00154 {
00155 KSelectionOwner::getAtoms();
00156 if( xa_version == None )
00157 {
00158 Atom atoms[ 1 ];
00159 const char* const names[] =
00160 { "VERSION" };
00161 XInternAtoms( qt_xdisplay(), const_cast< char** >( names ), 1, False, atoms );
00162 xa_version = atoms[ 0 ];
00163 }
00164 }
00165
00166 void KWinSelectionOwner::replyTargets( Atom property_P, Window requestor_P )
00167 {
00168 KSelectionOwner::replyTargets( property_P, requestor_P );
00169 Atom atoms[ 1 ] = { xa_version };
00170
00171 XChangeProperty( qt_xdisplay(), requestor_P, property_P, XA_ATOM, 32, PropModeAppend,
00172 reinterpret_cast< unsigned char* >( atoms ), 1 );
00173 }
00174
00175 bool KWinSelectionOwner::genericReply( Atom target_P, Atom property_P, Window requestor_P )
00176 {
00177 if( target_P == xa_version )
00178 {
00179 long version[] = { 2, 0 };
00180 XChangeProperty( qt_xdisplay(), requestor_P, property_P, XA_INTEGER, 32,
00181 PropModeReplace, reinterpret_cast< unsigned char* >( &version ), 2 );
00182 }
00183 else
00184 return KSelectionOwner::genericReply( target_P, property_P, requestor_P );
00185 return true;
00186 }
00187
00188 Atom KWinSelectionOwner::xa_version = None;
00189
00190
00191 TQCString getStringProperty(WId w, Atom prop, char separator)
00192 {
00193 Atom type;
00194 int format, status;
00195 unsigned long nitems = 0;
00196 unsigned long extra = 0;
00197 unsigned char *data = 0;
00198 TQCString result = "";
00199 KXErrorHandler handler;
00200 status = XGetWindowProperty( qt_xdisplay(), w, prop, 0, 10000,
00201 FALSE, XA_STRING, &type, &format,
00202 &nitems, &extra, &data );
00203 if ( status == Success)
00204 {
00205 if (data && separator)
00206 {
00207 for (int i=0; i<(int)nitems; i++)
00208 if (!data[i] && i+1<(int)nitems)
00209 data[i] = separator;
00210 }
00211 if (data)
00212 result = (const char*) data;
00213 XFree(data);
00214 }
00215 return result;
00216 }
00217
00218 static Time next_x_time;
00219 static Bool update_x_time_predicate( Display*, XEvent* event, XPointer )
00220 {
00221 if( next_x_time != CurrentTime )
00222 return False;
00223
00224 switch ( event->type ) {
00225 case ButtonPress:
00226
00227 case ButtonRelease:
00228 next_x_time = event->xbutton.time;
00229 break;
00230 case MotionNotify:
00231 next_x_time = event->xmotion.time;
00232 break;
00233 case KeyPress:
00234
00235 case KeyRelease:
00236 next_x_time = event->xkey.time;
00237 break;
00238 case PropertyNotify:
00239 next_x_time = event->xproperty.time;
00240 break;
00241 case EnterNotify:
00242 case LeaveNotify:
00243 next_x_time = event->xcrossing.time;
00244 break;
00245 case SelectionClear:
00246 next_x_time = event->xselectionclear.time;
00247 break;
00248 default:
00249 break;
00250 }
00251 return False;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 void updateXTime()
00263 {
00264 static TQWidget* w = 0;
00265 if ( !w )
00266 w = new TQWidget;
00267 long data = 1;
00268 XChangeProperty(qt_xdisplay(), w->winId(), atoms->kwin_running, atoms->kwin_running, 32,
00269 PropModeAppend, (unsigned char*) &data, 1);
00270 next_x_time = CurrentTime;
00271 XEvent dummy;
00272 XCheckIfEvent( qt_xdisplay(), &dummy, update_x_time_predicate, NULL );
00273 if( next_x_time == CurrentTime )
00274 {
00275 XSync( qt_xdisplay(), False );
00276 XCheckIfEvent( qt_xdisplay(), &dummy, update_x_time_predicate, NULL );
00277 }
00278 assert( next_x_time != CurrentTime );
00279 SET_QT_X_TIME(next_x_time);
00280 XEvent ev;
00281 XWindowEvent( qt_xdisplay(), w->winId(), PropertyChangeMask, &ev );
00282 }
00283
00284 static int server_grab_count = 0;
00285
00286 void grabXServer()
00287 {
00288 if( ++server_grab_count == 1 )
00289 XGrabServer( qt_xdisplay());
00290 }
00291
00292 void ungrabXServer()
00293 {
00294 assert( server_grab_count > 0 );
00295 if( --server_grab_count == 0 )
00296 {
00297 XUngrabServer( qt_xdisplay());
00298 XFlush( qt_xdisplay());
00299 Notify::sendPendingEvents();
00300 }
00301 }
00302
00303 bool grabbedXServer()
00304 {
00305 return server_grab_count > 0;
00306 }
00307
00308 #endif
00309
00310 bool isLocalMachine( const TQCString& host )
00311 {
00312 #ifdef HOST_NAME_MAX
00313 char hostnamebuf[HOST_NAME_MAX];
00314 #else
00315 char hostnamebuf[256];
00316 #endif
00317 if (gethostname (hostnamebuf, sizeof hostnamebuf) >= 0)
00318 {
00319 hostnamebuf[sizeof(hostnamebuf)-1] = 0;
00320 if (host == hostnamebuf)
00321 return true;
00322 if( char *dot = strchr(hostnamebuf, '.'))
00323 {
00324 *dot = '\0';
00325 if( host == hostnamebuf )
00326 return true;
00327 }
00328 else
00329 {
00330 struct addrinfo hints, *res, *addr;
00331 bool is_local = false;
00332
00333 memset (&hints, 0, sizeof (hints));
00334 hints.ai_family = PF_UNSPEC;
00335 hints.ai_socktype = SOCK_STREAM;
00336 hints.ai_flags |= AI_CANONNAME;
00337
00338 if( getaddrinfo( host, NULL, &hints, &res ) != 0)
00339 return false;
00340 for(addr = res; !is_local && addr; addr = addr->ai_next)
00341 {
00342 if( addr->ai_canonname &&
00343 host == TQCString( addr->ai_canonname ))
00344 is_local = true;
00345 }
00346 freeaddrinfo(res);
00347 return is_local;
00348 }
00349 }
00350 return false;
00351 }
00352
00353 #ifndef KCMRULES
00354 ShortcutDialog::ShortcutDialog( const KShortcut& cut )
00355 : KShortcutDialog( cut, false )
00356 {
00357
00358 XSetWindowAttributes attrs;
00359 attrs.override_redirect = True;
00360 XChangeWindowAttributes( qt_xdisplay(), winId(), CWOverrideRedirect, &attrs );
00361 setWFlags( WType_Popup );
00362 }
00363
00364 void ShortcutDialog::accept()
00365 {
00366 for( int i = 0;
00367 ;
00368 ++i )
00369 {
00370 KKeySequence seq = shortcut().seq( i );
00371 if( seq.isNull())
00372 break;
00373 if( seq.key( 0 ) == Key_Escape )
00374 {
00375 reject();
00376 return;
00377 }
00378 if( seq.key( 0 ) == Key_Space )
00379 {
00380 setShortcut( KShortcut());
00381 KShortcutDialog::accept();
00382 return;
00383 }
00384 if( seq.key( 0 ).modFlags() == 0 )
00385 {
00386 KShortcut cut = shortcut();
00387 cut.setSeq( i, KKeySequence());
00388 setShortcut( cut );
00389 return;
00390 }
00391 }
00392 KShortcutDialog::accept();
00393 }
00394
00395
00396
00397
00398
00399 void ShortcutDialog::hide()
00400 {
00401 close();
00402 return KShortcutDialog::hide();
00403 }
00404
00405 #endif
00406
00407
00408 }
00409
00410 #ifndef KCMRULES
00411 #include "utils.moc"
00412 #endif