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 74 StatusWindow::StatusWindow( WinBits nWinBits ) : 75 WorkWindow( NULL, nWinBits ) 76 { 77 } 78 79 StatusWindow::~StatusWindow() {} 80 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 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 139 XIMStatusWindow::~XIMStatusWindow() 140 { 141 if( m_nDelayedEvent ) 142 Application::RemoveUserEvent( m_nDelayedEvent ); 143 } 144 145 void XIMStatusWindow::toggle( bool bOn ) 146 { 147 m_bOn = bOn; 148 show( bOn, I18NStatus::contextmap ); 149 } 150 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 180 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 194 void XIMStatusWindow::DataChanged( const DataChangedEvent& ) 195 { 196 m_aStatusText.SetSettings( GetSettings() ); 197 layout(); 198 } 199 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 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 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 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 300 void XIMStatusWindow::setText( const String& rText ) 301 { 302 m_aStatusText.SetText( rText ); 303 m_aWindowSize.Width() = m_aStatusText.GetTextWidth( rText )+8; 304 } 305 306 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 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 386 IIIMPStatusWindow::~IIIMPStatusWindow() 387 { 388 } 389 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 402 void IIIMPStatusWindow::DataChanged( const DataChangedEvent& ) 403 { 404 m_aStatusBtn.SetSettings( GetSettings() ); 405 layout(); 406 } 407 408 void IIIMPStatusWindow::setText( const String& rText ) 409 { 410 m_aStatusBtn.SetText( rText ); 411 } 412 413 String IIIMPStatusWindow::getText() const 414 { 415 return m_aStatusBtn.GetText(); 416 } 417 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 430 void IIIMPStatusWindow::toggle( bool bOn ) 431 { 432 if (bOn != m_bOn) 433 { 434 m_bOn = bOn; 435 show(); 436 } 437 } 438 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 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 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 521 I18NStatus& I18NStatus::get() 522 { 523 if( ! pInstance ) 524 pInstance = new I18NStatus(); 525 return *pInstance; 526 } 527 528 // -------------------------------------------------------------------------- 529 530 bool I18NStatus::exists() 531 { 532 return pInstance != NULL; 533 } 534 535 // -------------------------------------------------------------------------- 536 537 void I18NStatus::free() 538 { 539 if( pInstance ) 540 delete pInstance, pInstance = NULL; 541 } 542 543 // -------------------------------------------------------------------------- 544 545 I18NStatus::I18NStatus() : 546 m_pParent( NULL ), 547 m_pStatusWindow( NULL ) 548 { 549 } 550 551 // -------------------------------------------------------------------------- 552 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 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 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 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 630 void I18NStatus::changeIM( const String& rIM ) 631 { 632 m_aCurrentIM = rIM; 633 } 634 635 // -------------------------------------------------------------------------- 636 637 String I18NStatus::getStatusText() const 638 { 639 return m_pStatusWindow ? m_pStatusWindow->getText() : String(); 640 } 641 642 // -------------------------------------------------------------------------- 643 644 void I18NStatus::clearChoices() 645 { 646 m_aChoices.clear(); 647 } 648 649 // -------------------------------------------------------------------------- 650 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 661 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 673 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 684 bool I18NStatus::canToggleStatusWindow() const 685 { 686 return true; 687 } 688 689 void I18NStatus::toggleStatusWindow() 690 { 691 if (m_pStatusWindow != 0) 692 m_pStatusWindow->toggle(getStatusWindowMode()); 693 } 694 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 */ 711 X11ImeStatus::~X11ImeStatus() 712 { 713 vcl::I18NStatus::free(); 714 } 715 716 bool X11ImeStatus::canToggle() 717 { 718 return vcl::I18NStatus::get().canToggleStatusWindow(); 719 } 720 721 void X11ImeStatus::toggle() 722 { 723 vcl::I18NStatus::get().toggleStatusWindow(); 724 } 725 726 SalI18NImeStatus* X11SalInstance::CreateI18NImeStatus() 727 { 728 return new X11ImeStatus(); 729 } 730