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 #include <rtl/process.h>
28 #include <rtl/ref.hxx>
29
30 #include <tools/rc.h>
31
32 // declare system types in sysdata.hxx
33 #include <svsys.h>
34
35 #include <vcl/window.hxx>
36 #include <vcl/sysdata.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/syschild.hxx>
39 #include <vcl/unohelp.hxx>
40
41 #include <window.h>
42 #include <salinst.hxx>
43 #include <salframe.hxx>
44 #include <salobj.hxx>
45 #include <svdata.hxx>
46
47 #ifdef SOLAR_JAVA
48 #include <jni.h>
49 #endif
50
51 #include <comphelper/processfactory.hxx>
52 #include <jvmaccess/virtualmachine.hxx>
53 #include <com/sun/star/java/XJavaVM.hpp>
54 #include <com/sun/star/java/XJavaThreadRegister_11.hpp>
55 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
56
57 using namespace ::com::sun::star;
58
59 // =======================================================================
60
ImplSysChildProc(void * pInst,SalObject *,sal_uInt16 nEvent,const void *)61 long ImplSysChildProc( void* pInst, SalObject* /* pObject */,
62 sal_uInt16 nEvent, const void* /* pEvent */ )
63 {
64 SystemChildWindow* pWindow = (SystemChildWindow*)pInst;
65 long nRet = 0;
66
67 ImplDelData aDogTag( pWindow );
68 switch ( nEvent )
69 {
70 case SALOBJ_EVENT_GETFOCUS:
71 // Focus holen und zwar so, das alle Handler gerufen
72 // werden, als ob dieses Fenster den Focus bekommt,
73 // ohne das der Frame den Focus wieder klaut
74 pWindow->ImplGetFrameData()->mbSysObjFocus = sal_True;
75 pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = sal_True;
76 pWindow->ToTop( TOTOP_NOGRABFOCUS );
77 if( aDogTag.IsDead() )
78 break;
79 pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = sal_False;
80 pWindow->ImplGetFrameData()->mbInSysObjFocusHdl = sal_True;
81 pWindow->GrabFocus();
82 if( aDogTag.IsDead() )
83 break;
84 pWindow->ImplGetFrameData()->mbInSysObjFocusHdl = sal_False;
85 break;
86
87 case SALOBJ_EVENT_LOSEFOCUS:
88 // Hintenrum einen LoseFocus ausloesen, das der Status
89 // der Fenster dem entsprechenden Activate-Status
90 // entspricht
91 pWindow->ImplGetFrameData()->mbSysObjFocus = sal_False;
92 if ( !pWindow->ImplGetFrameData()->mnFocusId )
93 {
94 pWindow->ImplGetFrameData()->mbStartFocusState = sal_True;
95 Application::PostUserEvent( pWindow->ImplGetFrameData()->mnFocusId, LINK( pWindow->ImplGetFrameWindow(), Window, ImplAsyncFocusHdl ) );
96 }
97 break;
98
99 case SALOBJ_EVENT_TOTOP:
100 pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = sal_True;
101 if ( !Application::GetFocusWindow() || pWindow->HasChildPathFocus() )
102 pWindow->ToTop( TOTOP_NOGRABFOCUS );
103 else
104 pWindow->ToTop();
105 if( aDogTag.IsDead() )
106 break;
107 pWindow->GrabFocus();
108 if( aDogTag.IsDead() )
109 break;
110 pWindow->ImplGetFrameData()->mbInSysObjToTopHdl = sal_False;
111 break;
112 }
113
114 return nRet;
115 }
116
117 // =======================================================================
118
ImplInitSysChild(Window * pParent,WinBits nStyle,SystemWindowData * pData,sal_Bool bShow)119 void SystemChildWindow::ImplInitSysChild( Window* pParent, WinBits nStyle, SystemWindowData *pData, sal_Bool bShow )
120 {
121 mpWindowImpl->mpSysObj = ImplGetSVData()->mpDefInst->CreateObject( pParent->ImplGetFrame(), pData, bShow );
122
123 Window::ImplInit( pParent, nStyle, NULL );
124
125 // Wenn es ein richtiges SysChild ist, dann painten wir auch nicht
126 if ( GetSystemData() )
127 {
128 mpWindowImpl->mpSysObj->SetCallback( this, ImplSysChildProc );
129 SetParentClipMode( PARENTCLIPMODE_CLIP );
130 SetBackground();
131 }
132 }
133
134 // -----------------------------------------------------------------------
135
SystemChildWindow(Window * pParent,WinBits nStyle)136 SystemChildWindow::SystemChildWindow( Window* pParent, WinBits nStyle ) :
137 Window( WINDOW_SYSTEMCHILDWINDOW )
138 {
139 ImplInitSysChild( pParent, nStyle, NULL );
140 }
141
142 // -----------------------------------------------------------------------
143
SystemChildWindow(Window * pParent,WinBits nStyle,SystemWindowData * pData,sal_Bool bShow)144 SystemChildWindow::SystemChildWindow( Window* pParent, WinBits nStyle, SystemWindowData *pData, sal_Bool bShow ) :
145 Window( WINDOW_SYSTEMCHILDWINDOW )
146 {
147 ImplInitSysChild( pParent, nStyle, pData, bShow );
148 }
149
150 // -----------------------------------------------------------------------
151
SystemChildWindow(Window * pParent,const ResId & rResId)152 SystemChildWindow::SystemChildWindow( Window* pParent, const ResId& rResId ) :
153 Window( WINDOW_SYSTEMCHILDWINDOW )
154 {
155 rResId.SetRT( RSC_WINDOW );
156 WinBits nStyle = ImplInitRes( rResId );
157 ImplInitSysChild( pParent, nStyle, NULL );
158 ImplLoadRes( rResId );
159
160 if ( !(nStyle & WB_HIDE) )
161 Show();
162 }
163
164 // -----------------------------------------------------------------------
165
~SystemChildWindow()166 SystemChildWindow::~SystemChildWindow()
167 {
168 Hide();
169 if ( mpWindowImpl->mpSysObj )
170 {
171 ImplGetSVData()->mpDefInst->DestroyObject( mpWindowImpl->mpSysObj );
172 mpWindowImpl->mpSysObj = NULL;
173 }
174 }
175
176 // -----------------------------------------------------------------------
177
GetSystemData() const178 const SystemEnvData* SystemChildWindow::GetSystemData() const
179 {
180 if ( mpWindowImpl->mpSysObj )
181 return mpWindowImpl->mpSysObj->GetSystemData();
182 else
183 return NULL;
184 }
185
186 // -----------------------------------------------------------------------
187
EnableEraseBackground(sal_Bool bEnable)188 void SystemChildWindow::EnableEraseBackground( sal_Bool bEnable )
189 {
190 if ( mpWindowImpl->mpSysObj )
191 mpWindowImpl->mpSysObj->EnableEraseBackground( bEnable );
192 }
193
194 // -----------------------------------------------------------------------
195
IsEraseBackgroundEnabled()196 sal_Bool SystemChildWindow::IsEraseBackgroundEnabled()
197 {
198 if ( mpWindowImpl->mpSysObj )
199 return mpWindowImpl->mpSysObj->IsEraseBackgroundEnabled();
200 else
201 return sal_False;
202 }
203
204 // -----------------------------------------------------------------------
205
ImplTestJavaException(void * pEnv)206 void SystemChildWindow::ImplTestJavaException( void* pEnv )
207 {
208 #ifdef SOLAR_JAVA
209 JNIEnv* pJavaEnv = reinterpret_cast< JNIEnv* >( pEnv );
210 jthrowable jtThrowable = pJavaEnv->ExceptionOccurred();
211
212 if( jtThrowable )
213 { // is it a java exception ?
214 #if OSL_DEBUG_LEVEL > 1
215 pJavaEnv->ExceptionDescribe();
216 #endif // OSL_DEBUG_LEVEL > 1
217 pJavaEnv->ExceptionClear();
218
219 jclass jcThrowable = pJavaEnv->FindClass("java/lang/Throwable");
220 jmethodID jmThrowable_getMessage = pJavaEnv->GetMethodID(jcThrowable, "getMessage", "()Ljava/lang/String;");
221 jstring jsMessage = (jstring) pJavaEnv->CallObjectMethod(jtThrowable, jmThrowable_getMessage);
222 ::rtl::OUString ouMessage;
223
224 if(jsMessage)
225 {
226 const jchar * jcMessage = pJavaEnv->GetStringChars(jsMessage, NULL);
227 ouMessage = ::rtl::OUString(jcMessage);
228 pJavaEnv->ReleaseStringChars(jsMessage, jcMessage);
229 }
230
231 throw uno::RuntimeException(ouMessage, uno::Reference<uno::XInterface>());
232 }
233 #endif // SOLAR_JAVA
234 }
235
236 // -----------------------------------------------------------------------
237
GetParentWindowHandle(sal_Bool bUseJava)238 sal_IntPtr SystemChildWindow::GetParentWindowHandle( sal_Bool bUseJava )
239 {
240 sal_IntPtr nRet = 0;
241
242 (void)bUseJava;
243 #if defined WNT
244 nRet = reinterpret_cast< sal_IntPtr >( GetSystemData()->hWnd );
245 #elif defined OS2
246 nRet = reinterpret_cast< sal_IntPtr >( (long)GetSystemData()->hWnd );
247 #elif defined QUARTZ
248 // FIXME: this is wrong
249 nRet = reinterpret_cast< sal_IntPtr >( GetSystemData()->mpNSView );
250 #elif defined UNX
251 if( !bUseJava )
252 {
253 nRet = (sal_IntPtr) GetSystemData()->aWindow;
254 }
255 #ifdef SOLAR_JAVA
256 else
257 {
258 uno::Reference< lang::XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() );
259
260 if( xFactory.is() && ( GetSystemData()->aWindow > 0 ) )
261 {
262 try
263 {
264 ::rtl::Reference< ::jvmaccess::VirtualMachine > xVM;
265 uno::Reference< java::XJavaVM > xJavaVM( xFactory->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.java.JavaVirtualMachine") ) ), uno::UNO_QUERY );
266 uno::Sequence< sal_Int8 > aProcessID( 17 );
267
268 rtl_getGlobalProcessId( (sal_uInt8*) aProcessID.getArray() );
269 aProcessID[ 16 ] = 0;
270 OSL_ENSURE(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *), "Pointer cannot be represented as sal_Int64");
271 sal_Int64 nPointer = reinterpret_cast< sal_Int64 >( static_cast< jvmaccess::VirtualMachine * >(0));
272 xJavaVM->getJavaVM(aProcessID) >>= nPointer;
273 xVM = reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer);
274
275 if( xVM.is() )
276 {
277 try
278 {
279 ::jvmaccess::VirtualMachine::AttachGuard aVMAttachGuard( xVM );
280 JNIEnv* pEnv = aVMAttachGuard.getEnvironment();
281
282 jclass jcToolkit = pEnv->FindClass("java/awt/Toolkit");
283 ImplTestJavaException(pEnv);
284
285 jmethodID jmToolkit_getDefaultToolkit = pEnv->GetStaticMethodID( jcToolkit, "getDefaultToolkit", "()Ljava/awt/Toolkit;" );
286 ImplTestJavaException(pEnv);
287
288 pEnv->CallStaticObjectMethod(jcToolkit, jmToolkit_getDefaultToolkit);
289 ImplTestJavaException(pEnv);
290
291 jclass jcMotifAppletViewer = pEnv->FindClass("sun/plugin/navig/motif/MotifAppletViewer");
292 if( pEnv->ExceptionOccurred() )
293 {
294 pEnv->ExceptionClear();
295
296 jcMotifAppletViewer = pEnv->FindClass( "sun/plugin/viewer/MNetscapePluginContext");
297 ImplTestJavaException(pEnv);
298 }
299
300 jclass jcClassLoader = pEnv->FindClass("java/lang/ClassLoader");
301 ImplTestJavaException(pEnv);
302
303 jmethodID jmClassLoader_loadLibrary = pEnv->GetStaticMethodID( jcClassLoader, "loadLibrary", "(Ljava/lang/Class;Ljava/lang/String;Z)V");
304 ImplTestJavaException(pEnv);
305
306 jstring jsplugin = pEnv->NewStringUTF("javaplugin_jni");
307 ImplTestJavaException(pEnv);
308
309 pEnv->CallStaticVoidMethod(jcClassLoader, jmClassLoader_loadLibrary, jcMotifAppletViewer, jsplugin, JNI_FALSE);
310 ImplTestJavaException(pEnv);
311
312 jmethodID jmMotifAppletViewer_getWidget = pEnv->GetStaticMethodID( jcMotifAppletViewer, "getWidget", "(IIIII)I" );
313 ImplTestJavaException(pEnv);
314
315 const Size aSize( GetOutputSizePixel() );
316 jint ji_widget = pEnv->CallStaticIntMethod( jcMotifAppletViewer, jmMotifAppletViewer_getWidget,
317 GetSystemData()->aWindow, 0, 0, aSize.Width(), aSize.Height() );
318 ImplTestJavaException(pEnv);
319
320 nRet = static_cast< sal_IntPtr >( ji_widget );
321 }
322 catch( uno::RuntimeException& )
323 {
324 }
325
326 if( !nRet )
327 nRet = static_cast< sal_IntPtr >( GetSystemData()->aWindow );
328 }
329 }
330 catch( ... )
331 {
332 }
333 }
334 }
335 #endif // SOLAR_JAVA
336 #else // WNT || QUARTZ || UNX
337 #endif
338
339 return nRet;
340 }
341