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