Jogamp
moved com.jogamp.javafx.* to com.jogamp.*.
[jogl.git] / src / newt / native / KDWindow.c
1 /*
2  * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  * 
8  * - Redistribution of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * 
11  * - Redistribution in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in the
13  *   documentation and/or other materials provided with the distribution.
14  * 
15  * Neither the name of Sun Microsystems, Inc. or the names of
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  * 
19  * This software is provided "AS IS," without a warranty of any kind. ALL
20  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
23  * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
24  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
25  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
26  * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
27  * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
28  * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
29  * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
30  * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  * 
32  */
33
34 #ifdef _WIN32
35   #include <windows.h>
36 #endif
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41
42 #ifdef _WIN32
43     /* This typedef is apparently needed for Microsoft compilers before VC8,
44        and on Windows CE */
45     #if (_MSC_VER < 1400) || defined(UNDER_CE)
46         #ifdef _WIN64
47             typedef long long intptr_t;
48         #else
49             typedef int intptr_t;
50         #endif
51     #elif _MSC_VER <= 1500
52         #ifdef _WIN64 // [
53             typedef __int64           intptr_t;
54         #else // _WIN64 ][
55             typedef int               intptr_t;
56         #endif // _WIN64 ]
57     #else
58         #include <inttypes.h>
59     #endif
60 #else
61     #include <inttypes.h>
62 #endif
63
64 #include <KD/kd.h>
65 #include <KD/NV_extwindowprops.h>
66
67 #include "com_jogamp_newt_opengl_kd_KDWindow.h"
68
69 #include "EventListener.h"
70 #include "MouseEvent.h"
71 #include "KeyEvent.h"
72
73 // #define VERBOSE_ON 1
74
75 #ifdef VERBOSE_ON
76     #define DBG_PRINT(...) fprintf(stdout, __VA_ARGS__)
77 #else
78     #define DBG_PRINT(...)
79 #endif
80
81 #ifdef VERBOSE_ON
82     #ifdef _WIN32_WCE
83         #define STDOUT_FILE "\\Storage Card\\stdout.txt"
84         #define STDERR_FILE "\\Storage Card\\stderr.txt"
85     #endif
86 #endif
87
88 #define JOGL_KD_USERDATA_MAGIC 0xDEADBEEF
89 typedef struct {
90     long magic;
91     KDWindow * kdWindow;
92     jobject javaWindow;
93 } JOGLKDUserdata;
94
95 static jmethodID windowCreatedID = NULL;
96 static jmethodID sizeChangedID = NULL;
97 static jmethodID windowDestroyNotifyID = NULL;
98 static jmethodID windowDestroyedID = NULL;
99 static jmethodID sendMouseEventID = NULL;
100 static jmethodID sendKeyEventID = NULL;
101
102 /**
103  * Display
104  */
105
106 JNIEXPORT void JNICALL Java_com_jogamp_newt_opengl_kd_KDDisplay_DispatchMessages
107   (JNIEnv *env, jobject obj)
108 {
109     const KDEvent * evt;
110     int numEvents = 0;
111
112     // Periodically take a break
113     while( numEvents<100 && NULL!=(evt=kdWaitEvent(0)) ) {
114         KDWindow *kdWindow;
115         jobject javaWindow;
116         JOGLKDUserdata * userData = (JOGLKDUserdata *)(intptr_t)evt->userptr;
117         if(NULL == userData || userData->magic!=JOGL_KD_USERDATA_MAGIC) {
118             DBG_PRINT( "event unrelated: evt type: 0x%X\n", evt->type);
119             continue;
120         }
121         kdWindow = userData->kdWindow;
122         javaWindow = userData->javaWindow;
123         DBG_PRINT( "[DispatchMessages]: userData %p, evt type: 0x%X\n", userData, evt->type);
124
125         numEvents++;
126
127         // FIXME: support resize and window re-positioning events
128
129         switch(evt->type) {
130             case KD_EVENT_WINDOW_FOCUS:
131                 {
132                     KDboolean hasFocus;
133                     kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_FOCUS, &hasFocus);
134                     DBG_PRINT( "event window focus : src: %p\n", userData);
135                 }
136                 break;
137             case KD_EVENT_WINDOW_CLOSE:
138                 {
139                     DBG_PRINT( "event window close : src: %p\n", userData);
140                     (*env)->CallVoidMethod(env, javaWindow, windowDestroyNotifyID);
141                     // Called by Window.java: DestroyWindow(wnd);
142                     //  (*env)->CallVoidMethod(env, javaWindow, windowDestroyedID);
143                 }
144                 break;
145             case KD_EVENT_WINDOWPROPERTY_CHANGE:
146                 {
147                     const KDEventWindowProperty* prop = &evt->data.windowproperty;
148                     switch (prop->pname) {
149                         case KD_WINDOWPROPERTY_SIZE:
150                             {
151                                 KDint32 v[2];
152                                 if(!kdGetWindowPropertyiv(kdWindow, KD_WINDOWPROPERTY_SIZE, v)) {
153                                     DBG_PRINT( "event window size change : src: %p %dx%d\n", userData, v[0], v[1]);
154                                     (*env)->CallVoidMethod(env, javaWindow, sizeChangedID, (jint) v[0], (jint) v[1]);
155                                 } else {
156                                     DBG_PRINT( "event window size change error: src: %p %dx%d\n", userData, v[0], v[1]);
157                                 }
158                             }
159                             break;
160                         case KD_WINDOWPROPERTY_FOCUS:
161                             DBG_PRINT( "event window focus: src: %p\n", userData);
162                             break;
163                         case KD_WINDOWPROPERTY_VISIBILITY:
164                             {
165                                 KDboolean visible;
166                                 kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visible);
167                                 DBG_PRINT( "event window visibility: src: %p, v:%d\n", userData, visible);
168                             }
169                             break;
170                         default:
171                             break;
172                     }
173                 }
174                 break;
175             case KD_EVENT_INPUT_POINTER:
176                 {
177                     const KDEventInputPointer* ptr = &(evt->data.inputpointer);
178                     // button idx: evt->data.input.index
179                     // pressed = ev->data.input.value.i
180                     // time = ev->timestamp
181                     if(KD_INPUT_POINTER_SELECT==ptr->index) {
182                         DBG_PRINT( "event mouse click: src: %p, s:%d, (%d,%d)\n", userData, ptr->select, ptr->x, ptr->y);
183                         (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, 
184                                               (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED, 
185                                               (jint) 0,
186                                               (jint) ptr->x, (jint) ptr->y, 1, 0);
187                     } else {
188                         DBG_PRINT( "event mouse: src: %d, s:%p, i:0x%X (%d,%d)\n", userData, ptr->select, ptr->index, ptr->x, ptr->y);
189                         (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, 
190                                               0,
191                                               (jint) ptr->x, (jint) ptr->y, 0, 0);
192                     }
193                 }
194                 break;
195         }
196     } 
197 }
198
199 /**
200  * Window
201  */
202
203 JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_opengl_kd_KDWindow_initIDs
204   (JNIEnv *env, jclass clazz)
205 {
206 #ifdef VERBOSE_ON
207     #ifdef _WIN32_WCE
208         _wfreopen(TEXT(STDOUT_FILE),L"w",stdout);
209         _wfreopen(TEXT(STDERR_FILE),L"w",stderr);
210     #endif
211 #endif
212     windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
213     sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
214     windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify",    "()V");
215     windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
216     sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
217     sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
218     if (windowCreatedID == NULL ||
219         sizeChangedID == NULL ||
220         windowDestroyNotifyID == NULL ||
221         windowDestroyedID == NULL ||
222         sendMouseEventID == NULL ||
223         sendKeyEventID == NULL) {
224         DBG_PRINT( "initIDs failed\n" );
225         return JNI_FALSE;
226     }
227     DBG_PRINT( "initIDs ok\n" );
228     return JNI_TRUE;
229 }
230
231 JNIEXPORT jlong JNICALL Java_com_jogamp_newt_opengl_kd_KDWindow_CreateWindow
232   (JNIEnv *env, jobject obj, jlong display, jintArray jAttrs)
233 {
234     jint * attrs = NULL;
235     jsize attrsLen;
236     EGLDisplay dpy  = (EGLDisplay)(intptr_t)display;
237     KDWindow *window = 0;
238
239     if(dpy==NULL) {
240         fprintf(stderr, "[CreateWindow] invalid display connection..\n");
241         return 0;
242     }
243
244     attrsLen = (*env)->GetArrayLength(env, jAttrs);
245     if(0==attrsLen) {
246         fprintf(stderr, "[CreateWindow] attribute array size 0..\n");
247         return 0;
248     }
249     attrs = (*env)->GetIntArrayElements(env, jAttrs, 0);
250     if(NULL==attrs) {
251         fprintf(stderr, "[CreateWindow] attribute array NULL..\n");
252         return 0;
253     }
254
255     JOGLKDUserdata * userData = kdMalloc(sizeof(JOGLKDUserdata));
256     userData->magic = JOGL_KD_USERDATA_MAGIC;
257     window = kdCreateWindow(dpy, attrs, (void *)userData);
258
259     (*env)->ReleaseIntArrayElements(env, jAttrs, attrs, 0);
260
261     if(NULL==window) {
262         kdFree(userData);
263         fprintf(stderr, "[CreateWindow] failed: 0x%X\n", kdGetError());
264     } else {
265         userData->javaWindow = (*env)->NewGlobalRef(env, obj);
266         userData->kdWindow = window;
267         (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) (intptr_t) userData);
268         DBG_PRINT( "[CreateWindow] ok: %p, userdata %p\n", window, userData);
269     }
270     return (jlong) (intptr_t) window;
271 }
272
273 JNIEXPORT jlong JNICALL Java_com_jogamp_newt_opengl_kd_KDWindow_RealizeWindow
274   (JNIEnv *env, jobject obj, jlong window)
275 {
276     KDWindow *w = (KDWindow*) (intptr_t) window;
277     EGLNativeWindowType nativeWindow=0;
278
279     jint res = kdRealizeWindow(w, &nativeWindow);
280     if(res) {
281         fprintf(stderr, "[RealizeWindow] failed: 0x%X, 0x%X\n", res, kdGetError());
282         nativeWindow = NULL;
283     }
284     DBG_PRINT( "[RealizeWindow] ok: %p\n", nativeWindow);
285     return (jlong) (intptr_t) nativeWindow;
286 }
287
288 JNIEXPORT jint JNICALL Java_com_jogamp_newt_opengl_kd_KDWindow_CloseWindow
289   (JNIEnv *env, jobject obj, jlong window, jlong juserData)
290 {
291     KDWindow *w = (KDWindow*) (intptr_t) window;
292     JOGLKDUserdata * userData = (JOGLKDUserdata*) (intptr_t) juserData;
293     int res = kdDestroyWindow(w);
294     (*env)->DeleteGlobalRef(env, userData->javaWindow);
295     kdFree(userData);
296
297     DBG_PRINT( "[CloseWindow] res: %d\n", res);
298     return res;
299 }
300
301 /*
302  * Class:     com_jogamp_newt_opengl_kd_KDWindow
303  * Method:    setVisible0
304  * Signature: (JJZ)V
305  */
306 JNIEXPORT void JNICALL Java_com_jogamp_newt_opengl_kd_KDWindow_setVisible0
307   (JNIEnv *env, jobject obj, jlong window, jboolean visible)
308 {
309     KDWindow *w = (KDWindow*) (intptr_t) window;
310     KDboolean v = (visible==JNI_TRUE)?KD_TRUE:KD_FALSE;
311     kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &v);
312     DBG_PRINT( "[setVisible] v=%d\n", visible);
313 }
314
315 JNIEXPORT void JNICALL Java_com_jogamp_newt_opengl_kd_KDWindow_setFullScreen0
316   (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen)
317 {
318     KDWindow *w = (KDWindow*) (intptr_t) window;
319     KDboolean v = fullscreen;
320
321     int res = kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_FULLSCREEN_NV, &v);
322     DBG_PRINT( "[setFullScreen] v=%d, res=%d\n", fullscreen, res);
323     (void)res;
324 }
325
326 JNIEXPORT void JNICALL Java_com_jogamp_newt_opengl_kd_KDWindow_setSize0
327   (JNIEnv *env, jobject obj, jlong window, jint width, jint height)
328 {
329     KDWindow *w = (KDWindow*) (intptr_t) window;
330     KDint32 v[] = { width, height };
331
332     int res = kdSetWindowPropertyiv(w, KD_WINDOWPROPERTY_SIZE, v);
333     DBG_PRINT( "[setSize] v=%dx%d, res=%d\n", width, height, res);
334     (void)res;
335
336     (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height);
337 }
338
http://JogAmp.org git info: FAQ, tutorial and man pages.