twin.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999 Matthias Ettrich (ettrich@kde.org) 00003 00004 $Id$ 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include <stdlib.h> 00023 #include <unistd.h> 00024 00025 #ifdef HAVE_SYSENT_H 00026 #include <sysent.h> 00027 #endif 00028 00029 #include <kuniqueapplication.h> 00030 #include <tqbitmap.h> 00031 #include <tqimage.h> 00032 #include <tqwhatsthis.h> 00033 #include <tqcstring.h> 00034 #include <tqdialog.h> 00035 00036 #include "config.h" 00037 #include "twin.h" 00038 #include "tdeapplication.h" 00039 00040 #include <tdeglobal.h> 00041 #include <kiconloader.h> 00042 #include <kdebug.h> 00043 00044 #include <kdatastream.h> 00045 #include <tdelocale.h> 00046 #include <dcopclient.h> 00047 #include <dcopref.h> 00048 #ifdef Q_WS_X11 00049 #include <tdestartupinfo.h> 00050 #include <kxerrorhandler.h> 00051 00052 #include <X11/Xlib.h> 00053 #include <X11/Xatom.h> 00054 #include <X11/Xutil.h> 00055 00056 #include "netwm.h" 00057 00058 static bool atoms_created = false; 00059 extern Atom tqt_wm_protocols; 00060 00061 static Atom net_wm_context_help; 00062 static Atom kde_wm_change_state; 00063 static Atom kde_wm_window_opacity; 00064 static Atom kde_wm_window_shadow; 00065 static Atom twin_UTF8_STRING; 00066 static Atom net_wm_cm; 00067 00068 static void twin_net_create_atoms() { 00069 if (!atoms_created){ 00070 const int max = 20; 00071 Atom* atoms[max]; 00072 const char* names[max]; 00073 Atom atoms_return[max]; 00074 int n = 0; 00075 00076 atoms[n] = &net_wm_context_help; 00077 names[n++] = "_NET_WM_CONTEXT_HELP"; 00078 00079 atoms[n] = &kde_wm_change_state; 00080 names[n++] = "_TDE_WM_CHANGE_STATE"; 00081 00082 atoms[n] = &kde_wm_window_opacity; 00083 names[n++] = (char*) "_TDE_WM_WINDOW_OPACITY"; 00084 00085 atoms[n] = &kde_wm_window_shadow; 00086 names[n++] = (char*) "_TDE_WM_WINDOW_SHADOW"; 00087 00088 char net_wm_cm_name[ 100 ]; 00089 sprintf( net_wm_cm_name, "_NET_WM_CM_S%d", DefaultScreen( tqt_xdisplay())); 00090 atoms[n] = &net_wm_cm; 00091 names[n++] = net_wm_cm_name; 00092 00093 // we need a const_cast for the horrible X API 00094 XInternAtoms( tqt_xdisplay(), const_cast<char**>(names), n, false, atoms_return ); 00095 for (int i = 0; i < n; i++ ) 00096 *atoms[i] = atoms_return[i]; 00097 00098 atoms_created = True; 00099 } 00100 } 00101 #endif 00102 00103 /* 00104 Sends a client message to the ROOT window. 00105 */ 00106 #ifdef Q_WS_X11 00107 static void sendClientMessageToRoot(Window w, Atom a, long x, long y = 0, long z = 0 ){ 00108 XEvent ev; 00109 long mask; 00110 00111 memset(&ev, 0, sizeof(ev)); 00112 ev.xclient.type = ClientMessage; 00113 ev.xclient.window = w; 00114 ev.xclient.message_type = a; 00115 ev.xclient.format = 32; 00116 ev.xclient.data.l[0] = x; 00117 ev.xclient.data.l[1] = y; 00118 ev.xclient.data.l[2] = z; 00119 mask = SubstructureRedirectMask; 00120 XSendEvent(tqt_xdisplay(), tqt_xrootwin(), False, mask, &ev); 00121 } 00122 #endif 00123 00124 /* 00125 Send a client message to window w 00126 */ 00127 #ifdef Q_WS_X11 00128 static void sendClientMessage(Window w, Atom a, long x){ 00129 XEvent ev; 00130 long mask; 00131 00132 memset(&ev, 0, sizeof(ev)); 00133 ev.xclient.type = ClientMessage; 00134 ev.xclient.window = w; 00135 ev.xclient.message_type = a; 00136 ev.xclient.format = 32; 00137 ev.xclient.data.l[0] = x; 00138 ev.xclient.data.l[1] = CurrentTime; 00139 mask = 0L; 00140 if (w == tqt_xrootwin()) 00141 mask = SubstructureRedirectMask; /* magic! */ 00142 XSendEvent(tqt_xdisplay(), w, False, mask, &ev); 00143 } 00144 #endif 00145 00146 bool KWin::compositingActive() 00147 { 00148 #ifdef Q_WS_X11 00149 twin_net_create_atoms(); 00150 return XGetSelectionOwner( tqt_xdisplay(), net_wm_cm ) != None; 00151 #else 00152 return false; 00153 #endif 00154 } 00155 00156 #ifdef Q_WS_X11 00157 namespace 00158 { 00159 class ContextWidget : public TQWidget 00160 { 00161 public: 00162 ContextWidget(); 00163 virtual bool x11Event( XEvent * ev); 00164 }; 00165 00166 ContextWidget::ContextWidget() 00167 : TQWidget(0,0) 00168 { 00169 twin_net_create_atoms(); 00170 kapp->installX11EventFilter( this ); 00171 TQWhatsThis::enterWhatsThisMode(); 00172 TQCursor c = *TQApplication::overrideCursor(); 00173 TQWhatsThis::leaveWhatsThisMode(); 00174 XGrabPointer( tqt_xdisplay(), tqt_xrootwin(), true, 00175 (uint)( ButtonPressMask | ButtonReleaseMask | 00176 PointerMotionMask | EnterWindowMask | 00177 LeaveWindowMask ), 00178 GrabModeAsync, GrabModeAsync, 00179 None, c.handle(), CurrentTime ); 00180 tqApp->enter_loop(); 00181 } 00182 00183 00184 bool ContextWidget::x11Event( XEvent * ev) 00185 { 00186 if ( ev->type == ButtonPress && ev->xbutton.button == Button1 ) { 00187 XUngrabPointer( tqt_xdisplay(), ev->xbutton.time ); 00188 Window root; 00189 Window child = tqt_xrootwin(); 00190 int root_x, root_y, lx, ly; 00191 uint state; 00192 Window w; 00193 do { 00194 w = child; 00195 XQueryPointer( tqt_xdisplay(), w, &root, &child, 00196 &root_x, &root_y, &lx, &ly, &state ); 00197 } while ( child != None && child != w ); 00198 00199 ::sendClientMessage(w, tqt_wm_protocols, net_wm_context_help); 00200 XEvent e = *ev; 00201 e.xbutton.window = w; 00202 e.xbutton.subwindow = w; 00203 e.xbutton.x = lx; 00204 e.xbutton.y = ly; 00205 XSendEvent( tqt_xdisplay(), w, true, ButtonPressMask, &e ); 00206 tqApp->exit_loop(); 00207 return true; 00208 } 00209 return false; 00210 } 00211 } // namespace 00212 #endif 00213 00214 void KWin::invokeContextHelp() 00215 { 00216 #ifdef Q_WS_X11 00217 ContextWidget w; 00218 #endif 00219 } 00220 00221 void KWin::setSystemTrayWindowFor( WId trayWin, WId forWin ) 00222 { 00223 #ifdef Q_WS_X11 00224 NETWinInfo info( tqt_xdisplay(), trayWin, tqt_xrootwin(), 0 ); 00225 if ( !forWin ) 00226 forWin = tqt_xrootwin(); 00227 info.setKDESystemTrayWinFor( forWin ); 00228 NETRootInfo rootinfo( tqt_xdisplay(), NET::Supported ); 00229 if( !rootinfo.isSupported( NET::WMKDESystemTrayWinFor )) { 00230 DCOPRef ref( "kded", "kded" ); 00231 if( !ref.send( "loadModule", TQCString( "kdetrayproxy" ))) 00232 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl; 00233 } 00234 #endif 00235 } 00236 00237 void KWin::activateWindow( WId win, long time ) 00238 { 00239 #ifdef Q_WS_X11 00240 NETRootInfo info( tqt_xdisplay(), 0 ); 00241 if( time == 0 ) 00242 time = GET_QT_X_USER_TIME(); 00243 info.setActiveWindow( win, NET::FromApplication, time, 00244 kapp->activeWindow() ? kapp->activeWindow()->winId() : 0 ); 00245 #endif // Q_WS_X11 ... 00246 KUniqueApplication::setHandleAutoStarted(); 00247 } 00248 00249 void KWin::forceActiveWindow( WId win, long time ) 00250 { 00251 #ifdef Q_WS_X11 00252 NETRootInfo info( tqt_xdisplay(), 0 ); 00253 if( time == 0 ) 00254 time = GET_QT_X_TIME(); 00255 info.setActiveWindow( win, NET::FromTool, time, 0 ); 00256 #endif // Q_WS_X11 00257 KUniqueApplication::setHandleAutoStarted(); 00258 } 00259 00260 void KWin::setActiveWindow( WId win ) 00261 { 00262 #ifdef Q_WS_X11 00263 NETRootInfo info( tqt_xdisplay(), 0 ); 00264 info.setActiveWindow( win, NET::FromUnknown, 0, 0 ); 00265 #endif 00266 KUniqueApplication::setHandleAutoStarted(); 00267 } 00268 00269 void KWin::demandAttention( WId win, bool set ) 00270 { 00271 #ifdef Q_WS_X11 00272 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), 0 ); 00273 info.setState( set ? NET::DemandsAttention : 0, NET::DemandsAttention ); 00274 #endif 00275 } 00276 00277 void KWin::setUserTime( WId win, long time ) 00278 { 00279 #ifdef Q_WS_X11 00280 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), 0 ); 00281 info.setUserTime( time ); 00282 #endif 00283 } 00284 00285 KWin::WindowInfo KWin::windowInfo( WId win, unsigned long properties, unsigned long properties2 ) 00286 { 00287 return WindowInfo( win, properties, properties2 ); 00288 } 00289 00290 00291 WId KWin::transientFor( WId win ) 00292 { 00293 #ifdef Q_WS_X11 00294 KXErrorHandler handler; // ignore badwindow 00295 Window transient_for = None; 00296 if( XGetTransientForHint( tqt_xdisplay(), win, &transient_for )) 00297 return transient_for; 00298 // XGetTransientForHint() did sync 00299 return None; 00300 #else 00301 return 0L; 00302 #endif 00303 } 00304 00305 void KWin::setMainWindow( TQWidget* subwindow, WId mainwindow ) 00306 { 00307 #ifdef Q_WS_X11 00308 if( mainwindow != 0 ) 00309 { 00310 /* 00311 Grmbl. See TQDialog::show(). That should get fixed in Qt somehow. 00312 */ 00313 if( tqqt_cast< TQDialog* >( subwindow ) != NULL 00314 && subwindow->parentWidget() == NULL 00315 && kapp->mainWidget() != NULL ) 00316 { 00317 kdWarning() << "KWin::setMainWindow(): There either mustn't be kapp->mainWidget()," 00318 " or the dialog must have a non-NULL parent, otherwise Qt will reset the change. Bummer." << endl; 00319 } 00320 XSetTransientForHint( tqt_xdisplay(), subwindow->winId(), mainwindow ); 00321 } 00322 else 00323 XDeleteProperty( tqt_xdisplay(), subwindow->winId(), XA_WM_TRANSIENT_FOR ); 00324 #endif 00325 } 00326 00327 WId KWin::groupLeader( WId win ) 00328 { 00329 #ifdef Q_WS_X11 00330 KXErrorHandler handler; // ignore badwindow 00331 XWMHints *hints = XGetWMHints( tqt_xdisplay(), win ); 00332 Window window_group = None; 00333 if ( hints ) 00334 { 00335 if( hints->flags & WindowGroupHint ) 00336 window_group = hints->window_group; 00337 XFree( reinterpret_cast< char* >( hints )); 00338 } 00339 // XGetWMHints() did sync 00340 return window_group; 00341 #else 00342 return 0L; 00343 #endif 00344 } 00345 00346 // this one is deprecated, KWin::WindowInfo should be used instead 00347 KWin::Info KWin::info( WId win ) 00348 { 00349 Info w; 00350 #ifdef Q_WS_X11 00351 NETWinInfo inf( tqt_xdisplay(), win, tqt_xrootwin(), 00352 NET::WMState | 00353 NET::WMStrut | 00354 NET::WMWindowType | 00355 NET::WMName | 00356 NET::WMVisibleName | 00357 NET::WMDesktop | 00358 NET::WMPid | 00359 NET::WMKDEFrameStrut | 00360 NET::XAWMState 00361 ); 00362 00363 w.win = win; 00364 w.state = inf.state(); 00365 w.mappingState = inf.mappingState(); 00366 w.strut = inf.strut(); 00367 w.windowType = inf.windowType( -1U ); 00368 if ( inf.name() ) { 00369 w.name = TQString::fromUtf8( inf.name() ); 00370 } else { 00371 char* c = 0; 00372 if ( XFetchName( tqt_xdisplay(), win, &c ) != 0 ) { 00373 w.name = TQString::fromLocal8Bit( c ); 00374 XFree( c ); 00375 } 00376 } 00377 if ( inf.visibleName() ) 00378 w.visibleName = TQString::fromUtf8( inf.visibleName() ); 00379 else 00380 w.visibleName = w.name; 00381 00382 w.desktop = inf.desktop(); 00383 w.onAllDesktops = inf.desktop() == NETWinInfo::OnAllDesktops; 00384 w.pid = inf.pid(); 00385 NETRect frame, geom; 00386 inf.kdeGeometry( frame, geom ); 00387 w.geometry.setRect( geom.pos.x, geom.pos.y, geom.size.width, geom.size.height ); 00388 w.frameGeometry.setRect( frame.pos.x, frame.pos.y, frame.size.width, frame.size.height ); 00389 #endif 00390 return w; 00391 } 00392 00393 TQPixmap KWin::icon( WId win, int width, int height, bool scale ) 00394 { 00395 return icon( win, width, height, scale, NETWM | WMHints | ClassHint | XApp ); 00396 } 00397 00398 00399 TQPixmap KWin::icon( WId win, int width, int height, bool scale, int flags ) 00400 { 00401 #ifdef Q_WS_X11 00402 KXErrorHandler handler; // ignore badwindow 00403 #endif 00404 TQPixmap result; 00405 #ifdef Q_WS_X11 00406 if( flags & NETWM ) { 00407 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), NET::WMIcon ); 00408 NETIcon ni = info.icon( width, height ); 00409 if ( ni.data && ni.size.width > 0 && ni.size.height > 0 ) { 00410 TQImage img( (uchar*) ni.data, (int) ni.size.width, (int) ni.size.height, 32, 0, 0, TQImage::IgnoreEndian ); 00411 img.setAlphaBuffer( true ); 00412 if ( scale && width > 0 && height > 0 &&img.size() != TQSize( width, height ) && !img.isNull() ) 00413 img = TQImage(img).smoothScale( width, height ); 00414 if ( !img.isNull() ) 00415 result.convertFromImage( img ); 00416 return result; 00417 } 00418 } 00419 00420 if( flags & WMHints ) { 00421 Pixmap p = None; 00422 Pixmap p_mask = None; 00423 00424 XWMHints *hints = XGetWMHints(tqt_xdisplay(), win ); 00425 if (hints && (hints->flags & IconPixmapHint)){ 00426 p = hints->icon_pixmap; 00427 } 00428 if (hints && (hints->flags & IconMaskHint)){ 00429 p_mask = hints->icon_mask; 00430 } 00431 if (hints) 00432 XFree((char*)hints); 00433 00434 if (p != None){ 00435 Window root; 00436 int x, y; 00437 unsigned int w = 0; 00438 unsigned int h = 0; 00439 unsigned int border_w, depth; 00440 XGetGeometry(tqt_xdisplay(), p, &root, 00441 &x, &y, &w, &h, &border_w, &depth); 00442 if (w > 0 && h > 0){ 00443 TQPixmap pm(w, h, depth); 00444 // Always detach before doing something behind QPixmap's back. 00445 pm.detach(); 00446 XCopyArea(tqt_xdisplay(), p, pm.handle(), 00447 tqt_xget_temp_gc(tqt_xscreen(), depth==1), 00448 0, 0, w, h, 0, 0); 00449 if (p_mask != None){ 00450 TQBitmap bm(w, h); 00451 XCopyArea(tqt_xdisplay(), p_mask, bm.handle(), 00452 tqt_xget_temp_gc(tqt_xscreen(), true), 00453 0, 0, w, h, 0, 0); 00454 pm.setMask(bm); 00455 } 00456 if ( scale && width > 0 && height > 0 && !pm.isNull() && 00457 ( (int) w != width || (int) h != height) ){ 00458 result.convertFromImage( TQImage(pm.convertToImage()).smoothScale( width, height ) ); 00459 } else { 00460 result = pm; 00461 } 00462 } 00463 } 00464 } 00465 00466 // Since width can be any arbitrary size, but the icons cannot, 00467 // take the nearest value for best results (ignoring 22 pixel 00468 // icons as they don't exist for apps): 00469 int iconWidth; 00470 if( width < 24 ) 00471 iconWidth = 16; 00472 else if( width < 40 ) 00473 iconWidth = 32; 00474 else 00475 iconWidth = 48; 00476 00477 if( flags & ClassHint ) { 00478 // Try to load the icon from the classhint if the app didn't specify 00479 // its own: 00480 if( result.isNull() ) { 00481 00482 XClassHint hint; 00483 if( XGetClassHint( tqt_xdisplay(), win, &hint ) ) { 00484 TQString className = hint.res_class; 00485 00486 TQPixmap pm = TDEGlobal::instance()->iconLoader()->loadIcon( className.lower(), TDEIcon::Small, iconWidth, 00487 TDEIcon::DefaultState, 0, true ); 00488 if( scale && !pm.isNull() ) 00489 result.convertFromImage( TQImage(pm.convertToImage()).smoothScale( width, height ) ); 00490 else 00491 result = pm; 00492 00493 XFree( hint.res_name ); 00494 XFree( hint.res_class ); 00495 } 00496 } 00497 } 00498 00499 if( flags & XApp ) { 00500 // If the icon is still a null pixmap, load the 'xapp' icon 00501 // as a last resort: 00502 if ( result.isNull() ) { 00503 TQPixmap pm = TDEGlobal::instance()->iconLoader()->loadIcon( "xapp", TDEIcon::Small, iconWidth, 00504 TDEIcon::DefaultState, 0, true ); 00505 if( scale && !pm.isNull() ) 00506 result.convertFromImage( TQImage(pm.convertToImage()).smoothScale( width, height ) ); 00507 else 00508 result = pm; 00509 } 00510 } 00511 #endif 00512 return result; 00513 } 00514 00515 void KWin::setIcons( WId win, const TQPixmap& icon, const TQPixmap& miniIcon ) 00516 { 00517 #ifdef Q_WS_X11 00518 if ( icon.isNull() ) 00519 return; 00520 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), 0 ); 00521 TQImage img = TQImage(icon.convertToImage()).convertDepth( 32 ); 00522 NETIcon ni; 00523 ni.size.width = img.size().width(); 00524 ni.size.height = img.size().height(); 00525 ni.data = (unsigned char *) img.bits(); 00526 info.setIcon( ni, true ); 00527 if ( miniIcon.isNull() ) 00528 return; 00529 img = TQImage(miniIcon.convertToImage()).convertDepth( 32 ); 00530 ni.size.width = img.size().width(); 00531 ni.size.height = img.size().height(); 00532 ni.data = (unsigned char *) img.bits(); 00533 info.setIcon( ni, false ); 00534 #endif 00535 } 00536 00537 void KWin::setType( WId win, NET::WindowType windowType ) 00538 { 00539 #ifdef Q_WS_X11 00540 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), 0 ); 00541 info.setWindowType( windowType ); 00542 #endif 00543 } 00544 00545 void KWin::setState( WId win, unsigned long state ) 00546 { 00547 #ifdef Q_WS_X11 00548 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), NET::WMState ); 00549 info.setState( state, state ); 00550 #endif 00551 } 00552 00553 void KWin::clearState( WId win, unsigned long state ) 00554 { 00555 #ifdef Q_WS_X11 00556 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), NET::WMState ); 00557 info.setState( 0, state ); 00558 #endif 00559 } 00560 00561 void KWin::setOpacity( WId win, uint percent ) 00562 { 00563 #ifdef Q_WS_X11 00564 twin_net_create_atoms(); 00565 if (percent > 99) 00566 XDeleteProperty (tqt_xdisplay(), win, kde_wm_window_opacity); 00567 else 00568 { 00569 long opacity = long(0xFFFFFFFF/100.0*percent); 00570 XChangeProperty(tqt_xdisplay(), win, kde_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &opacity, 1L); 00571 } 00572 #endif 00573 } 00574 00575 void KWin::setShadowSize( WId win, uint percent ) 00576 { 00577 #ifdef Q_WS_X11 00578 twin_net_create_atoms(); 00579 long shadowSize = long(0xFFFFFFFF/100.0*percent); 00580 XChangeProperty(tqt_xdisplay(), win, kde_wm_window_shadow, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &shadowSize, 1L); 00581 #endif 00582 } 00583 00584 void KWin::setOnAllDesktops( WId win, bool b ) 00585 { 00586 #ifdef Q_WS_X11 00587 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), NET::WMDesktop ); 00588 if ( b ) 00589 info.setDesktop( NETWinInfo::OnAllDesktops ); 00590 else if ( info.desktop() == NETWinInfo::OnAllDesktops ) { 00591 NETRootInfo rinfo( tqt_xdisplay(), NET::CurrentDesktop ); 00592 info.setDesktop( rinfo.currentDesktop() ); 00593 } 00594 #endif 00595 } 00596 00597 void KWin::setOnDesktop( WId win, int desktop ) 00598 { 00599 #ifdef Q_WS_X11 00600 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), NET::WMDesktop ); 00601 info.setDesktop( desktop ); 00602 #endif 00603 } 00604 00605 void KWin::setExtendedStrut( WId win, int left_width, int left_start, int left_end, 00606 int right_width, int right_start, int right_end, int top_width, int top_start, int top_end, 00607 int bottom_width, int bottom_start, int bottom_end ) 00608 { 00609 #ifdef Q_WS_X11 00610 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), 0 ); 00611 NETExtendedStrut strut; 00612 strut.left_width = left_width; 00613 strut.right_width = right_width; 00614 strut.top_width = top_width; 00615 strut.bottom_width = bottom_width; 00616 strut.left_start = left_start; 00617 strut.left_end = left_end; 00618 strut.right_start = right_start; 00619 strut.right_end = right_end; 00620 strut.top_start = top_start; 00621 strut.top_end = top_end; 00622 strut.bottom_start = bottom_start; 00623 strut.bottom_end = bottom_end; 00624 info.setExtendedStrut( strut ); 00625 #endif 00626 } 00627 00628 void KWin::setStrut( WId win, int left, int right, int top, int bottom ) 00629 { 00630 #ifdef Q_WS_X11 00631 NETWinInfo info( tqt_xdisplay(), win, tqt_xrootwin(), 0 ); 00632 NETStrut strut; 00633 strut.left = left; 00634 strut.right = right; 00635 strut.top = top; 00636 strut.bottom = bottom; 00637 info.setStrut( strut ); 00638 #endif 00639 } 00640 00641 int KWin::currentDesktop() 00642 { 00643 #ifdef Q_WS_X11 00644 if (!tqt_xdisplay()) 00645 #endif 00646 return 1; 00647 #ifdef Q_WS_X11 00648 NETRootInfo info( tqt_xdisplay(), NET::CurrentDesktop ); 00649 return info.currentDesktop(); 00650 #endif 00651 } 00652 00653 int KWin::numberOfDesktops() 00654 { 00655 #ifdef Q_WS_X11 00656 if (!tqt_xdisplay()) 00657 #endif 00658 return 0; 00659 #ifdef Q_WS_X11 00660 NETRootInfo info( tqt_xdisplay(), NET::NumberOfDesktops ); 00661 return info.numberOfDesktops(); 00662 #endif 00663 } 00664 00665 void KWin::setCurrentDesktop( int desktop ) 00666 { 00667 #ifdef Q_WS_X11 00668 NETRootInfo info( tqt_xdisplay(), NET::CurrentDesktop ); 00669 info.setCurrentDesktop( desktop ); 00670 #endif 00671 } 00672 00673 void KWin::setCurrentDesktopViewport( int desktop, TQPoint viewport ) 00674 { 00675 #ifdef Q_WS_X11 00676 NETRootInfo info( tqt_xdisplay(), NET::CurrentDesktop ); 00677 NETPoint netview; 00678 netview.x = viewport.x(); 00679 netview.y = viewport.y(); 00680 info.setDesktopViewport( desktop, netview ); 00681 #endif 00682 } 00683 00684 void KWin::iconifyWindow( WId win, bool animation) 00685 { 00686 #ifdef Q_WS_X11 00687 if ( !animation ) 00688 { 00689 twin_net_create_atoms(); 00690 sendClientMessageToRoot( win, kde_wm_change_state, IconicState, 1 ); 00691 } 00692 XIconifyWindow( tqt_xdisplay(), win, tqt_xscreen() ); 00693 #endif 00694 } 00695 00696 00697 void KWin::deIconifyWindow( WId win, bool animation ) 00698 { 00699 #ifdef Q_WS_X11 00700 if ( !animation ) 00701 { 00702 twin_net_create_atoms(); 00703 sendClientMessageToRoot( win, kde_wm_change_state, NormalState, 1 ); 00704 } 00705 XMapWindow( tqt_xdisplay(), win ); 00706 #endif 00707 } 00708 00709 void KWin::raiseWindow( WId win ) 00710 { 00711 #ifdef Q_WS_X11 00712 NETRootInfo info( tqt_xdisplay(), NET::Supported ); 00713 if( info.isSupported( NET::WM2RestackWindow )) 00714 info.restackRequest( win, None, Above ); 00715 else 00716 XRaiseWindow( tqt_xdisplay(), win ); 00717 #endif 00718 } 00719 00720 void KWin::lowerWindow( WId win ) 00721 { 00722 #ifdef Q_WS_X11 00723 NETRootInfo info( tqt_xdisplay(), NET::Supported ); 00724 if( info.isSupported( NET::WM2RestackWindow )) 00725 info.restackRequest( win, None, Below ); 00726 else 00727 XLowerWindow( tqt_xdisplay(), win ); 00728 #endif 00729 } 00730 00731 void KWin::appStarted() 00732 { 00733 #ifdef Q_WS_X11 00734 TDEStartupInfo::appStarted(); 00735 #endif 00736 } 00737 00738 class KWin::WindowInfoPrivate 00739 { 00740 public: 00741 WindowInfoPrivate() 00742 #ifdef Q_WS_X11 00743 : info( NULL ) 00744 #endif 00745 {} 00746 #ifdef Q_WS_X11 00747 ~WindowInfoPrivate() { delete info; } 00748 NETWinInfo* info; 00749 #endif 00750 WId win_; 00751 TQString name_; 00752 TQString iconic_name_; 00753 TQRect geometry_; 00754 TQRect frame_geometry_; 00755 int ref; 00756 bool valid; 00757 private: 00758 WindowInfoPrivate( const WindowInfoPrivate& ); 00759 void operator=( const WindowInfoPrivate& ); 00760 }; 00761 00762 // KWin::info() should be updated too if something has to be changed here 00763 KWin::WindowInfo::WindowInfo( WId win, unsigned long properties, unsigned long properties2 ) 00764 { 00765 #ifdef Q_WS_X11 00766 KXErrorHandler handler; 00767 d = new WindowInfoPrivate; 00768 d->ref = 1; 00769 if( properties == 0 ) 00770 properties = NET::WMState | 00771 NET::WMStrut | 00772 NET::WMWindowType | 00773 NET::WMName | 00774 NET::WMVisibleName | 00775 NET::WMIconName | 00776 NET::WMVisibleIconName | 00777 NET::WMDesktop | 00778 NET::WMPid | 00779 NET::WMKDEFrameStrut | 00780 NET::XAWMState | 00781 NET::WMGeometry; 00782 if( properties & NET::WMVisibleIconName ) 00783 properties |= NET::WMIconName | NET::WMVisibleName; // force, in case it will be used as a fallback 00784 if( properties & NET::WMVisibleName ) 00785 properties |= NET::WMName; // force, in case it will be used as a fallback 00786 if( properties2 & NET::WM2ExtendedStrut ) 00787 properties |= NET::WMStrut; // will be used as fallback 00788 properties |= NET::XAWMState; // force to get error detection for valid() 00789 unsigned long props[ 2 ] = { properties, properties2 }; 00790 d->info = new NETWinInfo( tqt_xdisplay(), win, tqt_xrootwin(), props, 2 ); 00791 d->win_ = win; 00792 if( properties & NET::WMName ) { 00793 if( d->info->name() && d->info->name()[ 0 ] != '\0' ) 00794 d->name_ = TQString::fromUtf8( d->info->name() ); 00795 else 00796 d->name_ = readNameProperty( win, XA_WM_NAME ); 00797 } 00798 if( properties & NET::WMIconName ) { 00799 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' ) 00800 d->iconic_name_ = TQString::fromUtf8( d->info->iconName()); 00801 else 00802 d->iconic_name_ = readNameProperty( win, XA_WM_ICON_NAME ); 00803 } 00804 if( properties & ( NET::WMGeometry | NET::WMKDEFrameStrut )) { 00805 NETRect frame, geom; 00806 d->info->kdeGeometry( frame, geom ); 00807 d->geometry_.setRect( geom.pos.x, geom.pos.y, geom.size.width, geom.size.height ); 00808 d->frame_geometry_.setRect( frame.pos.x, frame.pos.y, frame.size.width, frame.size.height ); 00809 } 00810 d->valid = !handler.error( false ); // no sync - NETWinInfo did roundtrips 00811 #endif 00812 } 00813 00814 // this one is only to make TQValueList<> or similar happy 00815 KWin::WindowInfo::WindowInfo() 00816 : d( NULL ) 00817 { 00818 } 00819 00820 KWin::WindowInfo::~WindowInfo() 00821 { 00822 if( d != NULL ) { 00823 if( --d->ref == 0 ) { 00824 delete d; 00825 } 00826 } 00827 } 00828 00829 KWin::WindowInfo::WindowInfo( const WindowInfo& wininfo ) 00830 : d( wininfo.d ) 00831 { 00832 if( d != NULL ) 00833 ++d->ref; 00834 } 00835 00836 KWin::WindowInfo& KWin::WindowInfo::operator=( const WindowInfo& wininfo ) 00837 { 00838 if( d != wininfo.d ) { 00839 if( d != NULL ) 00840 if( --d->ref == 0 ) 00841 delete d; 00842 d = wininfo.d; 00843 if( d != NULL ) 00844 ++d->ref; 00845 } 00846 return *this; 00847 } 00848 00849 bool KWin::WindowInfo::valid( bool withdrawn_is_valid ) const 00850 { 00851 if( !d->valid ) 00852 return false; 00853 if( !withdrawn_is_valid && mappingState() == NET::Withdrawn ) 00854 return false; 00855 return true; 00856 } 00857 00858 WId KWin::WindowInfo::win() const 00859 { 00860 return d->win_; 00861 } 00862 00863 unsigned long KWin::WindowInfo::state() const 00864 { 00865 #ifdef Q_WS_X11 00866 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMState ) == 0, 176 ) 00867 << "Pass NET::WMState to KWin::windowInfo()" << endl; 00868 return d->info->state(); 00869 #else 00870 return 0; 00871 #endif 00872 } 00873 00874 NET::MappingState KWin::WindowInfo::mappingState() const 00875 { 00876 #ifdef Q_WS_X11 00877 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::XAWMState ) == 0, 176 ) 00878 << "Pass NET::XAWMState to KWin::windowInfo()" << endl; 00879 return d->info->mappingState(); 00880 #else 00881 return NET::Visible; 00882 #endif 00883 } 00884 00885 NETExtendedStrut KWin::WindowInfo::extendedStrut() const 00886 { 00887 #ifdef Q_WS_X11 00888 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut ) == 0, 176 ) 00889 << "Pass NET::WM2ExtendedStrut to second argument of KWin::windowInfo()" << endl; 00890 NETExtendedStrut ext = d->info->extendedStrut(); 00891 NETStrut str = d->info->strut(); 00892 if( ext.left_width == 0 && ext.right_width == 0 && ext.top_width == 0 && ext.bottom_width == 0 00893 && ( str.left != 0 || str.right != 0 || str.top != 0 || str.bottom != 0 )) { 00894 // build extended from simple 00895 if( str.left != 0 ) { 00896 ext.left_width = str.left; 00897 ext.left_start = 0; 00898 ext.left_end = XDisplayHeight( tqt_xdisplay(), DefaultScreen( tqt_xdisplay())); 00899 } 00900 if( str.right != 0 ) { 00901 ext.right_width = str.right; 00902 ext.right_start = 0; 00903 ext.right_end = XDisplayHeight( tqt_xdisplay(), DefaultScreen( tqt_xdisplay())); 00904 } 00905 if( str.top != 0 ) { 00906 ext.top_width = str.top; 00907 ext.top_start = 0; 00908 ext.top_end = XDisplayWidth( tqt_xdisplay(), DefaultScreen( tqt_xdisplay())); 00909 } 00910 if( str.bottom != 0 ) { 00911 ext.bottom_width = str.bottom; 00912 ext.bottom_start = 0; 00913 ext.bottom_end = XDisplayWidth( tqt_xdisplay(), DefaultScreen( tqt_xdisplay())); 00914 } 00915 } 00916 return ext; 00917 #else 00918 NETExtendedStrut n; 00919 return n; 00920 #endif 00921 } 00922 00923 NETStrut KWin::WindowInfo::strut() const 00924 { 00925 #ifdef Q_WS_X11 00926 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMStrut ) == 0, 176 ) 00927 << "Pass NET::WMStrut to KWin::windowInfo()" << endl; 00928 return d->info->strut(); 00929 #else 00930 NETStrut n; 00931 return n; 00932 #endif 00933 } 00934 00935 NET::WindowType KWin::WindowInfo::windowType( int supported_types ) const 00936 { 00937 #ifdef Q_WS_X11 00938 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMWindowType ) == 0, 176 ) 00939 << "Pass NET::WMWindowType to KWin::windowInfo()" << endl; 00940 return d->info->windowType( supported_types ); 00941 #else 00942 return 0; 00943 #endif 00944 } 00945 00946 TQString KWin::WindowInfo::visibleNameWithState() const 00947 { 00948 TQString s = visibleName(); 00949 if ( isMinimized() ) { 00950 s.prepend('('); 00951 s.append(')'); 00952 } 00953 return s; 00954 } 00955 00956 TQString KWin::Info::visibleNameWithState() const 00957 { 00958 TQString s = visibleName; 00959 if ( isMinimized() ) { 00960 s.prepend('('); 00961 s.append(')'); 00962 } 00963 return s; 00964 } 00965 00966 TQString KWin::WindowInfo::visibleName() const 00967 { 00968 #ifdef Q_WS_X11 00969 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleName ) == 0, 176 ) 00970 << "Pass NET::WMVisibleName to KWin::windowInfo()" << endl; 00971 return d->info->visibleName() && d->info->visibleName()[ 0 ] != '\0' 00972 ? TQString::fromUtf8(d->info->visibleName()) : name(); 00973 #else 00974 return TQString("name"); 00975 #endif 00976 } 00977 00978 TQString KWin::WindowInfo::name() const 00979 { 00980 #ifdef Q_WS_X11 00981 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMName ) == 0, 176 ) 00982 << "Pass NET::WMName to KWin::windowInfo()" << endl; 00983 return d->name_; 00984 #else 00985 return TQString(); 00986 #endif 00987 } 00988 00989 TQString KWin::WindowInfo::visibleIconNameWithState() const 00990 { 00991 TQString s = visibleIconName(); 00992 if ( isMinimized() ) { 00993 s.prepend('('); 00994 s.append(')'); 00995 } 00996 return s; 00997 } 00998 00999 TQString KWin::WindowInfo::visibleIconName() const 01000 { 01001 #ifdef Q_WS_X11 01002 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMVisibleIconName ) == 0, 176 ) 01003 << "Pass NET::WMVisibleIconName to KWin::windowInfo()" << endl; 01004 if( d->info->visibleIconName() && d->info->visibleIconName()[ 0 ] != '\0' ) 01005 return TQString::fromUtf8( d->info->visibleIconName()); 01006 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' ) 01007 return TQString::fromUtf8( d->info->iconName()); 01008 if( !d->iconic_name_.isEmpty()) 01009 return d->iconic_name_; 01010 #endif 01011 return visibleName(); 01012 } 01013 01014 TQString KWin::WindowInfo::iconName() const 01015 { 01016 #ifdef Q_WS_X11 01017 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMIconName ) == 0, 176 ) 01018 << "Pass NET::WMIconName to KWin::windowInfo()" << endl; 01019 if( d->info->iconName() && d->info->iconName()[ 0 ] != '\0' ) 01020 return TQString::fromUtf8( d->info->iconName()); 01021 if( !d->iconic_name_.isEmpty()) 01022 return d->iconic_name_; 01023 #endif 01024 return name(); 01025 } 01026 01027 bool KWin::WindowInfo::isOnCurrentDesktop() const 01028 { 01029 #ifdef Q_WS_X11 01030 return isOnDesktop( KWin::currentDesktop()); 01031 #else 01032 return false; 01033 #endif 01034 } 01035 01036 bool KWin::WindowInfo::isOnDesktop( int desktop ) const 01037 { 01038 #ifdef Q_WS_X11 01039 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 ) 01040 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl; 01041 return d->info->desktop() == desktop || d->info->desktop() == NET::OnAllDesktops; 01042 #else 01043 return false; 01044 #endif 01045 } 01046 01047 bool KWin::WindowInfo::onAllDesktops() const 01048 { 01049 #ifdef Q_WS_X11 01050 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 ) 01051 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl; 01052 return d->info->desktop() == NET::OnAllDesktops; 01053 #else 01054 return false; 01055 #endif 01056 } 01057 01058 int KWin::WindowInfo::desktop() const 01059 { 01060 #ifdef Q_WS_X11 01061 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMDesktop ) == 0, 176 ) 01062 << "Pass NET::WMDesktop to KWin::windowInfo()" << endl; 01063 return d->info->desktop(); 01064 #else 01065 return 1; 01066 #endif 01067 } 01068 01069 TQRect KWin::WindowInfo::geometry() const 01070 { 01071 #ifdef Q_WS_X11 01072 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMGeometry ) == 0, 176 ) 01073 << "Pass NET::WMGeometry to KWin::windowInfo()" << endl; 01074 return d->geometry_; 01075 #else 01076 return TQRect( 100, 100, 200, 200 ); 01077 #endif 01078 } 01079 01080 TQRect KWin::WindowInfo::frameGeometry() const 01081 { 01082 #ifdef Q_WS_X11 01083 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS ] & NET::WMKDEFrameStrut ) == 0, 176 ) 01084 << "Pass NET::WMKDEFrameStrut to KWin::windowInfo()" << endl; 01085 return d->frame_geometry_; 01086 #else 01087 return TQRect(); 01088 #endif 01089 } 01090 01091 WId KWin::WindowInfo::transientFor() const 01092 { 01093 #ifdef Q_WS_X11 01094 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2TransientFor ) == 0, 176 ) 01095 << "Pass NET::WM2TransientFor to KWin::windowInfo()" << endl; 01096 return d->info->transientFor(); 01097 #else 01098 return 0; 01099 #endif 01100 } 01101 01102 WId KWin::WindowInfo::groupLeader() const 01103 { 01104 #ifdef Q_WS_X11 01105 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2GroupLeader ) == 0, 176 ) 01106 << "Pass NET::WM2GroupLeader to KWin::windowInfo()" << endl; 01107 return d->info->groupLeader(); 01108 #else 01109 return 0; 01110 #endif 01111 } 01112 01113 TQCString KWin::WindowInfo::windowClassClass() const 01114 { 01115 #ifdef Q_WS_X11 01116 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 ) 01117 << "Pass NET::WM2WindowClass to KWin::windowInfo()" << endl; 01118 return d->info->windowClassClass(); 01119 #else 01120 return 0; 01121 #endif 01122 } 01123 01124 TQCString KWin::WindowInfo::windowClassName() const 01125 { 01126 #ifdef Q_WS_X11 01127 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowClass ) == 0, 176 ) 01128 << "Pass NET::WM2WindowClass to KWin::windowInfo()" << endl; 01129 return d->info->windowClassName(); 01130 #else 01131 return 0; 01132 #endif 01133 } 01134 01135 TQCString KWin::WindowInfo::windowRole() const 01136 { 01137 #ifdef Q_WS_X11 01138 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2WindowRole ) == 0, 176 ) 01139 << "Pass NET::WM2WindowRole to KWin::windowInfo()" << endl; 01140 return d->info->windowRole(); 01141 #else 01142 return 0; 01143 #endif 01144 } 01145 01146 TQCString KWin::WindowInfo::clientMachine() const 01147 { 01148 #ifdef Q_WS_X11 01149 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2ClientMachine ) == 0, 176 ) 01150 << "Pass NET::WM2ClientMachine to KWin::windowInfo()" << endl; 01151 return d->info->clientMachine(); 01152 #else 01153 return 0; 01154 #endif 01155 } 01156 01157 bool KWin::WindowInfo::actionSupported( NET::Action action ) const 01158 { 01159 #ifdef Q_WS_X11 01160 kdWarning(( d->info->passedProperties()[ NETWinInfo::PROTOCOLS2 ] & NET::WM2AllowedActions ) == 0, 176 ) 01161 << "Pass NET::WM2AllowedActions to KWin::windowInfo()" << endl; 01162 if( allowedActionsSupported()) 01163 return d->info->allowedActions() & action; 01164 else 01165 #endif 01166 return true; // no idea if it's supported or not -> pretend it is 01167 } 01168 01169 // see NETWM spec section 7.6 01170 bool KWin::WindowInfo::isMinimized() const 01171 { 01172 #ifdef Q_WS_X11 01173 if( mappingState() != NET::Iconic ) 01174 return false; 01175 // NETWM 1.2 compliant WM - uses NET::Hidden for minimized windows 01176 if(( state() & NET::Hidden ) != 0 01177 && ( state() & NET::Shaded ) == 0 ) // shaded may have NET::Hidden too 01178 return true; 01179 // older WMs use WithdrawnState for other virtual desktops 01180 // and IconicState only for minimized 01181 return icccmCompliantMappingState() ? false : true; 01182 #else 01183 return false; 01184 #endif 01185 } 01186 01187 bool KWin::Info::isMinimized() const 01188 { 01189 #ifdef Q_WS_X11 01190 if( mappingState != NET::Iconic ) 01191 return false; 01192 // NETWM 1.2 compliant WM - uses NET::Hidden for minimized windows 01193 if(( state & NET::Hidden ) != 0 01194 && ( state & NET::Shaded ) == 0 ) // shaded may have NET::Hidden too 01195 return true; 01196 // older WMs use WithdrawnState for other virtual desktops 01197 // and IconicState only for minimized 01198 return icccmCompliantMappingState() ? false : true; 01199 #else 01200 return false; 01201 #endif 01202 } 01203 01204 bool KWin::Info::isIconified() const 01205 { 01206 return isMinimized(); 01207 } 01208 01209 bool KWin::icccmCompliantMappingState() 01210 { 01211 #ifdef Q_WS_X11 01212 static enum { noidea, yes, no } wm_is_1_2_compliant = noidea; 01213 if( wm_is_1_2_compliant == noidea ) { 01214 NETRootInfo info( tqt_xdisplay(), NET::Supported ); 01215 wm_is_1_2_compliant = info.isSupported( NET::Hidden ) ? yes : no; 01216 } 01217 return wm_is_1_2_compliant == yes; 01218 #else 01219 return false; 01220 #endif 01221 } 01222 01223 bool KWin::allowedActionsSupported() 01224 { 01225 #ifdef Q_WS_X11 01226 static enum { noidea, yes, no } wm_supports_allowed_actions = noidea; 01227 if( wm_supports_allowed_actions == noidea ) { 01228 NETRootInfo info( tqt_xdisplay(), NET::Supported ); 01229 wm_supports_allowed_actions = info.isSupported( NET::WM2AllowedActions ) ? yes : no; 01230 } 01231 return wm_supports_allowed_actions == yes; 01232 #else 01233 return false; 01234 #endif 01235 } 01236 01237 TQString KWin::readNameProperty( WId win, unsigned long atom ) 01238 { 01239 #ifdef Q_WS_X11 01240 XTextProperty tp; 01241 char **text = NULL; 01242 int count; 01243 #endif 01244 TQString result; 01245 #ifdef Q_WS_X11 01246 if ( XGetTextProperty( tqt_xdisplay(), win, &tp, atom ) != 0 && tp.value != NULL ) 01247 { 01248 if (!twin_UTF8_STRING) 01249 twin_UTF8_STRING = XInternAtom( tqt_xdisplay(), "UTF8_STRING", False); 01250 01251 if ( tp.encoding == twin_UTF8_STRING ) { 01252 result = TQString::fromUtf8 ( (const char*) tp.value ); 01253 } 01254 else if ( XmbTextPropertyToTextList( tqt_xdisplay(), &tp, &text, &count) == Success && 01255 text != NULL && count > 0 ) { 01256 result = TQString::fromLocal8Bit( text[0] ); 01257 } else if ( tp.encoding == XA_STRING ) 01258 result = TQString::fromLocal8Bit( (const char*) tp.value ); 01259 if( text != NULL ) 01260 XFreeStringList( text ); 01261 XFree( tp.value ); 01262 } 01263 #endif 01264 return result; 01265 } 01266 01267 //#endif