LCOV - code coverage report
Current view: top level - vcl/unx/generic/app - saldata.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 270 0.0 %
Date: 2012-08-25 Functions: 0 31 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.10