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

Generated by: LCOV version 1.10