LCOV - code coverage report
Current view: top level - libreoffice/vcl/unx/generic/app - saldata.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 272 0.0 %
Date: 2012-12-27 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10