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