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