1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 #include <android/looper.h>
13 #include <android/bitmap.h>
15 #include <android/androidinst.hxx>
16 #include <headless/svpdummies.hxx>
17 #include <unx/gendata.hxx>
18 #include <osl/detail/android-bootstrap.h>
19 #include <rtl/strbuf.hxx>
20 #include <vcl/settings.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/weld.hxx>
27 static int viewWidth
= 1, viewHeight
= 1;
29 class AndroidSalData
: public GenericUnixSalData
32 explicit AndroidSalData( SalInstance
*pInstance
) : GenericUnixSalData( SAL_DATA_ANDROID
, pInstance
) {}
33 virtual void ErrorTrapPush() {}
34 virtual bool ErrorTrapPop( bool ) { return false; }
37 void AndroidSalInstance::GetWorkArea(tools::Rectangle
& rRect
)
39 rRect
= tools::Rectangle( Point( 0, 0 ),
40 Size( viewWidth
, viewHeight
) );
43 AndroidSalInstance
*AndroidSalInstance::getInstance()
47 AndroidSalData
*pData
= static_cast<AndroidSalData
*>(ImplGetSVData()->mpSalData
);
50 return static_cast<AndroidSalInstance
*>(pData
->m_pInstance
);
53 AndroidSalInstance::AndroidSalInstance( std::unique_ptr
<SalYieldMutex
> pMutex
)
54 : SvpSalInstance( std::move(pMutex
) )
56 // FIXME: remove when uniPoll & runLoop is the only Android entry point.
57 int res
= (lo_get_javavm())->AttachCurrentThread(&m_pJNIEnv
, NULL
);
58 LOGI("AttachCurrentThread res=%d env=%p", res
, m_pJNIEnv
);
61 // This is never called on Android until app exit.
62 AndroidSalInstance::~AndroidSalInstance()
64 int res
= (lo_get_javavm())->DetachCurrentThread();
65 LOGI("DetachCurrentThread res=%d", res
);
66 LOGI("destroyed Android Sal Instance");
69 bool AndroidSalInstance::AnyInput( VclInputFlags nType
)
71 if( nType
& VclInputFlags::TIMER
)
72 return CheckTimeout( false );
74 // Unfortunately there is no way to check for a specific type of
75 // input being queued. That information is too hidden, sigh.
76 return SvpSalInstance::s_pDefaultInstance
->HasUserEvents();
79 void AndroidSalInstance::updateMainThread()
81 int res
= (lo_get_javavm())->AttachCurrentThread(&m_pJNIEnv
, NULL
);
82 LOGI("updateMainThread AttachCurrentThread res=%d env=%p", res
, m_pJNIEnv
);
83 SvpSalInstance::updateMainThread();
86 void AndroidSalInstance::releaseMainThread()
88 int res
= (lo_get_javavm())->DetachCurrentThread();
89 LOGI("releaseMainThread DetachCurrentThread res=%d", res
);
91 SvpSalInstance::releaseMainThread();
94 class AndroidSalSystem
: public SvpSalSystem
{
96 AndroidSalSystem() : SvpSalSystem() {}
97 virtual ~AndroidSalSystem() {}
98 virtual int ShowNativeDialog( const OUString
& rTitle
,
99 const OUString
& rMessage
,
100 const std::vector
< OUString
>& rButtons
);
103 SalSystem
*AndroidSalInstance::CreateSalSystem()
105 return new AndroidSalSystem();
108 class AndroidSalFrame
: public SvpSalFrame
111 AndroidSalFrame( AndroidSalInstance
*pInstance
,
113 SalFrameStyleFlags nSalFrameStyle
)
114 : SvpSalFrame(pInstance
, pParent
, nSalFrameStyle
)
116 if (pParent
== NULL
&& viewWidth
> 1 && viewHeight
> 1)
117 SetPosSize(0, 0, viewWidth
, viewHeight
, SAL_FRAME_POSSIZE_WIDTH
| SAL_FRAME_POSSIZE_HEIGHT
);
120 virtual void GetWorkArea(tools::Rectangle
& rRect
)
122 AndroidSalInstance::getInstance()->GetWorkArea( rRect
);
125 virtual void UpdateSettings( AllSettings
&rSettings
)
127 // Clobber the UI fonts
129 psp::FastPrintFontInfo aInfo
;
130 aInfo
.m_aFamilyName
= "Roboto";
131 aInfo
.m_eItalic
= ITALIC_NORMAL
;
132 aInfo
.m_eWeight
= WEIGHT_NORMAL
;
133 aInfo
.m_eWidth
= WIDTH_NORMAL
;
134 psp::PrintFontManager::get().matchFont( aInfo
, rSettings
.GetUILocale() );
137 // FIXME: is 14 point enough ?
138 vcl::Font
aFont( OUString( "Roboto" ), Size( 0, 14 ) );
140 StyleSettings aStyleSet
= rSettings
.GetStyleSettings();
141 aStyleSet
.SetAppFont( aFont
);
142 aStyleSet
.SetHelpFont( aFont
);
143 aStyleSet
.SetMenuFont( aFont
);
144 aStyleSet
.SetToolFont( aFont
);
145 aStyleSet
.SetLabelFont( aFont
);
146 aStyleSet
.SetRadioCheckFont( aFont
);
147 aStyleSet
.SetPushButtonFont( aFont
);
148 aStyleSet
.SetFieldFont( aFont
);
149 aStyleSet
.SetIconFont( aFont
);
150 aStyleSet
.SetTabFont( aFont
);
151 aStyleSet
.SetGroupFont( aFont
);
153 rSettings
.SetStyleSettings( aStyleSet
);
157 SalFrame
*AndroidSalInstance::CreateChildFrame( SystemParentData
* /*pParent*/, SalFrameStyleFlags nStyle
)
159 return new AndroidSalFrame( this, NULL
, nStyle
);
162 SalFrame
*AndroidSalInstance::CreateFrame( SalFrame
* pParent
, SalFrameStyleFlags nStyle
)
164 return new AndroidSalFrame( this, pParent
, nStyle
);
167 // This is our main entry point:
168 extern "C" SalInstance
*create_SalInstance()
170 LOGI("Android: CreateSalInstance!");
171 AndroidSalInstance
* pInstance
= new AndroidSalInstance( std::make_unique
<SvpSalYieldMutex
>() );
172 new AndroidSalData( pInstance
);
176 int AndroidSalSystem::ShowNativeDialog( const OUString
& rTitle
,
177 const OUString
& rMessage
,
178 const std::vector
< OUString
>& rButtons
)
181 LOGI("LibreOffice native dialog '%s': '%s'",
182 OUStringToOString(rTitle
, RTL_TEXTENCODING_ASCII_US
).getStr(),
183 OUStringToOString(rMessage
, RTL_TEXTENCODING_ASCII_US
).getStr());
184 LOGI("Dialog '%s': '%s'",
185 OUStringToOString(rTitle
, RTL_TEXTENCODING_ASCII_US
).getStr(),
186 OUStringToOString(rMessage
, RTL_TEXTENCODING_ASCII_US
).getStr());
188 if (AndroidSalInstance::getInstance() != NULL
)
190 // Does Android have a native dialog ? if not,. we have to do this ...
192 // Of course it has. android.app.AlertDialog seems like a good
193 // choice, it even has one, two or three buttons. Naturally,
194 // it intended to be used from Java, so some verbose JNI
195 // horror would be needed to use it directly here. Probably we
196 // want some easier to use magic wrapper, hmm.
197 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(nullptr,
198 VclMessageType::Warning
, VclButtonsType::Ok
,
200 xBox
->set_title(rTitle
);
204 LOGE("VCL not initialized");
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */