1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #ifdef USE_XTOOLKIT 32*cdf0e10cSrcweir # define SAL_XT 33*cdf0e10cSrcweir #endif 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir // -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #include <unistd.h> 38*cdf0e10cSrcweir #include <fcntl.h> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <cstdio> 41*cdf0e10cSrcweir #include <cstring> 42*cdf0e10cSrcweir #include <cstdlib> 43*cdf0e10cSrcweir #include <stdio.h> // snprintf, seems not to be in namespace std on every platform 44*cdf0e10cSrcweir #include <limits.h> 45*cdf0e10cSrcweir #include <errno.h> 46*cdf0e10cSrcweir #include <pthread.h> 47*cdf0e10cSrcweir #include <sys/resource.h> 48*cdf0e10cSrcweir #ifdef SUN 49*cdf0e10cSrcweir #include <sys/systeminfo.h> 50*cdf0e10cSrcweir #endif 51*cdf0e10cSrcweir #ifdef AIX 52*cdf0e10cSrcweir #include <strings.h> 53*cdf0e10cSrcweir #endif 54*cdf0e10cSrcweir #ifdef FREEBSD 55*cdf0e10cSrcweir #include <sys/types.h> 56*cdf0e10cSrcweir #include <sys/time.h> 57*cdf0e10cSrcweir #include <unistd.h> 58*cdf0e10cSrcweir #endif 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir #include <vos/process.hxx> 61*cdf0e10cSrcweir #include <vos/mutex.hxx> 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir #include "unx/Xproto.h" 64*cdf0e10cSrcweir #include "unx/saldisp.hxx" 65*cdf0e10cSrcweir #include "unx/saldata.hxx" 66*cdf0e10cSrcweir #include "unx/salframe.h" 67*cdf0e10cSrcweir #include "unx/sm.hxx" 68*cdf0e10cSrcweir #include "unx/i18n_im.hxx" 69*cdf0e10cSrcweir #include "unx/i18n_xkb.hxx" 70*cdf0e10cSrcweir #include "salinst.hxx" 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir #include <osl/signal.h> 73*cdf0e10cSrcweir #include <osl/thread.h> 74*cdf0e10cSrcweir #include <osl/process.h> 75*cdf0e10cSrcweir #include <rtl/strbuf.hxx> 76*cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir #include <tools/debug.hxx> 79*cdf0e10cSrcweir #include <vcl/svapp.hxx> 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir // -=-= <signal.h> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 82*cdf0e10cSrcweir #ifndef UNX 83*cdf0e10cSrcweir #ifndef SIGBUS 84*cdf0e10cSrcweir #define SIGBUS 10 85*cdf0e10cSrcweir #endif 86*cdf0e10cSrcweir #ifndef SIGSEGV 87*cdf0e10cSrcweir #define SIGSEGV 11 88*cdf0e10cSrcweir #endif 89*cdf0e10cSrcweir #ifndef SIGIOT 90*cdf0e10cSrcweir #define SIGIOT SIGABRT 91*cdf0e10cSrcweir #endif 92*cdf0e10cSrcweir #endif 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 95*cdf0e10cSrcweir static const struct timeval noyield__ = { 0, 0 }; 96*cdf0e10cSrcweir static const struct timeval yield__ = { 0, 10000 }; 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir static const char* XRequest[] = { 99*cdf0e10cSrcweir // see /usr/lib/X11/XErrorDB, /usr/openwin/lib/XErrorDB ... 100*cdf0e10cSrcweir NULL, 101*cdf0e10cSrcweir "X_CreateWindow", 102*cdf0e10cSrcweir "X_ChangeWindowAttributes", 103*cdf0e10cSrcweir "X_GetWindowAttributes", 104*cdf0e10cSrcweir "X_DestroyWindow", 105*cdf0e10cSrcweir "X_DestroySubwindows", 106*cdf0e10cSrcweir "X_ChangeSaveSet", 107*cdf0e10cSrcweir "X_ReparentWindow", 108*cdf0e10cSrcweir "X_MapWindow", 109*cdf0e10cSrcweir "X_MapSubwindows", 110*cdf0e10cSrcweir "X_UnmapWindow", 111*cdf0e10cSrcweir "X_UnmapSubwindows", 112*cdf0e10cSrcweir "X_ConfigureWindow", 113*cdf0e10cSrcweir "X_CirculateWindow", 114*cdf0e10cSrcweir "X_GetGeometry", 115*cdf0e10cSrcweir "X_QueryTree", 116*cdf0e10cSrcweir "X_InternAtom", 117*cdf0e10cSrcweir "X_GetAtomName", 118*cdf0e10cSrcweir "X_ChangeProperty", 119*cdf0e10cSrcweir "X_DeleteProperty", 120*cdf0e10cSrcweir "X_GetProperty", 121*cdf0e10cSrcweir "X_ListProperties", 122*cdf0e10cSrcweir "X_SetSelectionOwner", 123*cdf0e10cSrcweir "X_GetSelectionOwner", 124*cdf0e10cSrcweir "X_ConvertSelection", 125*cdf0e10cSrcweir "X_SendEvent", 126*cdf0e10cSrcweir "X_GrabPointer", 127*cdf0e10cSrcweir "X_UngrabPointer", 128*cdf0e10cSrcweir "X_GrabButton", 129*cdf0e10cSrcweir "X_UngrabButton", 130*cdf0e10cSrcweir "X_ChangeActivePointerGrab", 131*cdf0e10cSrcweir "X_GrabKeyboard", 132*cdf0e10cSrcweir "X_UngrabKeyboard", 133*cdf0e10cSrcweir "X_GrabKey", 134*cdf0e10cSrcweir "X_UngrabKey", 135*cdf0e10cSrcweir "X_AllowEvents", 136*cdf0e10cSrcweir "X_GrabServer", 137*cdf0e10cSrcweir "X_UngrabServer", 138*cdf0e10cSrcweir "X_QueryPointer", 139*cdf0e10cSrcweir "X_GetMotionEvents", 140*cdf0e10cSrcweir "X_TranslateCoords", 141*cdf0e10cSrcweir "X_WarpPointer", 142*cdf0e10cSrcweir "X_SetInputFocus", 143*cdf0e10cSrcweir "X_GetInputFocus", 144*cdf0e10cSrcweir "X_QueryKeymap", 145*cdf0e10cSrcweir "X_OpenFont", 146*cdf0e10cSrcweir "X_CloseFont", 147*cdf0e10cSrcweir "X_QueryFont", 148*cdf0e10cSrcweir "X_QueryTextExtents", 149*cdf0e10cSrcweir "X_ListFonts", 150*cdf0e10cSrcweir "X_ListFontsWithInfo", 151*cdf0e10cSrcweir "X_SetFontPath", 152*cdf0e10cSrcweir "X_GetFontPath", 153*cdf0e10cSrcweir "X_CreatePixmap", 154*cdf0e10cSrcweir "X_FreePixmap", 155*cdf0e10cSrcweir "X_CreateGC", 156*cdf0e10cSrcweir "X_ChangeGC", 157*cdf0e10cSrcweir "X_CopyGC", 158*cdf0e10cSrcweir "X_SetDashes", 159*cdf0e10cSrcweir "X_SetClipRectangles", 160*cdf0e10cSrcweir "X_FreeGC", 161*cdf0e10cSrcweir "X_ClearArea", 162*cdf0e10cSrcweir "X_CopyArea", 163*cdf0e10cSrcweir "X_CopyPlane", 164*cdf0e10cSrcweir "X_PolyPoint", 165*cdf0e10cSrcweir "X_PolyLine", 166*cdf0e10cSrcweir "X_PolySegment", 167*cdf0e10cSrcweir "X_PolyRectangle", 168*cdf0e10cSrcweir "X_PolyArc", 169*cdf0e10cSrcweir "X_FillPoly", 170*cdf0e10cSrcweir "X_PolyFillRectangle", 171*cdf0e10cSrcweir "X_PolyFillArc", 172*cdf0e10cSrcweir "X_PutImage", 173*cdf0e10cSrcweir "X_GetImage", 174*cdf0e10cSrcweir "X_PolyText8", 175*cdf0e10cSrcweir "X_PolyText16", 176*cdf0e10cSrcweir "X_ImageText8", 177*cdf0e10cSrcweir "X_ImageText16", 178*cdf0e10cSrcweir "X_CreateColormap", 179*cdf0e10cSrcweir "X_FreeColormap", 180*cdf0e10cSrcweir "X_CopyColormapAndFree", 181*cdf0e10cSrcweir "X_InstallColormap", 182*cdf0e10cSrcweir "X_UninstallColormap", 183*cdf0e10cSrcweir "X_ListInstalledColormaps", 184*cdf0e10cSrcweir "X_AllocColor", 185*cdf0e10cSrcweir "X_AllocNamedColor", 186*cdf0e10cSrcweir "X_AllocColorCells", 187*cdf0e10cSrcweir "X_AllocColorPlanes", 188*cdf0e10cSrcweir "X_FreeColors", 189*cdf0e10cSrcweir "X_StoreColors", 190*cdf0e10cSrcweir "X_StoreNamedColor", 191*cdf0e10cSrcweir "X_QueryColors", 192*cdf0e10cSrcweir "X_LookupColor", 193*cdf0e10cSrcweir "X_CreateCursor", 194*cdf0e10cSrcweir "X_CreateGlyphCursor", 195*cdf0e10cSrcweir "X_FreeCursor", 196*cdf0e10cSrcweir "X_RecolorCursor", 197*cdf0e10cSrcweir "X_QueryBestSize", 198*cdf0e10cSrcweir "X_QueryExtension", 199*cdf0e10cSrcweir "X_ListExtensions", 200*cdf0e10cSrcweir "X_ChangeKeyboardMapping", 201*cdf0e10cSrcweir "X_GetKeyboardMapping", 202*cdf0e10cSrcweir "X_ChangeKeyboardControl", 203*cdf0e10cSrcweir "X_GetKeyboardControl", 204*cdf0e10cSrcweir "X_Bell", 205*cdf0e10cSrcweir "X_ChangePointerControl", 206*cdf0e10cSrcweir "X_GetPointerControl", 207*cdf0e10cSrcweir "X_SetScreenSaver", 208*cdf0e10cSrcweir "X_GetScreenSaver", 209*cdf0e10cSrcweir "X_ChangeHosts", 210*cdf0e10cSrcweir "X_ListHosts", 211*cdf0e10cSrcweir "X_SetAccessControl", 212*cdf0e10cSrcweir "X_SetCloseDownMode", 213*cdf0e10cSrcweir "X_KillClient", 214*cdf0e10cSrcweir "X_RotateProperties", 215*cdf0e10cSrcweir "X_ForceScreenSaver", 216*cdf0e10cSrcweir "X_SetPointerMapping", 217*cdf0e10cSrcweir "X_GetPointerMapping", 218*cdf0e10cSrcweir "X_SetModifierMapping", 219*cdf0e10cSrcweir "X_GetModifierMapping", 220*cdf0e10cSrcweir NULL, 221*cdf0e10cSrcweir NULL, 222*cdf0e10cSrcweir NULL, 223*cdf0e10cSrcweir NULL, 224*cdf0e10cSrcweir NULL, 225*cdf0e10cSrcweir NULL, 226*cdf0e10cSrcweir NULL, 227*cdf0e10cSrcweir "X_NoOperation" 228*cdf0e10cSrcweir }; 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir // -=-= C statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 231*cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir int X11SalData::XErrorHdl( Display *pDisplay, XErrorEvent *pEvent ) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir GetX11SalData()->XError( pDisplay, pEvent ); 236*cdf0e10cSrcweir return 0; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir int X11SalData::XIOErrorHdl( Display * ) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir /* #106197# hack: until a real shutdown procedure exists 242*cdf0e10cSrcweir * _exit ASAP 243*cdf0e10cSrcweir */ 244*cdf0e10cSrcweir if( ImplGetSVData()->maAppData.mbAppQuit ) 245*cdf0e10cSrcweir _exit(1); 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir // really bad hack 248*cdf0e10cSrcweir if( ! SessionManagerClient::checkDocumentsSaved() ) 249*cdf0e10cSrcweir /* oslSignalAction eToDo = */ osl_raiseSignal (OSL_SIGNAL_USER_X11SUBSYSTEMERROR, NULL); 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir std::fprintf( stderr, "X IO Error\n" ); 252*cdf0e10cSrcweir std::fflush( stdout ); 253*cdf0e10cSrcweir std::fflush( stderr ); 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir /* #106197# the same reasons to use _exit instead of exit in salmain 256*cdf0e10cSrcweir * do apply here. Since there is nothing to be done after an XIO 257*cdf0e10cSrcweir * error we have to _exit immediately. 258*cdf0e10cSrcweir */ 259*cdf0e10cSrcweir _exit(0); 260*cdf0e10cSrcweir return 0; 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir // -=-= SalData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 264*cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 265*cdf0e10cSrcweir #include <pthread.h> 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir X11SalData::X11SalData() 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir bNoExceptions_ = !!getenv( "SAL_NOSEGV" ); 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir pXLib_ = NULL; 272*cdf0e10cSrcweir m_pSalDisplay = NULL; 273*cdf0e10cSrcweir m_pInstance = NULL; 274*cdf0e10cSrcweir m_pPlugin = NULL; 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir hMainThread_ = pthread_self(); 277*cdf0e10cSrcweir osl_getLocalHostname( &maLocalHostName.pData ); 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir 280*cdf0e10cSrcweir X11SalData::~X11SalData() 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir DeleteDisplay(); 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir void X11SalData::DeleteDisplay() 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir delete m_pSalDisplay; 288*cdf0e10cSrcweir m_pSalDisplay = NULL; 289*cdf0e10cSrcweir delete pXLib_; 290*cdf0e10cSrcweir pXLib_ = NULL; 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir void X11SalData::Init() 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir pXLib_ = new SalXLib(); 296*cdf0e10cSrcweir pXLib_->Init(); 297*cdf0e10cSrcweir } 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir void X11SalData::initNWF( void ) 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir void X11SalData::deInitNWF( void ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir // -=-= SalXLib =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 308*cdf0e10cSrcweir // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 309*cdf0e10cSrcweir SalXLib::SalXLib() 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir m_aTimeout.tv_sec = 0; 312*cdf0e10cSrcweir m_aTimeout.tv_usec = 0; 313*cdf0e10cSrcweir m_nTimeoutMS = 0; 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir nFDs_ = 0; 316*cdf0e10cSrcweir FD_ZERO( &aReadFDS_ ); 317*cdf0e10cSrcweir FD_ZERO( &aExceptionFDS_ ); 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1; 320*cdf0e10cSrcweir if (pipe (m_pTimeoutFDS) != -1) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir // initialize 'wakeup' pipe. 323*cdf0e10cSrcweir int flags; 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir // set close-on-exec descriptor flag. 326*cdf0e10cSrcweir if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir flags |= FD_CLOEXEC; 329*cdf0e10cSrcweir fcntl (m_pTimeoutFDS[0], F_SETFD, flags); 330*cdf0e10cSrcweir } 331*cdf0e10cSrcweir if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir flags |= FD_CLOEXEC; 334*cdf0e10cSrcweir fcntl (m_pTimeoutFDS[1], F_SETFD, flags); 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir // set non-blocking I/O flag. 338*cdf0e10cSrcweir if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir flags |= O_NONBLOCK; 341*cdf0e10cSrcweir fcntl (m_pTimeoutFDS[0], F_SETFL, flags); 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1) 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir flags |= O_NONBLOCK; 346*cdf0e10cSrcweir fcntl (m_pTimeoutFDS[1], F_SETFL, flags); 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir // insert [0] into read descriptor set. 350*cdf0e10cSrcweir FD_SET( m_pTimeoutFDS[0], &aReadFDS_ ); 351*cdf0e10cSrcweir nFDs_ = m_pTimeoutFDS[0] + 1; 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir m_bHaveSystemChildFrames = false; 355*cdf0e10cSrcweir m_aOrigXIOErrorHandler = XSetIOErrorHandler ( (XIOErrorHandler)X11SalData::XIOErrorHdl ); 356*cdf0e10cSrcweir PushXErrorLevel( !!getenv( "SAL_IGNOREXERRORS" ) ); 357*cdf0e10cSrcweir } 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir SalXLib::~SalXLib() 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir // close 'wakeup' pipe. 362*cdf0e10cSrcweir close (m_pTimeoutFDS[0]); 363*cdf0e10cSrcweir close (m_pTimeoutFDS[1]); 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir PopXErrorLevel(); 366*cdf0e10cSrcweir XSetIOErrorHandler (m_aOrigXIOErrorHandler); 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir void SalXLib::PushXErrorLevel( bool bIgnore ) 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir m_aXErrorHandlerStack.push_back( XErrorStackEntry() ); 372*cdf0e10cSrcweir XErrorStackEntry& rEnt = m_aXErrorHandlerStack.back(); 373*cdf0e10cSrcweir rEnt.m_bWas = false; 374*cdf0e10cSrcweir rEnt.m_bIgnore = bIgnore; 375*cdf0e10cSrcweir rEnt.m_nLastErrorRequest = 0; 376*cdf0e10cSrcweir rEnt.m_aHandler = XSetErrorHandler( (XErrorHandler)X11SalData::XErrorHdl ); 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir void SalXLib::PopXErrorLevel() 380*cdf0e10cSrcweir { 381*cdf0e10cSrcweir if( m_aXErrorHandlerStack.size() ) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir XSetErrorHandler( m_aXErrorHandlerStack.back().m_aHandler ); 384*cdf0e10cSrcweir m_aXErrorHandlerStack.pop_back(); 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir 388*cdf0e10cSrcweir void SalXLib::Init() 389*cdf0e10cSrcweir { 390*cdf0e10cSrcweir SalI18N_InputMethod* pInputMethod = new SalI18N_InputMethod; 391*cdf0e10cSrcweir pInputMethod->SetLocale(); 392*cdf0e10cSrcweir XrmInitialize(); 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir /* 395*cdf0e10cSrcweir * open connection to X11 Display 396*cdf0e10cSrcweir * try in this order: 397*cdf0e10cSrcweir * o -display command line parameter, 398*cdf0e10cSrcweir * o $DISPLAY environment variable 399*cdf0e10cSrcweir * o default display 400*cdf0e10cSrcweir */ 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir Display *pDisp = NULL; 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir // is there a -display command line parameter? 405*cdf0e10cSrcweir vos::OExtCommandLine aCommandLine; 406*cdf0e10cSrcweir sal_uInt32 nParams = aCommandLine.getCommandArgCount(); 407*cdf0e10cSrcweir rtl::OUString aParam; 408*cdf0e10cSrcweir rtl::OString aDisplay; 409*cdf0e10cSrcweir for (sal_uInt16 i=0; i<nParams; i++) 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir aCommandLine.getCommandArg(i, aParam); 412*cdf0e10cSrcweir if (aParam.equalsAscii("-display")) 413*cdf0e10cSrcweir { 414*cdf0e10cSrcweir aCommandLine.getCommandArg(i+1, aParam); 415*cdf0e10cSrcweir aDisplay = rtl::OUStringToOString( 416*cdf0e10cSrcweir aParam, osl_getThreadTextEncoding()); 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir if ((pDisp = XOpenDisplay(aDisplay.getStr()))!=NULL) 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir /* 421*cdf0e10cSrcweir * if a -display switch was used, we need 422*cdf0e10cSrcweir * to set the environment accoringly since 423*cdf0e10cSrcweir * the clipboard build another connection 424*cdf0e10cSrcweir * to the xserver using $DISPLAY 425*cdf0e10cSrcweir */ 426*cdf0e10cSrcweir rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("DISPLAY")); 427*cdf0e10cSrcweir osl_setEnvironment(envVar.pData, aParam.pData); 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir break; 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir if (!pDisp && !aDisplay.getLength()) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir // Open $DISPLAY or default... 436*cdf0e10cSrcweir char *pDisplay = getenv("DISPLAY"); 437*cdf0e10cSrcweir if (pDisplay != NULL) 438*cdf0e10cSrcweir aDisplay = rtl::OString(pDisplay); 439*cdf0e10cSrcweir pDisp = XOpenDisplay(pDisplay); 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir if ( !pDisp ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir rtl::OUString aProgramFileURL; 445*cdf0e10cSrcweir osl_getExecutableFile( &aProgramFileURL.pData ); 446*cdf0e10cSrcweir rtl::OUString aProgramSystemPath; 447*cdf0e10cSrcweir osl_getSystemPathFromFileURL (aProgramFileURL.pData, &aProgramSystemPath.pData); 448*cdf0e10cSrcweir rtl::OString aProgramName = rtl::OUStringToOString( 449*cdf0e10cSrcweir aProgramSystemPath, 450*cdf0e10cSrcweir osl_getThreadTextEncoding() ); 451*cdf0e10cSrcweir std::fprintf( stderr, "%s X11 error: Can't open display: %s\n", 452*cdf0e10cSrcweir aProgramName.getStr(), aDisplay.getStr()); 453*cdf0e10cSrcweir std::fprintf( stderr, " Set DISPLAY environment variable, use -display option\n"); 454*cdf0e10cSrcweir std::fprintf( stderr, " or check permissions of your X-Server\n"); 455*cdf0e10cSrcweir std::fprintf( stderr, " (See \"man X\" resp. \"man xhost\" for details)\n"); 456*cdf0e10cSrcweir std::fflush( stderr ); 457*cdf0e10cSrcweir exit(0); 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir SalDisplay *pSalDisplay = new SalX11Display( pDisp ); 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir pInputMethod->CreateMethod( pDisp ); 463*cdf0e10cSrcweir pInputMethod->AddConnectionWatch( pDisp, (void*)this ); 464*cdf0e10cSrcweir pSalDisplay->SetInputMethod( pInputMethod ); 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir PushXErrorLevel( true ); 467*cdf0e10cSrcweir SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp ); 468*cdf0e10cSrcweir XSync( pDisp, False ); 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir pKbdExtension->UseExtension( ! HasXErrorOccured() ); 471*cdf0e10cSrcweir PopXErrorLevel(); 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir pSalDisplay->SetKbdExtension( pKbdExtension ); 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir extern "C" { 477*cdf0e10cSrcweir void EmitFontpathWarning( void ) 478*cdf0e10cSrcweir { 479*cdf0e10cSrcweir static Bool bOnce = False; 480*cdf0e10cSrcweir if ( !bOnce ) 481*cdf0e10cSrcweir { 482*cdf0e10cSrcweir bOnce = True; 483*cdf0e10cSrcweir std::fprintf( stderr, "Please verify your fontpath settings\n" 484*cdf0e10cSrcweir "\t(See \"man xset\" for details" 485*cdf0e10cSrcweir " or ask your system administrator)\n" ); 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir } /* extern "C" */ 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir static void PrintXError( Display *pDisplay, XErrorEvent *pEvent ) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir char msg[ 120 ] = ""; 494*cdf0e10cSrcweir #if ! ( defined LINUX && defined PPC ) 495*cdf0e10cSrcweir XGetErrorText( pDisplay, pEvent->error_code, msg, sizeof( msg ) ); 496*cdf0e10cSrcweir #endif 497*cdf0e10cSrcweir std::fprintf( stderr, "X-Error: %s\n", msg ); 498*cdf0e10cSrcweir if( pEvent->request_code < capacityof( XRequest ) ) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir const char* pName = XRequest[pEvent->request_code]; 501*cdf0e10cSrcweir if( !pName ) 502*cdf0e10cSrcweir pName = "BadRequest?"; 503*cdf0e10cSrcweir std::fprintf( stderr, "\tMajor opcode: %d (%s)\n", pEvent->request_code, pName ); 504*cdf0e10cSrcweir } 505*cdf0e10cSrcweir else 506*cdf0e10cSrcweir { 507*cdf0e10cSrcweir std::fprintf( stderr, "\tMajor opcode: %d\n", pEvent->request_code ); 508*cdf0e10cSrcweir // TODO: also display extension name? 509*cdf0e10cSrcweir std::fprintf( stderr, "\tMinor opcode: %d\n", pEvent->minor_code ); 510*cdf0e10cSrcweir } 511*cdf0e10cSrcweir 512*cdf0e10cSrcweir std::fprintf( stderr, "\tResource ID: 0x%lx\n", 513*cdf0e10cSrcweir pEvent->resourceid ); 514*cdf0e10cSrcweir std::fprintf( stderr, "\tSerial No: %ld (%ld)\n", 515*cdf0e10cSrcweir pEvent->serial, LastKnownRequestProcessed(pDisplay) ); 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir if( !getenv( "SAL_SYNCHRONIZE" ) ) 518*cdf0e10cSrcweir { 519*cdf0e10cSrcweir std::fprintf( stderr, "These errors are reported asynchronously,\n"); 520*cdf0e10cSrcweir std::fprintf( stderr, "set environment variable SAL_SYNCHRONIZE to 1 to help debugging\n"); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir std::fflush( stdout ); 524*cdf0e10cSrcweir std::fflush( stderr ); 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir void SalXLib::XError( Display *pDisplay, XErrorEvent *pEvent ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir if( m_bHaveSystemChildFrames ) 530*cdf0e10cSrcweir return; 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir if( ! m_aXErrorHandlerStack.back().m_bIgnore ) 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir if ( (pEvent->error_code == BadAlloc) 535*cdf0e10cSrcweir && (pEvent->request_code == X_OpenFont) ) 536*cdf0e10cSrcweir { 537*cdf0e10cSrcweir static Bool bOnce = False; 538*cdf0e10cSrcweir if ( !bOnce ) 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir std::fprintf(stderr, "X-Error occured in a request for X_OpenFont\n"); 541*cdf0e10cSrcweir EmitFontpathWarning(); 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir bOnce = True ; 544*cdf0e10cSrcweir } 545*cdf0e10cSrcweir return; 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir /* ignore 548*cdf0e10cSrcweir * X_SetInputFocus: it's a hint only anyway 549*cdf0e10cSrcweir * X_GetProperty: this is part of the XGetWindowProperty call and will 550*cdf0e10cSrcweir * be handled by the return value of that function 551*cdf0e10cSrcweir */ 552*cdf0e10cSrcweir else if( pEvent->request_code == X_SetInputFocus || 553*cdf0e10cSrcweir pEvent->request_code == X_GetProperty 554*cdf0e10cSrcweir ) 555*cdf0e10cSrcweir return; 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir if( pDisplay != GetX11SalData()->GetDisplay()->GetDisplay() ) 559*cdf0e10cSrcweir return; 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir PrintXError( pDisplay, pEvent ); 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir oslSignalAction eToDo = osl_raiseSignal (OSL_SIGNAL_USER_X11SUBSYSTEMERROR, NULL); 564*cdf0e10cSrcweir switch (eToDo) 565*cdf0e10cSrcweir { 566*cdf0e10cSrcweir case osl_Signal_ActIgnore : 567*cdf0e10cSrcweir return; 568*cdf0e10cSrcweir case osl_Signal_ActAbortApp : 569*cdf0e10cSrcweir abort(); 570*cdf0e10cSrcweir case osl_Signal_ActKillApp : 571*cdf0e10cSrcweir exit(0); 572*cdf0e10cSrcweir case osl_Signal_ActCallNextHdl : 573*cdf0e10cSrcweir break; 574*cdf0e10cSrcweir default : 575*cdf0e10cSrcweir break; 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir } 579*cdf0e10cSrcweir 580*cdf0e10cSrcweir m_aXErrorHandlerStack.back().m_bWas = true; 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir struct YieldEntry 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir YieldEntry* next; // pointer to next entry 586*cdf0e10cSrcweir int fd; // file descriptor for reading 587*cdf0e10cSrcweir void* data; // data for predicate and callback 588*cdf0e10cSrcweir YieldFunc pending; // predicate (determins pending events) 589*cdf0e10cSrcweir YieldFunc queued; // read and queue up events 590*cdf0e10cSrcweir YieldFunc handle; // handle pending events 591*cdf0e10cSrcweir 592*cdf0e10cSrcweir inline int HasPendingEvent() const { return pending( fd, data ); } 593*cdf0e10cSrcweir inline int IsEventQueued() const { return queued( fd, data ); } 594*cdf0e10cSrcweir inline void HandleNextEvent() const { handle( fd, data ); } 595*cdf0e10cSrcweir }; 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir #define MAX_NUM_DESCRIPTORS 128 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir static YieldEntry yieldTable[ MAX_NUM_DESCRIPTORS ]; 600*cdf0e10cSrcweir 601*cdf0e10cSrcweir void SalXLib::Insert( int nFD, void* data, 602*cdf0e10cSrcweir YieldFunc pending, 603*cdf0e10cSrcweir YieldFunc queued, 604*cdf0e10cSrcweir YieldFunc handle ) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir DBG_ASSERT( nFD, "can not insert stdin descriptor" ); 607*cdf0e10cSrcweir DBG_ASSERT( !yieldTable[nFD].fd, "SalXLib::Insert fd twice" ); 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir yieldTable[nFD].fd = nFD; 610*cdf0e10cSrcweir yieldTable[nFD].data = data; 611*cdf0e10cSrcweir yieldTable[nFD].pending = pending; 612*cdf0e10cSrcweir yieldTable[nFD].queued = queued; 613*cdf0e10cSrcweir yieldTable[nFD].handle = handle; 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir FD_SET( nFD, &aReadFDS_ ); 616*cdf0e10cSrcweir FD_SET( nFD, &aExceptionFDS_ ); 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir if( nFD >= nFDs_ ) 619*cdf0e10cSrcweir nFDs_ = nFD + 1; 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir void SalXLib::Remove( int nFD ) 623*cdf0e10cSrcweir { 624*cdf0e10cSrcweir FD_CLR( nFD, &aReadFDS_ ); 625*cdf0e10cSrcweir FD_CLR( nFD, &aExceptionFDS_ ); 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir yieldTable[nFD].fd = 0; 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir if ( nFD == nFDs_ ) 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir for ( nFD = nFDs_ - 1; 632*cdf0e10cSrcweir nFD >= 0 && !yieldTable[nFD].fd; 633*cdf0e10cSrcweir nFD-- ) ; 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir nFDs_ = nFD + 1; 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir bool SalXLib::CheckTimeout( bool bExecuteTimers ) 640*cdf0e10cSrcweir { 641*cdf0e10cSrcweir bool bRet = false; 642*cdf0e10cSrcweir if( m_aTimeout.tv_sec ) // timer is started 643*cdf0e10cSrcweir { 644*cdf0e10cSrcweir timeval aTimeOfDay; 645*cdf0e10cSrcweir gettimeofday( &aTimeOfDay, 0 ); 646*cdf0e10cSrcweir if( aTimeOfDay >= m_aTimeout ) 647*cdf0e10cSrcweir { 648*cdf0e10cSrcweir bRet = true; 649*cdf0e10cSrcweir if( bExecuteTimers ) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir // timed out, update timeout 652*cdf0e10cSrcweir m_aTimeout = aTimeOfDay; 653*cdf0e10cSrcweir /* 654*cdf0e10cSrcweir * #107827# autorestart immediately, will be stopped (or set 655*cdf0e10cSrcweir * to different value in notify hdl if necessary; 656*cdf0e10cSrcweir * CheckTimeout should return false while 657*cdf0e10cSrcweir * timers are being dispatched. 658*cdf0e10cSrcweir */ 659*cdf0e10cSrcweir m_aTimeout += m_nTimeoutMS; 660*cdf0e10cSrcweir // notify 661*cdf0e10cSrcweir GetX11SalData()->Timeout(); 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir return bRet; 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) 669*cdf0e10cSrcweir { 670*cdf0e10cSrcweir // check for timeouts here if you want to make screenshots 671*cdf0e10cSrcweir static char* p_prioritize_timer = getenv ("SAL_HIGHPRIORITY_REPAINT"); 672*cdf0e10cSrcweir if (p_prioritize_timer != NULL) 673*cdf0e10cSrcweir CheckTimeout(); 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir const int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1; 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir // first, check for already queued events. 678*cdf0e10cSrcweir for ( int nFD = 0; nFD < nFDs_; nFD++ ) 679*cdf0e10cSrcweir { 680*cdf0e10cSrcweir YieldEntry* pEntry = &(yieldTable[nFD]); 681*cdf0e10cSrcweir if ( pEntry->fd ) 682*cdf0e10cSrcweir { 683*cdf0e10cSrcweir DBG_ASSERT( nFD == pEntry->fd, "wrong fd in Yield()" ); 684*cdf0e10cSrcweir for( int i = 0; i < nMaxEvents && pEntry->HasPendingEvent(); i++ ) 685*cdf0e10cSrcweir { 686*cdf0e10cSrcweir pEntry->HandleNextEvent(); 687*cdf0e10cSrcweir if( ! bHandleAllCurrentEvents ) 688*cdf0e10cSrcweir return; 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir } 691*cdf0e10cSrcweir } 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir // next, select with or without timeout according to bWait. 694*cdf0e10cSrcweir int nFDs = nFDs_; 695*cdf0e10cSrcweir fd_set ReadFDS = aReadFDS_; 696*cdf0e10cSrcweir fd_set ExceptionFDS = aExceptionFDS_; 697*cdf0e10cSrcweir int nFound = 0; 698*cdf0e10cSrcweir 699*cdf0e10cSrcweir timeval Timeout = noyield__; 700*cdf0e10cSrcweir timeval *pTimeout = &Timeout; 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir if (bWait) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir pTimeout = 0; 705*cdf0e10cSrcweir if (m_aTimeout.tv_sec) // Timer is started. 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir // determine remaining timeout. 708*cdf0e10cSrcweir gettimeofday (&Timeout, 0); 709*cdf0e10cSrcweir Timeout = m_aTimeout - Timeout; 710*cdf0e10cSrcweir if (yield__ >= Timeout) 711*cdf0e10cSrcweir { 712*cdf0e10cSrcweir // guard against micro timeout. 713*cdf0e10cSrcweir Timeout = yield__; 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir pTimeout = &Timeout; 716*cdf0e10cSrcweir } 717*cdf0e10cSrcweir } 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir // release YieldMutex (and re-acquire at block end) 721*cdf0e10cSrcweir YieldMutexReleaser aReleaser; 722*cdf0e10cSrcweir nFound = select( nFDs, &ReadFDS, NULL, &ExceptionFDS, pTimeout ); 723*cdf0e10cSrcweir } 724*cdf0e10cSrcweir if( nFound < 0 ) // error 725*cdf0e10cSrcweir { 726*cdf0e10cSrcweir #ifdef DBG_UTIL 727*cdf0e10cSrcweir std::fprintf( stderr, "SalXLib::Yield e=%d f=%d\n", errno, nFound ); 728*cdf0e10cSrcweir #endif 729*cdf0e10cSrcweir if( EINTR == errno ) 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir errno = 0; 732*cdf0e10cSrcweir } 733*cdf0e10cSrcweir } 734*cdf0e10cSrcweir 735*cdf0e10cSrcweir // usually handle timeouts here (as in 5.2) 736*cdf0e10cSrcweir if (p_prioritize_timer == NULL) 737*cdf0e10cSrcweir CheckTimeout(); 738*cdf0e10cSrcweir 739*cdf0e10cSrcweir // handle wakeup events. 740*cdf0e10cSrcweir if ((nFound > 0) && (FD_ISSET(m_pTimeoutFDS[0], &ReadFDS))) 741*cdf0e10cSrcweir { 742*cdf0e10cSrcweir int buffer; 743*cdf0e10cSrcweir while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0) 744*cdf0e10cSrcweir continue; 745*cdf0e10cSrcweir nFound -= 1; 746*cdf0e10cSrcweir } 747*cdf0e10cSrcweir 748*cdf0e10cSrcweir // handle other events. 749*cdf0e10cSrcweir if( nFound > 0 ) 750*cdf0e10cSrcweir { 751*cdf0e10cSrcweir // now we are in the protected section ! 752*cdf0e10cSrcweir // recall select if we have acquired fd's, ready for reading, 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir struct timeval noTimeout = { 0, 0 }; 755*cdf0e10cSrcweir nFound = select( nFDs_, &ReadFDS, NULL, 756*cdf0e10cSrcweir &ExceptionFDS, &noTimeout ); 757*cdf0e10cSrcweir 758*cdf0e10cSrcweir // someone-else has done the job for us 759*cdf0e10cSrcweir if (nFound == 0) 760*cdf0e10cSrcweir return; 761*cdf0e10cSrcweir 762*cdf0e10cSrcweir for ( int nFD = 0; nFD < nFDs_; nFD++ ) 763*cdf0e10cSrcweir { 764*cdf0e10cSrcweir YieldEntry* pEntry = &(yieldTable[nFD]); 765*cdf0e10cSrcweir if ( pEntry->fd ) 766*cdf0e10cSrcweir { 767*cdf0e10cSrcweir if ( FD_ISSET( nFD, &ExceptionFDS ) ) { 768*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 769*cdf0e10cSrcweir std::fprintf( stderr, "SalXLib::Yield exception\n" ); 770*cdf0e10cSrcweir #endif 771*cdf0e10cSrcweir nFound--; 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir if ( FD_ISSET( nFD, &ReadFDS ) ) 774*cdf0e10cSrcweir { 775*cdf0e10cSrcweir for( int i = 0; pEntry->IsEventQueued() && i < nMaxEvents; i++ ) 776*cdf0e10cSrcweir { 777*cdf0e10cSrcweir pEntry->HandleNextEvent(); 778*cdf0e10cSrcweir // if a recursive call has done the job 779*cdf0e10cSrcweir // so abort here 780*cdf0e10cSrcweir } 781*cdf0e10cSrcweir nFound--; 782*cdf0e10cSrcweir } 783*cdf0e10cSrcweir } 784*cdf0e10cSrcweir } 785*cdf0e10cSrcweir } 786*cdf0e10cSrcweir } 787*cdf0e10cSrcweir 788*cdf0e10cSrcweir void SalXLib::Wakeup() 789*cdf0e10cSrcweir { 790*cdf0e10cSrcweir write (m_pTimeoutFDS[1], "", 1); 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir 793*cdf0e10cSrcweir void SalXLib::PostUserEvent() 794*cdf0e10cSrcweir { 795*cdf0e10cSrcweir Wakeup(); 796*cdf0e10cSrcweir } 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir const char* X11SalData::getFrameResName() 799*cdf0e10cSrcweir { 800*cdf0e10cSrcweir /* according to ICCCM: 801*cdf0e10cSrcweir * first search command line for -name parameter 802*cdf0e10cSrcweir * then try RESOURCE_NAME environment variable 803*cdf0e10cSrcweir * then use argv[0] stripped by directories 804*cdf0e10cSrcweir */ 805*cdf0e10cSrcweir static rtl::OStringBuffer aResName; 806*cdf0e10cSrcweir if( !aResName.getLength() ) 807*cdf0e10cSrcweir { 808*cdf0e10cSrcweir int nArgs = osl_getCommandArgCount(); 809*cdf0e10cSrcweir for( int n = 0; n < nArgs-1; n++ ) 810*cdf0e10cSrcweir { 811*cdf0e10cSrcweir rtl::OUString aArg; 812*cdf0e10cSrcweir if( ! osl_getCommandArg( n, &aArg.pData ) && 813*cdf0e10cSrcweir aArg.equalsIgnoreAsciiCaseAscii( "-name" ) && 814*cdf0e10cSrcweir ! osl_getCommandArg( n+1, &aArg.pData ) ) 815*cdf0e10cSrcweir { 816*cdf0e10cSrcweir aResName.append( rtl::OUStringToOString( aArg, osl_getThreadTextEncoding() ) ); 817*cdf0e10cSrcweir break; 818*cdf0e10cSrcweir } 819*cdf0e10cSrcweir } 820*cdf0e10cSrcweir if( !aResName.getLength() ) 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir const char* pEnv = getenv( "RESOURCE_NAME" ); 823*cdf0e10cSrcweir if( pEnv && *pEnv ) 824*cdf0e10cSrcweir aResName.append( pEnv ); 825*cdf0e10cSrcweir } 826*cdf0e10cSrcweir if( !aResName.getLength() ) 827*cdf0e10cSrcweir aResName.append( "VCLSalFrame" ); 828*cdf0e10cSrcweir } 829*cdf0e10cSrcweir return aResName.getStr(); 830*cdf0e10cSrcweir } 831*cdf0e10cSrcweir 832*cdf0e10cSrcweir const char* X11SalData::getFrameClassName() 833*cdf0e10cSrcweir { 834*cdf0e10cSrcweir static rtl::OStringBuffer aClassName; 835*cdf0e10cSrcweir if( !aClassName.getLength() ) 836*cdf0e10cSrcweir { 837*cdf0e10cSrcweir rtl::OUString aIni, aProduct; 838*cdf0e10cSrcweir rtl::Bootstrap::get( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ), aIni ); 839*cdf0e10cSrcweir aIni += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/" SAL_CONFIGFILE( "bootstrap" ) ) ); 840*cdf0e10cSrcweir rtl::Bootstrap aBootstrap( aIni ); 841*cdf0e10cSrcweir aBootstrap.getFrom( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ProductKey" ) ), aProduct ); 842*cdf0e10cSrcweir 843*cdf0e10cSrcweir if( aProduct.getLength() ) 844*cdf0e10cSrcweir aClassName.append( rtl::OUStringToOString( aProduct, osl_getThreadTextEncoding() ) ); 845*cdf0e10cSrcweir else 846*cdf0e10cSrcweir aClassName.append( "VCLSalFrame" ); 847*cdf0e10cSrcweir } 848*cdf0e10cSrcweir return aClassName.getStr(); 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir rtl::OString X11SalData::getFrameResName( SalExtStyle nStyle ) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir rtl::OStringBuffer aBuf( 64 ); 854*cdf0e10cSrcweir aBuf.append( getFrameResName() ); 855*cdf0e10cSrcweir if( (nStyle & SAL_FRAME_EXT_STYLE_DOCUMENT) ) 856*cdf0e10cSrcweir aBuf.append( ".DocumentWindow" ); 857*cdf0e10cSrcweir 858*cdf0e10cSrcweir return aBuf.makeStringAndClear(); 859*cdf0e10cSrcweir } 860