xref: /aoo41x/main/vcl/unx/gtk/app/gtkdata.cxx (revision 30c1b1ef)
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
109f62ea84SAndrew Rist  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
129f62ea84SAndrew Rist  *
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.
199f62ea84SAndrew Rist  *
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 
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 
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 
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" {
103cdf0e10cSrcweir GdkFilterReturn call_filterGdkEvent( GdkXEvent* sys_event,
104cdf0e10cSrcweir                                      GdkEvent* event,
105cdf0e10cSrcweir                                      gpointer data )
106cdf0e10cSrcweir {
107cdf0e10cSrcweir     return GtkSalDisplay::filterGdkEvent( sys_event, event, data );
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
110cdf0e10cSrcweir void signalKeysChanged( GdkKeymap*, gpointer data )
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
113cdf0e10cSrcweir     pDisp->GetKeyboardName(TRUE);
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir void signalScreenSizeChanged( GdkScreen* pScreen, gpointer data )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
119cdf0e10cSrcweir     pDisp->screenSizeChanged( pScreen );
120cdf0e10cSrcweir }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir void signalMonitorsChanged( GdkScreen* pScreen, gpointer data )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir     GtkSalDisplay* pDisp = (GtkSalDisplay*)data;
125cdf0e10cSrcweir     pDisp->monitorsChanged( pScreen );
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
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 
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 
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 
260cdf0e10cSrcweir 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 
281cdf0e10cSrcweir 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 
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 
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: \
356*30c1b1efSHerbert 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 
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 
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 
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 
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 
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 
636cdf0e10cSrcweir     // Set consistant 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);
641cdf0e10cSrcweir         g_set_prgname(aPrgName);
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
681cdf0e10cSrcweir 	 * to set the environment accoringly 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 {
723cdf0e10cSrcweir     gboolean call_timeoutFn(gpointer data)
724cdf0e10cSrcweir     {
725cdf0e10cSrcweir         return GtkXLib::timeoutFn(data);
726cdf0e10cSrcweir     }
727cdf0e10cSrcweir }
728cdf0e10cSrcweir 
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 
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 
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 {
788cdf0e10cSrcweir     gboolean call_userEventFn( gpointer data )
789cdf0e10cSrcweir     {
790cdf0e10cSrcweir         return GtkXLib::userEventFn( data );
791cdf0e10cSrcweir     }
792cdf0e10cSrcweir }
793cdf0e10cSrcweir 
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
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 
839cdf0e10cSrcweir void GtkXLib::Wakeup()
840cdf0e10cSrcweir {
841cdf0e10cSrcweir 	g_main_context_wakeup( g_main_context_default () );
842cdf0e10cSrcweir }
843cdf0e10cSrcweir 
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
848cdf0e10cSrcweir      * another thread in in there. Having only one yieldin 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
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
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
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
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 *
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 
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 
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 
1033cdf0e10cSrcweir GtkData::~GtkData()
1034cdf0e10cSrcweir {
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir void GtkData::Init()
1038cdf0e10cSrcweir {
1039cdf0e10cSrcweir     pXLib_ = new GtkXLib();
1040cdf0e10cSrcweir     pXLib_->Init();
1041cdf0e10cSrcweir }
1042