LCOV - code coverage report
Current view: top level - vcl/unx/gtk/app - gtkdata.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 451 0.0 %
Date: 2012-08-25 Functions: 0 39 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 <stdio.h>
      33                 :            : #include <string.h>
      34                 :            : #include <stdlib.h>
      35                 :            : #include <limits.h>
      36                 :            : #include <errno.h>
      37                 :            : #include <poll.h>
      38                 :            : #if defined(FREEBSD) || defined(NETBSD)
      39                 :            : #include <sys/types.h>
      40                 :            : #include <sys/time.h>
      41                 :            : #include <unistd.h>
      42                 :            : #endif
      43                 :            : #define GLIB_DISABLE_DEPRECATION_WARNINGS
      44                 :            : #include <unx/gtk/gtkdata.hxx>
      45                 :            : #include <unx/gtk/gtkinst.hxx>
      46                 :            : #include <unx/gtk/gtkframe.hxx>
      47                 :            : #include <unx/salobj.h>
      48                 :            : #include <generic/geninst.h>
      49                 :            : #include <osl/thread.h>
      50                 :            : #include <osl/process.h>
      51                 :            : 
      52                 :            : #include "unx/i18n_im.hxx"
      53                 :            : #include "unx/i18n_xkb.hxx"
      54                 :            : #include <unx/wmadaptor.hxx>
      55                 :            : 
      56                 :            : #include "unx/x11_cursors/salcursors.h"
      57                 :            : 
      58                 :            : #include <vcl/svapp.hxx>
      59                 :            : 
      60                 :            : using namespace vcl_sal;
      61                 :            : 
      62                 :            : using ::rtl::OUString;
      63                 :            : 
      64                 :            : /***************************************************************
      65                 :            :  * class GtkSalDisplay                                         *
      66                 :            :  ***************************************************************/
      67                 :            : extern "C" {
      68                 :          0 : GdkFilterReturn call_filterGdkEvent( GdkXEvent* sys_event,
      69                 :            :                                      GdkEvent* event,
      70                 :            :                                      gpointer data )
      71                 :            : {
      72                 :          0 :     GtkSalDisplay *pDisplay = (GtkSalDisplay *)data;
      73                 :          0 :     return pDisplay->filterGdkEvent( sys_event, event );
      74                 :            : }
      75                 :            : }
      76                 :            : 
      77                 :          0 : GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay ) :
      78                 :            : #if !GTK_CHECK_VERSION(3,0,0)
      79                 :            :             SalDisplay( gdk_x11_display_get_xdisplay( pDisplay ) ),
      80                 :            : #endif
      81                 :          0 :             m_pSys( GtkSalSystem::GetSingleton() ),
      82                 :            :             m_pGdkDisplay( pDisplay ),
      83                 :          0 :             m_bStartupCompleted( false )
      84                 :            : {
      85                 :          0 :     for(int i = 0; i < POINTER_COUNT; i++)
      86                 :          0 :         m_aCursors[ i ] = NULL;
      87                 :            : #if !GTK_CHECK_VERSION(3,0,0)
      88                 :          0 :     m_bUseRandRWrapper = false; // use gdk signal instead
      89                 :          0 :     Init ();
      90                 :            : #endif
      91                 :            : 
      92                 :            :     // FIXME: unify this with SalInst's filter too ?
      93                 :          0 :     gdk_window_add_filter( NULL, call_filterGdkEvent, this );
      94                 :            : 
      95                 :          0 :     if ( getenv( "SAL_IGNOREXERRORS" ) )
      96                 :          0 :         GetGenericData()->ErrorTrapPush(); // and leak the trap
      97                 :            : 
      98                 :            : #if GTK_CHECK_VERSION(3,0,0)
      99                 :            :     m_bX11Display = GDK_IS_X11_DISPLAY( m_pGdkDisplay );
     100                 :            : #else
     101                 :          0 :     m_bX11Display = true;
     102                 :            : #endif
     103                 :          0 : }
     104                 :            : 
     105                 :          0 : GtkSalDisplay::~GtkSalDisplay()
     106                 :            : {
     107                 :          0 :     gdk_window_remove_filter( NULL, call_filterGdkEvent, this );
     108                 :            : 
     109                 :          0 :     if( !m_bStartupCompleted )
     110                 :          0 :         gdk_notify_startup_complete();
     111                 :            : 
     112                 :            : #if !GTK_CHECK_VERSION(3,0,0)
     113                 :          0 :     doDestruct();
     114                 :          0 :     pDisp_ = NULL;
     115                 :            : #endif
     116                 :            : 
     117                 :          0 :     for(int i = 0; i < POINTER_COUNT; i++)
     118                 :          0 :         if( m_aCursors[ i ] )
     119                 :          0 :             gdk_cursor_unref( m_aCursors[ i ] );
     120                 :          0 : }
     121                 :            : 
     122                 :            : extern "C" {
     123                 :            : 
     124                 :          0 : void signalScreenSizeChanged( GdkScreen* pScreen, gpointer data )
     125                 :            : {
     126                 :          0 :     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
     127                 :          0 :     pDisp->screenSizeChanged( pScreen );
     128                 :          0 : }
     129                 :            : 
     130                 :          0 : void signalMonitorsChanged( GdkScreen* pScreen, gpointer data )
     131                 :            : {
     132                 :          0 :     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
     133                 :          0 :     pDisp->monitorsChanged( pScreen );
     134                 :          0 : }
     135                 :            : 
     136                 :            : }
     137                 :            : 
     138                 :          0 : GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event,
     139                 :            :                                                GdkEvent* )
     140                 :            : {
     141                 :            : #if !GTK_CHECK_VERSION(3,0,0)
     142                 :          0 :     GdkFilterReturn aFilterReturn = GDK_FILTER_CONTINUE;
     143                 :          0 :     XEvent *pEvent = (XEvent *)sys_event;
     144                 :            : 
     145                 :            :     // dispatch all XEvents to event callback
     146                 :          0 :     if( GetSalData()->m_pInstance->
     147                 :          0 :         CallEventCallback( pEvent, sizeof( XEvent ) ) )
     148                 :          0 :         aFilterReturn = GDK_FILTER_REMOVE;
     149                 :            : 
     150                 :          0 :     GTK_YIELD_GRAB();
     151                 :            : 
     152                 :          0 :     if (GetDisplay() == pEvent->xany.display )
     153                 :            :     {
     154                 :            :         // #i53471# gtk has no callback mechanism that lets us be notified
     155                 :            :         // when settings (as in XSETTING and opposed to styles) are changed.
     156                 :            :         // so we need to listen for corresponding property notifications here
     157                 :            :         // these should be rare enough so that we can assume that the settings
     158                 :            :         // actually change when a corresponding PropertyNotify occurs
     159                 :          0 :         if( pEvent->type == PropertyNotify &&
     160                 :          0 :             pEvent->xproperty.atom == getWMAdaptor()->getAtom( WMAdaptor::XSETTINGS ) &&
     161                 :          0 :             ! m_aFrames.empty()
     162                 :            :            )
     163                 :            :         {
     164                 :          0 :             SendInternalEvent( m_aFrames.front(), NULL, SALEVENT_SETTINGSCHANGED );
     165                 :            :         }
     166                 :            :         // let's see if one of our frames wants to swallow these events
     167                 :            :         // get the frame
     168                 :          0 :         for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
     169                 :          0 :                  it != m_aFrames.end(); ++it )
     170                 :            :         {
     171                 :          0 :             GtkSalFrame* pFrame = static_cast<GtkSalFrame*>(*it);
     172                 :          0 :             if( (GdkNativeWindow)pFrame->GetSystemData()->aWindow == pEvent->xany.window ||
     173                 :          0 :                 ( pFrame->getForeignParent() && pFrame->getForeignParentWindow() == pEvent->xany.window ) ||
     174                 :          0 :                 ( pFrame->getForeignTopLevel() && pFrame->getForeignTopLevelWindow() == pEvent->xany.window )
     175                 :            :                 )
     176                 :            :             {
     177                 :          0 :                 if( ! pFrame->Dispatch( pEvent ) )
     178                 :          0 :                     aFilterReturn = GDK_FILTER_REMOVE;
     179                 :          0 :                 break;
     180                 :            :             }
     181                 :            :         }
     182                 :          0 :         X11SalObject::Dispatch( pEvent );
     183                 :            :     }
     184                 :            : 
     185                 :          0 :     return aFilterReturn;
     186                 :            : #else
     187                 :            :     (void) sys_event;
     188                 :            : #warning FIXME: implement filterGdkEvent ...
     189                 :            :     return GDK_FILTER_CONTINUE;
     190                 :            : #endif
     191                 :            : }
     192                 :            : 
     193                 :          0 : void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen )
     194                 :            : {
     195                 :          0 :     m_pSys->countScreenMonitors();
     196                 :          0 :     if (pScreen)
     197                 :          0 :         emitDisplayChanged();
     198                 :          0 : }
     199                 :            : 
     200                 :          0 : void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen )
     201                 :            : {
     202                 :          0 :     m_pSys->countScreenMonitors();
     203                 :          0 :     if (pScreen)
     204                 :          0 :         emitDisplayChanged();
     205                 :          0 : }
     206                 :            : 
     207                 :            : #if !GTK_CHECK_VERSION(3,0,0)
     208                 :            : SalDisplay::ScreenData *
     209                 :          0 : GtkSalDisplay::initScreen( SalX11Screen nXScreen ) const
     210                 :            : {
     211                 :            :     // choose visual for screen
     212                 :            :     ScreenData *pSD;
     213                 :          0 :     if (!(pSD = SalDisplay::initScreen( nXScreen )))
     214                 :          0 :         return NULL;
     215                 :            : 
     216                 :            :     // now set a gdk default colormap matching the chosen visual to the screen
     217                 :          0 :     GdkScreen* pScreen = gdk_display_get_screen( m_pGdkDisplay, nXScreen.getXScreen() );
     218                 :            : //  should really use this:
     219                 :            : //  GdkVisual* pVis = gdk_x11_screen_lookup_visual_get( screen, pSD->m_aVisual.visualid );
     220                 :            : //  and not this:
     221                 :          0 :     GdkVisual* pVis = gdkx_visual_get( pSD->m_aVisual.visualid );
     222                 :          0 :     if( pVis )
     223                 :            :     {
     224                 :          0 :         GdkColormap* pDefCol = gdk_screen_get_default_colormap( pScreen );
     225                 :          0 :         GdkVisual* pDefVis = gdk_colormap_get_visual( pDefCol );
     226                 :          0 :         if( pDefVis != pVis )
     227                 :            :         {
     228                 :          0 :            pDefCol = gdk_x11_colormap_foreign_new( pVis, pSD->m_aColormap.GetXColormap() );
     229                 :          0 :            gdk_screen_set_default_colormap( pScreen, pDefCol );
     230                 :            :            #if OSL_DEBUG_LEVEL > 1
     231                 :            :            fprintf( stderr, "set new gdk color map for screen %d\n", nXScreen.getXScreen() );
     232                 :            :            #endif
     233                 :            :         }
     234                 :            :     }
     235                 :            :     #if OSL_DEBUG_LEVEL > 1
     236                 :            :     else
     237                 :            :         fprintf( stderr, "not GdkVisual for visual id %d\n", (int)pSD->m_aVisual.visualid );
     238                 :            :     #endif
     239                 :          0 :     return pSD;
     240                 :            : }
     241                 :            : 
     242                 :          0 : long GtkSalDisplay::Dispatch( XEvent* pEvent )
     243                 :            : {
     244                 :          0 :     if( GetDisplay() == pEvent->xany.display )
     245                 :            :     {
     246                 :            :         // let's see if one of our frames wants to swallow these events
     247                 :            :         // get the child frame
     248                 :          0 :         for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
     249                 :          0 :              it != m_aFrames.end(); ++it )
     250                 :            :         {
     251                 :          0 :             if( (GdkNativeWindow)(*it)->GetSystemData()->aWindow == pEvent->xany.window )
     252                 :          0 :                 return static_cast<GtkSalFrame*>(*it)->Dispatch( pEvent );
     253                 :            :         }
     254                 :            :     }
     255                 :            : 
     256                 :          0 :     return GDK_FILTER_CONTINUE;
     257                 :            : }
     258                 :            : #endif
     259                 :            : 
     260                 :            : #if GTK_CHECK_VERSION(3,0,0)
     261                 :            : namespace
     262                 :            : {
     263                 :            :     //cairo annoyingly won't take raw xbm data unless it fits
     264                 :            :     //the required cairo stride
     265                 :            :     unsigned char* ensurePaddedForCairo(const unsigned char *pXBM,
     266                 :            :         int nWidth, int nHeight, int nStride)
     267                 :            :     {
     268                 :            :         unsigned char *pPaddedXBM = const_cast<unsigned char*>(pXBM);
     269                 :            : 
     270                 :            :         int bytes_per_row = (nWidth + 7) / 8;
     271                 :            : 
     272                 :            :         if (nStride != bytes_per_row)
     273                 :            :         {
     274                 :            :             pPaddedXBM = new unsigned char[nStride * nHeight];
     275                 :            :             for (int row = 0; row < nHeight; ++row)
     276                 :            :             {
     277                 :            :                 memcpy(pPaddedXBM + (nStride * row),
     278                 :            :                     pXBM + (bytes_per_row * row), bytes_per_row);
     279                 :            :                 memset(pPaddedXBM + (nStride * row) + bytes_per_row,
     280                 :            :                     0, nStride - bytes_per_row);
     281                 :            :             }
     282                 :            :         }
     283                 :            : 
     284                 :            :         return pPaddedXBM;
     285                 :            :     }
     286                 :            : }
     287                 :            : #endif
     288                 :            : 
     289                 :          0 : GdkCursor* GtkSalDisplay::getFromXBM( const unsigned char *pBitmap,
     290                 :            :                                       const unsigned char *pMask,
     291                 :            :                                       int nWidth, int nHeight,
     292                 :            :                                       int nXHot, int nYHot )
     293                 :            : {
     294                 :            : #if GTK_CHECK_VERSION(3,0,0)
     295                 :            :     int cairo_stride = cairo_format_stride_for_width(CAIRO_FORMAT_A1, nWidth);
     296                 :            : 
     297                 :            :     unsigned char *pPaddedXBM = ensurePaddedForCairo(pBitmap, nWidth, nHeight, cairo_stride);
     298                 :            :     cairo_surface_t *s = cairo_image_surface_create_for_data(
     299                 :            :         pPaddedXBM,
     300                 :            :         CAIRO_FORMAT_A1, nWidth, nHeight,
     301                 :            :         cairo_stride);
     302                 :            : 
     303                 :            :     cairo_t *cr = cairo_create(s);
     304                 :            :     unsigned char *pPaddedMaskXBM = ensurePaddedForCairo(pMask, nWidth, nHeight, cairo_stride);
     305                 :            :     cairo_surface_t *mask = cairo_image_surface_create_for_data(
     306                 :            :         pPaddedMaskXBM,
     307                 :            :         CAIRO_FORMAT_A1, nWidth, nHeight,
     308                 :            :         cairo_stride);
     309                 :            :     cairo_mask_surface(cr, mask, 0, 0);
     310                 :            :     cairo_destroy(cr);
     311                 :            :     cairo_surface_destroy(mask);
     312                 :            :     if (pPaddedMaskXBM != pMask)
     313                 :            :         delete [] pPaddedMaskXBM;
     314                 :            : 
     315                 :            :     GdkPixbuf *pixbuf = gdk_pixbuf_get_from_surface(s, 0, 0, nWidth, nHeight);
     316                 :            :     cairo_surface_destroy(s);
     317                 :            :     if (pPaddedXBM != pBitmap)
     318                 :            :         delete [] pPaddedXBM;
     319                 :            : 
     320                 :            :     GdkCursor *cursor = gdk_cursor_new_from_pixbuf(m_pGdkDisplay, pixbuf, nXHot, nYHot);
     321                 :            :     g_object_unref(pixbuf);
     322                 :            : 
     323                 :            :     return cursor;
     324                 :            : #else
     325                 :          0 :     GdkScreen *pScreen = gdk_display_get_default_screen( m_pGdkDisplay );
     326                 :          0 :     GdkDrawable *pDrawable = GDK_DRAWABLE( gdk_screen_get_root_window (pScreen) );
     327                 :            :     GdkBitmap *pBitmapPix = gdk_bitmap_create_from_data
     328                 :          0 :             ( pDrawable, reinterpret_cast<const char*>(pBitmap), nWidth, nHeight );
     329                 :            :     GdkBitmap *pMaskPix = gdk_bitmap_create_from_data
     330                 :          0 :             ( pDrawable, reinterpret_cast<const char*>(pMask), nWidth, nHeight );
     331                 :          0 :     GdkColormap *pColormap = gdk_drawable_get_colormap( pDrawable );
     332                 :            : 
     333                 :          0 :     GdkColor aWhite = { 0, 0xffff, 0xffff, 0xffff };
     334                 :          0 :     GdkColor aBlack = { 0, 0, 0, 0 };
     335                 :            : 
     336                 :          0 :     gdk_colormap_alloc_color( pColormap, &aBlack, FALSE, TRUE);
     337                 :          0 :     gdk_colormap_alloc_color( pColormap, &aWhite, FALSE, TRUE);
     338                 :            : 
     339                 :            :     return gdk_cursor_new_from_pixmap
     340                 :            :             ( pBitmapPix, pMaskPix,
     341                 :          0 :               &aBlack, &aWhite, nXHot, nYHot);
     342                 :            : #endif
     343                 :            : }
     344                 :            : 
     345                 :            : #define MAKE_CURSOR( vcl_name, name ) \
     346                 :            :     case vcl_name: \
     347                 :            :         pCursor = getFromXBM( name##curs##_bits, name##mask##_bits, \
     348                 :            :                               name##curs_width, name##curs_height, \
     349                 :            :                               name##curs_x_hot, name##curs_y_hot ); \
     350                 :            :         break
     351                 :            : #define MAP_BUILTIN( vcl_name, gdk_name ) \
     352                 :            :         case vcl_name: \
     353                 :            :             pCursor = gdk_cursor_new_for_display( m_pGdkDisplay, gdk_name ); \
     354                 :            :             break
     355                 :            : 
     356                 :          0 : GdkCursor *GtkSalDisplay::getCursor( PointerStyle ePointerStyle )
     357                 :            : {
     358                 :          0 :     if( ePointerStyle >= POINTER_COUNT )
     359                 :          0 :         return NULL;
     360                 :            : 
     361                 :          0 :     if ( !m_aCursors[ ePointerStyle ] )
     362                 :            :     {
     363                 :          0 :         GdkCursor *pCursor = NULL;
     364                 :            : 
     365                 :          0 :         switch( ePointerStyle )
     366                 :            :         {
     367                 :          0 :             MAP_BUILTIN( POINTER_ARROW, GDK_LEFT_PTR );
     368                 :          0 :             MAP_BUILTIN( POINTER_TEXT, GDK_XTERM );
     369                 :          0 :             MAP_BUILTIN( POINTER_HELP, GDK_QUESTION_ARROW );
     370                 :          0 :             MAP_BUILTIN( POINTER_CROSS, GDK_CROSSHAIR );
     371                 :          0 :             MAP_BUILTIN( POINTER_WAIT, GDK_WATCH );
     372                 :            : 
     373                 :          0 :             MAP_BUILTIN( POINTER_NSIZE, GDK_SB_V_DOUBLE_ARROW );
     374                 :          0 :             MAP_BUILTIN( POINTER_SSIZE, GDK_SB_V_DOUBLE_ARROW );
     375                 :          0 :             MAP_BUILTIN( POINTER_WSIZE, GDK_SB_H_DOUBLE_ARROW );
     376                 :          0 :             MAP_BUILTIN( POINTER_ESIZE, GDK_SB_H_DOUBLE_ARROW );
     377                 :            : 
     378                 :          0 :             MAP_BUILTIN( POINTER_NWSIZE, GDK_TOP_LEFT_CORNER );
     379                 :          0 :             MAP_BUILTIN( POINTER_NESIZE, GDK_TOP_RIGHT_CORNER );
     380                 :          0 :             MAP_BUILTIN( POINTER_SWSIZE, GDK_BOTTOM_LEFT_CORNER );
     381                 :          0 :             MAP_BUILTIN( POINTER_SESIZE, GDK_BOTTOM_RIGHT_CORNER );
     382                 :            : 
     383                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_NSIZE, GDK_TOP_SIDE );
     384                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_SSIZE, GDK_BOTTOM_SIDE );
     385                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_WSIZE, GDK_LEFT_SIDE );
     386                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_ESIZE, GDK_RIGHT_SIDE );
     387                 :            : 
     388                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_NWSIZE, GDK_TOP_LEFT_CORNER );
     389                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_NESIZE, GDK_TOP_RIGHT_CORNER );
     390                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_SWSIZE, GDK_BOTTOM_LEFT_CORNER );
     391                 :          0 :             MAP_BUILTIN( POINTER_WINDOW_SESIZE, GDK_BOTTOM_RIGHT_CORNER );
     392                 :            : 
     393                 :          0 :             MAP_BUILTIN( POINTER_HSIZEBAR, GDK_SB_H_DOUBLE_ARROW );
     394                 :          0 :             MAP_BUILTIN( POINTER_VSIZEBAR, GDK_SB_V_DOUBLE_ARROW );
     395                 :            : 
     396                 :          0 :             MAP_BUILTIN( POINTER_REFHAND, GDK_HAND2 );
     397                 :          0 :             MAP_BUILTIN( POINTER_HAND, GDK_HAND2 );
     398                 :          0 :             MAP_BUILTIN( POINTER_PEN, GDK_PENCIL );
     399                 :            : 
     400                 :          0 :             MAP_BUILTIN( POINTER_HSPLIT, GDK_SB_H_DOUBLE_ARROW );
     401                 :          0 :             MAP_BUILTIN( POINTER_VSPLIT, GDK_SB_V_DOUBLE_ARROW );
     402                 :            : 
     403                 :          0 :             MAP_BUILTIN( POINTER_MOVE, GDK_FLEUR );
     404                 :            : 
     405                 :          0 :             MAKE_CURSOR( POINTER_NULL, null );
     406                 :          0 :             MAKE_CURSOR( POINTER_MAGNIFY, magnify_ );
     407                 :          0 :             MAKE_CURSOR( POINTER_FILL, fill_ );
     408                 :          0 :             MAKE_CURSOR( POINTER_MOVEDATA, movedata_ );
     409                 :          0 :             MAKE_CURSOR( POINTER_COPYDATA, copydata_ );
     410                 :          0 :             MAKE_CURSOR( POINTER_MOVEFILE, movefile_ );
     411                 :          0 :             MAKE_CURSOR( POINTER_COPYFILE, copyfile_ );
     412                 :          0 :             MAKE_CURSOR( POINTER_MOVEFILES, movefiles_ );
     413                 :          0 :             MAKE_CURSOR( POINTER_COPYFILES, copyfiles_ );
     414                 :          0 :             MAKE_CURSOR( POINTER_NOTALLOWED, nodrop_ );
     415                 :          0 :             MAKE_CURSOR( POINTER_ROTATE, rotate_ );
     416                 :          0 :             MAKE_CURSOR( POINTER_HSHEAR, hshear_ );
     417                 :          0 :             MAKE_CURSOR( POINTER_VSHEAR, vshear_ );
     418                 :          0 :             MAKE_CURSOR( POINTER_DRAW_LINE, drawline_ );
     419                 :          0 :             MAKE_CURSOR( POINTER_DRAW_RECT, drawrect_ );
     420                 :          0 :             MAKE_CURSOR( POINTER_DRAW_POLYGON, drawpolygon_ );
     421                 :          0 :             MAKE_CURSOR( POINTER_DRAW_BEZIER, drawbezier_ );
     422                 :          0 :             MAKE_CURSOR( POINTER_DRAW_ARC, drawarc_ );
     423                 :          0 :             MAKE_CURSOR( POINTER_DRAW_PIE, drawpie_ );
     424                 :          0 :             MAKE_CURSOR( POINTER_DRAW_CIRCLECUT, drawcirclecut_ );
     425                 :          0 :             MAKE_CURSOR( POINTER_DRAW_ELLIPSE, drawellipse_ );
     426                 :          0 :             MAKE_CURSOR( POINTER_DRAW_CONNECT, drawconnect_ );
     427                 :          0 :             MAKE_CURSOR( POINTER_DRAW_TEXT, drawtext_ );
     428                 :          0 :             MAKE_CURSOR( POINTER_MIRROR, mirror_ );
     429                 :          0 :             MAKE_CURSOR( POINTER_CROOK, crook_ );
     430                 :          0 :             MAKE_CURSOR( POINTER_CROP, crop_ );
     431                 :          0 :             MAKE_CURSOR( POINTER_MOVEPOINT, movepoint_ );
     432                 :          0 :             MAKE_CURSOR( POINTER_MOVEBEZIERWEIGHT, movebezierweight_ );
     433                 :          0 :             MAKE_CURSOR( POINTER_DRAW_FREEHAND, drawfreehand_ );
     434                 :          0 :             MAKE_CURSOR( POINTER_DRAW_CAPTION, drawcaption_ );
     435                 :          0 :             MAKE_CURSOR( POINTER_LINKDATA, linkdata_ );
     436                 :          0 :             MAKE_CURSOR( POINTER_MOVEDATALINK, movedlnk_ );
     437                 :          0 :             MAKE_CURSOR( POINTER_COPYDATALINK, copydlnk_ );
     438                 :          0 :             MAKE_CURSOR( POINTER_LINKFILE, linkfile_ );
     439                 :          0 :             MAKE_CURSOR( POINTER_MOVEFILELINK, moveflnk_ );
     440                 :          0 :             MAKE_CURSOR( POINTER_COPYFILELINK, copyflnk_ );
     441                 :          0 :             MAKE_CURSOR( POINTER_CHART, chart_ );
     442                 :          0 :             MAKE_CURSOR( POINTER_DETECTIVE, detective_ );
     443                 :          0 :             MAKE_CURSOR( POINTER_PIVOT_COL, pivotcol_ );
     444                 :          0 :             MAKE_CURSOR( POINTER_PIVOT_ROW, pivotrow_ );
     445                 :          0 :             MAKE_CURSOR( POINTER_PIVOT_FIELD, pivotfld_ );
     446                 :          0 :             MAKE_CURSOR( POINTER_PIVOT_DELETE, pivotdel_ );
     447                 :          0 :             MAKE_CURSOR( POINTER_CHAIN, chain_ );
     448                 :          0 :             MAKE_CURSOR( POINTER_CHAIN_NOTALLOWED, chainnot_ );
     449                 :          0 :             MAKE_CURSOR( POINTER_TIMEEVENT_MOVE, timemove_ );
     450                 :          0 :             MAKE_CURSOR( POINTER_TIMEEVENT_SIZE, timesize_ );
     451                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_N, asn_ );
     452                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_S, ass_ );
     453                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_W, asw_ );
     454                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_E, ase_ );
     455                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_NW, asnw_ );
     456                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_NE, asne_ );
     457                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_SW, assw_ );
     458                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_SE, asse_ );
     459                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_NS, asns_ );
     460                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_WE, aswe_ );
     461                 :          0 :             MAKE_CURSOR( POINTER_AUTOSCROLL_NSWE, asnswe_ );
     462                 :          0 :             MAKE_CURSOR( POINTER_AIRBRUSH, airbrush_ );
     463                 :          0 :             MAKE_CURSOR( POINTER_TEXT_VERTICAL, vertcurs_ );
     464                 :            : 
     465                 :            :             // #i32329#
     466                 :          0 :             MAKE_CURSOR( POINTER_TAB_SELECT_S, tblsels_ );
     467                 :          0 :             MAKE_CURSOR( POINTER_TAB_SELECT_E, tblsele_ );
     468                 :          0 :             MAKE_CURSOR( POINTER_TAB_SELECT_SE, tblselse_ );
     469                 :          0 :             MAKE_CURSOR( POINTER_TAB_SELECT_W, tblselw_ );
     470                 :          0 :             MAKE_CURSOR( POINTER_TAB_SELECT_SW, tblselsw_ );
     471                 :            : 
     472                 :            :             // #i20119#
     473                 :          0 :             MAKE_CURSOR( POINTER_PAINTBRUSH, paintbrush_ );
     474                 :            : 
     475                 :            :         default:
     476                 :          0 :             fprintf( stderr, "pointer %d not implemented", ePointerStyle );
     477                 :          0 :             break;
     478                 :            :         }
     479                 :          0 :         if( !pCursor )
     480                 :          0 :             pCursor = gdk_cursor_new_for_display( m_pGdkDisplay, GDK_LEFT_PTR );
     481                 :            : 
     482                 :          0 :         m_aCursors[ ePointerStyle ] = pCursor;
     483                 :            :     }
     484                 :            : 
     485                 :          0 :     return m_aCursors[ ePointerStyle ];
     486                 :            : }
     487                 :            : 
     488                 :          0 : int GtkSalDisplay::CaptureMouse( SalFrame* pSFrame )
     489                 :            : {
     490                 :          0 :     GtkSalFrame* pFrame = static_cast<GtkSalFrame*>(pSFrame);
     491                 :            : 
     492                 :          0 :     if( !pFrame )
     493                 :            :     {
     494                 :          0 :         if( m_pCapture )
     495                 :          0 :             static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
     496                 :          0 :         m_pCapture = NULL;
     497                 :          0 :         return 0;
     498                 :            :     }
     499                 :            : 
     500                 :          0 :     if( m_pCapture )
     501                 :            :     {
     502                 :          0 :         if( pFrame == m_pCapture )
     503                 :          0 :             return 1;
     504                 :          0 :         static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
     505                 :            :     }
     506                 :            : 
     507                 :          0 :     m_pCapture = pFrame;
     508                 :          0 :     static_cast<GtkSalFrame*>(pFrame)->grabPointer( TRUE );
     509                 :          0 :     return 1;
     510                 :            : }
     511                 :            : 
     512                 :            : 
     513                 :            : /**********************************************************************
     514                 :            :  * class GtkData                                                      *
     515                 :            :  **********************************************************************/
     516                 :            : 
     517                 :          0 : GtkData::GtkData( SalInstance *pInstance )
     518                 :            : #if GTK_CHECK_VERSION(3,0,0)
     519                 :            :     : SalGenericData( SAL_DATA_GTK3, pInstance )
     520                 :            : #else
     521                 :          0 :     : SalGenericData( SAL_DATA_GTK, pInstance )
     522                 :            : #endif
     523                 :            : {
     524                 :          0 :     m_pUserEvent = NULL;
     525                 :          0 :     m_aDispatchMutex = osl_createMutex();
     526                 :          0 :     m_aDispatchCondition = osl_createCondition();
     527                 :          0 : }
     528                 :            : 
     529                 :          0 : GtkData::~GtkData()
     530                 :            : {
     531                 :          0 :     Yield( true, true );
     532                 :          0 :     g_warning ("TESTME: We used to have a stop-timer here, but the central code should do this");
     533                 :            : 
     534                 :            :      // sanity check: at this point nobody should be yielding, but wake them
     535                 :            :      // up anyway before the condition they're waiting on gets destroyed.
     536                 :          0 :     osl_setCondition( m_aDispatchCondition );
     537                 :            : 
     538                 :          0 :     osl_acquireMutex( m_aDispatchMutex );
     539                 :          0 :     if (m_pUserEvent)
     540                 :            :     {
     541                 :          0 :         g_source_destroy (m_pUserEvent);
     542                 :          0 :         g_source_unref (m_pUserEvent);
     543                 :          0 :         m_pUserEvent = NULL;
     544                 :            :     }
     545                 :          0 :     osl_destroyCondition( m_aDispatchCondition );
     546                 :          0 :     osl_releaseMutex( m_aDispatchMutex );
     547                 :          0 :     osl_destroyMutex( m_aDispatchMutex );
     548                 :          0 : }
     549                 :            : 
     550                 :          0 : void GtkData::Dispose()
     551                 :            : {
     552                 :          0 :     deInitNWF();
     553                 :          0 : }
     554                 :            : 
     555                 :          0 : void GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents )
     556                 :            : {
     557                 :            :     /* #i33212# only enter g_main_context_iteration in one thread at any one
     558                 :            :      * time, else one of them potentially will never end as long as there is
     559                 :            :      * another thread in in there. Having only one yieldin thread actually dispatch
     560                 :            :      * fits the vcl event model (see e.g. the generic plugin).
     561                 :            :      */
     562                 :          0 :     bool bDispatchThread = false;
     563                 :          0 :     bool bWasEvent = false;
     564                 :            :     {
     565                 :            :         // release YieldMutex (and re-acquire at block end)
     566                 :          0 :         SalYieldMutexReleaser aReleaser;
     567                 :          0 :         if( osl_tryToAcquireMutex( m_aDispatchMutex ) )
     568                 :          0 :             bDispatchThread = true;
     569                 :          0 :         else if( ! bWait )
     570                 :          0 :             return; // someone else is waiting already, return
     571                 :            : 
     572                 :          0 :         if( bDispatchThread )
     573                 :            :         {
     574                 :          0 :             int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1;
     575                 :          0 :             gboolean wasOneEvent = TRUE;
     576                 :          0 :             while( nMaxEvents-- && wasOneEvent )
     577                 :            :             {
     578                 :          0 :                 wasOneEvent = g_main_context_iteration( NULL, FALSE );
     579                 :          0 :                 if( wasOneEvent )
     580                 :          0 :                     bWasEvent = true;
     581                 :            :             }
     582                 :          0 :             if( bWait && ! bWasEvent )
     583                 :          0 :                 bWasEvent = g_main_context_iteration( NULL, TRUE ) != 0;
     584                 :            :         }
     585                 :          0 :         else if( bWait )
     586                 :            :         {
     587                 :            :             /* #i41693# in case the dispatch thread hangs in join
     588                 :            :              * for this thread the condition will never be set
     589                 :            :              * workaround: timeout of 1 second a emergency exit
     590                 :            :              */
     591                 :            :             // we are the dispatch thread
     592                 :          0 :             osl_resetCondition( m_aDispatchCondition );
     593                 :          0 :             TimeValue aValue = { 1, 0 };
     594                 :          0 :             osl_waitCondition( m_aDispatchCondition, &aValue );
     595                 :          0 :         }
     596                 :            :     }
     597                 :            : 
     598                 :          0 :     if( bDispatchThread )
     599                 :            :     {
     600                 :          0 :         osl_releaseMutex( m_aDispatchMutex );
     601                 :          0 :         if( bWasEvent )
     602                 :          0 :             osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields
     603                 :            :     }
     604                 :            : }
     605                 :            : 
     606                 :          0 : void GtkData::Init()
     607                 :            : {
     608                 :            :     int i;
     609                 :            : #if OSL_DEBUG_LEVEL > 1
     610                 :            :     fprintf( stderr, "GtkMainloop::Init()\n" );
     611                 :            : #endif
     612                 :          0 :     XrmInitialize();
     613                 :            : 
     614                 :            : #if !GTK_CHECK_VERSION(3,0,0)
     615                 :          0 :     gtk_set_locale();
     616                 :            : #endif
     617                 :            : 
     618                 :            :     /*
     619                 :            :      * open connection to X11 Display
     620                 :            :      * try in this order:
     621                 :            :      *  o  -display command line parameter,
     622                 :            :      *  o  $DISPLAY environment variable
     623                 :            :      *  o  default display
     624                 :            :      */
     625                 :            : 
     626                 :          0 :     GdkDisplay *pGdkDisp = NULL;
     627                 :            : 
     628                 :            :     // is there a -display command line parameter?
     629                 :          0 :     rtl_TextEncoding aEnc = osl_getThreadTextEncoding();
     630                 :          0 :     int nParams = osl_getCommandArgCount();
     631                 :          0 :     rtl::OString aDisplay;
     632                 :          0 :     rtl::OUString aParam, aBin;
     633                 :          0 :     char** pCmdLineAry = new char*[ nParams+1 ];
     634                 :          0 :     osl_getExecutableFile( &aParam.pData );
     635                 :          0 :     osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData );
     636                 :          0 :     pCmdLineAry[0] = g_strdup( OUStringToOString( aBin, aEnc ).getStr() );
     637                 :          0 :     for (i=0; i<nParams; i++)
     638                 :            :     {
     639                 :          0 :         osl_getCommandArg(i, &aParam.pData );
     640                 :          0 :         OString aBParam( OUStringToOString( aParam, aEnc ) );
     641                 :            : 
     642                 :          0 :         if( aParam == "-display" || aParam == "--display" )
     643                 :            :         {
     644                 :          0 :             pCmdLineAry[i+1] = g_strdup( "--display" );
     645                 :          0 :             osl_getCommandArg(i+1, &aParam.pData );
     646                 :          0 :             aDisplay = rtl::OUStringToOString( aParam, aEnc );
     647                 :            :         }
     648                 :            :         else
     649                 :          0 :             pCmdLineAry[i+1] = g_strdup( aBParam.getStr() );
     650                 :          0 :     }
     651                 :            :     // add executable
     652                 :          0 :     nParams++;
     653                 :            : 
     654                 :          0 :     g_set_application_name(SalGenericSystem::getFrameClassName());
     655                 :            : 
     656                 :            :     // Set consistant name of the root accessible
     657                 :          0 :     rtl::OUString aAppName = Application::GetAppName();
     658                 :          0 :     if( !aAppName.isEmpty() )
     659                 :            :     {
     660                 :          0 :         rtl::OString aPrgName = rtl::OUStringToOString(aAppName, aEnc);
     661                 :          0 :         g_set_prgname(aPrgName.getStr());
     662                 :            :     }
     663                 :            : 
     664                 :            :     // init gtk/gdk
     665                 :          0 :     gtk_init_check( &nParams, &pCmdLineAry );
     666                 :          0 :     gdk_error_trap_push();
     667                 :            : 
     668                 :          0 :     for (i = 0; i < nParams; i++ )
     669                 :          0 :         g_free( pCmdLineAry[i] );
     670                 :          0 :     delete [] pCmdLineAry;
     671                 :            : 
     672                 :            : #if OSL_DEBUG_LEVEL > 1
     673                 :            :     if (g_getenv ("SAL_DEBUG_UPDATES"))
     674                 :            :         gdk_window_set_debug_updates (TRUE);
     675                 :            : #endif
     676                 :            : 
     677                 :          0 :     pGdkDisp = gdk_display_get_default();
     678                 :          0 :     if ( !pGdkDisp )
     679                 :            :     {
     680                 :          0 :         rtl::OUString aProgramFileURL;
     681                 :          0 :         osl_getExecutableFile( &aProgramFileURL.pData );
     682                 :          0 :         rtl::OUString aProgramSystemPath;
     683                 :          0 :         osl_getSystemPathFromFileURL (aProgramFileURL.pData, &aProgramSystemPath.pData);
     684                 :            :         rtl::OString  aProgramName = rtl::OUStringToOString(
     685                 :            :                                             aProgramSystemPath,
     686                 :          0 :                                             osl_getThreadTextEncoding() );
     687                 :            :         fprintf( stderr, "%s X11 error: Can't open display: %s\n",
     688                 :          0 :                 aProgramName.getStr(), aDisplay.getStr());
     689                 :          0 :         fprintf( stderr, "   Set DISPLAY environment variable, use -display option\n");
     690                 :          0 :         fprintf( stderr, "   or check permissions of your X-Server\n");
     691                 :          0 :         fprintf( stderr, "   (See \"man X\" resp. \"man xhost\" for details)\n");
     692                 :          0 :         fflush( stderr );
     693                 :          0 :         exit(0);
     694                 :            :     }
     695                 :            : 
     696                 :            :     /*
     697                 :            :      * if a -display switch was used, we need
     698                 :            :      * to set the environment accoringly since
     699                 :            :      * the clipboard build another connection
     700                 :            :      * to the xserver using $DISPLAY
     701                 :            :      */
     702                 :          0 :     rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("DISPLAY"));
     703                 :          0 :     const gchar *name = gdk_display_get_name( pGdkDisp );
     704                 :          0 :     rtl::OUString envValue(name, strlen(name), aEnc);
     705                 :          0 :     osl_setEnvironment(envVar.pData, envValue.pData);
     706                 :            : 
     707                 :          0 :     GtkSalDisplay *pDisplay = new GtkSalDisplay( pGdkDisp );
     708                 :          0 :     SetDisplay( pDisplay );
     709                 :            : 
     710                 :            : #if !GTK_CHECK_VERSION(3,0,0)
     711                 :          0 :     Display *pDisp = gdk_x11_display_get_xdisplay( pGdkDisp );
     712                 :            : 
     713                 :          0 :     gdk_error_trap_push();
     714                 :          0 :     SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp );
     715                 :          0 :     bool bErrorOccured = gdk_error_trap_pop() != 0;
     716                 :          0 :     gdk_error_trap_push();
     717                 :          0 :     pKbdExtension->UseExtension( bErrorOccured );
     718                 :          0 :     gdk_error_trap_pop();
     719                 :          0 :     GetGtkDisplay()->SetKbdExtension( pKbdExtension );
     720                 :            : #else
     721                 :            : #  warning unwind keyboard extension bits
     722                 :            : #endif
     723                 :            : 
     724                 :            :     // add signal handler to notify screen size changes
     725                 :          0 :     int nScreens = gdk_display_get_n_screens( pGdkDisp );
     726                 :          0 :     for( int n = 0; n < nScreens; n++ )
     727                 :            :     {
     728                 :          0 :         GdkScreen *pScreen = gdk_display_get_screen( pGdkDisp, n );
     729                 :          0 :         if( pScreen )
     730                 :            :         {
     731                 :          0 :             pDisplay->screenSizeChanged( pScreen );
     732                 :          0 :             pDisplay->monitorsChanged( pScreen );
     733                 :          0 :             g_signal_connect( G_OBJECT(pScreen), "size-changed",
     734                 :          0 :                               G_CALLBACK(signalScreenSizeChanged), pDisplay );
     735                 :          0 :             if( ! gtk_check_version( 2, 14, 0 ) ) // monitors-changed came in with 2.14, avoid an assertion
     736                 :          0 :                 g_signal_connect( G_OBJECT(pScreen), "monitors-changed",
     737                 :          0 :                                   G_CALLBACK(signalMonitorsChanged), GetGtkDisplay() );
     738                 :            :         }
     739                 :          0 :     }
     740                 :          0 : }
     741                 :            : 
     742                 :          0 : void GtkData::ErrorTrapPush()
     743                 :            : {
     744                 :          0 :     gdk_error_trap_push ();
     745                 :          0 : }
     746                 :            : 
     747                 :          0 : bool GtkData::ErrorTrapPop( bool bIgnoreError )
     748                 :            : {
     749                 :            : #if GTK_CHECK_VERSION(3,0,0)
     750                 :            :     if( bIgnoreError )
     751                 :            :     {
     752                 :            :         gdk_error_trap_pop_ignored (); // faster
     753                 :            :         return false;
     754                 :            :     }
     755                 :            : #else
     756                 :            :     (void) bIgnoreError;
     757                 :            : #endif
     758                 :          0 :     return gdk_error_trap_pop () != 0;
     759                 :            : }
     760                 :            : 
     761                 :            : extern "C" {
     762                 :            : 
     763                 :            :     struct SalGtkTimeoutSource {
     764                 :            :         GSource      aParent;
     765                 :            :         GTimeVal     aFireTime;
     766                 :            :         GtkSalTimer *pInstance;
     767                 :            :     };
     768                 :            : 
     769                 :          0 :     static void sal_gtk_timeout_defer( SalGtkTimeoutSource *pTSource )
     770                 :            :     {
     771                 :          0 :         g_get_current_time( &pTSource->aFireTime );
     772                 :          0 :         g_time_val_add( &pTSource->aFireTime, pTSource->pInstance->m_nTimeoutMS * 1000 );
     773                 :          0 :     }
     774                 :            : 
     775                 :          0 :     static gboolean sal_gtk_timeout_expired( SalGtkTimeoutSource *pTSource,
     776                 :            :                                              gint *nTimeoutMS, GTimeVal *pTimeNow )
     777                 :            :     {
     778                 :          0 :         glong nDeltaSec = pTSource->aFireTime.tv_sec - pTimeNow->tv_sec;
     779                 :          0 :         glong nDeltaUSec = pTSource->aFireTime.tv_usec - pTimeNow->tv_usec;
     780                 :          0 :         if( nDeltaSec < 0 || ( nDeltaSec == 0 && nDeltaUSec < 0) )
     781                 :            :         {
     782                 :          0 :             *nTimeoutMS = 0;
     783                 :          0 :             return TRUE;
     784                 :            :         }
     785                 :          0 :         if( nDeltaUSec < 0 )
     786                 :            :         {
     787                 :          0 :             nDeltaUSec += 1000000;
     788                 :          0 :             nDeltaSec -= 1;
     789                 :            :         }
     790                 :            :         // if the clock changes backwards we need to cope ...
     791                 :          0 :         if( (unsigned long) nDeltaSec > 1 + ( pTSource->pInstance->m_nTimeoutMS / 1000 ) )
     792                 :            :         {
     793                 :          0 :             sal_gtk_timeout_defer( pTSource );
     794                 :          0 :             return TRUE;
     795                 :            :         }
     796                 :            : 
     797                 :          0 :         *nTimeoutMS = MIN( G_MAXINT, ( nDeltaSec * 1000 + (nDeltaUSec + 999) / 1000 ) );
     798                 :            : 
     799                 :          0 :         return *nTimeoutMS == 0;
     800                 :            :     }
     801                 :            : 
     802                 :          0 :     static gboolean sal_gtk_timeout_prepare( GSource *pSource, gint *nTimeoutMS )
     803                 :            :     {
     804                 :          0 :         SalGtkTimeoutSource *pTSource = (SalGtkTimeoutSource *)pSource;
     805                 :            : 
     806                 :            :         GTimeVal aTimeNow;
     807                 :          0 :         g_get_current_time( &aTimeNow );
     808                 :            : 
     809                 :          0 :         return sal_gtk_timeout_expired( pTSource, nTimeoutMS, &aTimeNow );
     810                 :            :     }
     811                 :            : 
     812                 :          0 :     static gboolean sal_gtk_timeout_check( GSource *pSource )
     813                 :            :     {
     814                 :          0 :         SalGtkTimeoutSource *pTSource = (SalGtkTimeoutSource *)pSource;
     815                 :            : 
     816                 :            :         GTimeVal aTimeNow;
     817                 :          0 :         g_get_current_time( &aTimeNow );
     818                 :            : 
     819                 :            :         return ( pTSource->aFireTime.tv_sec < aTimeNow.tv_sec ||
     820                 :            :                  ( pTSource->aFireTime.tv_sec == aTimeNow.tv_sec &&
     821                 :          0 :                    pTSource->aFireTime.tv_usec < aTimeNow.tv_usec ) );
     822                 :            :     }
     823                 :            : 
     824                 :          0 :     static gboolean sal_gtk_timeout_dispatch( GSource *pSource, GSourceFunc, gpointer )
     825                 :            :     {
     826                 :          0 :         SalGtkTimeoutSource *pTSource = (SalGtkTimeoutSource *)pSource;
     827                 :            : 
     828                 :          0 :         if( !pTSource->pInstance )
     829                 :          0 :             return FALSE;
     830                 :            : 
     831                 :          0 :         SalData *pSalData = GetSalData();
     832                 :            : 
     833                 :          0 :         osl::SolarGuard aGuard( pSalData->m_pInstance->GetYieldMutex() );
     834                 :            : 
     835                 :          0 :         sal_gtk_timeout_defer( pTSource );
     836                 :            : 
     837                 :          0 :         ImplSVData* pSVData = ImplGetSVData();
     838                 :          0 :         if( pSVData->mpSalTimer )
     839                 :          0 :             pSVData->mpSalTimer->CallCallback();
     840                 :            : 
     841                 :          0 :         return TRUE;
     842                 :            :     }
     843                 :            : 
     844                 :            :     static GSourceFuncs sal_gtk_timeout_funcs =
     845                 :            :     {
     846                 :            :         sal_gtk_timeout_prepare,
     847                 :            :         sal_gtk_timeout_check,
     848                 :            :         sal_gtk_timeout_dispatch,
     849                 :            :         NULL, NULL, NULL
     850                 :            :     };
     851                 :            : }
     852                 :            : 
     853                 :            : static SalGtkTimeoutSource *
     854                 :          0 : create_sal_gtk_timeout( GtkSalTimer *pTimer )
     855                 :            : {
     856                 :          0 :   GSource *pSource = g_source_new( &sal_gtk_timeout_funcs, sizeof( SalGtkTimeoutSource ) );
     857                 :          0 :   SalGtkTimeoutSource *pTSource = (SalGtkTimeoutSource *)pSource;
     858                 :          0 :   pTSource->pInstance = pTimer;
     859                 :            : 
     860                 :            :   // #i36226# timers should be executed with lower priority
     861                 :            :   // than XEvents like in generic plugin
     862                 :          0 :   g_source_set_priority( pSource, G_PRIORITY_LOW );
     863                 :          0 :   g_source_set_can_recurse( pSource, TRUE );
     864                 :            :   g_source_set_callback( pSource,
     865                 :            :                          /* unused dummy */ g_idle_remove_by_data,
     866                 :          0 :                          NULL, NULL );
     867                 :          0 :   g_source_attach( pSource, g_main_context_default() );
     868                 :            : 
     869                 :          0 :   sal_gtk_timeout_defer( pTSource );
     870                 :            : 
     871                 :          0 :   return pTSource;
     872                 :            : }
     873                 :            : 
     874                 :          0 : GtkSalTimer::GtkSalTimer()
     875                 :          0 :     : m_pTimeout( NULL )
     876                 :            : {
     877                 :          0 : }
     878                 :            : 
     879                 :          0 : GtkSalTimer::~GtkSalTimer()
     880                 :            : {
     881                 :          0 :     GtkInstance *pInstance = static_cast<GtkInstance *>(GetSalData()->m_pInstance);
     882                 :          0 :     pInstance->RemoveTimer( this );
     883                 :          0 :     Stop();
     884                 :          0 : }
     885                 :            : 
     886                 :          0 : bool GtkSalTimer::Expired()
     887                 :            : {
     888                 :          0 :     if( !m_pTimeout )
     889                 :          0 :         return false;
     890                 :            : 
     891                 :          0 :     gint nDummy = 0;
     892                 :            :     GTimeVal aTimeNow;
     893                 :          0 :     g_get_current_time( &aTimeNow );
     894                 :          0 :     return !!sal_gtk_timeout_expired( m_pTimeout, &nDummy, &aTimeNow);
     895                 :            : }
     896                 :            : 
     897                 :          0 : void GtkSalTimer::Start( sal_uLong nMS )
     898                 :            : {
     899                 :          0 :     m_nTimeoutMS = nMS; // for restarting
     900                 :          0 :     Stop(); // FIXME: ideally re-use an existing m_pTimeout
     901                 :          0 :     m_pTimeout = create_sal_gtk_timeout( this );
     902                 :          0 : }
     903                 :            : 
     904                 :          0 : void GtkSalTimer::Stop()
     905                 :            : {
     906                 :          0 :     if( m_pTimeout )
     907                 :            :     {
     908                 :          0 :         g_source_destroy( (GSource *)m_pTimeout );
     909                 :          0 :         g_source_unref( (GSource *)m_pTimeout );
     910                 :          0 :         m_pTimeout = NULL;
     911                 :            :     }
     912                 :          0 : }
     913                 :            : 
     914                 :          0 : gboolean GtkData::userEventFn( gpointer data )
     915                 :            : {
     916                 :          0 :     gboolean bContinue = FALSE;
     917                 :          0 :     GtkData *pThis = (GtkData *) data;
     918                 :          0 :     SalGenericData *pData = GetGenericData();
     919                 :          0 :     osl::SolarGuard aGuard( pData->m_pInstance->GetYieldMutex() );
     920                 :          0 :     const SalGenericDisplay *pDisplay = pData->GetDisplay();
     921                 :          0 :     if (pDisplay)
     922                 :            :     {
     923                 :            :         OSL_ASSERT(static_cast<const SalGenericDisplay *>(pThis->GetGtkDisplay()) == pDisplay);
     924                 :          0 :         pThis->GetGtkDisplay()->EventGuardAcquire();
     925                 :            : 
     926                 :          0 :         if( !pThis->GetGtkDisplay()->HasUserEvents() )
     927                 :            :         {
     928                 :          0 :             if( pThis->m_pUserEvent )
     929                 :            :             {
     930                 :          0 :                 g_source_unref (pThis->m_pUserEvent);
     931                 :          0 :                 pThis->m_pUserEvent = NULL;
     932                 :            :             }
     933                 :          0 :             bContinue = FALSE;
     934                 :            :         }
     935                 :            :         else
     936                 :          0 :             bContinue = TRUE;
     937                 :            : 
     938                 :          0 :         pThis->GetGtkDisplay()->EventGuardRelease();
     939                 :            : 
     940                 :          0 :         pThis->GetGtkDisplay()->DispatchInternalEvent();
     941                 :            :     }
     942                 :            : 
     943                 :          0 :     return bContinue;
     944                 :            : }
     945                 :            : 
     946                 :            : extern "C" {
     947                 :          0 :     static gboolean call_userEventFn( void *data )
     948                 :            :     {
     949                 :          0 :         SolarMutexGuard aGuard;
     950                 :          0 :         return GtkData::userEventFn( data );
     951                 :            :     }
     952                 :            : }
     953                 :            : 
     954                 :            : // hEventGuard_ held during this invocation
     955                 :          0 : void GtkData::PostUserEvent()
     956                 :            : {
     957                 :          0 :     if (m_pUserEvent)
     958                 :          0 :         g_main_context_wakeup (NULL); // really needed ?
     959                 :            :     else // nothing pending anyway
     960                 :            :     {
     961                 :          0 :         m_pUserEvent = g_idle_source_new();
     962                 :          0 :         g_source_set_priority (m_pUserEvent, G_PRIORITY_HIGH);
     963                 :          0 :         g_source_set_can_recurse (m_pUserEvent, TRUE);
     964                 :            :         g_source_set_callback (m_pUserEvent, call_userEventFn,
     965                 :          0 :                                (gpointer) this, NULL);
     966                 :          0 :         g_source_attach (m_pUserEvent, g_main_context_default ());
     967                 :            :     }
     968                 :          0 : }
     969                 :            : 
     970                 :          0 : void GtkSalDisplay::PostUserEvent()
     971                 :            : {
     972                 :          0 :     GetGtkSalData()->PostUserEvent();
     973                 :          0 : }
     974                 :            : 
     975                 :          0 : void GtkSalDisplay::deregisterFrame( SalFrame* pFrame )
     976                 :            : {
     977                 :          0 :     if( m_pCapture == pFrame )
     978                 :            :     {
     979                 :          0 :         static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
     980                 :          0 :         m_pCapture = NULL;
     981                 :            :     }
     982                 :          0 :     SalGenericDisplay::deregisterFrame( pFrame );
     983                 :          0 : }
     984                 :            : 
     985                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10