merge the formfield patch from ooo-build
[ooovba.git] / vcl / unx / source / app / saldata.cxx
blob3d3bd9ba2da22c9575fbdf4aa42b7b359f5bc1b6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: saldata.cxx,v $
10 * $Revision: 1.58.98.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #ifdef USE_XTOOLKIT
35 # define SAL_XT
36 #endif
38 // -=-= #includes =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
40 #include <unistd.h>
41 #include <fcntl.h>
43 #include <cstdio>
44 #include <cstring>
45 #include <cstdlib>
46 #include <stdio.h> // snprintf, seems not to be in namespace std on every platform
47 #include <limits.h>
48 #include <errno.h>
49 #include <pthread.h>
50 #include <sys/resource.h>
51 #ifdef SUN
52 #include <sys/systeminfo.h>
53 #endif
54 #ifdef AIX
55 #include <strings.h>
56 #endif
57 #ifdef FREEBSD
58 #include <sys/types.h>
59 #include <sys/time.h>
60 #include <unistd.h>
61 #endif
62 #include <vos/process.hxx>
63 #ifndef _VOS_MUTEX_HXX
64 #include <vos/mutex.hxx>
65 #endif
67 #include "Xproto.h"
68 #include <saldisp.hxx>
69 #include <saldata.hxx>
70 #include <vcl/salinst.hxx>
71 #include <salframe.h>
72 #include <osl/signal.h>
73 #include <osl/thread.h>
74 #include <osl/process.h>
75 #include <rtl/strbuf.hxx>
76 #ifndef _RTL_BOOTSTRAP_HXX
77 #include <rtl/bootstrap.hxx>
78 #endif
80 #include <tools/debug.hxx>
81 #include <sm.hxx>
82 #include <vcl/svapp.hxx>
83 #include "i18n_im.hxx"
84 #include "i18n_xkb.hxx"
86 // -=-= <signal.h> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
87 #ifndef UNX
88 #ifndef SIGBUS
89 #define SIGBUS 10
90 #endif
91 #ifndef SIGSEGV
92 #define SIGSEGV 11
93 #endif
94 #ifndef SIGIOT
95 #define SIGIOT SIGABRT
96 #endif
97 #endif
99 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
100 static const struct timeval noyield__ = { 0, 0 };
101 static const struct timeval yield__ = { 0, 10000 };
103 static const char* XRequest[] = {
104 // see /usr/lib/X11/XErrorDB, /usr/openwin/lib/XErrorDB ...
105 NULL,
106 "X_CreateWindow",
107 "X_ChangeWindowAttributes",
108 "X_GetWindowAttributes",
109 "X_DestroyWindow",
110 "X_DestroySubwindows",
111 "X_ChangeSaveSet",
112 "X_ReparentWindow",
113 "X_MapWindow",
114 "X_MapSubwindows",
115 "X_UnmapWindow",
116 "X_UnmapSubwindows",
117 "X_ConfigureWindow",
118 "X_CirculateWindow",
119 "X_GetGeometry",
120 "X_QueryTree",
121 "X_InternAtom",
122 "X_GetAtomName",
123 "X_ChangeProperty",
124 "X_DeleteProperty",
125 "X_GetProperty",
126 "X_ListProperties",
127 "X_SetSelectionOwner",
128 "X_GetSelectionOwner",
129 "X_ConvertSelection",
130 "X_SendEvent",
131 "X_GrabPointer",
132 "X_UngrabPointer",
133 "X_GrabButton",
134 "X_UngrabButton",
135 "X_ChangeActivePointerGrab",
136 "X_GrabKeyboard",
137 "X_UngrabKeyboard",
138 "X_GrabKey",
139 "X_UngrabKey",
140 "X_AllowEvents",
141 "X_GrabServer",
142 "X_UngrabServer",
143 "X_QueryPointer",
144 "X_GetMotionEvents",
145 "X_TranslateCoords",
146 "X_WarpPointer",
147 "X_SetInputFocus",
148 "X_GetInputFocus",
149 "X_QueryKeymap",
150 "X_OpenFont",
151 "X_CloseFont",
152 "X_QueryFont",
153 "X_QueryTextExtents",
154 "X_ListFonts",
155 "X_ListFontsWithInfo",
156 "X_SetFontPath",
157 "X_GetFontPath",
158 "X_CreatePixmap",
159 "X_FreePixmap",
160 "X_CreateGC",
161 "X_ChangeGC",
162 "X_CopyGC",
163 "X_SetDashes",
164 "X_SetClipRectangles",
165 "X_FreeGC",
166 "X_ClearArea",
167 "X_CopyArea",
168 "X_CopyPlane",
169 "X_PolyPoint",
170 "X_PolyLine",
171 "X_PolySegment",
172 "X_PolyRectangle",
173 "X_PolyArc",
174 "X_FillPoly",
175 "X_PolyFillRectangle",
176 "X_PolyFillArc",
177 "X_PutImage",
178 "X_GetImage",
179 "X_PolyText8",
180 "X_PolyText16",
181 "X_ImageText8",
182 "X_ImageText16",
183 "X_CreateColormap",
184 "X_FreeColormap",
185 "X_CopyColormapAndFree",
186 "X_InstallColormap",
187 "X_UninstallColormap",
188 "X_ListInstalledColormaps",
189 "X_AllocColor",
190 "X_AllocNamedColor",
191 "X_AllocColorCells",
192 "X_AllocColorPlanes",
193 "X_FreeColors",
194 "X_StoreColors",
195 "X_StoreNamedColor",
196 "X_QueryColors",
197 "X_LookupColor",
198 "X_CreateCursor",
199 "X_CreateGlyphCursor",
200 "X_FreeCursor",
201 "X_RecolorCursor",
202 "X_QueryBestSize",
203 "X_QueryExtension",
204 "X_ListExtensions",
205 "X_ChangeKeyboardMapping",
206 "X_GetKeyboardMapping",
207 "X_ChangeKeyboardControl",
208 "X_GetKeyboardControl",
209 "X_Bell",
210 "X_ChangePointerControl",
211 "X_GetPointerControl",
212 "X_SetScreenSaver",
213 "X_GetScreenSaver",
214 "X_ChangeHosts",
215 "X_ListHosts",
216 "X_SetAccessControl",
217 "X_SetCloseDownMode",
218 "X_KillClient",
219 "X_RotateProperties",
220 "X_ForceScreenSaver",
221 "X_SetPointerMapping",
222 "X_GetPointerMapping",
223 "X_SetModifierMapping",
224 "X_GetModifierMapping",
225 NULL,
226 NULL,
227 NULL,
228 NULL,
229 NULL,
230 NULL,
231 NULL,
232 "X_NoOperation"
235 // -=-= C statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
236 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
238 int X11SalData::XErrorHdl( Display *pDisplay, XErrorEvent *pEvent )
240 GetX11SalData()->XError( pDisplay, pEvent );
241 return 0;
244 int X11SalData::XIOErrorHdl( Display * )
246 /* #106197# hack: until a real shutdown procedure exists
247 * _exit ASAP
249 if( ImplGetSVData()->maAppData.mbAppQuit )
250 _exit(1);
252 // really bad hack
253 if( ! SessionManagerClient::checkDocumentsSaved() )
254 /* oslSignalAction eToDo = */ osl_raiseSignal (OSL_SIGNAL_USER_X11SUBSYSTEMERROR, NULL);
256 std::fprintf( stderr, "X IO Error\n" );
257 std::fflush( stdout );
258 std::fflush( stderr );
260 /* #106197# the same reasons to use _exit instead of exit in salmain
261 * do apply here. Since there is nothing to be done after an XIO
262 * error we have to _exit immediately.
264 _exit(0);
265 return 0;
268 // -=-= SalData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
269 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
270 #include <pthread.h>
272 X11SalData::X11SalData()
274 bNoExceptions_ = !!getenv( "SAL_NOSEGV" );
276 pXLib_ = NULL;
277 m_pSalDisplay = NULL;
278 m_pInstance = NULL;
279 m_pPlugin = NULL;
281 hMainThread_ = pthread_self();
284 X11SalData::~X11SalData()
286 DeleteDisplay();
289 void X11SalData::DeleteDisplay()
291 delete m_pSalDisplay;
292 m_pSalDisplay = NULL;
293 delete pXLib_;
294 pXLib_ = NULL;
297 void X11SalData::Init()
299 pXLib_ = new SalXLib();
300 pXLib_->Init();
303 void X11SalData::initNWF( void )
307 void X11SalData::deInitNWF( void )
311 // -=-= SalXLib =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
312 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
313 SalXLib::SalXLib()
315 m_aTimeout.tv_sec = 0;
316 m_aTimeout.tv_usec = 0;
317 m_nTimeoutMS = 0;
319 nFDs_ = 0;
320 FD_ZERO( &aReadFDS_ );
321 FD_ZERO( &aExceptionFDS_ );
323 m_pTimeoutFDS[0] = m_pTimeoutFDS[1] = -1;
324 if (pipe (m_pTimeoutFDS) != -1)
326 // initialize 'wakeup' pipe.
327 int flags;
329 // set close-on-exec descriptor flag.
330 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFD)) != -1)
332 flags |= FD_CLOEXEC;
333 fcntl (m_pTimeoutFDS[0], F_SETFD, flags);
335 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFD)) != -1)
337 flags |= FD_CLOEXEC;
338 fcntl (m_pTimeoutFDS[1], F_SETFD, flags);
341 // set non-blocking I/O flag.
342 if ((flags = fcntl (m_pTimeoutFDS[0], F_GETFL)) != -1)
344 flags |= O_NONBLOCK;
345 fcntl (m_pTimeoutFDS[0], F_SETFL, flags);
347 if ((flags = fcntl (m_pTimeoutFDS[1], F_GETFL)) != -1)
349 flags |= O_NONBLOCK;
350 fcntl (m_pTimeoutFDS[1], F_SETFL, flags);
353 // insert [0] into read descriptor set.
354 FD_SET( m_pTimeoutFDS[0], &aReadFDS_ );
355 nFDs_ = m_pTimeoutFDS[0] + 1;
358 PushXErrorLevel( !!getenv( "SAL_IGNOREXERRORS" ) );
359 m_bHaveSystemChildFrames = false;
362 SalXLib::~SalXLib()
364 // close 'wakeup' pipe.
365 close (m_pTimeoutFDS[0]);
366 close (m_pTimeoutFDS[1]);
368 PopXErrorLevel();
371 void SalXLib::PushXErrorLevel( bool bIgnore )
373 m_aXErrorHandlerStack.push_back( XErrorStackEntry() );
374 XErrorStackEntry& rEnt = m_aXErrorHandlerStack.back();
375 rEnt.m_bWas = false;
376 rEnt.m_bIgnore = bIgnore;
377 rEnt.m_nLastErrorRequest = 0;
378 rEnt.m_aHandler = XSetErrorHandler( (XErrorHandler)X11SalData::XErrorHdl );
381 void SalXLib::PopXErrorLevel()
383 if( m_aXErrorHandlerStack.size() )
385 XSetErrorHandler( m_aXErrorHandlerStack.back().m_aHandler );
386 m_aXErrorHandlerStack.pop_back();
390 void SalXLib::Init()
392 SalI18N_InputMethod* pInputMethod = new SalI18N_InputMethod;
393 pInputMethod->SetLocale();
394 XrmInitialize();
397 * open connection to X11 Display
398 * try in this order:
399 * o -display command line parameter,
400 * o $DISPLAY environment variable
401 * o default display
404 Display *pDisp = NULL;
406 // is there a -display command line parameter?
407 vos::OExtCommandLine aCommandLine;
408 sal_uInt32 nParams = aCommandLine.getCommandArgCount();
409 rtl::OUString aParam;
410 rtl::OString aDisplay;
411 for (USHORT i=0; i<nParams; i++)
413 aCommandLine.getCommandArg(i, aParam);
414 if (aParam.equalsAscii("-display"))
416 aCommandLine.getCommandArg(i+1, aParam);
417 aDisplay = rtl::OUStringToOString(
418 aParam, osl_getThreadTextEncoding());
420 if ((pDisp = XOpenDisplay(aDisplay.getStr()))!=NULL)
423 * if a -display switch was used, we need
424 * to set the environment accoringly since
425 * the clipboard build another connection
426 * to the xserver using $DISPLAY
428 const char envpre[] = "DISPLAY=";
429 char *envstr = new char[sizeof(envpre)+aDisplay.getLength()];
430 snprintf(envstr, sizeof(envpre)+aDisplay.getLength(), "DISPLAY=%s", aDisplay.getStr());
431 putenv(envstr);
433 break;
437 if (!pDisp && !aDisplay.getLength())
439 // Open $DISPLAY or default...
440 char *pDisplay = getenv("DISPLAY");
441 if (pDisplay != NULL)
442 aDisplay = rtl::OString(pDisplay);
443 pDisp = XOpenDisplay(pDisplay);
446 if ( !pDisp )
448 rtl::OUString aProgramFileURL;
449 osl_getExecutableFile( &aProgramFileURL.pData );
450 rtl::OUString aProgramSystemPath;
451 osl_getSystemPathFromFileURL (aProgramFileURL.pData, &aProgramSystemPath.pData);
452 rtl::OString aProgramName = rtl::OUStringToOString(
453 aProgramSystemPath,
454 osl_getThreadTextEncoding() );
455 std::fprintf( stderr, "%s X11 error: Can't open display: %s\n",
456 aProgramName.getStr(), aDisplay.getStr());
457 std::fprintf( stderr, " Set DISPLAY environment variable, use -display option\n");
458 std::fprintf( stderr, " or check permissions of your X-Server\n");
459 std::fprintf( stderr, " (See \"man X\" resp. \"man xhost\" for details)\n");
460 std::fflush( stderr );
461 exit(0);
464 XSetIOErrorHandler ( (XIOErrorHandler)X11SalData::XIOErrorHdl );
466 SalDisplay *pSalDisplay = new SalX11Display( pDisp );
468 pInputMethod->CreateMethod( pDisp );
469 pInputMethod->AddConnectionWatch( pDisp, (void*)this );
470 pSalDisplay->SetInputMethod( pInputMethod );
472 PushXErrorLevel( true );
473 SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp );
474 XSync( pDisp, False );
476 pKbdExtension->UseExtension( ! HasXErrorOccured() );
477 PopXErrorLevel();
479 pSalDisplay->SetKbdExtension( pKbdExtension );
482 extern "C" {
483 void EmitFontpathWarning( void )
485 static Bool bOnce = False;
486 if ( !bOnce )
488 bOnce = True;
489 std::fprintf( stderr, "Please verify your fontpath settings\n"
490 "\t(See \"man xset\" for details"
491 " or ask your system administrator)\n" );
495 } /* extern "C" */
497 static void PrintXError( Display *pDisplay, XErrorEvent *pEvent )
499 char msg[ 120 ] = "";
500 #if ! ( defined LINUX && defined PPC )
501 XGetErrorText( pDisplay, pEvent->error_code, msg, sizeof( msg ) );
502 #endif
503 std::fprintf( stderr, "X-Error: %s\n", msg );
504 if( pEvent->request_code < capacityof( XRequest ) )
506 const char* pName = XRequest[pEvent->request_code];
507 if( !pName )
508 pName = "BadRequest?";
509 std::fprintf( stderr, "\tMajor opcode: %d (%s)\n", pEvent->request_code, pName );
511 else
513 std::fprintf( stderr, "\tMajor opcode: %d\n", pEvent->request_code );
514 // TODO: also display extension name?
515 std::fprintf( stderr, "\tMinor opcode: %d\n", pEvent->minor_code );
518 std::fprintf( stderr, "\tResource ID: 0x%lx\n",
519 pEvent->resourceid );
520 std::fprintf( stderr, "\tSerial No: %ld (%ld)\n",
521 pEvent->serial, LastKnownRequestProcessed(pDisplay) );
523 if( !getenv( "SAL_SYNCHRONIZE" ) )
525 std::fprintf( stderr, "These errors are reported asynchronously,\n");
526 std::fprintf( stderr, "set environment variable SAL_SYNCHRONIZE to 1 to help debugging\n");
529 std::fflush( stdout );
530 std::fflush( stderr );
533 void SalXLib::XError( Display *pDisplay, XErrorEvent *pEvent )
535 if( m_bHaveSystemChildFrames )
536 return;
538 if( ! m_aXErrorHandlerStack.back().m_bIgnore )
540 if ( (pEvent->error_code == BadAlloc)
541 && (pEvent->request_code == X_OpenFont) )
543 static Bool bOnce = False;
544 if ( !bOnce )
546 std::fprintf(stderr, "X-Error occured in a request for X_OpenFont\n");
547 EmitFontpathWarning();
549 bOnce = True ;
551 return;
553 /* ignore
554 * X_SetInputFocus: it's a hint only anyway
555 * X_GetProperty: this is part of the XGetWindowProperty call and will
556 * be handled by the return value of that function
558 else if( pEvent->request_code == X_SetInputFocus ||
559 pEvent->request_code == X_GetProperty
561 return;
564 if( pDisplay != GetX11SalData()->GetDisplay()->GetDisplay() )
565 return;
567 PrintXError( pDisplay, pEvent );
569 oslSignalAction eToDo = osl_raiseSignal (OSL_SIGNAL_USER_X11SUBSYSTEMERROR, NULL);
570 switch (eToDo)
572 case osl_Signal_ActIgnore :
573 return;
574 case osl_Signal_ActAbortApp :
575 abort();
576 case osl_Signal_ActKillApp :
577 exit(0);
578 case osl_Signal_ActCallNextHdl :
579 break;
580 default :
581 break;
586 m_aXErrorHandlerStack.back().m_bWas = true;
589 struct YieldEntry
591 YieldEntry* next; // pointer to next entry
592 int fd; // file descriptor for reading
593 void* data; // data for predicate and callback
594 YieldFunc pending; // predicate (determins pending events)
595 YieldFunc queued; // read and queue up events
596 YieldFunc handle; // handle pending events
598 inline int HasPendingEvent() const { return pending( fd, data ); }
599 inline int IsEventQueued() const { return queued( fd, data ); }
600 inline void HandleNextEvent() const { handle( fd, data ); }
603 #define MAX_NUM_DESCRIPTORS 128
605 static YieldEntry yieldTable[ MAX_NUM_DESCRIPTORS ];
607 void SalXLib::Insert( int nFD, void* data,
608 YieldFunc pending,
609 YieldFunc queued,
610 YieldFunc handle )
612 DBG_ASSERT( nFD, "can not insert stdin descriptor" );
613 DBG_ASSERT( !yieldTable[nFD].fd, "SalXLib::Insert fd twice" );
615 yieldTable[nFD].fd = nFD;
616 yieldTable[nFD].data = data;
617 yieldTable[nFD].pending = pending;
618 yieldTable[nFD].queued = queued;
619 yieldTable[nFD].handle = handle;
621 FD_SET( nFD, &aReadFDS_ );
622 FD_SET( nFD, &aExceptionFDS_ );
624 if( nFD >= nFDs_ )
625 nFDs_ = nFD + 1;
628 void SalXLib::Remove( int nFD )
630 FD_CLR( nFD, &aReadFDS_ );
631 FD_CLR( nFD, &aExceptionFDS_ );
633 yieldTable[nFD].fd = 0;
635 if ( nFD == nFDs_ )
637 for ( nFD = nFDs_ - 1;
638 nFD >= 0 && !yieldTable[nFD].fd;
639 nFD-- ) ;
641 nFDs_ = nFD + 1;
645 bool SalXLib::CheckTimeout( bool bExecuteTimers )
647 bool bRet = false;
648 if( m_aTimeout.tv_sec ) // timer is started
650 timeval aTimeOfDay;
651 gettimeofday( &aTimeOfDay, 0 );
652 if( aTimeOfDay >= m_aTimeout )
654 bRet = true;
655 if( bExecuteTimers )
657 // timed out, update timeout
658 m_aTimeout = aTimeOfDay;
660 * #107827# autorestart immediately, will be stopped (or set
661 * to different value in notify hdl if necessary;
662 * CheckTimeout should return false while
663 * timers are being dispatched.
665 m_aTimeout += m_nTimeoutMS;
666 // notify
667 GetX11SalData()->Timeout();
671 return bRet;
674 void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
676 // check for timeouts here if you want to make screenshots
677 static char* p_prioritize_timer = getenv ("SAL_HIGHPRIORITY_REPAINT");
678 if (p_prioritize_timer != NULL)
679 CheckTimeout();
681 // first, check for already queued events.
682 for ( int nFD = 0; nFD < nFDs_; nFD++ )
684 YieldEntry* pEntry = &(yieldTable[nFD]);
685 if ( pEntry->fd )
687 DBG_ASSERT( nFD == pEntry->fd, "wrong fd in Yield()" );
688 if ( pEntry->HasPendingEvent() )
690 pEntry->HandleNextEvent();
691 // #63862# da jetzt alle user-events ueber die interne
692 // queue kommen, wird die Kontrolle analog zum select
693 // gesteuerten Zweig einmal bei bWait abgegeben
695 /* #i9277# do not reschedule since performance gets down the
696 the drain under heavy load
697 YieldMutexReleaser aReleaser;
698 if ( bWait ) osl_yieldThread();
701 return;
706 // next, select with or without timeout according to bWait.
707 int nFDs = nFDs_;
708 fd_set ReadFDS = aReadFDS_;
709 fd_set ExceptionFDS = aExceptionFDS_;
710 int nFound = 0;
712 timeval Timeout = noyield__;
713 timeval *pTimeout = &Timeout;
715 if (bWait)
717 pTimeout = 0;
718 if (m_aTimeout.tv_sec) // Timer is started.
720 // determine remaining timeout.
721 gettimeofday (&Timeout, 0);
722 Timeout = m_aTimeout - Timeout;
723 if (yield__ >= Timeout)
725 // guard against micro timeout.
726 Timeout = yield__;
728 pTimeout = &Timeout;
733 // release YieldMutex (and re-acquire at block end)
734 YieldMutexReleaser aReleaser;
735 nFound = select( nFDs, &ReadFDS, NULL, &ExceptionFDS, pTimeout );
737 if( nFound < 0 ) // error
739 #ifdef DBG_UTIL
740 std::fprintf( stderr, "SalXLib::Yield e=%d f=%d\n", errno, nFound );
741 #endif
742 if( EINTR == errno )
744 errno = 0;
748 // usually handle timeouts here (as in 5.2)
749 if (p_prioritize_timer == NULL)
750 CheckTimeout();
752 // handle wakeup events.
753 if ((nFound > 0) && (FD_ISSET(m_pTimeoutFDS[0], &ReadFDS)))
755 int buffer;
756 while (read (m_pTimeoutFDS[0], &buffer, sizeof(buffer)) > 0)
757 continue;
758 nFound -= 1;
761 // handle other events.
762 if( nFound > 0 )
764 // now we are in the protected section !
765 // recall select if we have acquired fd's, ready for reading,
767 struct timeval noTimeout = { 0, 0 };
768 nFound = select( nFDs_, &ReadFDS, NULL,
769 &ExceptionFDS, &noTimeout );
771 // someone-else has done the job for us
772 if (nFound == 0)
773 return;
775 for ( int nFD = 0; nFD < nFDs_; nFD++ )
777 YieldEntry* pEntry = &(yieldTable[nFD]);
778 if ( pEntry->fd )
780 if ( FD_ISSET( nFD, &ExceptionFDS ) ) {
781 #if OSL_DEBUG_LEVEL > 1
782 std::fprintf( stderr, "SalXLib::Yield exception\n" );
783 #endif
784 nFound--;
786 if ( FD_ISSET( nFD, &ReadFDS ) )
788 int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1;
789 for( int i = 0; pEntry->IsEventQueued() && i < nMaxEvents; i++ )
791 pEntry->HandleNextEvent();
792 // if a recursive call has done the job
793 // so abort here
795 nFound--;
802 void SalXLib::Wakeup()
804 write (m_pTimeoutFDS[1], "", 1);
807 void SalXLib::PostUserEvent()
809 Wakeup();
812 const char* X11SalData::getFrameResName()
814 /* according to ICCCM:
815 * first search command line for -name parameter
816 * then try RESOURCE_NAME environment variable
817 * then use argv[0] stripped by directories
819 static rtl::OStringBuffer aResName;
820 if( !aResName.getLength() )
822 int nArgs = osl_getCommandArgCount();
823 for( int n = 0; n < nArgs-1; n++ )
825 rtl::OUString aArg;
826 if( ! osl_getCommandArg( n, &aArg.pData ) &&
827 aArg.equalsIgnoreAsciiCaseAscii( "-name" ) &&
828 ! osl_getCommandArg( n+1, &aArg.pData ) )
830 aResName.append( rtl::OUStringToOString( aArg, osl_getThreadTextEncoding() ) );
831 break;
834 if( !aResName.getLength() )
836 const char* pEnv = getenv( "RESOURCE_NAME" );
837 if( pEnv && *pEnv )
838 aResName.append( pEnv );
840 if( !aResName.getLength() )
841 aResName.append( "VCLSalFrame" );
843 return aResName.getStr();
846 const char* X11SalData::getFrameClassName()
848 static rtl::OStringBuffer aClassName;
849 if( !aClassName.getLength() )
851 rtl::OUString aIni, aProduct;
852 rtl::Bootstrap::get( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ), aIni );
853 aIni += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/" SAL_CONFIGFILE( "bootstrap" ) ) );
854 rtl::Bootstrap aBootstrap( aIni );
855 aBootstrap.getFrom( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ProductKey" ) ), aProduct );
857 if( aProduct.getLength() )
858 aClassName.append( rtl::OUStringToOString( aProduct, osl_getThreadTextEncoding() ) );
859 else
860 aClassName.append( "VCLSalFrame" );
862 return aClassName.getStr();
865 rtl::OString X11SalData::getFrameResName( SalExtStyle nStyle )
867 rtl::OStringBuffer aBuf( 64 );
868 aBuf.append( getFrameResName() );
869 if( (nStyle & SAL_FRAME_EXT_STYLE_DOCUMENT) )
870 aBuf.append( ".DocumentWindow" );
872 return aBuf.makeStringAndClear();