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

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

Generated by: LCOV version 1.10