xref: /trunk/main/vcl/unx/generic/app/i18n_status.cxx (revision c82f2877)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 
27 #if OSL_DEBUG_LEVEL > 1
28 #include <stdio.h>
29 #endif
30 #include <sal/alloca.h>
31 
32 #include <tools/prex.h>
33 #include <X11/Xlib.h>
34 #include <unx/XIM.h>
35 #include <tools/postx.h>
36 
37 #include <unx/salunx.h>
38 #include <unx/i18n_status.hxx>
39 #include <unx/i18n_ic.hxx>
40 #include <unx/saldisp.hxx>
41 #include <unx/salframe.h>
42 #include <unx/saldata.hxx>
43 
44 #include <vcl/wrkwin.hxx>
45 #include <vcl/fixed.hxx>
46 #include <vcl/menubtn.hxx>
47 #include <vcl/menu.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/sysdata.hxx>
50 
51 #include <svdata.hxx>
52 
53 using namespace vcl;
54 using namespace rtl;
55 
56 namespace vcl {
57 
58 class StatusWindow : public WorkWindow
59 {
60 protected:
61     StatusWindow( WinBits nWinBits );
62 public:
63     virtual ~StatusWindow();
64 
65     virtual void setPosition( SalFrame* );
66     virtual void setText( const String & ) = 0;
67     virtual String getText() const = 0;
68     virtual void show( bool bShow, I18NStatus::ShowReason eReason ) = 0;
69     virtual void toggle( bool bOn ) = 0;
70 };
71 
72 }
73 
StatusWindow(WinBits nWinBits)74 StatusWindow::StatusWindow( WinBits nWinBits ) :
75         WorkWindow( NULL, nWinBits )
76 {
77 }
78 
~StatusWindow()79 StatusWindow::~StatusWindow() {}
80 
setPosition(SalFrame *)81 void StatusWindow::setPosition( SalFrame* )
82 {
83 }
84 
85 // --------------------------------------------------------------------------
86 
87 namespace vcl {
88 
89 class XIMStatusWindow : public StatusWindow
90 {
91     FixedText				m_aStatusText;
92     SalFrame*				m_pLastParent;
93     Size					m_aWindowSize;
94     bool                    m_bAnchoredAtRight;
95         // true if the right edge (instead of the left edge) should stay at a
96         // fixed position when re-sizing the window
97 
98     // for delayed showing
99     bool					m_bDelayedShow;
100     I18NStatus::ShowReason	m_eDelayedReason;
101     sal_uLong					m_nDelayedEvent;
102     // for toggling
103     bool                    m_bOn;
104 
105     Point updatePosition();
106     void layout();
107     bool checkLastParent() const;
108 
109     DECL_LINK( DelayedShowHdl, void* );
110 public:
111     XIMStatusWindow( bool bOn );
112     virtual ~XIMStatusWindow();
113 
114     virtual void setPosition( SalFrame* );
115     virtual void setText( const String & );
116     virtual String getText() const;
117     virtual void show( bool bShow, I18NStatus::ShowReason eReason );
118     virtual void toggle( bool bOn );
119 
120     // overload WorkWindow::DataChanged
121     virtual void DataChanged( const DataChangedEvent& rEvt );
122 };
123 
124 }
125 
XIMStatusWindow(bool bOn)126 XIMStatusWindow::XIMStatusWindow( bool bOn ) :
127         StatusWindow( WB_BORDER | WB_SYSTEMFLOATWIN | WB_TOOLTIPWIN ),
128         m_aStatusText( this, 0 ),
129         m_pLastParent( NULL ),
130         m_bAnchoredAtRight( false ),
131         m_bDelayedShow( false ),
132         m_eDelayedReason( I18NStatus::contextmap ),
133         m_nDelayedEvent( 0 ),
134         m_bOn( bOn )
135 {
136     layout();
137 }
138 
~XIMStatusWindow()139 XIMStatusWindow::~XIMStatusWindow()
140 {
141     if( m_nDelayedEvent )
142         Application::RemoveUserEvent( m_nDelayedEvent );
143 }
144 
toggle(bool bOn)145 void XIMStatusWindow::toggle( bool bOn )
146 {
147     m_bOn = bOn;
148     show( bOn, I18NStatus::contextmap );
149 }
150 
layout()151 void XIMStatusWindow::layout()
152 {
153     m_aWindowSize.Width() = m_aStatusText.GetTextWidth( m_aStatusText.GetText() )+8;
154     Font aFont( m_aStatusText.GetFont() );
155     m_aWindowSize.Height() = aFont.GetHeight()+10;
156     m_aWindowSize = LogicToPixel( m_aWindowSize );
157 
158     Size aControlSize( m_aWindowSize );
159     aControlSize.Width()  -= 4;
160     aControlSize.Height() -= 4;
161 
162     m_aStatusText.SetPosSizePixel( Point( 1, 1 ), aControlSize );
163     m_aStatusText.SetFont( aFont );
164     m_aStatusText.Show( sal_True );
165 
166     if (m_bAnchoredAtRight && IsVisible())
167     {
168         SalFrame* pFrame = (SalFrame*)GetSystemData()->pSalFrame;
169         long nDelta = pFrame->maGeometry.nWidth - m_aWindowSize.Width();
170         pFrame->SetPosSize( pFrame->maGeometry.nX + nDelta,
171                             pFrame->maGeometry.nY,
172                             m_aWindowSize.Width(),
173                             m_aWindowSize.Height(),
174                             SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y | SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
175     }
176     else
177         SetOutputSizePixel( m_aWindowSize );
178 }
179 
checkLastParent() const180 bool XIMStatusWindow::checkLastParent() const
181 {
182     if( m_pLastParent )
183     {
184         const std::list< SalFrame* >& rFrames = GetX11SalData()->GetDisplay()->getFrames();
185         for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
186         {
187             if( *it == m_pLastParent )
188                 return true;
189         }
190     }
191     return false;
192 }
193 
DataChanged(const DataChangedEvent &)194 void XIMStatusWindow::DataChanged( const DataChangedEvent& )
195 {
196     m_aStatusText.SetSettings( GetSettings() );
197     layout();
198 }
199 
updatePosition()200 Point XIMStatusWindow::updatePosition()
201 {
202     Point aRet;
203     if( checkLastParent() )
204     {
205         const SystemEnvData* pParentEnvData = m_pLastParent->GetSystemData();
206 
207         SalExtTextInputPosEvent aPosEvent;
208         m_pLastParent->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvent );
209         int x, y;
210         XLIB_Window aChild;
211         XTranslateCoordinates( (Display*)pParentEnvData->pDisplay,
212                                (XLIB_Window)pParentEnvData->aShellWindow,
213                                GetX11SalData()->GetDisplay()->GetRootWindow( GetX11SalData()->GetDisplay()->GetDefaultScreenNumber() ),
214                                0, 0,
215                                &x, &y,
216                                &aChild );
217 
218         // TODO:  Currently, place the status window to the (physical) left of
219         // the cursor iff in vertical mode (assuming that the columns in
220         // vertical mode are always written from right to left, this causes the
221         // status window to keep out of the text already written).  This
222         // heuristic would break if there is ever a vertical mode in which the
223         // columns are written from left to right.  Also, more elaborate
224         // positioning for (both horizontal and vertical) left-to-right and
225         // right-to-left text would be possible.
226         bool bLeft = aPosEvent.mbVertical;
227             // true if status window is to the left of the cursor
228 
229         int const nGap = 4; // between cursor and status window
230         if (aPosEvent.mbVertical)
231         {
232             aRet.X() = x + aPosEvent.mnX + (bLeft
233                                             ? -m_aWindowSize.Width() - nGap
234                                             : aPosEvent.mnHeight + nGap);
235             aRet.Y() = y + aPosEvent.mnY;
236         }
237         else
238         {
239             aRet.X() = x + aPosEvent.mnX + (bLeft ? -m_aWindowSize.Width() : 0);
240             aRet.Y() = y + aPosEvent.mnY+aPosEvent.mnHeight + nGap;
241         }
242 
243         m_bAnchoredAtRight = bLeft;
244     }
245     return aRet;
246 }
247 
setPosition(SalFrame * pParent)248 void XIMStatusWindow::setPosition( SalFrame* pParent )
249 {
250     if( pParent )
251     {
252         if( pParent != m_pLastParent )
253         {
254             setText( String() );
255             m_pLastParent = pParent;
256             Show( sal_False, SHOW_NOACTIVATE );
257         }
258         if( IsVisible() )
259         {
260             const SystemEnvData* pEnvData = GetSystemData();
261             SalFrame* pStatusFrame = (SalFrame*)pEnvData->pSalFrame;
262             Point aPoint = updatePosition();
263             pStatusFrame->SetPosSize( aPoint.X(), aPoint.Y(), m_aWindowSize.Width(), m_aWindowSize.Height(), SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y | SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
264         }
265     }
266 }
267 
IMPL_LINK(XIMStatusWindow,DelayedShowHdl,void *,EMPTYARG)268 IMPL_LINK( XIMStatusWindow, DelayedShowHdl, void*, EMPTYARG )
269 {
270     m_nDelayedEvent = 0;
271     const SystemEnvData* pData = GetSystemData();
272     SalFrame* pStatusFrame = (SalFrame*)pData->pSalFrame;
273     if( m_bDelayedShow )
274     {
275         Size aControlSize( m_aWindowSize.Width()-4, m_aWindowSize.Height()-4 );
276         m_aStatusText.SetPosSizePixel( Point( 1, 1 ), aControlSize );
277         Point aPoint = updatePosition();
278         pStatusFrame->SetPosSize( aPoint.X(), aPoint.Y(), m_aWindowSize.Width(), m_aWindowSize.Height(), SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y | SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
279     }
280     Show( m_bDelayedShow && m_bOn, SHOW_NOACTIVATE );
281     if( m_bDelayedShow )
282     {
283 		XRaiseWindow( (Display*)pData->pDisplay,
284                       (XLIB_Window)pData->aShellWindow );
285     }
286     return 0;
287 }
288 
show(bool bShow,I18NStatus::ShowReason eReason)289 void XIMStatusWindow::show( bool bShow, I18NStatus::ShowReason eReason )
290 {
291     if( bShow && ! m_aStatusText.GetText().Len() )
292         bShow = false;
293 
294     m_bDelayedShow = bShow;
295     m_eDelayedReason = eReason;
296     if( ! m_nDelayedEvent )
297         m_nDelayedEvent = Application::PostUserEvent( LINK( this, XIMStatusWindow, DelayedShowHdl ) );
298 }
299 
setText(const String & rText)300 void XIMStatusWindow::setText( const String& rText )
301 {
302     m_aStatusText.SetText( rText );
303     m_aWindowSize.Width() = m_aStatusText.GetTextWidth( rText )+8;
304 }
305 
getText() const306 String XIMStatusWindow::getText() const
307 {
308     return m_aStatusText.GetText();
309 }
310 
311 // --------------------------------------------------------------------------
312 
313 namespace vcl {
314 
315 class IIIMPStatusWindow : public StatusWindow
316 {
317     MenuButton				m_aStatusBtn;
318     PopupMenu				m_aMenu;
319     SalFrame*				m_pResetFocus;
320     bool                    m_bShow;
321     bool                    m_bOn;
322 
323     DECL_LINK( SelectHdl, MenuButton* );
324 
325     void show();
326 
327 public:
328     IIIMPStatusWindow( SalFrame* pParent, bool bOn ); // for initial position
329     virtual ~IIIMPStatusWindow();
330 
331     virtual void setText( const String & );
332     virtual String getText() const;
333     virtual void show( bool bShow, I18NStatus::ShowReason eReason );
334     virtual void toggle( bool bOn );
335     void layout();
336 
337     // overload Window focus handler
338     virtual void        GetFocus();
339     // overload WorkWindow::DataChanged
340     virtual void DataChanged( const DataChangedEvent& rEvt );
341 };
342 
343 }
344 
IIIMPStatusWindow(SalFrame * pParent,bool bOn)345 IIIMPStatusWindow::IIIMPStatusWindow( SalFrame* pParent, bool bOn ) :
346         StatusWindow( WB_MOVEABLE ),
347         m_aStatusBtn( this, WB_BORDER ),
348         m_pResetFocus( pParent ),
349         m_bShow( true ),
350         m_bOn( bOn )
351 {
352     SetText( String( RTL_CONSTASCII_USTRINGPARAM( "IME Status" ) ) );
353 
354     layout();
355 
356     m_aStatusBtn.SetSelectHdl( LINK( this, IIIMPStatusWindow, SelectHdl ) );
357     m_aStatusBtn.SetPopupMenu( &m_aMenu );
358     m_aStatusBtn.Show( sal_True );
359 
360     const ::std::vector< I18NStatus::ChoiceData >& rChoices( I18NStatus::get().getChoices() );
361     int i = 1;
362     for( ::std::vector< I18NStatus::ChoiceData >::const_iterator it = rChoices.begin(); it != rChoices.end(); ++it, i++ )
363         m_aMenu.InsertItem( i, it->aString );
364 
365     if( pParent )
366     {
367         const SystemEnvData* pEnvData = GetSystemData();
368 
369         const SalFrameGeometry& rGeom( pParent->GetUnmirroredGeometry() );
370         int nDistance = rGeom.nTopDecoration;
371         if( nDistance < 20 )
372             nDistance = 20;
373         XMoveWindow( (Display*)pEnvData->pDisplay,
374                      (XLIB_Window)pEnvData->aShellWindow,
375                      rGeom.nX,
376                      rGeom.nY + rGeom.nHeight + nDistance
377                      );
378     }
379 #if OSL_DEBUG_LEVEL > 1
380     else
381         fprintf( stderr, "Warning: could not reposition status window since no frame\n" );
382 #endif
383     EnableAlwaysOnTop( sal_True );
384 }
385 
~IIIMPStatusWindow()386 IIIMPStatusWindow::~IIIMPStatusWindow()
387 {
388 }
389 
layout()390 void IIIMPStatusWindow::layout()
391 {
392     Font aFont( m_aStatusBtn.GetFont() );
393     Size aSize( 15*aFont.GetHeight(), aFont.GetHeight()+14 );
394     aSize = m_aStatusBtn.LogicToPixel( aSize );
395 
396     m_aStatusBtn.SetPosSizePixel( Point( 0, 0 ), aSize );
397     SetOutputSizePixel( aSize );
398     if( IsVisible() )
399         Invalidate();
400 }
401 
DataChanged(const DataChangedEvent &)402 void IIIMPStatusWindow::DataChanged( const DataChangedEvent& )
403 {
404     m_aStatusBtn.SetSettings( GetSettings() );
405     layout();
406 }
407 
setText(const String & rText)408 void IIIMPStatusWindow::setText( const String& rText )
409 {
410     m_aStatusBtn.SetText( rText );
411 }
412 
getText() const413 String IIIMPStatusWindow::getText() const
414 {
415     return m_aStatusBtn.GetText();
416 }
417 
show(bool bShow,I18NStatus::ShowReason eReason)418 void IIIMPStatusWindow::show( bool bShow, I18NStatus::ShowReason eReason )
419 {
420     // hide IIIMPStatusWindow only in presentations
421     if( ! bShow
422         && eReason != I18NStatus::presentation
423         )
424         return;
425 
426     m_bShow = bShow;
427     show();
428 }
429 
toggle(bool bOn)430 void IIIMPStatusWindow::toggle( bool bOn )
431 {
432     if (bOn != m_bOn)
433     {
434         m_bOn = bOn;
435         show();
436     }
437 }
438 
show()439 void IIIMPStatusWindow::show()
440 {
441     if (m_bOn && m_bShow && !IsVisible())
442         m_pResetFocus = I18NStatus::get().getParent();
443     Show(m_bOn && m_bShow);
444 }
445 
GetFocus()446 void IIIMPStatusWindow::GetFocus()
447 {
448     /*
449      *  this is here just to put the focus back to the application
450      *  window at startup on clickToFocus WMs
451      */
452     WorkWindow::GetFocus();
453     if( m_pResetFocus )
454     {
455         /*
456          *  look if reset focus still exists
457          *  since reset focus really is an internal hack there should
458          *  not be a method to be called in SalFrame destructor
459          */
460         const std::list< SalFrame* >& rFrames = GetX11SalData()->GetDisplay()->getFrames();
461         std::list< SalFrame* >::const_iterator it;
462         for( it = rFrames.begin(); it != rFrames.end() && *it != m_pResetFocus; ++it )
463             ;
464         if( it != rFrames.end() )
465         {
466             const SystemEnvData* pParentEnvData = m_pResetFocus->GetSystemData();
467             SalXLib* pXLib = GetX11SalData()->GetDisplay()->GetXLib();
468             pXLib->PushXErrorLevel( true );
469             XSetInputFocus( (Display*)pParentEnvData->pDisplay,
470                             (XLIB_Window)pParentEnvData->aShellWindow,
471                             RevertToNone,
472                             CurrentTime
473                             );
474             XSync( (Display*)pParentEnvData->pDisplay, False );
475             pXLib->PopXErrorLevel();
476         }
477         m_pResetFocus = NULL;
478     }
479 }
480 
481 // --------------------------------------------------------------------------
482 
IMPL_LINK(IIIMPStatusWindow,SelectHdl,MenuButton *,pBtn)483 IMPL_LINK( IIIMPStatusWindow, SelectHdl, MenuButton*, pBtn )
484 {
485     if( pBtn == & m_aStatusBtn )
486     {
487         const ::std::vector< I18NStatus::ChoiceData >& rChoices( I18NStatus::get().getChoices() );
488         unsigned int nIndex = m_aStatusBtn.GetCurItemId()-1;
489         if( nIndex < rChoices.size() )
490         {
491             XSetICValues( static_cast<X11SalFrame*>(I18NStatus::get().getParent())->getInputContext()->GetContext(),
492                           XNUnicodeCharacterSubset,
493                           rChoices[nIndex].pData,
494                           NULL);
495             // FIXME: get rid of X11SalFrame
496             X11SalFrame* pParent = static_cast<X11SalFrame*>(I18NStatus::get().getParent());
497             if( pParent && pParent->isMapped() )
498             {
499                 const SystemEnvData* pEnv = pParent->GetSystemData();
500                 SalXLib* pXLib = GetX11SalData()->GetDisplay()->GetXLib();
501                 pXLib->PushXErrorLevel( true );
502                 XSetInputFocus( (Display*)pEnv->pDisplay,
503                                 (XLIB_Window)pEnv->aShellWindow,
504                                 RevertToNone,
505                                 CurrentTime
506                                 );
507                 XSync( (Display*)pEnv->pDisplay, False );
508                 pXLib->PopXErrorLevel();
509             }
510         }
511     }
512     return 0;
513 }
514 
515 /*
516  *  I18NStatus
517  */
518 
519 I18NStatus* I18NStatus::pInstance = NULL;
520 
get()521 I18NStatus& I18NStatus::get()
522 {
523     if( ! pInstance )
524         pInstance = new I18NStatus();
525     return *pInstance;
526 }
527 
528 // --------------------------------------------------------------------------
529 
exists()530 bool I18NStatus::exists()
531 {
532     return pInstance != NULL;
533 }
534 
535 // --------------------------------------------------------------------------
536 
free()537 void I18NStatus::free()
538 {
539     if( pInstance )
540         delete pInstance, pInstance = NULL;
541 }
542 
543 // --------------------------------------------------------------------------
544 
I18NStatus()545 I18NStatus::I18NStatus() :
546         m_pParent( NULL ),
547         m_pStatusWindow( NULL )
548 {
549 }
550 
551 // --------------------------------------------------------------------------
552 
~I18NStatus()553 I18NStatus::~I18NStatus()
554 {
555     if( m_pStatusWindow )
556         delete m_pStatusWindow, m_pStatusWindow = NULL;
557     if( pInstance == this )
558         pInstance = NULL;
559 }
560 
561 // --------------------------------------------------------------------------
562 
setParent(SalFrame * pParent)563 void I18NStatus::setParent( SalFrame* pParent )
564 {
565     m_pParent = pParent;
566     if( ! m_pStatusWindow )
567     {
568         bool bIIIMPmode = m_aChoices.begin() != m_aChoices.end();
569         if( bIIIMPmode )
570             m_pStatusWindow = new IIIMPStatusWindow( pParent,
571                                                      getStatusWindowMode() );
572         else
573             m_pStatusWindow = new XIMStatusWindow( getStatusWindowMode() );
574         setStatusText( m_aCurrentIM );
575     }
576     m_pStatusWindow->setPosition( m_pParent );
577 }
578 
579 // --------------------------------------------------------------------------
580 
show(bool bShow,ShowReason eReason)581 void I18NStatus::show( bool bShow, ShowReason eReason )
582 {
583     if( m_pStatusWindow )
584     {
585         m_pStatusWindow->setPosition( m_pParent );
586         m_pStatusWindow->show( bShow, eReason );
587     }
588 }
589 
590 // --------------------------------------------------------------------------
591 
setStatusText(const String & rText)592 void I18NStatus::setStatusText( const String& rText )
593 {
594     if( m_pStatusWindow )
595     {
596         /*
597          *  #93614# convert fullwidth ASCII forms to ascii
598          */
599         int nChars = rText.Len()+1;
600         sal_Unicode* pBuffer = (sal_Unicode*)alloca( nChars*sizeof( sal_Unicode ) );
601         const sal_Unicode* pCopy = rText.GetBuffer();
602         for( int i = 0; i < nChars; i++ )
603         {
604             if( pCopy[i] >=0xff00 && pCopy[i] <= 0xff5f )
605                 pBuffer[i] = (pCopy[i] & 0xff) + 0x20;
606             else
607                 pBuffer[i] = pCopy[i];
608         }
609         String aText( pBuffer );
610         m_pStatusWindow->setText( aText );
611         m_pStatusWindow->setPosition( m_pParent );
612 
613         bool bVisible = true;
614         if( m_pParent )
615         {
616             long w, h;
617             m_pParent->GetClientSize( w, h );
618             if( w == 0 || h == 0 )
619             {
620                 bVisible = false;
621             }
622         }
623 
624         m_pStatusWindow->show( bVisible, contextmap );
625     }
626 }
627 
628 // --------------------------------------------------------------------------
629 
changeIM(const String & rIM)630 void I18NStatus::changeIM( const String& rIM )
631 {
632     m_aCurrentIM = rIM;
633 }
634 
635 // --------------------------------------------------------------------------
636 
getStatusText() const637 String I18NStatus::getStatusText() const
638 {
639     return m_pStatusWindow ? m_pStatusWindow->getText() :  String();
640 }
641 
642 // --------------------------------------------------------------------------
643 
clearChoices()644 void I18NStatus::clearChoices()
645 {
646     m_aChoices.clear();
647 }
648 
649 // --------------------------------------------------------------------------
650 
addChoice(const String & rChoice,void * pData)651 void I18NStatus::addChoice( const String& rChoice, void* pData )
652 {
653     ChoiceData aData;
654     aData.pData		= pData;
655     aData.aString	= rChoice;
656     m_aChoices.push_back( aData );
657 }
658 
659 // --------------------------------------------------------------------------
660 
toTop() const661 void I18NStatus::toTop() const
662 {
663     if( m_pStatusWindow )
664 	{
665 		const SystemEnvData* pData = m_pStatusWindow->GetSystemData();
666 		XRaiseWindow( (Display*)pData->pDisplay,
667                       (XLIB_Window)pData->aShellWindow );
668 	}
669 }
670 
671 // --------------------------------------------------------------------------
672 
getStatusFrame() const673 SalFrame* I18NStatus::getStatusFrame() const
674 {
675     SalFrame* pRet = NULL;
676     if( m_pStatusWindow )
677     {
678 		const SystemEnvData* pData = m_pStatusWindow->GetSystemData();
679         pRet = (SalFrame*)pData->pSalFrame;
680     }
681     return pRet;
682 }
683 
canToggleStatusWindow() const684 bool I18NStatus::canToggleStatusWindow() const
685 {
686     return true;
687 }
688 
toggleStatusWindow()689 void I18NStatus::toggleStatusWindow()
690 {
691     if (m_pStatusWindow != 0)
692         m_pStatusWindow->toggle(getStatusWindowMode());
693 }
694 
getStatusWindowMode()695 bool I18NStatus::getStatusWindowMode()
696 {
697     switch (ImplGetSVData()->maAppData.meShowImeStatusWindow)
698     {
699     default: // ImplSVAppData::ImeStatusWindowMode_UNKNOWN
700         return Application::GetShowImeStatusWindowDefault();
701     case ImplSVAppData::ImeStatusWindowMode_HIDE:
702         return false;
703     case ImplSVAppData::ImeStatusWindowMode_SHOW:
704         return true;
705     }
706 }
707 
708 /*
709  * X11ImeStatus
710  */
~X11ImeStatus()711 X11ImeStatus::~X11ImeStatus()
712 {
713     vcl::I18NStatus::free();
714 }
715 
canToggle()716 bool X11ImeStatus::canToggle()
717 {
718     return vcl::I18NStatus::get().canToggleStatusWindow();
719 }
720 
toggle()721 void X11ImeStatus::toggle()
722 {
723     vcl::I18NStatus::get().toggleStatusWindow();
724 }
725 
CreateI18NImeStatus()726 SalI18NImeStatus* X11SalInstance::CreateI18NImeStatus()
727 {
728     return new X11ImeStatus();
729 }
730