xref: /trunk/main/vcl/unx/gtk/app/gtkdata.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
229f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #define _SV_SALDATA_CXX
28cdf0e10cSrcweir 
29cdf0e10cSrcweir // -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <unistd.h>
32cdf0e10cSrcweir #include <fcntl.h>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <stdio.h>
35cdf0e10cSrcweir #include <string.h>
36cdf0e10cSrcweir #include <stdlib.h>
37cdf0e10cSrcweir #include <limits.h>
38cdf0e10cSrcweir #include <errno.h>
39cdf0e10cSrcweir #include <poll.h>
40cdf0e10cSrcweir #ifdef FREEBSD
41cdf0e10cSrcweir #include <sys/types.h>
42cdf0e10cSrcweir #include <sys/time.h>
43cdf0e10cSrcweir #include <unistd.h>
44cdf0e10cSrcweir #endif
45cdf0e10cSrcweir #include <unx/gtk/gtkdata.hxx>
46cdf0e10cSrcweir #include <unx/gtk/gtkinst.hxx>
47cdf0e10cSrcweir #include <unx/gtk/gtkframe.hxx>
48cdf0e10cSrcweir #include <unx/salobj.h>
49cdf0e10cSrcweir #include <osl/thread.h>
50cdf0e10cSrcweir #include <osl/process.h>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #include <tools/debug.hxx>
53cdf0e10cSrcweir #include "unx/i18n_im.hxx"
54cdf0e10cSrcweir #include "unx/i18n_xkb.hxx"
55cdf0e10cSrcweir #include <unx/wmadaptor.hxx>
56cdf0e10cSrcweir 
57cdf0e10cSrcweir #include "unx/x11_cursors/salcursors.h"
58cdf0e10cSrcweir 
59cdf0e10cSrcweir #include <vcl/svapp.hxx>
60cdf0e10cSrcweir 
61cdf0e10cSrcweir using namespace rtl;
62cdf0e10cSrcweir using namespace vcl_sal;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir /***************************************************************************
65cdf0e10cSrcweir  * class GtkDisplay                                                        *
66cdf0e10cSrcweir  ***************************************************************************/
67cdf0e10cSrcweir 
GtkSalDisplay(GdkDisplay * pDisplay)68cdf0e10cSrcweir GtkSalDisplay::GtkSalDisplay( GdkDisplay* pDisplay )
69cdf0e10cSrcweir             : SalDisplay( gdk_x11_display_get_xdisplay( pDisplay ) ),
70cdf0e10cSrcweir               m_pGdkDisplay( pDisplay ),
71cdf0e10cSrcweir               m_bStartupCompleted( false )
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     m_bUseRandRWrapper = false; // use gdk signal instead
74cdf0e10cSrcweir     for(int i = 0; i < POINTER_COUNT; i++)
75cdf0e10cSrcweir         m_aCursors[ i ] = NULL;
76cdf0e10cSrcweir     Init ();
77cdf0e10cSrcweir }
78cdf0e10cSrcweir 
~GtkSalDisplay()79cdf0e10cSrcweir GtkSalDisplay::~GtkSalDisplay()
80cdf0e10cSrcweir {
81cdf0e10cSrcweir     if( !m_bStartupCompleted )
82cdf0e10cSrcweir         gdk_notify_startup_complete();
83cdf0e10cSrcweir     doDestruct();
84cdf0e10cSrcweir 
85cdf0e10cSrcweir     for(int i = 0; i < POINTER_COUNT; i++)
86cdf0e10cSrcweir         if( m_aCursors[ i ] )
87cdf0e10cSrcweir             gdk_cursor_unref( m_aCursors[ i ] );
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     pDisp_ = NULL;
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
deregisterFrame(SalFrame * pFrame)92cdf0e10cSrcweir void GtkSalDisplay::deregisterFrame( SalFrame* pFrame )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir     if( m_pCapture == pFrame )
95cdf0e10cSrcweir     {
96cdf0e10cSrcweir         static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
97cdf0e10cSrcweir         m_pCapture = NULL;
98cdf0e10cSrcweir     }
99cdf0e10cSrcweir     SalDisplay::deregisterFrame( pFrame );
100cdf0e10cSrcweir }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir extern "C" {
call_filterGdkEvent(GdkXEvent * sys_event,GdkEvent * event,gpointer data)103cdf0e10cSrcweir GdkFilterReturn call_filterGdkEvent( GdkXEvent* sys_event,
104cdf0e10cSrcweir                                      GdkEvent* event,
105cdf0e10cSrcweir                                      gpointer data )
106cdf0e10cSrcweir {
107cdf0e10cSrcweir     return GtkSalDisplay::filterGdkEvent( sys_event, event, data );
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
signalKeysChanged(GdkKeymap *,gpointer data)110cdf0e10cSrcweir void signalKeysChanged( GdkKeymap*, gpointer data )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
113cdf0e10cSrcweir     pDisp->GetKeyboardName(TRUE);
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
signalScreenSizeChanged(GdkScreen * pScreen,gpointer data)116cdf0e10cSrcweir void signalScreenSizeChanged( GdkScreen* pScreen, gpointer data )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
119cdf0e10cSrcweir     pDisp->screenSizeChanged( pScreen );
120cdf0e10cSrcweir }
121cdf0e10cSrcweir 
signalMonitorsChanged(GdkScreen * pScreen,gpointer data)122cdf0e10cSrcweir void signalMonitorsChanged( GdkScreen* pScreen, gpointer data )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
125cdf0e10cSrcweir     pDisp->monitorsChanged( pScreen );
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
filterGdkEvent(GdkXEvent * sys_event,GdkEvent *,gpointer data)130cdf0e10cSrcweir GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event,
131cdf0e10cSrcweir                                                GdkEvent*,
132cdf0e10cSrcweir                                                gpointer data )
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     GdkFilterReturn aFilterReturn = GDK_FILTER_CONTINUE;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir     XEvent *pEvent = (XEvent *)sys_event;
137cdf0e10cSrcweir     GtkSalDisplay *pDisplay = (GtkSalDisplay *)data;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     // dispatch all XEvents to event callback
140cdf0e10cSrcweir     if( GetSalData()->m_pInstance->
141cdf0e10cSrcweir         CallEventCallback( pEvent, sizeof( XEvent ) ) )
142cdf0e10cSrcweir         aFilterReturn = GDK_FILTER_REMOVE;
143cdf0e10cSrcweir 
144cdf0e10cSrcweir     GTK_YIELD_GRAB();
145cdf0e10cSrcweir 
146cdf0e10cSrcweir     if (pDisplay->GetDisplay() == pEvent->xany.display )
147cdf0e10cSrcweir     {
148cdf0e10cSrcweir         // #i53471# gtk has no callback mechanism that lets us be notified
149cdf0e10cSrcweir         // when settings (as in XSETTING and opposed to styles) are changed.
150cdf0e10cSrcweir         // so we need to listen for corresponding property notifications here
151cdf0e10cSrcweir         // these should be rare enough so that we can assume that the settings
152cdf0e10cSrcweir         // actually change when a corresponding PropertyNotify occurs
153cdf0e10cSrcweir         if( pEvent->type == PropertyNotify &&
154cdf0e10cSrcweir             pEvent->xproperty.atom == pDisplay->getWMAdaptor()->getAtom( WMAdaptor::XSETTINGS ) &&
155cdf0e10cSrcweir             ! pDisplay->m_aFrames.empty()
156cdf0e10cSrcweir            )
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             pDisplay->SendInternalEvent( pDisplay->m_aFrames.front(), NULL, SALEVENT_SETTINGSCHANGED );
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir         // let's see if one of our frames wants to swallow these events
161cdf0e10cSrcweir         // get the frame
162cdf0e10cSrcweir         for( std::list< SalFrame* >::const_iterator it = pDisplay->m_aFrames.begin();
163cdf0e10cSrcweir                  it != pDisplay->m_aFrames.end(); ++it )
164cdf0e10cSrcweir         {
165cdf0e10cSrcweir             GtkSalFrame* pFrame = static_cast<GtkSalFrame*>(*it);
166cdf0e10cSrcweir             if( (GdkNativeWindow)pFrame->GetSystemData()->aWindow == pEvent->xany.window ||
167cdf0e10cSrcweir                 ( pFrame->getForeignParent() && pFrame->getForeignParentWindow() == pEvent->xany.window ) ||
168cdf0e10cSrcweir                 ( pFrame->getForeignTopLevel() && pFrame->getForeignTopLevelWindow() == pEvent->xany.window )
169cdf0e10cSrcweir                 )
170cdf0e10cSrcweir             {
171cdf0e10cSrcweir                 if( ! pFrame->Dispatch( pEvent ) )
172cdf0e10cSrcweir                     aFilterReturn = GDK_FILTER_REMOVE;
173cdf0e10cSrcweir                 break;
174cdf0e10cSrcweir             }
175cdf0e10cSrcweir         }
176cdf0e10cSrcweir         X11SalObject::Dispatch( pEvent );
177cdf0e10cSrcweir     }
178cdf0e10cSrcweir 
179cdf0e10cSrcweir     return aFilterReturn;
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
screenSizeChanged(GdkScreen * pScreen)182cdf0e10cSrcweir void GtkSalDisplay::screenSizeChanged( GdkScreen* pScreen )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     if( pScreen )
185cdf0e10cSrcweir     {
186cdf0e10cSrcweir         int nScreen = gdk_screen_get_number( pScreen );
187cdf0e10cSrcweir         if( nScreen < static_cast<int>(m_aScreens.size()) )
188cdf0e10cSrcweir         {
189cdf0e10cSrcweir             ScreenData& rSD = const_cast<ScreenData&>(m_aScreens[nScreen]);
190cdf0e10cSrcweir             if( rSD.m_bInit )
191cdf0e10cSrcweir             {
192cdf0e10cSrcweir                 rSD.m_aSize = Size( gdk_screen_get_width( pScreen ),
193cdf0e10cSrcweir                                     gdk_screen_get_height( pScreen ) );
194cdf0e10cSrcweir                 if( ! m_aFrames.empty() )
195cdf0e10cSrcweir                     m_aFrames.front()->CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
196cdf0e10cSrcweir             }
197cdf0e10cSrcweir         }
198cdf0e10cSrcweir         else
199cdf0e10cSrcweir         {
200cdf0e10cSrcweir             DBG_ERROR( "unknown screen changed size" );
201cdf0e10cSrcweir         }
202cdf0e10cSrcweir     }
203cdf0e10cSrcweir }
204cdf0e10cSrcweir 
monitorsChanged(GdkScreen * pScreen)205cdf0e10cSrcweir void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir     /* Caution: since we support the _NET_WM_FULLSCREEN_MONITORS property now and
208cdf0e10cSrcweir        the EWMH spec says, the index used for that needs to be that of the
209cdf0e10cSrcweir        Xinerama extension, we need to ensure that the order of m_aXineramaScreens is actually intact.
210cdf0e10cSrcweir 
211cdf0e10cSrcweir        gdk_screen_get_monitor_geometry however has a different sort order that has a default monitor number
212cdf0e10cSrcweir        Xinerama returns the default monitor as 0.
213cdf0e10cSrcweir        That means if we fill in the multiple montors vector from gdk, we'll get the wrong order unless
214cdf0e10cSrcweir        the default monitor is incidentally the same (number 0).
215cdf0e10cSrcweir 
216cdf0e10cSrcweir        Given that XRandR (which is what gdk_screen_get_monitor_geometry is based on) is
217cdf0e10cSrcweir        supposed to replace Xinerama, this is bound to get a problem at some time again,
218cdf0e10cSrcweir        unfortunately there does not currently seem to be a way to map the returns of xinerama to
219cdf0e10cSrcweir        that of randr. Currently getting Xinerama values again works with updated values, given
220cdf0e10cSrcweir        a new enough Xserver.
221cdf0e10cSrcweir     */
222cdf0e10cSrcweir     InitXinerama();
223cdf0e10cSrcweir     (void)pScreen;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     #if 0
226cdf0e10cSrcweir     if( pScreen )
227cdf0e10cSrcweir     {
228cdf0e10cSrcweir         if( gdk_display_get_n_screens(m_pGdkDisplay) == 1 )
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             int nScreen = gdk_screen_get_number( pScreen );
231cdf0e10cSrcweir             if( nScreen == m_nDefaultScreen ) //To-Do, make m_aXineramaScreens a per-screen thing ?
232cdf0e10cSrcweir             {
233cdf0e10cSrcweir                 gint nMonitors = gdk_screen_get_n_monitors(pScreen);
234cdf0e10cSrcweir                 m_aXineramaScreens = std::vector<Rectangle>();
235cdf0e10cSrcweir                 m_aXineramaScreenIndexMap = std::vector<int>(nMonitors);
236cdf0e10cSrcweir                 for (gint i = 0; i < nMonitors; ++i)
237cdf0e10cSrcweir                 {
238cdf0e10cSrcweir                     GdkRectangle dest;
239cdf0e10cSrcweir                     gdk_screen_get_monitor_geometry(pScreen, i, &dest);
240cdf0e10cSrcweir                     m_aXineramaScreenIndexMap[i] = addXineramaScreenUnique( dest.x, dest.y, dest.width, dest.height );
241cdf0e10cSrcweir                 }
242cdf0e10cSrcweir                 m_bXinerama = m_aXineramaScreens.size() > 1;
243cdf0e10cSrcweir                 if( ! m_aFrames.empty() )
244cdf0e10cSrcweir                     m_aFrames.front()->CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
245cdf0e10cSrcweir             }
246cdf0e10cSrcweir             else
247cdf0e10cSrcweir             {
248cdf0e10cSrcweir                 DBG_ERROR( "monitors for non-default screen changed, extend-me" );
249cdf0e10cSrcweir             }
250cdf0e10cSrcweir         }
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir     #endif
253cdf0e10cSrcweir }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir extern "C"
256cdf0e10cSrcweir {
257cdf0e10cSrcweir     typedef gint(* screen_get_primary_monitor)(GdkScreen *screen);
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
GetDefaultMonitorNumber() const260cdf0e10cSrcweir int GtkSalDisplay::GetDefaultMonitorNumber() const
261cdf0e10cSrcweir {
262cdf0e10cSrcweir     int n = 0;
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     // currently disabled, see remarks in monitorsChanged
265cdf0e10cSrcweir #if 0
266cdf0e10cSrcweir     GdkScreen* pScreen = gdk_display_get_screen( m_pGdkDisplay, m_nDefaultScreen );
267cdf0e10cSrcweir #if GTK_CHECK_VERSION(2,20,0)
268cdf0e10cSrcweir     n = gdk_screen_get_primary_monitor(pScreen);
269cdf0e10cSrcweir #else
270cdf0e10cSrcweir     static screen_get_primary_monitor sym_gdk_screen_get_primary_monitor =
271cdf0e10cSrcweir         (screen_get_primary_monitor)osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_screen_get_primary_monitor" );
272cdf0e10cSrcweir     if (sym_gdk_screen_get_primary_monitor)
273cdf0e10cSrcweir         n = sym_gdk_screen_get_primary_monitor( pScreen );
274cdf0e10cSrcweir #endif
275cdf0e10cSrcweir     if( n >= 0 && size_t(n) < m_aXineramaScreenIndexMap.size() )
276cdf0e10cSrcweir         n = m_aXineramaScreenIndexMap[n];
277cdf0e10cSrcweir #endif
278cdf0e10cSrcweir     return n;
279cdf0e10cSrcweir }
280cdf0e10cSrcweir 
initScreen(int nScreen) const281cdf0e10cSrcweir void GtkSalDisplay::initScreen( int nScreen ) const
282cdf0e10cSrcweir {
283cdf0e10cSrcweir     if( nScreen < 0 || nScreen >= static_cast<int>(m_aScreens.size()) )
284cdf0e10cSrcweir         nScreen = m_nDefaultScreen;
285cdf0e10cSrcweir     ScreenData& rSD = const_cast<ScreenData&>(m_aScreens[nScreen]);
286cdf0e10cSrcweir     if( rSD.m_bInit )
287cdf0e10cSrcweir         return;
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     // choose visual for screen
290cdf0e10cSrcweir     SalDisplay::initScreen( nScreen );
291cdf0e10cSrcweir     // now set a gdk default colormap matching the chosen visual to the screen
292cdf0e10cSrcweir     GdkVisual* pVis = gdkx_visual_get( rSD.m_aVisual.visualid );
293cdf0e10cSrcweir     GdkScreen* pScreen = gdk_display_get_screen( m_pGdkDisplay, nScreen );
294cdf0e10cSrcweir     if( pVis )
295cdf0e10cSrcweir     {
296cdf0e10cSrcweir         GdkColormap* pDefCol = gdk_screen_get_default_colormap( pScreen );
297cdf0e10cSrcweir         GdkVisual* pDefVis = gdk_colormap_get_visual( pDefCol );
298cdf0e10cSrcweir         if( pDefVis != pVis )
299cdf0e10cSrcweir         {
300cdf0e10cSrcweir            pDefCol = gdk_x11_colormap_foreign_new( pVis, rSD.m_aColormap.GetXColormap() );
301cdf0e10cSrcweir            gdk_screen_set_default_colormap( pScreen, pDefCol );
302cdf0e10cSrcweir            #if OSL_DEBUG_LEVEL > 1
303cdf0e10cSrcweir            fprintf( stderr, "set new gdk color map for screen %d\n", nScreen );
304cdf0e10cSrcweir            #endif
305cdf0e10cSrcweir         }
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir     #if OSL_DEBUG_LEVEL > 1
308cdf0e10cSrcweir     else
309cdf0e10cSrcweir         fprintf( stderr, "not GdkVisual for visual id %d\n", (int)rSD.m_aVisual.visualid );
310cdf0e10cSrcweir     #endif
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
Dispatch(XEvent * pEvent)313cdf0e10cSrcweir long GtkSalDisplay::Dispatch( XEvent* pEvent )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     if( GetDisplay() == pEvent->xany.display )
316cdf0e10cSrcweir     {
317cdf0e10cSrcweir         // let's see if one of our frames wants to swallow these events
318cdf0e10cSrcweir         // get the child frame
319cdf0e10cSrcweir         for( std::list< SalFrame* >::const_iterator it = m_aFrames.begin();
320cdf0e10cSrcweir              it != m_aFrames.end(); ++it )
321cdf0e10cSrcweir         {
322cdf0e10cSrcweir             if( (GdkNativeWindow)(*it)->GetSystemData()->aWindow == pEvent->xany.window )
323cdf0e10cSrcweir                 return static_cast<GtkSalFrame*>(*it)->Dispatch( pEvent );
324cdf0e10cSrcweir         }
325cdf0e10cSrcweir     }
326cdf0e10cSrcweir 
327cdf0e10cSrcweir     return GDK_FILTER_CONTINUE;
328cdf0e10cSrcweir }
329cdf0e10cSrcweir 
getFromXPM(const char * pBitmap,const char * pMask,int nWidth,int nHeight,int nXHot,int nYHot)330cdf0e10cSrcweir GdkCursor* GtkSalDisplay::getFromXPM( const char *pBitmap,
331cdf0e10cSrcweir                                       const char *pMask,
332cdf0e10cSrcweir                                       int nWidth, int nHeight,
333cdf0e10cSrcweir                                       int nXHot, int nYHot )
334cdf0e10cSrcweir {
335cdf0e10cSrcweir     GdkScreen *pScreen = gdk_display_get_default_screen( m_pGdkDisplay );
336cdf0e10cSrcweir     GdkDrawable *pDrawable = GDK_DRAWABLE( gdk_screen_get_root_window (pScreen) );
337cdf0e10cSrcweir     GdkBitmap *pBitmapPix = gdk_bitmap_create_from_data
338cdf0e10cSrcweir             ( pDrawable, pBitmap, nWidth, nHeight );
339cdf0e10cSrcweir     GdkBitmap *pMaskPix = gdk_bitmap_create_from_data
340cdf0e10cSrcweir             ( pDrawable, pMask, nWidth, nHeight );
341cdf0e10cSrcweir     GdkColormap *pColormap = gdk_drawable_get_colormap( pDrawable );
342cdf0e10cSrcweir 
343cdf0e10cSrcweir     GdkColor aWhite = { 0, 0xffff, 0xffff, 0xffff };
344cdf0e10cSrcweir     GdkColor aBlack = { 0, 0, 0, 0 };
345cdf0e10cSrcweir 
346cdf0e10cSrcweir     gdk_colormap_alloc_color( pColormap, &aBlack, FALSE, TRUE);
347cdf0e10cSrcweir     gdk_colormap_alloc_color( pColormap, &aWhite, FALSE, TRUE);
348cdf0e10cSrcweir 
349cdf0e10cSrcweir     return gdk_cursor_new_from_pixmap
350cdf0e10cSrcweir             ( pBitmapPix, pMaskPix,
351cdf0e10cSrcweir               &aBlack, &aWhite, nXHot, nYHot);
352cdf0e10cSrcweir }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir #define MAKE_CURSOR( vcl_name, name ) \
355cdf0e10cSrcweir     case vcl_name: \
35630c1b1efSHerbert Dürr         pCursor = getFromXPM( (const char*)name##curs##_bits, (const char*)name##mask##_bits, \
357cdf0e10cSrcweir                               name##curs_width, name##curs_height, \
358cdf0e10cSrcweir                               name##curs_x_hot, name##curs_y_hot ); \
359cdf0e10cSrcweir         break
360cdf0e10cSrcweir #define MAP_BUILTIN( vcl_name, gdk_name ) \
361cdf0e10cSrcweir         case vcl_name: \
362cdf0e10cSrcweir             pCursor = gdk_cursor_new_for_display( m_pGdkDisplay, gdk_name ); \
363cdf0e10cSrcweir             break
364cdf0e10cSrcweir 
getCursor(PointerStyle ePointerStyle)365cdf0e10cSrcweir GdkCursor *GtkSalDisplay::getCursor( PointerStyle ePointerStyle )
366cdf0e10cSrcweir {
36793ed1f29SArmin Le Grand     if (ePointerStyle >= POINTER_COUNT)
368cdf0e10cSrcweir         return NULL;
369cdf0e10cSrcweir 
370cdf0e10cSrcweir     if ( !m_aCursors[ ePointerStyle ] )
371cdf0e10cSrcweir     {
372cdf0e10cSrcweir         GdkCursor *pCursor = NULL;
373cdf0e10cSrcweir 
374cdf0e10cSrcweir         switch( ePointerStyle )
375cdf0e10cSrcweir         {
376cdf0e10cSrcweir             MAP_BUILTIN( POINTER_ARROW, GDK_LEFT_PTR );
377cdf0e10cSrcweir             MAP_BUILTIN( POINTER_TEXT, GDK_XTERM );
378cdf0e10cSrcweir             MAP_BUILTIN( POINTER_HELP, GDK_QUESTION_ARROW );
379cdf0e10cSrcweir             MAP_BUILTIN( POINTER_CROSS, GDK_CROSSHAIR );
380cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WAIT, GDK_WATCH );
381cdf0e10cSrcweir 
382cdf0e10cSrcweir             MAP_BUILTIN( POINTER_NSIZE, GDK_SB_V_DOUBLE_ARROW );
383cdf0e10cSrcweir             MAP_BUILTIN( POINTER_SSIZE, GDK_SB_V_DOUBLE_ARROW );
384cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WSIZE, GDK_SB_H_DOUBLE_ARROW );
385cdf0e10cSrcweir             MAP_BUILTIN( POINTER_ESIZE, GDK_SB_H_DOUBLE_ARROW );
386cdf0e10cSrcweir 
387cdf0e10cSrcweir             MAP_BUILTIN( POINTER_NWSIZE, GDK_TOP_LEFT_CORNER );
388cdf0e10cSrcweir             MAP_BUILTIN( POINTER_NESIZE, GDK_TOP_RIGHT_CORNER );
389cdf0e10cSrcweir             MAP_BUILTIN( POINTER_SWSIZE, GDK_BOTTOM_LEFT_CORNER );
390cdf0e10cSrcweir             MAP_BUILTIN( POINTER_SESIZE, GDK_BOTTOM_RIGHT_CORNER );
391cdf0e10cSrcweir 
392cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_NSIZE, GDK_TOP_SIDE );
393cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_SSIZE, GDK_BOTTOM_SIDE );
394cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_WSIZE, GDK_LEFT_SIDE );
395cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_ESIZE, GDK_RIGHT_SIDE );
396cdf0e10cSrcweir 
397cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_NWSIZE, GDK_TOP_LEFT_CORNER );
398cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_NESIZE, GDK_TOP_RIGHT_CORNER );
399cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_SWSIZE, GDK_BOTTOM_LEFT_CORNER );
400cdf0e10cSrcweir             MAP_BUILTIN( POINTER_WINDOW_SESIZE, GDK_BOTTOM_RIGHT_CORNER );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir             MAP_BUILTIN( POINTER_HSIZEBAR, GDK_SB_H_DOUBLE_ARROW );
403cdf0e10cSrcweir             MAP_BUILTIN( POINTER_VSIZEBAR, GDK_SB_V_DOUBLE_ARROW );
404cdf0e10cSrcweir 
405cdf0e10cSrcweir             MAP_BUILTIN( POINTER_REFHAND, GDK_HAND1 );
406cdf0e10cSrcweir             MAP_BUILTIN( POINTER_HAND, GDK_HAND2 );
407cdf0e10cSrcweir             MAP_BUILTIN( POINTER_PEN, GDK_PENCIL );
408cdf0e10cSrcweir 
409cdf0e10cSrcweir             MAP_BUILTIN( POINTER_HSPLIT, GDK_SB_H_DOUBLE_ARROW );
410cdf0e10cSrcweir             MAP_BUILTIN( POINTER_VSPLIT, GDK_SB_V_DOUBLE_ARROW );
411cdf0e10cSrcweir 
412cdf0e10cSrcweir             MAP_BUILTIN( POINTER_MOVE, GDK_FLEUR );
413cdf0e10cSrcweir 
414cdf0e10cSrcweir             MAKE_CURSOR( POINTER_NULL, null );
415cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MAGNIFY, magnify_ );
416cdf0e10cSrcweir             MAKE_CURSOR( POINTER_FILL, fill_ );
417cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MOVEDATA, movedata_ );
418cdf0e10cSrcweir             MAKE_CURSOR( POINTER_COPYDATA, copydata_ );
419cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MOVEFILE, movefile_ );
420cdf0e10cSrcweir             MAKE_CURSOR( POINTER_COPYFILE, copyfile_ );
421cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MOVEFILES, movefiles_ );
422cdf0e10cSrcweir             MAKE_CURSOR( POINTER_COPYFILES, copyfiles_ );
423cdf0e10cSrcweir             MAKE_CURSOR( POINTER_NOTALLOWED, nodrop_ );
424cdf0e10cSrcweir             MAKE_CURSOR( POINTER_ROTATE, rotate_ );
425cdf0e10cSrcweir             MAKE_CURSOR( POINTER_HSHEAR, hshear_ );
426cdf0e10cSrcweir             MAKE_CURSOR( POINTER_VSHEAR, vshear_ );
427cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_LINE, drawline_ );
428cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_RECT, drawrect_ );
429cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_POLYGON, drawpolygon_ );
430cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_BEZIER, drawbezier_ );
431cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_ARC, drawarc_ );
432cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_PIE, drawpie_ );
433cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_CIRCLECUT, drawcirclecut_ );
434cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_ELLIPSE, drawellipse_ );
435cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_CONNECT, drawconnect_ );
436cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_TEXT, drawtext_ );
437cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MIRROR, mirror_ );
438cdf0e10cSrcweir             MAKE_CURSOR( POINTER_CROOK, crook_ );
439cdf0e10cSrcweir             MAKE_CURSOR( POINTER_CROP, crop_ );
440cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MOVEPOINT, movepoint_ );
441cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MOVEBEZIERWEIGHT, movebezierweight_ );
442cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_FREEHAND, drawfreehand_ );
443cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DRAW_CAPTION, drawcaption_ );
444cdf0e10cSrcweir             MAKE_CURSOR( POINTER_LINKDATA, linkdata_ );
445cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MOVEDATALINK, movedlnk_ );
446cdf0e10cSrcweir             MAKE_CURSOR( POINTER_COPYDATALINK, copydlnk_ );
447cdf0e10cSrcweir             MAKE_CURSOR( POINTER_LINKFILE, linkfile_ );
448cdf0e10cSrcweir             MAKE_CURSOR( POINTER_MOVEFILELINK, moveflnk_ );
449cdf0e10cSrcweir             MAKE_CURSOR( POINTER_COPYFILELINK, copyflnk_ );
450cdf0e10cSrcweir             MAKE_CURSOR( POINTER_CHART, chart_ );
451cdf0e10cSrcweir             MAKE_CURSOR( POINTER_DETECTIVE, detective_ );
452cdf0e10cSrcweir             MAKE_CURSOR( POINTER_PIVOT_COL, pivotcol_ );
453cdf0e10cSrcweir             MAKE_CURSOR( POINTER_PIVOT_ROW, pivotrow_ );
454cdf0e10cSrcweir             MAKE_CURSOR( POINTER_PIVOT_FIELD, pivotfld_ );
455cdf0e10cSrcweir             MAKE_CURSOR( POINTER_PIVOT_DELETE, pivotdel_ );
456cdf0e10cSrcweir             MAKE_CURSOR( POINTER_CHAIN, chain_ );
457cdf0e10cSrcweir             MAKE_CURSOR( POINTER_CHAIN_NOTALLOWED, chainnot_ );
458cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TIMEEVENT_MOVE, timemove_ );
459cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TIMEEVENT_SIZE, timesize_ );
460cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_N, asn_ );
461cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_S, ass_ );
462cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_W, asw_ );
463cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_E, ase_ );
464cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_NW, asnw_ );
465cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_NE, asne_ );
466cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_SW, assw_ );
467cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_SE, asse_ );
468cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_NS, asns_ );
469cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_WE, aswe_ );
470cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AUTOSCROLL_NSWE, asnswe_ );
471cdf0e10cSrcweir             MAKE_CURSOR( POINTER_AIRBRUSH, airbrush_ );
472cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TEXT_VERTICAL, vertcurs_ );
473cdf0e10cSrcweir 
474cdf0e10cSrcweir             // --> FME 2004-07-30 #i32329# Enhanced table selection
475cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TAB_SELECT_S, tblsels_ );
476cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TAB_SELECT_E, tblsele_ );
477cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TAB_SELECT_SE, tblselse_ );
478cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TAB_SELECT_W, tblselw_ );
479cdf0e10cSrcweir             MAKE_CURSOR( POINTER_TAB_SELECT_SW, tblselsw_ );
480cdf0e10cSrcweir             // <--
481cdf0e10cSrcweir 
482cdf0e10cSrcweir             // --> FME 2004-08-16 #i20119# Paintbrush tool
483cdf0e10cSrcweir             MAKE_CURSOR( POINTER_PAINTBRUSH, paintbrush_ );
484cdf0e10cSrcweir             // <--
485cdf0e10cSrcweir 
486cdf0e10cSrcweir         default:
487cdf0e10cSrcweir             fprintf( stderr, "pointer %d not implemented", ePointerStyle );
488cdf0e10cSrcweir             break;
489cdf0e10cSrcweir         }
490cdf0e10cSrcweir         if( !pCursor )
491cdf0e10cSrcweir             pCursor = gdk_cursor_new_for_display( m_pGdkDisplay, GDK_LEFT_PTR );
492cdf0e10cSrcweir 
493cdf0e10cSrcweir         m_aCursors[ ePointerStyle ] = pCursor;
494cdf0e10cSrcweir     }
495cdf0e10cSrcweir 
496cdf0e10cSrcweir     return m_aCursors[ ePointerStyle ];
497cdf0e10cSrcweir }
498cdf0e10cSrcweir 
CaptureMouse(SalFrame * pSFrame)499cdf0e10cSrcweir int GtkSalDisplay::CaptureMouse( SalFrame* pSFrame )
500cdf0e10cSrcweir {
501cdf0e10cSrcweir     GtkSalFrame* pFrame = static_cast<GtkSalFrame*>(pSFrame);
502cdf0e10cSrcweir 
503cdf0e10cSrcweir     if( !pFrame )
504cdf0e10cSrcweir     {
505cdf0e10cSrcweir         if( m_pCapture )
506cdf0e10cSrcweir             static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
507cdf0e10cSrcweir         m_pCapture = NULL;
508cdf0e10cSrcweir         return 0;
509cdf0e10cSrcweir     }
510cdf0e10cSrcweir 
511cdf0e10cSrcweir     if( m_pCapture )
512cdf0e10cSrcweir     {
513cdf0e10cSrcweir         if( pFrame == m_pCapture )
514cdf0e10cSrcweir             return 1;
515cdf0e10cSrcweir         static_cast<GtkSalFrame*>(m_pCapture)->grabPointer( FALSE );
516cdf0e10cSrcweir     }
517cdf0e10cSrcweir 
518cdf0e10cSrcweir     m_pCapture = pFrame;
519cdf0e10cSrcweir     static_cast<GtkSalFrame*>(pFrame)->grabPointer( TRUE );
520cdf0e10cSrcweir     return 1;
521cdf0e10cSrcweir }
522cdf0e10cSrcweir 
523cdf0e10cSrcweir /***************************************************************************
524cdf0e10cSrcweir  * class GtkXLib                                                           *
525cdf0e10cSrcweir  ***************************************************************************/
526cdf0e10cSrcweir 
527cdf0e10cSrcweir class GtkXLib : public SalXLib
528cdf0e10cSrcweir {
529cdf0e10cSrcweir     GtkSalDisplay       *m_pGtkSalDisplay;
530cdf0e10cSrcweir     std::list<GSource *> m_aSources;
531cdf0e10cSrcweir     GSource             *m_pTimeout;
532cdf0e10cSrcweir     GSource             *m_pUserEvent;
533cdf0e10cSrcweir     oslMutex             m_aDispatchMutex;
534cdf0e10cSrcweir     oslCondition         m_aDispatchCondition;
535cdf0e10cSrcweir     XIOErrorHandler      m_aOrigGTKXIOErrorHandler;
536cdf0e10cSrcweir 
537cdf0e10cSrcweir public:
538cdf0e10cSrcweir     static gboolean      timeoutFn(gpointer data);
539cdf0e10cSrcweir     static gboolean      userEventFn(gpointer data);
540cdf0e10cSrcweir 
541cdf0e10cSrcweir     GtkXLib();
542cdf0e10cSrcweir     virtual ~GtkXLib();
543cdf0e10cSrcweir 
544cdf0e10cSrcweir     virtual void    Init();
545cdf0e10cSrcweir     virtual void    Yield( bool bWait, bool bHandleAllCurrentEvents );
546cdf0e10cSrcweir     virtual void    Insert( int fd, void* data,
547cdf0e10cSrcweir                             YieldFunc   pending,
548cdf0e10cSrcweir                             YieldFunc   queued,
549cdf0e10cSrcweir                             YieldFunc   handle );
550cdf0e10cSrcweir     virtual void    Remove( int fd );
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     virtual void    StartTimer( sal_uLong nMS );
553cdf0e10cSrcweir     virtual void    StopTimer();
554cdf0e10cSrcweir     virtual void    Wakeup();
555cdf0e10cSrcweir     virtual void    PostUserEvent();
556cdf0e10cSrcweir };
557cdf0e10cSrcweir 
GtkXLib()558cdf0e10cSrcweir GtkXLib::GtkXLib()
559cdf0e10cSrcweir {
560cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
561cdf0e10cSrcweir     fprintf( stderr, "GtkXLib::GtkXLib()\n" );
562cdf0e10cSrcweir #endif
563cdf0e10cSrcweir     m_pGtkSalDisplay = NULL;
564cdf0e10cSrcweir     m_pTimeout = NULL;
565cdf0e10cSrcweir     m_nTimeoutMS = 0;
566cdf0e10cSrcweir     m_pUserEvent = NULL;
567cdf0e10cSrcweir     m_aDispatchCondition = osl_createCondition();
568cdf0e10cSrcweir     m_aDispatchMutex = osl_createMutex();
569cdf0e10cSrcweir     m_aOrigGTKXIOErrorHandler = NULL;
570cdf0e10cSrcweir }
571cdf0e10cSrcweir 
~GtkXLib()572cdf0e10cSrcweir GtkXLib::~GtkXLib()
573cdf0e10cSrcweir {
574cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
575cdf0e10cSrcweir     fprintf( stderr, "GtkXLib::~GtkXLib()\n" );
576cdf0e10cSrcweir #endif
577cdf0e10cSrcweir     StopTimer();
578cdf0e10cSrcweir      // sanity check: at this point nobody should be yielding, but wake them
579cdf0e10cSrcweir      // up anyway before the condition they're waiting on gets destroyed.
580cdf0e10cSrcweir     osl_setCondition( m_aDispatchCondition );
581cdf0e10cSrcweir     osl_destroyCondition( m_aDispatchCondition );
582cdf0e10cSrcweir     osl_destroyMutex( m_aDispatchMutex );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir     PopXErrorLevel();
585cdf0e10cSrcweir     XSetIOErrorHandler (m_aOrigGTKXIOErrorHandler);
586cdf0e10cSrcweir }
587cdf0e10cSrcweir 
Init()588cdf0e10cSrcweir void GtkXLib::Init()
589cdf0e10cSrcweir {
590cdf0e10cSrcweir     int i;
591cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
592cdf0e10cSrcweir     fprintf( stderr, "GtkXLib::Init()\n" );
593cdf0e10cSrcweir #endif
594cdf0e10cSrcweir     XrmInitialize();
595cdf0e10cSrcweir 
596cdf0e10cSrcweir     gtk_set_locale();
597cdf0e10cSrcweir 
598cdf0e10cSrcweir     /*
599cdf0e10cSrcweir      * open connection to X11 Display
600cdf0e10cSrcweir      * try in this order:
601cdf0e10cSrcweir      *  o  -display command line parameter,
602cdf0e10cSrcweir      *  o  $DISPLAY environment variable
603cdf0e10cSrcweir      *  o  default display
604cdf0e10cSrcweir      */
605cdf0e10cSrcweir 
606cdf0e10cSrcweir     GdkDisplay *pGdkDisp = NULL;
607cdf0e10cSrcweir 
608cdf0e10cSrcweir     // is there a -display command line parameter?
609cdf0e10cSrcweir     rtl_TextEncoding aEnc = osl_getThreadTextEncoding();
610cdf0e10cSrcweir     int nParams = osl_getCommandArgCount();
611cdf0e10cSrcweir     rtl::OString aDisplay;
612cdf0e10cSrcweir     rtl::OUString aParam, aBin;
613cdf0e10cSrcweir     char** pCmdLineAry = new char*[ nParams+1 ];
614cdf0e10cSrcweir     osl_getExecutableFile( &aParam.pData );
615cdf0e10cSrcweir     osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData );
616cdf0e10cSrcweir     pCmdLineAry[0] = g_strdup( OUStringToOString( aBin, aEnc ).getStr() );
617cdf0e10cSrcweir     for (i=0; i<nParams; i++)
618cdf0e10cSrcweir     {
619cdf0e10cSrcweir         osl_getCommandArg(i, &aParam.pData );
620cdf0e10cSrcweir         OString aBParam( OUStringToOString( aParam, aEnc ) );
621cdf0e10cSrcweir 
622cdf0e10cSrcweir         if( aParam.equalsAscii( "-display" ) || aParam.equalsAscii( "--display" ) )
623cdf0e10cSrcweir         {
624cdf0e10cSrcweir             pCmdLineAry[i+1] = g_strdup( "--display" );
625cdf0e10cSrcweir             osl_getCommandArg(i+1, &aParam.pData );
626cdf0e10cSrcweir             aDisplay = rtl::OUStringToOString( aParam, aEnc );
627cdf0e10cSrcweir         }
628cdf0e10cSrcweir         else
629cdf0e10cSrcweir             pCmdLineAry[i+1] = g_strdup( aBParam.getStr() );
630cdf0e10cSrcweir     }
631cdf0e10cSrcweir     // add executable
632cdf0e10cSrcweir     nParams++;
633cdf0e10cSrcweir 
634cdf0e10cSrcweir     g_set_application_name(X11SalData::getFrameClassName());
635cdf0e10cSrcweir 
63686e1cf34SPedro Giffuni     // Set consistent name of the root accessible
637cdf0e10cSrcweir     rtl::OUString aAppName = Application::GetAppName();
638cdf0e10cSrcweir     if( aAppName.getLength() > 0 )
639cdf0e10cSrcweir     {
640cdf0e10cSrcweir         rtl::OString aPrgName = rtl::OUStringToOString(aAppName, aEnc);
64124c56ab9SHerbert Dürr         g_set_prgname( aPrgName.getStr());
642cdf0e10cSrcweir     }
643cdf0e10cSrcweir 
644cdf0e10cSrcweir     // init gtk/gdk
645cdf0e10cSrcweir     gtk_init_check( &nParams, &pCmdLineAry );
646cdf0e10cSrcweir 
647cdf0e10cSrcweir     //gtk_init_check sets XError/XIOError handlers, we want our own one
648cdf0e10cSrcweir     m_aOrigGTKXIOErrorHandler = XSetIOErrorHandler ( (XIOErrorHandler)X11SalData::XIOErrorHdl );
649cdf0e10cSrcweir     PushXErrorLevel( !!getenv( "SAL_IGNOREXERRORS" ) );
650cdf0e10cSrcweir 
651cdf0e10cSrcweir     for (i = 0; i < nParams; i++ )
652cdf0e10cSrcweir         g_free( pCmdLineAry[i] );
653cdf0e10cSrcweir     delete [] pCmdLineAry;
654cdf0e10cSrcweir 
655cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
656cdf0e10cSrcweir     if (g_getenv ("SAL_DEBUG_UPDATES"))
657cdf0e10cSrcweir         gdk_window_set_debug_updates (TRUE);
658cdf0e10cSrcweir #endif
659cdf0e10cSrcweir 
660cdf0e10cSrcweir     pGdkDisp = gdk_display_get_default();
661cdf0e10cSrcweir     if ( !pGdkDisp )
662cdf0e10cSrcweir     {
663cdf0e10cSrcweir         rtl::OUString aProgramFileURL;
664cdf0e10cSrcweir         osl_getExecutableFile( &aProgramFileURL.pData );
665cdf0e10cSrcweir         rtl::OUString aProgramSystemPath;
666cdf0e10cSrcweir         osl_getSystemPathFromFileURL (aProgramFileURL.pData, &aProgramSystemPath.pData);
667cdf0e10cSrcweir         rtl::OString  aProgramName = rtl::OUStringToOString(
668cdf0e10cSrcweir                                             aProgramSystemPath,
669cdf0e10cSrcweir                                             osl_getThreadTextEncoding() );
670cdf0e10cSrcweir         fprintf( stderr, "%s X11 error: Can't open display: %s\n",
671cdf0e10cSrcweir                 aProgramName.getStr(), aDisplay.getStr());
672cdf0e10cSrcweir         fprintf( stderr, "   Set DISPLAY environment variable, use -display option\n");
673cdf0e10cSrcweir         fprintf( stderr, "   or check permissions of your X-Server\n");
674cdf0e10cSrcweir         fprintf( stderr, "   (See \"man X\" resp. \"man xhost\" for details)\n");
675cdf0e10cSrcweir         fflush( stderr );
676cdf0e10cSrcweir         exit(0);
677cdf0e10cSrcweir     }
678cdf0e10cSrcweir 
679cdf0e10cSrcweir     /*
680cdf0e10cSrcweir      * if a -display switch was used, we need
681582f2a02SJohn Bampton      * to set the environment accordingly since
682cdf0e10cSrcweir      * the clipboard build another connection
683cdf0e10cSrcweir      * to the xserver using $DISPLAY
684cdf0e10cSrcweir      */
685cdf0e10cSrcweir     rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("DISPLAY"));
686cdf0e10cSrcweir     const gchar *name = gdk_display_get_name( pGdkDisp );
687cdf0e10cSrcweir     rtl::OUString envValue(name, strlen(name), aEnc);
688cdf0e10cSrcweir     osl_setEnvironment(envVar.pData, envValue.pData);
689cdf0e10cSrcweir 
690cdf0e10cSrcweir     Display *pDisp = gdk_x11_display_get_xdisplay( pGdkDisp );
691cdf0e10cSrcweir 
692cdf0e10cSrcweir     m_pGtkSalDisplay = new GtkSalDisplay( pGdkDisp );
693cdf0e10cSrcweir 
694cdf0e10cSrcweir     gdk_window_add_filter( NULL, call_filterGdkEvent, m_pGtkSalDisplay );
695cdf0e10cSrcweir 
696cdf0e10cSrcweir     PushXErrorLevel( true );
697cdf0e10cSrcweir     SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp );
698cdf0e10cSrcweir     XSync( pDisp, False );
699cdf0e10cSrcweir 
700cdf0e10cSrcweir     pKbdExtension->UseExtension( ! HasXErrorOccured() );
701cdf0e10cSrcweir     PopXErrorLevel();
702cdf0e10cSrcweir 
703cdf0e10cSrcweir     m_pGtkSalDisplay->SetKbdExtension( pKbdExtension );
704cdf0e10cSrcweir 
705cdf0e10cSrcweir     g_signal_connect( G_OBJECT(gdk_keymap_get_default()), "keys_changed", G_CALLBACK(signalKeysChanged), m_pGtkSalDisplay );
706cdf0e10cSrcweir 
707cdf0e10cSrcweir     // add signal handler to notify screen size changes
708cdf0e10cSrcweir     int nScreens = gdk_display_get_n_screens( pGdkDisp );
709cdf0e10cSrcweir     for( int n = 0; n < nScreens; n++ )
710cdf0e10cSrcweir     {
711cdf0e10cSrcweir         GdkScreen *pScreen = gdk_display_get_screen( pGdkDisp, n );
712cdf0e10cSrcweir         if( pScreen )
713cdf0e10cSrcweir         {
714cdf0e10cSrcweir             g_signal_connect( G_OBJECT(pScreen), "size-changed", G_CALLBACK(signalScreenSizeChanged), m_pGtkSalDisplay );
715cdf0e10cSrcweir             if( ! gtk_check_version( 2, 14, 0 ) ) // monitors-changed came in with 2.14, avoid an assertion
716cdf0e10cSrcweir                 g_signal_connect( G_OBJECT(pScreen), "monitors-changed", G_CALLBACK(signalMonitorsChanged), m_pGtkSalDisplay );
717cdf0e10cSrcweir         }
718cdf0e10cSrcweir     }
719cdf0e10cSrcweir }
720cdf0e10cSrcweir 
721cdf0e10cSrcweir extern "C"
722cdf0e10cSrcweir {
call_timeoutFn(gpointer data)723cdf0e10cSrcweir     gboolean call_timeoutFn(gpointer data)
724cdf0e10cSrcweir     {
725cdf0e10cSrcweir         return GtkXLib::timeoutFn(data);
726cdf0e10cSrcweir     }
727cdf0e10cSrcweir }
728cdf0e10cSrcweir 
timeoutFn(gpointer data)729cdf0e10cSrcweir gboolean GtkXLib::timeoutFn(gpointer data)
730cdf0e10cSrcweir {
731cdf0e10cSrcweir     SalData *pSalData = GetSalData();
732cdf0e10cSrcweir     GtkXLib *pThis = (GtkXLib *) data;
733cdf0e10cSrcweir 
734cdf0e10cSrcweir     pSalData->m_pInstance->GetYieldMutex()->acquire();
735cdf0e10cSrcweir 
736cdf0e10cSrcweir     if( pThis->m_pTimeout )
737cdf0e10cSrcweir     {
738cdf0e10cSrcweir         g_source_unref (pThis->m_pTimeout);
739cdf0e10cSrcweir         pThis->m_pTimeout = NULL;
740cdf0e10cSrcweir     }
741cdf0e10cSrcweir 
742cdf0e10cSrcweir     // Auto-restart immediately
743cdf0e10cSrcweir     pThis->StartTimer( pThis->m_nTimeoutMS );
744cdf0e10cSrcweir 
745cdf0e10cSrcweir     GetX11SalData()->Timeout();
746cdf0e10cSrcweir 
747cdf0e10cSrcweir     pSalData->m_pInstance->GetYieldMutex()->release();
748cdf0e10cSrcweir 
749cdf0e10cSrcweir     return FALSE;
750cdf0e10cSrcweir }
751cdf0e10cSrcweir 
StartTimer(sal_uLong nMS)752cdf0e10cSrcweir void GtkXLib::StartTimer( sal_uLong nMS )
753cdf0e10cSrcweir {
754cdf0e10cSrcweir     m_nTimeoutMS = nMS; // for restarting
755cdf0e10cSrcweir 
756cdf0e10cSrcweir     if (m_pTimeout)
757cdf0e10cSrcweir     {
758cdf0e10cSrcweir         g_source_destroy (m_pTimeout);
759cdf0e10cSrcweir         g_source_unref (m_pTimeout);
760cdf0e10cSrcweir     }
761cdf0e10cSrcweir 
762cdf0e10cSrcweir     m_pTimeout = g_timeout_source_new (m_nTimeoutMS);
763cdf0e10cSrcweir     // #i36226# timers should be executed with lower priority
764cdf0e10cSrcweir     // than XEvents like in generic plugin
765cdf0e10cSrcweir     g_source_set_priority( m_pTimeout, G_PRIORITY_LOW );
766cdf0e10cSrcweir     g_source_set_can_recurse (m_pTimeout, TRUE);
767cdf0e10cSrcweir     g_source_set_callback (m_pTimeout, call_timeoutFn,
768cdf0e10cSrcweir                            (gpointer) this, NULL);
769cdf0e10cSrcweir     g_source_attach (m_pTimeout, g_main_context_default ());
770cdf0e10cSrcweir 
771cdf0e10cSrcweir     SalXLib::StartTimer( nMS );
772cdf0e10cSrcweir }
773cdf0e10cSrcweir 
StopTimer()774cdf0e10cSrcweir void GtkXLib::StopTimer()
775cdf0e10cSrcweir {
776cdf0e10cSrcweir     SalXLib::StopTimer();
777cdf0e10cSrcweir 
778cdf0e10cSrcweir     if (m_pTimeout)
779cdf0e10cSrcweir     {
780cdf0e10cSrcweir         g_source_destroy (m_pTimeout);
781cdf0e10cSrcweir         g_source_unref (m_pTimeout);
782cdf0e10cSrcweir         m_pTimeout = NULL;
783cdf0e10cSrcweir     }
784cdf0e10cSrcweir }
785cdf0e10cSrcweir 
786cdf0e10cSrcweir extern "C"
787cdf0e10cSrcweir {
call_userEventFn(gpointer data)788cdf0e10cSrcweir     gboolean call_userEventFn( gpointer data )
789cdf0e10cSrcweir     {
790cdf0e10cSrcweir         return GtkXLib::userEventFn( data );
791cdf0e10cSrcweir     }
792cdf0e10cSrcweir }
793cdf0e10cSrcweir 
userEventFn(gpointer data)794cdf0e10cSrcweir gboolean GtkXLib::userEventFn(gpointer data)
795cdf0e10cSrcweir {
796cdf0e10cSrcweir     gboolean bContinue;
797cdf0e10cSrcweir     GtkXLib *pThis = (GtkXLib *) data;
798cdf0e10cSrcweir     SalData *pSalData = GetSalData();
799cdf0e10cSrcweir 
800cdf0e10cSrcweir     pSalData->m_pInstance->GetYieldMutex()->acquire();
801cdf0e10cSrcweir     pThis->m_pGtkSalDisplay->EventGuardAcquire();
802cdf0e10cSrcweir 
803cdf0e10cSrcweir     if( !pThis->m_pGtkSalDisplay->HasMoreEvents() )
804cdf0e10cSrcweir     {
805cdf0e10cSrcweir         if( pThis->m_pUserEvent )
806cdf0e10cSrcweir         {
807cdf0e10cSrcweir             g_source_unref (pThis->m_pUserEvent);
808cdf0e10cSrcweir             pThis->m_pUserEvent = NULL;
809cdf0e10cSrcweir         }
810cdf0e10cSrcweir         bContinue = FALSE;
811cdf0e10cSrcweir     }
812cdf0e10cSrcweir     else
813cdf0e10cSrcweir         bContinue = TRUE;
814cdf0e10cSrcweir 
815cdf0e10cSrcweir     pThis->m_pGtkSalDisplay->EventGuardRelease();
816cdf0e10cSrcweir 
817cdf0e10cSrcweir     pThis->m_pGtkSalDisplay->DispatchInternalEvent();
818cdf0e10cSrcweir 
819cdf0e10cSrcweir     pSalData->m_pInstance->GetYieldMutex()->release();
820cdf0e10cSrcweir 
821cdf0e10cSrcweir     return bContinue;
822cdf0e10cSrcweir }
823cdf0e10cSrcweir 
824cdf0e10cSrcweir // hEventGuard_ held during this invocation
PostUserEvent()825cdf0e10cSrcweir void GtkXLib::PostUserEvent()
826cdf0e10cSrcweir {
827cdf0e10cSrcweir     if( !m_pUserEvent ) // not pending anyway
828cdf0e10cSrcweir     {
829cdf0e10cSrcweir         m_pUserEvent = g_idle_source_new();
830cdf0e10cSrcweir         g_source_set_priority( m_pUserEvent, G_PRIORITY_HIGH );
831cdf0e10cSrcweir         g_source_set_can_recurse (m_pUserEvent, TRUE);
832cdf0e10cSrcweir         g_source_set_callback (m_pUserEvent, call_userEventFn,
833cdf0e10cSrcweir                                (gpointer) this, NULL);
834cdf0e10cSrcweir         g_source_attach (m_pUserEvent, g_main_context_default ());
835cdf0e10cSrcweir     }
836cdf0e10cSrcweir     Wakeup();
837cdf0e10cSrcweir }
838cdf0e10cSrcweir 
Wakeup()839cdf0e10cSrcweir void GtkXLib::Wakeup()
840cdf0e10cSrcweir {
841cdf0e10cSrcweir     g_main_context_wakeup( g_main_context_default () );
842cdf0e10cSrcweir }
843cdf0e10cSrcweir 
Yield(bool bWait,bool bHandleAllCurrentEvents)844cdf0e10cSrcweir void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
845cdf0e10cSrcweir {
846cdf0e10cSrcweir     /* #i33212# only enter g_main_context_iteration in one thread at any one
847cdf0e10cSrcweir      * time, else one of them potentially will never end as long as there is
848*565bea5dSJohn Bampton      * another thread in in there. Having only one yielding thread actually dispatch
849cdf0e10cSrcweir      * fits the vcl event model (see e.g. the generic plugin).
850cdf0e10cSrcweir      */
851cdf0e10cSrcweir 
852cdf0e10cSrcweir     bool bDispatchThread = false;
853cdf0e10cSrcweir     gboolean wasEvent = FALSE;
854cdf0e10cSrcweir     {
855cdf0e10cSrcweir         // release YieldMutex (and re-acquire at block end)
856cdf0e10cSrcweir         YieldMutexReleaser aReleaser;
857cdf0e10cSrcweir         if( osl_tryToAcquireMutex( m_aDispatchMutex ) )
858cdf0e10cSrcweir             bDispatchThread = true;
859cdf0e10cSrcweir         else if( ! bWait )
860cdf0e10cSrcweir             return; // someone else is waiting already, return
861cdf0e10cSrcweir 
862cdf0e10cSrcweir 
863cdf0e10cSrcweir         if( bDispatchThread )
864cdf0e10cSrcweir         {
865cdf0e10cSrcweir             int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1;
866cdf0e10cSrcweir             gboolean wasOneEvent = TRUE;
867cdf0e10cSrcweir             while( nMaxEvents-- && wasOneEvent )
868cdf0e10cSrcweir             {
869cdf0e10cSrcweir                 wasOneEvent = g_main_context_iteration( NULL, FALSE );
870cdf0e10cSrcweir                 if( wasOneEvent )
871cdf0e10cSrcweir                     wasEvent = TRUE;
872cdf0e10cSrcweir             }
873cdf0e10cSrcweir             if( bWait && ! wasEvent )
874cdf0e10cSrcweir                 wasEvent = g_main_context_iteration( NULL, TRUE );
875cdf0e10cSrcweir         }
876cdf0e10cSrcweir         else if( bWait )
877cdf0e10cSrcweir         {
878cdf0e10cSrcweir             /* #i41693# in case the dispatch thread hangs in join
879cdf0e10cSrcweir              * for this thread the condition will never be set
880cdf0e10cSrcweir              * workaround: timeout of 1 second a emergency exit
881cdf0e10cSrcweir              */
882cdf0e10cSrcweir             // we are the dispatch thread
883cdf0e10cSrcweir             osl_resetCondition( m_aDispatchCondition );
884cdf0e10cSrcweir             TimeValue aValue = { 1, 0 };
885cdf0e10cSrcweir             osl_waitCondition( m_aDispatchCondition, &aValue );
886cdf0e10cSrcweir         }
887cdf0e10cSrcweir     }
888cdf0e10cSrcweir 
889cdf0e10cSrcweir     if( bDispatchThread )
890cdf0e10cSrcweir     {
891cdf0e10cSrcweir         osl_releaseMutex( m_aDispatchMutex );
892cdf0e10cSrcweir         if( wasEvent )
893cdf0e10cSrcweir             osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields
894cdf0e10cSrcweir     }
895cdf0e10cSrcweir }
896cdf0e10cSrcweir 
897cdf0e10cSrcweir extern "C" {
898cdf0e10cSrcweir 
899cdf0e10cSrcweir typedef struct {
900cdf0e10cSrcweir     GSource       source;
901cdf0e10cSrcweir 
902cdf0e10cSrcweir     GPollFD       pollfd;
903cdf0e10cSrcweir     GIOCondition  condition;
904cdf0e10cSrcweir 
905cdf0e10cSrcweir     YieldFunc     pending;
906cdf0e10cSrcweir     YieldFunc     handle;
907cdf0e10cSrcweir     gpointer      user_data;
908cdf0e10cSrcweir } SalWatch;
909cdf0e10cSrcweir 
910cdf0e10cSrcweir static gboolean
sal_source_prepare(GSource * source,gint * timeout)911cdf0e10cSrcweir sal_source_prepare (GSource *source,
912cdf0e10cSrcweir                     gint    *timeout)
913cdf0e10cSrcweir {
914cdf0e10cSrcweir     SalWatch *watch = (SalWatch *)source;
915cdf0e10cSrcweir 
916cdf0e10cSrcweir     *timeout = -1;
917cdf0e10cSrcweir 
918cdf0e10cSrcweir     if (watch->pending &&
919cdf0e10cSrcweir         watch->pending (watch->pollfd.fd, watch->user_data)) {
920cdf0e10cSrcweir         watch->pollfd.revents |= watch->condition;
921cdf0e10cSrcweir         return TRUE;
922cdf0e10cSrcweir     }
923cdf0e10cSrcweir 
924cdf0e10cSrcweir     return FALSE;
925cdf0e10cSrcweir }
926cdf0e10cSrcweir 
927cdf0e10cSrcweir static gboolean
sal_source_check(GSource * source)928cdf0e10cSrcweir sal_source_check (GSource *source)
929cdf0e10cSrcweir {
930cdf0e10cSrcweir     SalWatch *watch = (SalWatch *)source;
931cdf0e10cSrcweir 
932cdf0e10cSrcweir     return watch->pollfd.revents & watch->condition;
933cdf0e10cSrcweir }
934cdf0e10cSrcweir 
935cdf0e10cSrcweir static gboolean
sal_source_dispatch(GSource * source,GSourceFunc,gpointer)936cdf0e10cSrcweir sal_source_dispatch (GSource    *source,
937cdf0e10cSrcweir                      GSourceFunc,
938cdf0e10cSrcweir                      gpointer)
939cdf0e10cSrcweir {
940cdf0e10cSrcweir     SalData *pSalData = GetSalData();
941cdf0e10cSrcweir     SalWatch *watch = (SalWatch *) source;
942cdf0e10cSrcweir 
943cdf0e10cSrcweir     pSalData->m_pInstance->GetYieldMutex()->acquire();
944cdf0e10cSrcweir 
945cdf0e10cSrcweir     watch->handle (watch->pollfd.fd, watch->user_data);
946cdf0e10cSrcweir 
947cdf0e10cSrcweir     pSalData->m_pInstance->GetYieldMutex()->release();
948cdf0e10cSrcweir 
949cdf0e10cSrcweir     return TRUE;
950cdf0e10cSrcweir }
951cdf0e10cSrcweir 
952cdf0e10cSrcweir static void
sal_source_finalize(GSource *)953cdf0e10cSrcweir sal_source_finalize (GSource*)
954cdf0e10cSrcweir {
955cdf0e10cSrcweir }
956cdf0e10cSrcweir 
957cdf0e10cSrcweir static GSourceFuncs sal_source_watch_funcs = {
958cdf0e10cSrcweir     sal_source_prepare,
959cdf0e10cSrcweir     sal_source_check,
960cdf0e10cSrcweir     sal_source_dispatch,
961cdf0e10cSrcweir     sal_source_finalize,
962cdf0e10cSrcweir     NULL,
963cdf0e10cSrcweir     NULL
964cdf0e10cSrcweir };
965cdf0e10cSrcweir 
966cdf0e10cSrcweir static GSource *
sal_source_create_watch(int fd,GIOCondition condition,YieldFunc pending,YieldFunc handle,gpointer user_data)967cdf0e10cSrcweir sal_source_create_watch (int           fd,
968cdf0e10cSrcweir                          GIOCondition  condition,
969cdf0e10cSrcweir                          YieldFunc     pending,
970cdf0e10cSrcweir                          YieldFunc     handle,
971cdf0e10cSrcweir                          gpointer      user_data)
972cdf0e10cSrcweir {
973cdf0e10cSrcweir     GSource      *source;
974cdf0e10cSrcweir     SalWatch     *watch;
975cdf0e10cSrcweir     GMainContext *context = g_main_context_default ();
976cdf0e10cSrcweir 
977cdf0e10cSrcweir     source = g_source_new (&sal_source_watch_funcs,
978cdf0e10cSrcweir                    sizeof (SalWatch));
979cdf0e10cSrcweir     watch = (SalWatch *) source;
980cdf0e10cSrcweir 
981cdf0e10cSrcweir     watch->pollfd.fd     = fd;
982cdf0e10cSrcweir     watch->pollfd.events = condition;
983cdf0e10cSrcweir     watch->condition = condition;
984cdf0e10cSrcweir     watch->pending   = pending;
985cdf0e10cSrcweir     watch->handle    = handle;
986cdf0e10cSrcweir     watch->user_data = user_data;
987cdf0e10cSrcweir 
988cdf0e10cSrcweir     g_source_set_can_recurse (source, TRUE);
989cdf0e10cSrcweir     g_source_add_poll (source, &watch->pollfd);
990cdf0e10cSrcweir     g_source_attach (source, context);
991cdf0e10cSrcweir 
992cdf0e10cSrcweir     return source;
993cdf0e10cSrcweir }
994cdf0e10cSrcweir 
995cdf0e10cSrcweir } // extern "C"
996cdf0e10cSrcweir 
Insert(int nFD,void * data,YieldFunc pending,YieldFunc,YieldFunc handle)997cdf0e10cSrcweir void GtkXLib::Insert( int       nFD,
998cdf0e10cSrcweir               void     *data,
999cdf0e10cSrcweir               YieldFunc pending,
1000cdf0e10cSrcweir               YieldFunc,
1001cdf0e10cSrcweir               YieldFunc handle )
1002cdf0e10cSrcweir {
1003cdf0e10cSrcweir     GSource *source = sal_source_create_watch
1004cdf0e10cSrcweir         ( nFD, (GIOCondition) ((G_IO_IN|G_IO_PRI) |
1005cdf0e10cSrcweir                        (G_IO_ERR|G_IO_HUP|G_IO_NVAL)),
1006cdf0e10cSrcweir           pending, handle, data );
1007cdf0e10cSrcweir     m_aSources.push_back( source );
1008cdf0e10cSrcweir }
1009cdf0e10cSrcweir 
Remove(int nFD)1010cdf0e10cSrcweir void GtkXLib::Remove( int nFD )
1011cdf0e10cSrcweir {
1012cdf0e10cSrcweir     ::std::list< GSource * >::iterator it;
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir     for (it = m_aSources.begin(); it != m_aSources.end(); ++it)
1015cdf0e10cSrcweir     {
1016cdf0e10cSrcweir         SalWatch *watch = (SalWatch *) *it;
1017cdf0e10cSrcweir 
1018cdf0e10cSrcweir         if (watch->pollfd.fd == nFD)
1019cdf0e10cSrcweir         {
1020cdf0e10cSrcweir             m_aSources.erase( it );
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir             g_source_destroy ((GSource *)watch);
1023cdf0e10cSrcweir             g_source_unref   ((GSource *)watch);
1024cdf0e10cSrcweir             return;
1025cdf0e10cSrcweir         }
1026cdf0e10cSrcweir     }
1027cdf0e10cSrcweir }
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir /**********************************************************************
1030cdf0e10cSrcweir  * class GtkData                                                      *
1031cdf0e10cSrcweir  **********************************************************************/
1032cdf0e10cSrcweir 
~GtkData()1033cdf0e10cSrcweir GtkData::~GtkData()
1034cdf0e10cSrcweir {
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir 
Init()1037cdf0e10cSrcweir void GtkData::Init()
1038cdf0e10cSrcweir {
1039cdf0e10cSrcweir     pXLib_ = new GtkXLib();
1040cdf0e10cSrcweir     pXLib_->Init();
1041cdf0e10cSrcweir }
1042