LCOV - code coverage report
Current view: top level - vcl/unx/gtk/app - gtkdata.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 150 456 32.9 %
Date: 2015-06-13 12:38:46 Functions: 21 42 50.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 = static_cast<GtkSalDisplay *>(data);
      60           0 :     return pDisplay->filterGdkEvent( sys_event, event );
      61             : }
      62             : }
      63             : 
      64           3 : GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay ) :
      65             : #if !GTK_CHECK_VERSION(3,0,0)
      66             :             SalDisplay( gdk_x11_display_get_xdisplay( pDisplay ) ),
      67             : #endif
      68           3 :             m_pSys( GtkSalSystem::GetSingleton() ),
      69             :             m_pGdkDisplay( pDisplay ),
      70           6 :             m_bStartupCompleted( false )
      71             : {
      72         285 :     for(GdkCursor* & rpCsr : m_aCursors)
      73         282 :         rpCsr = NULL;
      74             : #if !GTK_CHECK_VERSION(3,0,0)
      75           3 :     m_bUseRandRWrapper = false; // use gdk signal instead
      76           3 :     Init ();
      77             : #endif
      78             : 
      79             :     // FIXME: unify this with SalInst's filter too ?
      80           3 :     gdk_window_add_filter( NULL, call_filterGdkEvent, this );
      81             : 
      82           3 :     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           3 :     m_bX11Display = true;
      89             : #endif
      90           3 : }
      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(GdkCursor* & rpCsr : m_aCursors)
     105           0 :         if( rpCsr )
     106           0 :             gdk_cursor_unref( rpCsr );
     107           0 : }
     108             : 
     109             : extern "C" {
     110             : 
     111           0 : void signalScreenSizeChanged( GdkScreen* pScreen, gpointer data )
     112             : {
     113           0 :     GtkSalDisplay* pDisp = static_cast<GtkSalDisplay*>(data);
     114           0 :     pDisp->screenSizeChanged( pScreen );
     115           0 : }
     116             : 
     117           0 : void signalMonitorsChanged( GdkScreen* pScreen, gpointer data )
     118             : {
     119           0 :     GtkSalDisplay* pDisp = static_cast<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 = static_cast<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) this; // loplugin:staticmethods
     173             :     (void) sys_event;
     174             :     //FIXME: implement filterGdkEvent ...
     175             :     return GDK_FILTER_CONTINUE;
     176             : #endif
     177             : }
     178             : 
     179           3 : void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen )
     180             : {
     181           3 :     m_pSys->countScreenMonitors();
     182           3 :     if (pScreen)
     183           3 :         emitDisplayChanged();
     184           3 : }
     185             : 
     186           3 : void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen )
     187             : {
     188           3 :     m_pSys->countScreenMonitors();
     189           3 :     if (pScreen)
     190           3 :         emitDisplayChanged();
     191           3 : }
     192             : 
     193             : #if !GTK_CHECK_VERSION(3,0,0)
     194             : SalDisplay::ScreenData *
     195           3 : GtkSalDisplay::initScreen( SalX11Screen nXScreen ) const
     196             : {
     197             :     // choose visual for screen
     198             :     ScreenData *pSD;
     199           3 :     if (!(pSD = SalDisplay::initScreen( nXScreen )))
     200           0 :         return NULL;
     201             : 
     202             :     // now set a gdk default colormap matching the chosen visual to the screen
     203           3 :     GdkScreen* pScreen = gdk_display_get_screen( m_pGdkDisplay, nXScreen.getXScreen() );
     204             : //  should really use this:
     205             : //  GdkVisual* pVis = gdk_x11_screen_lookup_visual_get( screen, pSD->m_aVisual.visualid );
     206             : //  and not this:
     207           3 :     GdkVisual* pVis = gdkx_visual_get( pSD->m_aVisual.visualid );
     208           3 :     if( pVis )
     209             :     {
     210           3 :         GdkColormap* pDefCol = gdk_screen_get_default_colormap( pScreen );
     211           3 :         GdkVisual* pDefVis = gdk_colormap_get_visual( pDefCol );
     212           3 :         if( pDefVis != pVis )
     213             :         {
     214           0 :            pDefCol = gdk_x11_colormap_foreign_new( pVis, pSD->m_aColormap.GetXColormap() );
     215           0 :            gdk_screen_set_default_colormap( pScreen, pDefCol );
     216             :            SAL_INFO( "vcl.gtk", "set new gdk color map for screen " << nXScreen.getXScreen() );
     217             :         }
     218             :     }
     219             :     else
     220             :         SAL_INFO( "vcl.gtk", "not GdkVisual for visual id " << pSD->m_aVisual.visualid );
     221             : 
     222           3 :     return pSD;
     223             : }
     224             : 
     225           0 : bool GtkSalDisplay::Dispatch( XEvent* pEvent )
     226             : {
     227           0 :     if( GetDisplay() == pEvent->xany.display )
     228             :     {
     229             :         // let's see if one of our frames wants to swallow these events
     230             :         // get the child frame
     231           0 :         for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
     232           0 :              it != m_aFrames.end(); ++it )
     233             :         {
     234           0 :             if( (GdkNativeWindow)(*it)->GetSystemData()->aWindow == pEvent->xany.window )
     235           0 :                 return static_cast<GtkSalFrame*>(*it)->Dispatch( pEvent );
     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 ( !m_aCursors[ ePointerStyle ] )
     342             :     {
     343           0 :         GdkCursor *pCursor = NULL;
     344             : 
     345           0 :         switch( ePointerStyle )
     346             :         {
     347           0 :             MAP_BUILTIN( PointerStyle::Arrow, GDK_LEFT_PTR );
     348           0 :             MAP_BUILTIN( PointerStyle::Text, GDK_XTERM );
     349           0 :             MAP_BUILTIN( PointerStyle::Help, GDK_QUESTION_ARROW );
     350           0 :             MAP_BUILTIN( PointerStyle::Cross, GDK_CROSSHAIR );
     351           0 :             MAP_BUILTIN( PointerStyle::Wait, GDK_WATCH );
     352             : 
     353           0 :             MAP_BUILTIN( PointerStyle::NSize, GDK_SB_V_DOUBLE_ARROW );
     354           0 :             MAP_BUILTIN( PointerStyle::SSize, GDK_SB_V_DOUBLE_ARROW );
     355           0 :             MAP_BUILTIN( PointerStyle::WSize, GDK_SB_H_DOUBLE_ARROW );
     356           0 :             MAP_BUILTIN( PointerStyle::ESize, GDK_SB_H_DOUBLE_ARROW );
     357             : 
     358           0 :             MAP_BUILTIN( PointerStyle::NWSize, GDK_TOP_LEFT_CORNER );
     359           0 :             MAP_BUILTIN( PointerStyle::NESize, GDK_TOP_RIGHT_CORNER );
     360           0 :             MAP_BUILTIN( PointerStyle::SWSize, GDK_BOTTOM_LEFT_CORNER );
     361           0 :             MAP_BUILTIN( PointerStyle::SESize, GDK_BOTTOM_RIGHT_CORNER );
     362             : 
     363           0 :             MAP_BUILTIN( PointerStyle::WindowNSize, GDK_TOP_SIDE );
     364           0 :             MAP_BUILTIN( PointerStyle::WindowSSize, GDK_BOTTOM_SIDE );
     365           0 :             MAP_BUILTIN( PointerStyle::WindowWSize, GDK_LEFT_SIDE );
     366           0 :             MAP_BUILTIN( PointerStyle::WindowESize, GDK_RIGHT_SIDE );
     367             : 
     368           0 :             MAP_BUILTIN( PointerStyle::WindowNWSize, GDK_TOP_LEFT_CORNER );
     369           0 :             MAP_BUILTIN( PointerStyle::WindowNESize, GDK_TOP_RIGHT_CORNER );
     370           0 :             MAP_BUILTIN( PointerStyle::WindowSWSize, GDK_BOTTOM_LEFT_CORNER );
     371           0 :             MAP_BUILTIN( PointerStyle::WindowSESize, GDK_BOTTOM_RIGHT_CORNER );
     372             : 
     373           0 :             MAP_BUILTIN( PointerStyle::HSizeBar, GDK_SB_H_DOUBLE_ARROW );
     374           0 :             MAP_BUILTIN( PointerStyle::VSizeBar, GDK_SB_V_DOUBLE_ARROW );
     375             : 
     376           0 :             MAP_BUILTIN( PointerStyle::RefHand, GDK_HAND2 );
     377           0 :             MAP_BUILTIN( PointerStyle::Hand, GDK_HAND2 );
     378           0 :             MAP_BUILTIN( PointerStyle::Pen, GDK_PENCIL );
     379             : 
     380           0 :             MAP_BUILTIN( PointerStyle::HSplit, GDK_SB_H_DOUBLE_ARROW );
     381           0 :             MAP_BUILTIN( PointerStyle::VSplit, GDK_SB_V_DOUBLE_ARROW );
     382             : 
     383           0 :             MAP_BUILTIN( PointerStyle::Move, GDK_FLEUR );
     384             : 
     385           0 :             MAKE_CURSOR( PointerStyle::Null, null );
     386           0 :             MAKE_CURSOR( PointerStyle::Magnify, magnify_ );
     387           0 :             MAKE_CURSOR( PointerStyle::Fill, fill_ );
     388           0 :             MAKE_CURSOR( PointerStyle::MoveData, movedata_ );
     389           0 :             MAKE_CURSOR( PointerStyle::CopyData, copydata_ );
     390           0 :             MAKE_CURSOR( PointerStyle::MoveFile, movefile_ );
     391           0 :             MAKE_CURSOR( PointerStyle::CopyFile, copyfile_ );
     392           0 :             MAKE_CURSOR( PointerStyle::MoveFiles, movefiles_ );
     393           0 :             MAKE_CURSOR( PointerStyle::CopyFiles, copyfiles_ );
     394           0 :             MAKE_CURSOR( PointerStyle::NotAllowed, nodrop_ );
     395           0 :             MAKE_CURSOR( PointerStyle::Rotate, rotate_ );
     396           0 :             MAKE_CURSOR( PointerStyle::HShear, hshear_ );
     397           0 :             MAKE_CURSOR( PointerStyle::VShear, vshear_ );
     398           0 :             MAKE_CURSOR( PointerStyle::DrawLine, drawline_ );
     399           0 :             MAKE_CURSOR( PointerStyle::DrawRect, drawrect_ );
     400           0 :             MAKE_CURSOR( PointerStyle::DrawPolygon, drawpolygon_ );
     401           0 :             MAKE_CURSOR( PointerStyle::DrawBezier, drawbezier_ );
     402           0 :             MAKE_CURSOR( PointerStyle::DrawArc, drawarc_ );
     403           0 :             MAKE_CURSOR( PointerStyle::DrawPie, drawpie_ );
     404           0 :             MAKE_CURSOR( PointerStyle::DrawCircleCut, drawcirclecut_ );
     405           0 :             MAKE_CURSOR( PointerStyle::DrawEllipse, drawellipse_ );
     406           0 :             MAKE_CURSOR( PointerStyle::DrawConnect, drawconnect_ );
     407           0 :             MAKE_CURSOR( PointerStyle::DrawText, drawtext_ );
     408           0 :             MAKE_CURSOR( PointerStyle::Mirror, mirror_ );
     409           0 :             MAKE_CURSOR( PointerStyle::Crook, crook_ );
     410           0 :             MAKE_CURSOR( PointerStyle::Crop, crop_ );
     411           0 :             MAKE_CURSOR( PointerStyle::MovePoint, movepoint_ );
     412           0 :             MAKE_CURSOR( PointerStyle::MoveBezierWeight, movebezierweight_ );
     413           0 :             MAKE_CURSOR( PointerStyle::DrawFreehand, drawfreehand_ );
     414           0 :             MAKE_CURSOR( PointerStyle::DrawCaption, drawcaption_ );
     415           0 :             MAKE_CURSOR( PointerStyle::LinkData, linkdata_ );
     416           0 :             MAKE_CURSOR( PointerStyle::MoveDataLink, movedlnk_ );
     417           0 :             MAKE_CURSOR( PointerStyle::CopyDataLink, copydlnk_ );
     418           0 :             MAKE_CURSOR( PointerStyle::LinkFile, linkfile_ );
     419           0 :             MAKE_CURSOR( PointerStyle::MoveFileLink, moveflnk_ );
     420           0 :             MAKE_CURSOR( PointerStyle::CopyFileLink, copyflnk_ );
     421           0 :             MAKE_CURSOR( PointerStyle::Chart, chart_ );
     422           0 :             MAKE_CURSOR( PointerStyle::Detective, detective_ );
     423           0 :             MAKE_CURSOR( PointerStyle::PivotCol, pivotcol_ );
     424           0 :             MAKE_CURSOR( PointerStyle::PivotRow, pivotrow_ );
     425           0 :             MAKE_CURSOR( PointerStyle::PivotField, pivotfld_ );
     426           0 :             MAKE_CURSOR( PointerStyle::PivotDelete, pivotdel_ );
     427           0 :             MAKE_CURSOR( PointerStyle::Chain, chain_ );
     428           0 :             MAKE_CURSOR( PointerStyle::ChainNotAllowed, chainnot_ );
     429           0 :             MAKE_CURSOR( PointerStyle::TimeEventMove, timemove_ );
     430           0 :             MAKE_CURSOR( PointerStyle::TimeEventSize, timesize_ );
     431           0 :             MAKE_CURSOR( PointerStyle::AutoScrollN, asn_ );
     432           0 :             MAKE_CURSOR( PointerStyle::AutoScrollS, ass_ );
     433           0 :             MAKE_CURSOR( PointerStyle::AutoScrollW, asw_ );
     434           0 :             MAKE_CURSOR( PointerStyle::AutoScrollE, ase_ );
     435           0 :             MAKE_CURSOR( PointerStyle::AutoScrollNW, asnw_ );
     436           0 :             MAKE_CURSOR( PointerStyle::AutoScrollNE, asne_ );
     437           0 :             MAKE_CURSOR( PointerStyle::AutoScrollSW, assw_ );
     438           0 :             MAKE_CURSOR( PointerStyle::AutoScrollSE, asse_ );
     439           0 :             MAKE_CURSOR( PointerStyle::AutoScrollNS, asns_ );
     440           0 :             MAKE_CURSOR( PointerStyle::AutoScrollWE, aswe_ );
     441           0 :             MAKE_CURSOR( PointerStyle::AutoScrollNSWE, asnswe_ );
     442           0 :             MAKE_CURSOR( PointerStyle::Airbrush, airbrush_ );
     443           0 :             MAKE_CURSOR( PointerStyle::TextVertical, vertcurs_ );
     444             : 
     445             :             // #i32329#
     446           0 :             MAKE_CURSOR( PointerStyle::TabSelectS, tblsels_ );
     447           0 :             MAKE_CURSOR( PointerStyle::TabSelectE, tblsele_ );
     448           0 :             MAKE_CURSOR( PointerStyle::TabSelectSE, tblselse_ );
     449           0 :             MAKE_CURSOR( PointerStyle::TabSelectW, tblselw_ );
     450           0 :             MAKE_CURSOR( PointerStyle::TabSelectSW, tblselsw_ );
     451             : 
     452             :             // #i20119#
     453           0 :             MAKE_CURSOR( PointerStyle::Paintbrush, paintbrush_ );
     454             : 
     455             :         default:
     456             :             SAL_WARN( "vcl.gtk", "pointer " << static_cast<int>(ePointerStyle) << "not implemented" );
     457           0 :             break;
     458             :         }
     459           0 :         if( !pCursor )
     460           0 :             pCursor = gdk_cursor_new_for_display( m_pGdkDisplay, GDK_LEFT_PTR );
     461             : 
     462           0 :         m_aCursors[ ePointerStyle ] = pCursor;
     463             :     }
     464             : 
     465           0 :     return m_aCursors[ ePointerStyle ];
     466             : }
     467             : 
     468           0 : int GtkSalDisplay::CaptureMouse( SalFrame* pSFrame )
     469             : {
     470           0 :     GtkSalFrame* pFrame = static_cast<GtkSalFrame*>(pSFrame);
     471             : 
     472           0 :     if( !pFrame )
     473             :     {
     474           0 :         if( m_pCapture )
     475           0 :             static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
     476           0 :         m_pCapture = NULL;
     477           0 :         return 0;
     478             :     }
     479             : 
     480           0 :     if( m_pCapture )
     481             :     {
     482           0 :         if( pFrame == m_pCapture )
     483           0 :             return 1;
     484           0 :         static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
     485             :     }
     486             : 
     487           0 :     m_pCapture = pFrame;
     488           0 :     static_cast<GtkSalFrame*>(pFrame)->grabPointer( TRUE );
     489           0 :     return 1;
     490             : }
     491             : 
     492             : /**********************************************************************
     493             :  * class GtkData                                                      *
     494             :  **********************************************************************/
     495             : 
     496           3 : GtkData::GtkData( SalInstance *pInstance )
     497             : #if GTK_CHECK_VERSION(3,0,0)
     498             :     : SalGenericData( SAL_DATA_GTK3, pInstance )
     499             : #else
     500             :     : SalGenericData( SAL_DATA_GTK, pInstance )
     501             : #endif
     502           3 :     , blockIdleTimeout( false )
     503             : {
     504           3 :     m_pUserEvent = NULL;
     505           3 :     m_aDispatchMutex = osl_createMutex();
     506           3 :     m_aDispatchCondition = osl_createCondition();
     507           3 : }
     508             : 
     509             : XIOErrorHandler aOrigXIOErrorHandler = NULL;
     510             : 
     511             : extern "C" {
     512             : 
     513           0 : static int XIOErrorHdl(Display *)
     514             : {
     515           0 :     fprintf(stderr, "X IO Error\n");
     516           0 :     _exit(1);
     517             :         // avoid crashes in unrelated threads that still run while atexit
     518             :         // handlers are in progress
     519             : }
     520             : 
     521             : }
     522             : 
     523           0 : GtkData::~GtkData()
     524             : {
     525           0 :     Yield( true, true );
     526           0 :     g_warning ("TESTME: We used to have a stop-timer here, but the central code should do this");
     527             : 
     528             :      // sanity check: at this point nobody should be yielding, but wake them
     529             :      // up anyway before the condition they're waiting on gets destroyed.
     530           0 :     osl_setCondition( m_aDispatchCondition );
     531             : 
     532           0 :     osl_acquireMutex( m_aDispatchMutex );
     533           0 :     if (m_pUserEvent)
     534             :     {
     535           0 :         g_source_destroy (m_pUserEvent);
     536           0 :         g_source_unref (m_pUserEvent);
     537           0 :         m_pUserEvent = NULL;
     538             :     }
     539           0 :     osl_destroyCondition( m_aDispatchCondition );
     540           0 :     osl_releaseMutex( m_aDispatchMutex );
     541           0 :     osl_destroyMutex( m_aDispatchMutex );
     542           0 :     XSetIOErrorHandler(aOrigXIOErrorHandler);
     543           0 : }
     544             : 
     545           1 : void GtkData::Dispose()
     546             : {
     547           1 :     deInitNWF();
     548           1 : }
     549             : 
     550           0 : void GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents )
     551             : {
     552           0 :     blockIdleTimeout = !bWait;
     553             :     /* #i33212# only enter g_main_context_iteration in one thread at any one
     554             :      * time, else one of them potentially will never end as long as there is
     555             :      * another thread in there. Having only one yieldin thread actually dispatch
     556             :      * fits the vcl event model (see e.g. the generic plugin).
     557             :      */
     558           0 :     bool bDispatchThread = false;
     559           0 :     bool bWasEvent = false;
     560             :     {
     561             :         // release YieldMutex (and re-acquire at block end)
     562           0 :         SalYieldMutexReleaser aReleaser;
     563           0 :         if( osl_tryToAcquireMutex( m_aDispatchMutex ) )
     564           0 :             bDispatchThread = true;
     565           0 :         else if( ! bWait )
     566             :         {
     567           0 :             blockIdleTimeout = false;
     568           0 :             return; // someone else is waiting already, return
     569             :         }
     570             : 
     571           0 :         if( bDispatchThread )
     572             :         {
     573           0 :             int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1;
     574           0 :             gboolean wasOneEvent = TRUE;
     575           0 :             while( nMaxEvents-- && wasOneEvent )
     576             :             {
     577           0 :                 wasOneEvent = g_main_context_iteration( NULL, bWait && !bWasEvent );
     578           0 :                 if( wasOneEvent )
     579           0 :                     bWasEvent = true;
     580             :             }
     581             :         }
     582           0 :         else if( bWait )
     583             :         {
     584             :             /* #i41693# in case the dispatch thread hangs in join
     585             :              * for this thread the condition will never be set
     586             :              * workaround: timeout of 1 second a emergency exit
     587             :              */
     588             :             // we are the dispatch thread
     589           0 :             osl_resetCondition( m_aDispatchCondition );
     590           0 :             TimeValue aValue = { 1, 0 };
     591           0 :             osl_waitCondition( m_aDispatchCondition, &aValue );
     592           0 :         }
     593             :     }
     594             : 
     595           0 :     if( bDispatchThread )
     596             :     {
     597           0 :         osl_releaseMutex( m_aDispatchMutex );
     598           0 :         if( bWasEvent )
     599           0 :             osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields
     600             :     }
     601           0 :     blockIdleTimeout = false;
     602             : }
     603             : 
     604           3 : void GtkData::Init()
     605             : {
     606             :     int i;
     607             :     SAL_INFO( "vcl.gtk", "GtkMainloop::Init()" );
     608           3 :     XrmInitialize();
     609             : 
     610             : #if !GTK_CHECK_VERSION(3,0,0)
     611           3 :     gtk_set_locale();
     612             : #endif
     613             : 
     614             :     /*
     615             :      * open connection to X11 Display
     616             :      * try in this order:
     617             :      *  o  -display command line parameter,
     618             :      *  o  $DISPLAY environment variable
     619             :      *  o  default display
     620             :      */
     621             : 
     622           3 :     GdkDisplay *pGdkDisp = NULL;
     623             : 
     624             :     // is there a -display command line parameter?
     625           3 :     rtl_TextEncoding aEnc = osl_getThreadTextEncoding();
     626           3 :     int nParams = osl_getCommandArgCount();
     627           3 :     OString aDisplay;
     628           6 :     OUString aParam, aBin;
     629           3 :     char** pCmdLineAry = new char*[ nParams+1 ];
     630           3 :     osl_getExecutableFile( &aParam.pData );
     631           3 :     osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData );
     632           3 :     pCmdLineAry[0] = g_strdup( OUStringToOString( aBin, aEnc ).getStr() );
     633          22 :     for (i=0; i<nParams; i++)
     634             :     {
     635          19 :         osl_getCommandArg(i, &aParam.pData );
     636          19 :         OString aBParam( OUStringToOString( aParam, aEnc ) );
     637             : 
     638          19 :         if( aParam == "-display" || aParam == "--display" )
     639             :         {
     640           0 :             pCmdLineAry[i+1] = g_strdup( "--display" );
     641           0 :             osl_getCommandArg(i+1, &aParam.pData );
     642           0 :             aDisplay = OUStringToOString( aParam, aEnc );
     643             :         }
     644             :         else
     645          19 :             pCmdLineAry[i+1] = g_strdup( aBParam.getStr() );
     646          19 :     }
     647             :     // add executable
     648           3 :     nParams++;
     649             : 
     650           3 :     g_set_application_name(SalGenericSystem::getFrameClassName());
     651             : 
     652             :     // Set consistent name of the root accessible
     653           6 :     OUString aAppName = Application::GetAppName();
     654           3 :     if( !aAppName.isEmpty() )
     655             :     {
     656           0 :         OString aPrgName = OUStringToOString(aAppName, aEnc);
     657           0 :         g_set_prgname(aPrgName.getStr());
     658             :     }
     659             : 
     660             :     // init gtk/gdk
     661           3 :     gtk_init_check( &nParams, &pCmdLineAry );
     662           3 :     gdk_error_trap_push();
     663           3 :     aOrigXIOErrorHandler = XSetIOErrorHandler(XIOErrorHdl);
     664             : 
     665          25 :     for (i = 0; i < nParams; i++ )
     666          22 :         g_free( pCmdLineAry[i] );
     667           3 :     delete [] pCmdLineAry;
     668             : 
     669             : #if OSL_DEBUG_LEVEL > 1
     670             :     if (g_getenv ("SAL_DEBUG_UPDATES"))
     671             :         gdk_window_set_debug_updates (TRUE);
     672             : #endif
     673             : 
     674           3 :     pGdkDisp = gdk_display_get_default();
     675           3 :     if ( !pGdkDisp )
     676             :     {
     677           0 :         OUString aProgramFileURL;
     678           0 :         osl_getExecutableFile( &aProgramFileURL.pData );
     679           0 :         OUString aProgramSystemPath;
     680           0 :         osl_getSystemPathFromFileURL (aProgramFileURL.pData, &aProgramSystemPath.pData);
     681             :         OString  aProgramName = OUStringToOString(
     682             :                                             aProgramSystemPath,
     683           0 :                                             osl_getThreadTextEncoding() );
     684             :         fprintf( stderr, "%s X11 error: Can't open display: %s\n",
     685           0 :                 aProgramName.getStr(), aDisplay.getStr());
     686           0 :         fprintf( stderr, "   Set DISPLAY environment variable, use -display option\n");
     687           0 :         fprintf( stderr, "   or check permissions of your X-Server\n");
     688           0 :         fprintf( stderr, "   (See \"man X\" resp. \"man xhost\" for details)\n");
     689           0 :         fflush( stderr );
     690           0 :         exit(0);
     691             :     }
     692             : 
     693             :     /*
     694             :      * if a -display switch was used, we need
     695             :      * to set the environment accoringly since
     696             :      * the clipboard build another connection
     697             :      * to the xserver using $DISPLAY
     698             :      */
     699           6 :     OUString envVar("DISPLAY");
     700           3 :     const gchar *name = gdk_display_get_name( pGdkDisp );
     701           6 :     OUString envValue(name, strlen(name), aEnc);
     702           3 :     osl_setEnvironment(envVar.pData, envValue.pData);
     703             : 
     704           3 :     GtkSalDisplay *pDisplay = new GtkSalDisplay( pGdkDisp );
     705           3 :     SetDisplay( pDisplay );
     706             : 
     707             : #if !GTK_CHECK_VERSION(3,0,0)
     708           3 :     Display *pDisp = gdk_x11_display_get_xdisplay( pGdkDisp );
     709             : 
     710           3 :     gdk_error_trap_push();
     711           3 :     SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp );
     712           3 :     bool bErrorOccured = gdk_error_trap_pop() != 0;
     713           3 :     gdk_error_trap_push();
     714           3 :     pKbdExtension->UseExtension( bErrorOccured );
     715           3 :     gdk_error_trap_pop();
     716           3 :     GetGtkDisplay()->SetKbdExtension( pKbdExtension );
     717             : #else
     718             :     //FIXME: unwind keyboard extension bits
     719             : #endif
     720             : 
     721             :     // add signal handler to notify screen size changes
     722           3 :     int nScreens = gdk_display_get_n_screens( pGdkDisp );
     723           6 :     for( int n = 0; n < nScreens; n++ )
     724             :     {
     725           3 :         GdkScreen *pScreen = gdk_display_get_screen( pGdkDisp, n );
     726           3 :         if( pScreen )
     727             :         {
     728           3 :             pDisplay->screenSizeChanged( pScreen );
     729           3 :             pDisplay->monitorsChanged( pScreen );
     730           3 :             g_signal_connect( G_OBJECT(pScreen), "size-changed",
     731           3 :                               G_CALLBACK(signalScreenSizeChanged), pDisplay );
     732           3 :             if( ! gtk_check_version( 2, 14, 0 ) ) // monitors-changed came in with 2.14, avoid an assertion
     733           3 :                 g_signal_connect( G_OBJECT(pScreen), "monitors-changed",
     734           3 :                                   G_CALLBACK(signalMonitorsChanged), GetGtkDisplay() );
     735             :         }
     736           3 :     }
     737           3 : }
     738             : 
     739          17 : void GtkData::ErrorTrapPush()
     740             : {
     741          17 :     gdk_error_trap_push ();
     742          17 : }
     743             : 
     744          17 : bool GtkData::ErrorTrapPop( bool bIgnoreError )
     745             : {
     746             : #if GTK_CHECK_VERSION(3,0,0)
     747             :     if( bIgnoreError )
     748             :     {
     749             :         gdk_error_trap_pop_ignored (); // faster
     750             :         return false;
     751             :     }
     752             : #else
     753             :     (void) bIgnoreError;
     754             : #endif
     755          17 :     return gdk_error_trap_pop () != 0;
     756             : }
     757             : 
     758             : extern "C" {
     759             : 
     760             :     struct SalGtkTimeoutSource {
     761             :         GSource      aParent;
     762             :         GTimeVal     aFireTime;
     763             :         GtkSalTimer *pInstance;
     764             :     };
     765             : 
     766           3 :     static void sal_gtk_timeout_defer( SalGtkTimeoutSource *pTSource )
     767             :     {
     768           3 :         g_get_current_time( &pTSource->aFireTime );
     769           3 :         g_time_val_add( &pTSource->aFireTime, pTSource->pInstance->m_nTimeoutMS * 1000 );
     770           3 :     }
     771             : 
     772           0 :     static gboolean sal_gtk_timeout_expired( SalGtkTimeoutSource *pTSource,
     773             :                                              gint *nTimeoutMS, GTimeVal *pTimeNow )
     774             :     {
     775           0 :         glong nDeltaSec = pTSource->aFireTime.tv_sec - pTimeNow->tv_sec;
     776           0 :         glong nDeltaUSec = pTSource->aFireTime.tv_usec - pTimeNow->tv_usec;
     777           0 :         if( nDeltaSec < 0 || ( nDeltaSec == 0 && nDeltaUSec < 0) )
     778             :         {
     779           0 :             *nTimeoutMS = 0;
     780           0 :             return TRUE;
     781             :         }
     782           0 :         if( nDeltaUSec < 0 )
     783             :         {
     784           0 :             nDeltaUSec += 1000000;
     785           0 :             nDeltaSec -= 1;
     786             :         }
     787             :         // if the clock changes backwards we need to cope ...
     788           0 :         if( (unsigned long) nDeltaSec > 1 + ( pTSource->pInstance->m_nTimeoutMS / 1000 ) )
     789             :         {
     790           0 :             sal_gtk_timeout_defer( pTSource );
     791           0 :             return TRUE;
     792             :         }
     793             : 
     794           0 :         *nTimeoutMS = MIN( G_MAXINT, ( nDeltaSec * 1000 + (nDeltaUSec + 999) / 1000 ) );
     795             : 
     796           0 :         return *nTimeoutMS == 0;
     797             :     }
     798             : 
     799           0 :     static gboolean sal_gtk_timeout_prepare( GSource *pSource, gint *nTimeoutMS )
     800             :     {
     801           0 :         SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource);
     802             : 
     803             :         GTimeVal aTimeNow;
     804           0 :         g_get_current_time( &aTimeNow );
     805             : 
     806           0 :         return sal_gtk_timeout_expired( pTSource, nTimeoutMS, &aTimeNow );
     807             :     }
     808             : 
     809           0 :     static gboolean sal_gtk_timeout_check( GSource *pSource )
     810             :     {
     811           0 :         SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource);
     812             : 
     813             :         GTimeVal aTimeNow;
     814           0 :         g_get_current_time( &aTimeNow );
     815             : 
     816           0 :         return ( pTSource->aFireTime.tv_sec < aTimeNow.tv_sec ||
     817           0 :                  ( pTSource->aFireTime.tv_sec == aTimeNow.tv_sec &&
     818           0 :                    pTSource->aFireTime.tv_usec < aTimeNow.tv_usec ) );
     819             :     }
     820             : 
     821           0 :     static gboolean sal_gtk_timeout_dispatch( GSource *pSource, GSourceFunc, gpointer )
     822             :     {
     823           0 :         SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource);
     824             : 
     825           0 :         if( !pTSource->pInstance )
     826           0 :             return FALSE;
     827             : 
     828           0 :         GtkData *pSalData = static_cast< GtkData* >( GetSalData());
     829             : 
     830           0 :         osl::Guard< comphelper::SolarMutex > aGuard( pSalData->m_pInstance->GetYieldMutex() );
     831             : 
     832           0 :         sal_gtk_timeout_defer( pTSource );
     833             : 
     834           0 :         ImplSVData* pSVData = ImplGetSVData();
     835           0 :         if( pSVData->mpSalTimer )
     836             :         {
     837             :             // TODO: context_pending should be probably checked too, but it causes locking assertion failures
     838           0 :             bool idle = !pSalData->BlockIdleTimeout() && /*!g_main_context_pending( NULL ) &&*/ !gdk_events_pending();
     839           0 :             pSVData->mpSalTimer->CallCallback( idle );
     840             :         }
     841             : 
     842           0 :         return TRUE;
     843             :     }
     844             : 
     845             :     static GSourceFuncs sal_gtk_timeout_funcs =
     846             :     {
     847             :         sal_gtk_timeout_prepare,
     848             :         sal_gtk_timeout_check,
     849             :         sal_gtk_timeout_dispatch,
     850             :         NULL, NULL, NULL
     851             :     };
     852             : }
     853             : 
     854             : static SalGtkTimeoutSource *
     855           3 : create_sal_gtk_timeout( GtkSalTimer *pTimer )
     856             : {
     857           3 :   GSource *pSource = g_source_new( &sal_gtk_timeout_funcs, sizeof( SalGtkTimeoutSource ) );
     858           3 :   SalGtkTimeoutSource *pTSource = reinterpret_cast<SalGtkTimeoutSource *>(pSource);
     859           3 :   pTSource->pInstance = pTimer;
     860             : 
     861             :   // #i36226# timers should be executed with lower priority
     862             :   // than XEvents like in generic plugin
     863           3 :   g_source_set_priority( pSource, G_PRIORITY_LOW );
     864           3 :   g_source_set_can_recurse( pSource, TRUE );
     865             :   g_source_set_callback( pSource,
     866             :                          /* unused dummy */ g_idle_remove_by_data,
     867           3 :                          NULL, NULL );
     868           3 :   g_source_attach( pSource, g_main_context_default() );
     869             : 
     870           3 :   sal_gtk_timeout_defer( pTSource );
     871             : 
     872           3 :   return pTSource;
     873             : }
     874             : 
     875           3 : GtkSalTimer::GtkSalTimer()
     876             :     : m_pTimeout(NULL)
     877           3 :     , m_nTimeoutMS(0)
     878             : {
     879           3 : }
     880             : 
     881           3 : GtkSalTimer::~GtkSalTimer()
     882             : {
     883           1 :     GtkInstance *pInstance = static_cast<GtkInstance *>(GetSalData()->m_pInstance);
     884           1 :     pInstance->RemoveTimer( this );
     885           1 :     Stop();
     886           2 : }
     887             : 
     888           0 : bool GtkSalTimer::Expired()
     889             : {
     890           0 :     if( !m_pTimeout )
     891           0 :         return false;
     892             : 
     893           0 :     gint nDummy = 0;
     894             :     GTimeVal aTimeNow;
     895           0 :     g_get_current_time( &aTimeNow );
     896           0 :     return !!sal_gtk_timeout_expired( m_pTimeout, &nDummy, &aTimeNow);
     897             : }
     898             : 
     899           3 : void GtkSalTimer::Start( sal_uLong nMS )
     900             : {
     901           3 :     m_nTimeoutMS = nMS; // for restarting
     902           3 :     Stop(); // FIXME: ideally re-use an existing m_pTimeout
     903           3 :     m_pTimeout = create_sal_gtk_timeout( this );
     904           3 : }
     905             : 
     906           5 : void GtkSalTimer::Stop()
     907             : {
     908           5 :     if( m_pTimeout )
     909             :     {
     910           1 :         g_source_destroy( &m_pTimeout->aParent );
     911           1 :         g_source_unref( &m_pTimeout->aParent );
     912           1 :         m_pTimeout = NULL;
     913             :     }
     914           5 : }
     915             : 
     916           0 : gboolean GtkData::userEventFn( gpointer data )
     917             : {
     918           0 :     gboolean bContinue = FALSE;
     919           0 :     GtkData *pThis = static_cast<GtkData *>(data);
     920           0 :     SalGenericData *pData = GetGenericData();
     921           0 :     osl::Guard< comphelper::SolarMutex > aGuard( pData->m_pInstance->GetYieldMutex() );
     922           0 :     const SalGenericDisplay *pDisplay = pData->GetDisplay();
     923           0 :     if (pDisplay)
     924             :     {
     925             :         OSL_ASSERT(static_cast<const SalGenericDisplay *>(pThis->GetGtkDisplay()) == pDisplay);
     926           0 :         pThis->GetGtkDisplay()->EventGuardAcquire();
     927             : 
     928           0 :         if( !pThis->GetGtkDisplay()->HasUserEvents() )
     929             :         {
     930           0 :             if( pThis->m_pUserEvent )
     931             :             {
     932           0 :                 g_source_unref (pThis->m_pUserEvent);
     933           0 :                 pThis->m_pUserEvent = NULL;
     934             :             }
     935           0 :             bContinue = FALSE;
     936             :         }
     937             :         else
     938           0 :             bContinue = TRUE;
     939             : 
     940           0 :         pThis->GetGtkDisplay()->EventGuardRelease();
     941             : 
     942           0 :         pThis->GetGtkDisplay()->DispatchInternalEvent();
     943             :     }
     944             : 
     945           0 :     return bContinue;
     946             : }
     947             : 
     948             : extern "C" {
     949           0 :     static gboolean call_userEventFn( void *data )
     950             :     {
     951           0 :         SolarMutexGuard aGuard;
     952           0 :         return GtkData::userEventFn( data );
     953             :     }
     954             : }
     955             : 
     956             : // hEventGuard_ held during this invocation
     957          58 : void GtkData::PostUserEvent()
     958             : {
     959          58 :     if (m_pUserEvent)
     960          55 :         g_main_context_wakeup (NULL); // really needed ?
     961             :     else // nothing pending anyway
     962             :     {
     963           3 :         m_pUserEvent = g_idle_source_new();
     964           3 :         g_source_set_priority (m_pUserEvent, G_PRIORITY_HIGH);
     965           3 :         g_source_set_can_recurse (m_pUserEvent, TRUE);
     966             :         g_source_set_callback (m_pUserEvent, call_userEventFn,
     967           3 :                                static_cast<gpointer>(this), NULL);
     968           3 :         g_source_attach (m_pUserEvent, g_main_context_default ());
     969             :     }
     970          58 : }
     971             : 
     972          58 : void GtkSalDisplay::PostUserEvent()
     973             : {
     974          58 :     GetGtkSalData()->PostUserEvent();
     975          58 : }
     976             : 
     977          13 : void GtkSalDisplay::deregisterFrame( SalFrame* pFrame )
     978             : {
     979          13 :     if( m_pCapture == pFrame )
     980             :     {
     981           0 :         static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
     982           0 :         m_pCapture = NULL;
     983             :     }
     984          13 :     SalGenericDisplay::deregisterFrame( pFrame );
     985          22 : }
     986             : 
     987             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11