diff options
author | Sven Gothel <[email protected]> | 2008-06-25 05:50:55 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2008-06-25 05:50:55 +0000 |
commit | b02adebb3213e19aecfe84e6966e52976e5c09cf (patch) | |
tree | 6435fdac5e3ccad90ae1e96b684e56d79fb57bcf /src/native/newt | |
parent | 800c7da4656277810d579e76b74558434bb6467c (diff) |
Native Compilation: Partitioning and X11 clean
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1680 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/native/newt')
-rw-r--r-- | src/native/newt/EventListener.h | 9 | ||||
-rw-r--r-- | src/native/newt/KeyEvent.h | 10 | ||||
-rw-r--r-- | src/native/newt/MouseEvent.h | 13 | ||||
-rwxr-xr-x | src/native/newt/WindowsWindow.c | 479 | ||||
-rwxr-xr-x | src/native/newt/X11Window.c | 530 |
5 files changed, 1041 insertions, 0 deletions
diff --git a/src/native/newt/EventListener.h b/src/native/newt/EventListener.h new file mode 100644 index 000000000..2e0e92323 --- /dev/null +++ b/src/native/newt/EventListener.h @@ -0,0 +1,9 @@ + +#ifndef _EVENT_LISTSENER_H +#define _EVENT_LISTSENER_H + +#define EVENT_WINDOW (1 << 0) +#define EVENT_MOUSE (1 << 1) +#define EVENT_KEY (1 << 2) + +#endif diff --git a/src/native/newt/KeyEvent.h b/src/native/newt/KeyEvent.h new file mode 100644 index 000000000..fed4636b1 --- /dev/null +++ b/src/native/newt/KeyEvent.h @@ -0,0 +1,10 @@ + +#ifndef _KEY_EVENT_H_ +#define _KEY_EVENT_H_ + +#define EVENT_KEY_PRESSED (1 << 0) +#define EVENT_KEY_RELEASED (1 << 1) +// Send by Java: EVENT_KEY_TYPED (1 << 2) + +#endif + diff --git a/src/native/newt/MouseEvent.h b/src/native/newt/MouseEvent.h new file mode 100644 index 000000000..13e805028 --- /dev/null +++ b/src/native/newt/MouseEvent.h @@ -0,0 +1,13 @@ + +#ifndef _MOUSE_EVENT_H_ +#define _MOUSE_EVENT_H_ + +// Generated by Java: EVENT_MOUSE_CLICKED +#define EVENT_MOUSE_ENTERED (1 << 1) +#define EVENT_MOUSE_EXITED (1 << 2) +#define EVENT_MOUSE_PRESSED (1 << 3) +#define EVENT_MOUSE_RELEASED (1 << 4) +#define EVENT_MOUSE_MOVED (1 << 5) +// Generated by Java: EVENT_MOUSE_DRAGGED (1 << 6) + +#endif diff --git a/src/native/newt/WindowsWindow.c b/src/native/newt/WindowsWindow.c new file mode 100755 index 000000000..cd6844cd2 --- /dev/null +++ b/src/native/newt/WindowsWindow.c @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +#include <windows.h> +#include <tchar.h> +#include <stdlib.h> +#ifdef UNDER_CE +#include "aygshell.h" +#endif + +/* This typedef is apparently needed for Microsoft compilers before VC8, + and on Windows CE */ +#if (_MSC_VER < 1400) || defined(UNDER_CE) +#ifdef _WIN64 +typedef long long intptr_t; +#else +typedef int intptr_t; +#endif +#endif + +#include "com_sun_javafx_newt_windows_WindowsWindow.h" + +#include "EventListener.h" +#include "MouseEvent.h" +#include "KeyEvent.h" + +static jmethodID sizeChangedID = NULL; +static jmethodID positionChangedID = NULL; +static jmethodID windowClosedID = NULL; +static jmethodID windowDestroyedID = NULL; +static jmethodID sendMouseEventID = NULL; +static jmethodID sendKeyEventID = NULL; + +// This is set by DispatchMessages, below, and cleared when it exits +static JNIEnv* env = NULL; + +// Really need to factor this out in to a separate run-time file +static jchar* GetNullTerminatedStringChars(JNIEnv* env, jstring str) +{ + jchar* strChars = NULL; + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } + return strChars; +} + +static LRESULT CALLBACK wndProc(HWND wnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + RECT rc; + int useDefWindowProc = 0; + jobject window = NULL; + BOOL isKeyDown = FALSE; + +#ifdef UNDER_CE + window = (jobject) GetWindowLong(wnd, GWL_USERDATA); +#else + window = (jobject) GetWindowLongPtr(wnd, GWLP_USERDATA); +#endif + if (window == NULL || env == NULL) { + // Shouldn't happen + return DefWindowProc(wnd, message, wParam, lParam); + } + + switch (message) { + case WM_CLOSE: + (*env)->CallVoidMethod(env, window, windowClosedID); + DestroyWindow(wnd); + break; + + case WM_DESTROY: + (*env)->CallVoidMethod(env, window, windowDestroyedID); + break; + + // Windows does the translation between key codes and key chars by + // producing synthetic WM_CHAR messages in response to WM_KEYDOWN + // messages. The Java level contains the state machine to assemble + // these multiple events into a single event. + case WM_CHAR: + // NOTE that the (1 << 31) bit is meaningless regardless of + // what the docs for WM_CHAR say; we never receive a WM_CHAR + // message in response to translating a WM_KEYUP message + (*env)->CallVoidMethod(env, window, sendKeyEventID, + (jint) EVENT_KEY_PRESSED, + // FIXME: need to interpret the key events in order to compute the modifiers + (jint) 0, + (jint) -1, + (jchar) wParam); + useDefWindowProc = 1; + break; + + case WM_KEYDOWN: + // FIXME: need to interpret the key events in order to compute the modifiers + (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_PRESSED, + (jint) 0, (jint) wParam, (jchar) -1); + useDefWindowProc = 1; + break; + + case WM_KEYUP: + // FIXME: need to interpret the key events in order to compute the modifiers + (*env)->CallVoidMethod(env, window, sendKeyEventID, (jint) EVENT_KEY_RELEASED, + (jint) 0, (jint) wParam, (jchar) -1); + useDefWindowProc = 1; + break; + + case WM_SIZE: + GetClientRect(wnd, &rc); + (*env)->CallVoidMethod(env, window, sizeChangedID, (jint) rc.right, (jint) rc.bottom); + break; + + // FIXME: define constants for the mouse buttons and modifiers + case WM_LBUTTONDOWN: + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (jint) wParam, (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 1); + useDefWindowProc = 1; + break; + + case WM_LBUTTONUP: + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + (jint) wParam, (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 1); + useDefWindowProc = 1; + break; + + case WM_MBUTTONDOWN: + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (jint) wParam, (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 2); + useDefWindowProc = 1; + break; + + case WM_MBUTTONUP: + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + (jint) wParam, (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 2); + useDefWindowProc = 1; + break; + + case WM_RBUTTONDOWN: + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (jint) wParam, (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 3); + useDefWindowProc = 1; + break; + + case WM_RBUTTONUP: + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + (jint) wParam, (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 3); + useDefWindowProc = 1; + break; + + case WM_MOUSEMOVE: + (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + (jint) wParam, (jint) LOWORD(lParam), (jint) HIWORD(lParam), (jint) 0); + useDefWindowProc = 1; + break; + + // FIXME: generate EVENT_MOUSE_ENTERED, EVENT_MOUSE_EXITED + default: + useDefWindowProc = 1; + } + + if (useDefWindowProc) + return DefWindowProc(wnd, message, wParam, lParam); + return 0; +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initIDs + (JNIEnv *env, jclass clazz) +{ + sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); + positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); + windowClosedID = (*env)->GetMethodID(env, clazz, "windowClosed", "()V"); + windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); + sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIII)V"); + sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + if (sizeChangedID == NULL || + positionChangedID == NULL || + windowClosedID == NULL || + windowDestroyedID == NULL || + sendMouseEventID == NULL || + sendKeyEventID == NULL) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: LoadLibraryW + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_LoadLibraryW + (JNIEnv *env, jclass clazz, jstring dllName) +{ + jchar* _dllName = GetNullTerminatedStringChars(env, dllName); + HMODULE lib = LoadLibraryW(_dllName); + free(_dllName); + return (jlong) (intptr_t) lib; +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: RegisterWindowClass + * Signature: (Ljava/lang/String;J)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_RegisterWindowClass + (JNIEnv *env, jclass clazz, jstring appName, jlong hInstance) +{ + WNDCLASS* wc; +#ifndef UNICODE + const char* _appName = NULL; +#endif + + wc = calloc(1, sizeof(WNDCLASS)); + /* register class */ + wc->style = CS_HREDRAW | CS_VREDRAW; + wc->lpfnWndProc = (WNDPROC)wndProc; + wc->cbClsExtra = 0; + wc->cbWndExtra = 0; + /* This cast is legal because the HMODULE for a DLL is the same as + its HINSTANCE -- see MSDN docs for DllMain */ + wc->hInstance = (HINSTANCE) hInstance; + wc->hIcon = NULL; + wc->hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); + wc->hbrBackground = GetStockObject(BLACK_BRUSH); + wc->lpszMenuName = NULL; +#ifdef UNICODE + wc->lpszClassName = GetNullTerminatedStringChars(env, appName); +#else + _appName = (*env)->GetStringUTFChars(env, appName, NULL); + wc->lpszClassName = strdup(_appName); + (*env)->ReleaseStringUTFChars(env, appName, _appName); +#endif + if (!RegisterClass(wc)) { + free(wc); + return 0; + } + return (jlong) (intptr_t) wc; +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: CreateWindow + * Signature: (Ljava/lang/String;JJIIII)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_CreateWindow + (JNIEnv *env, jobject obj, jstring windowClassName, jlong hInstance, jlong visualID, + jint jx, jint jy, jint defaultWidth, jint defaultHeight) +{ + const TCHAR* wndClassName = NULL; + DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + int x=(int)jx, y=(int)jy; + int width=(int)defaultWidth, height=(int)defaultHeight; + HWND window = NULL; + +#ifdef UNICODE + wndClassName = GetNullTerminatedStringChars(env, windowClassName); +#else + wndClassName = (*env)->GetStringUTFChars(env, windowClassName, NULL); +#endif + + // FIXME: until we have valid values coming down from the + // application code, use some default values +#ifdef UNDER_CE + // Prefer to not have any surprises in the initial window sizing or placement + width = GetSystemMetrics(SM_CXSCREEN); + height = GetSystemMetrics(SM_CYSCREEN); + x = y = 0; +#else + x = CW_USEDEFAULT; + y = 0; + windowStyle |= WS_OVERLAPPEDWINDOW; +#endif + + (void) visualID; // FIXME: use the visualID .. + + window = CreateWindow(wndClassName, wndClassName, windowStyle, + x, y, width, height, + NULL, NULL, + (HINSTANCE) hInstance, + NULL); +#ifdef UNICODE + free((void*) wndClassName); +#else + (*env)->ReleaseStringUTFChars(env, windowClassName, wndClassName); +#endif + + if (window != NULL) { +#ifdef UNDER_CE + SetWindowLong(window, GWL_USERDATA, (intptr_t) (*env)->NewGlobalRef(env, obj)); +#else + SetWindowLongPtr(window, GWLP_USERDATA, (intptr_t) (*env)->NewGlobalRef(env, obj)); +#endif + ShowWindow(window, SW_SHOWNORMAL); + } + return (jlong) (intptr_t) window; +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: setVisible0 + * Signature: (JZ)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_setVisible0 + (JNIEnv *_env, jclass clazz, jlong window, jboolean visible) +{ + HWND hWnd = (HWND) (intptr_t) window; + if (visible) { + ShowWindow(hWnd, SW_SHOW); + } else { + ShowWindow(hWnd, SW_HIDE); + } +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: DispatchMessages + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_DispatchMessages + (JNIEnv *_env, jclass clazz, jlong window, jint eventMask) +{ + int i = 0; + MSG msg; + BOOL gotOne; + + env = _env; + + if(eventMask<0) { + eventMask *= -1; + /* FIXME: re-select input mask + long xevent_mask_key = 0; + long xevent_mask_ptr = 0; + long xevent_mask_win = 0; + if( 0 != ( eventMask & EVENT_MOUSE ) ) { + xevent_mask_ptr |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask; + } + if( 0 != ( eventMask & EVENT_KEY ) ) { + xevent_mask_key |= KeyPressMask|KeyReleaseMask; + } + if( 0 != ( eventMask & EVENT_WINDOW ) ) { + xevent_mask_win |= ExposureMask; + } + + XSelectInput(dpy, w, xevent_mask_win|xevent_mask_key|xevent_mask_ptr); + */ + } + + // Periodically take a break + do { + gotOne = PeekMessage(&msg, (HWND) window, 0, 0, PM_REMOVE); + if (gotOne) { + ++i; + switch (msg.message) { + case WM_CLOSE: + case WM_DESTROY: + case WM_SIZE: + if( ! ( eventMask & EVENT_WINDOW ) ) { + continue; + } + break; + + case WM_CHAR: + case WM_KEYDOWN: + case WM_KEYUP: + if( ! ( eventMask & EVENT_KEY ) ) { + continue; + } + break; + + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MOUSEMOVE: + if( ! ( eventMask & EVENT_MOUSE ) ) { + continue; + } + break; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } while (gotOne && i < 100); + + env = NULL; +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: setSize0 + * Signature: (JII)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_setSize0 + (JNIEnv *env, jobject obj, jlong window, jint width, jint height) +{ + RECT r; + HWND w = (HWND) window; + GetWindowRect(w, &r); + MoveWindow(w, r.left, r.top, width, height, TRUE); + (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: setFullScreen0 + * Signature: (JZ)Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_setFullScreen0 + (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen) +{ +#ifdef UNDER_CE + int screenWidth; + int screenHeight; + HWND win = (HWND) window; + + if (fullscreen) { + screenWidth = GetSystemMetrics(SM_CXSCREEN); + screenHeight = GetSystemMetrics(SM_CYSCREEN); + /* First, hide all of the shell parts */ + SHFullScreen(win, + SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON); + MoveWindow(win, 0, 0, screenWidth, screenHeight, TRUE); + (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) screenWidth, (jint) screenHeight); + } else { + RECT rc; + int width, height; + + /* First, show all of the shell parts */ + SHFullScreen(win, + SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON); + /* Now resize the window to the size of the work area */ + SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, FALSE); + width = rc.right - rc.left; + height = rc.bottom - rc.top; + MoveWindow(win, rc.left, rc.top, width, height, TRUE); + (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); + } + return JNI_TRUE; +#else + /* For the time being, full-screen not supported on the desktop */ + return JNI_FALSE; +#endif +} diff --git a/src/native/newt/X11Window.c b/src/native/newt/X11Window.c new file mode 100755 index 000000000..3f08b5d49 --- /dev/null +++ b/src/native/newt/X11Window.c @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> + +#include "com_sun_javafx_newt_x11_X11Window.h" + +#include "EventListener.h" +#include "MouseEvent.h" +#include "KeyEvent.h" + +// #define VERBOSE_ON 1 + +#ifdef VERBOSE_ON + +static void _dumpVisualInfo(const char * msg, XVisualInfo *pVisualQuery) { + if(pVisualQuery!=NULL) { + fprintf(stderr, "%s: screen %d, visual: %p, visual-id: 0x%X, depth: %d, class %d, cmap sz: %d, bpp: 3x%d, rgb 0x%X 0x%X 0x%X\n", + msg, + pVisualQuery->screen, + pVisualQuery->visual, + (int)pVisualQuery->visualid, + pVisualQuery->depth, + pVisualQuery->class, + pVisualQuery->colormap_size, + pVisualQuery->bits_per_rgb, + (int)pVisualQuery->red_mask, + (int)pVisualQuery->green_mask, + (int)pVisualQuery->blue_mask + ); + } else { + fprintf(stderr, "%s: NULL XVisualInfo\n", msg); + } +} + +#define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b)) + +#else + +#define DUMP_VISUAL_INFO(a,b) + +#endif + +/** + * Display + */ + +/* + * Class: com_sun_javafx_newt_x11_X11Display + * Method: CreateDisplay + * Signature: (Ljava/lang/String;)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Display_CreateDisplay + (JNIEnv *env, jobject obj, jstring displayName) +{ + Display * dpy = NULL; + const char * _displayName = NULL; + if(displayName!=0) { + _displayName = (*env)->GetStringUTFChars(env, displayName, 0); + } + dpy = XOpenDisplay(_displayName); + if(dpy==NULL) { + fprintf(stderr, "couldn't open display connection..\n"); + } + return (jlong) (intptr_t) dpy; +} + +/** + * Screen + */ + +/* + * Class: com_sun_javafx_newt_x11_X11Screen + * Method: GetScreen + * Signature: (JI)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Screen_GetScreen + (JNIEnv *env, jobject obj, jlong display, jint screen_index) +{ + Display * dpy = (Display *)(intptr_t)display; + Screen * scrn= NULL; + if(dpy==NULL) { + fprintf(stderr, "[GetScreen] invalid display connection..\n"); + return 0; + } + scrn = ScreenOfDisplay(dpy,screen_index); + if(scrn==NULL) { + scrn=DefaultScreenOfDisplay(dpy); + } + if(scrn==NULL) { + fprintf(stderr, "couldn't get screen ..\n"); + } + return (jlong) (intptr_t) scrn; +} + +/** + * Window + */ + +static jmethodID sizeChangedID = NULL; +static jmethodID positionChangedID = NULL; +static jmethodID windowClosedID = NULL; +static jmethodID windowDestroyedID = NULL; +static jmethodID windowCreatedID = NULL; +static jmethodID sendMouseEventID = NULL; +static jmethodID sendKeyEventID = NULL; + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Window_initIDs + (JNIEnv *env, jclass clazz) +{ + sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); + positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); + windowClosedID = (*env)->GetMethodID(env, clazz, "windowClosed", "()V"); + windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); + windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(IJ)V"); + sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIII)V"); + sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + if (sizeChangedID == NULL || + positionChangedID == NULL || + windowClosedID == NULL || + windowDestroyedID == NULL || + windowCreatedID == NULL || + sendMouseEventID == NULL || + sendKeyEventID == NULL) { + return JNI_FALSE; + } + return JNI_TRUE; +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: CreateWindow + * Signature: (JJIJIIII)J + */ +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow + (JNIEnv *env, jobject obj, jlong display, jlong screen, jint screen_index, + jlong visualID, + jint x, jint y, jint width, jint height) +{ + Display * dpy = NULL; + Screen * scrn = NULL; + int scrn_idx = (int)screen_index; + Window windowParent = 0; + Window window = 0; + + XVisualInfo visualTemplate; + XVisualInfo *pVisualQuery = NULL; + Visual *visual = NULL; + int depth; + + XSetWindowAttributes xswa; + unsigned long attrMask; + + int n; + + dpy = (Display *)(intptr_t)display; + if(dpy==NULL) { + fprintf(stderr, "[CreateWindow] invalid display connection..\n"); + return 0; + } + + scrn = (Screen *)(intptr_t)screen; + if(scrn==NULL) { + fprintf(stderr, "invalid screen connection..\n"); + return 0; + } + + if(visualID>0) { + // try given VisualID on screen + memset(&visualTemplate, 0, sizeof(XVisualInfo)); + visualTemplate.screen = scrn_idx; + visualTemplate.visualid = (VisualID)visualID; + pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n); + DUMP_VISUAL_INFO("Given VisualID,ScreenIdx", pVisualQuery); + if(pVisualQuery!=NULL) { + visual = pVisualQuery->visual; + depth = pVisualQuery->depth; + visualID = pVisualQuery->visualid; + XFree(pVisualQuery); + pVisualQuery=NULL; + } +#ifdef VERBOSE_ON + fprintf(stderr, "trying given (screen %d, visualID: %d) found: %p\n", scrn_idx, (int)visualID, visual); +#endif + } + if (visual==NULL) + { + // try default .. + visual = XDefaultVisualOfScreen(scrn); + if(visual!=NULL) { + visualID = visual->visualid; + // try given VisualID on screen + memset(&visualTemplate, 0, sizeof(XVisualInfo)); + visualTemplate.screen = scrn_idx; + visualTemplate.visualid = (VisualID)visualID; + pVisualQuery = XGetVisualInfo(dpy, VisualIDMask|VisualScreenMask, &visualTemplate,&n); + DUMP_VISUAL_INFO("Given ScreenIdx, Default VisualID", pVisualQuery); + if(pVisualQuery!=NULL) { + visual = pVisualQuery->visual; + depth = pVisualQuery->depth; + visualID = pVisualQuery->visualid; + XFree(pVisualQuery); + pVisualQuery=NULL; + } else { + visual = NULL; + visualID = 0; + } +#ifdef VERBOSE_ON + fprintf(stderr, "default visual (screen %d, visualID: %d) found: %p\n", scrn_idx, (int)visualID, visual); +#endif + } + } + if (visual==NULL) + { + fprintf(stderr, "could not query any Visual, bail out!\n"); + return 0; + } + + if(pVisualQuery!=NULL) { + XFree(pVisualQuery); + pVisualQuery=NULL; + } + + windowParent = XRootWindowOfScreen(scrn); + + attrMask = (CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect); + memset(&xswa, 0, sizeof(xswa)); + xswa.override_redirect = True; + xswa.border_pixel = 0; + xswa.background_pixel = 0; + xswa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask; + xswa.colormap = XCreateColormap(dpy, + XRootWindow(dpy, scrn_idx), + visual, + AllocNone); + + window = XCreateWindow(dpy, + windowParent, + x, y, + width, height, + 0, // border width + depth, + InputOutput, + visual, + attrMask, + &xswa); + XClearWindow(dpy, window); + + (*env)->CallVoidMethod(env, obj, windowCreatedID, visualID, (jlong) window); + + return (jlong) window; +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: setVisible0 + * Signature: (JJZ)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_CloseWindow + (JNIEnv *env, jobject obj, jlong display, jlong window) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + + XUngrabPointer(dpy, CurrentTime); + XUngrabKeyboard(dpy, CurrentTime); + XSelectInput(dpy, w, 0); + XUnmapWindow(dpy, w); + XDestroyWindow(dpy, w); +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: setVisible0 + * Signature: (JJZ)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setVisible0 + (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean visible) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + if(visible==JNI_TRUE) { + XMapRaised(dpy, w); + + XSetInputFocus(dpy, w, RevertToNone, CurrentTime); + + XSync(dpy, False); + } else { + XUngrabPointer(dpy, CurrentTime); + XUngrabKeyboard(dpy, CurrentTime); + XSelectInput(dpy, w, 0); + XUnmapWindow(dpy, w); + } +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: DispatchMessages + * Signature: (JJI)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages + (JNIEnv *env, jobject obj, jlong display, jlong window, jint eventMask) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + + if(eventMask<0) { + long xevent_mask_key = 0; + long xevent_mask_ptr = 0; + long xevent_mask_win = 0; + eventMask *= -1; + if( 0 != ( eventMask & EVENT_MOUSE ) ) { + xevent_mask_ptr |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask; + } + if( 0 != ( eventMask & EVENT_KEY ) ) { + xevent_mask_key |= KeyPressMask|KeyReleaseMask; + } + if( 0 != ( eventMask & EVENT_WINDOW ) ) { + xevent_mask_win |= ExposureMask; + } + + XSelectInput(dpy, w, xevent_mask_win|xevent_mask_key|xevent_mask_ptr); + + if(0!=xevent_mask_ptr) { + XGrabPointer(dpy, w, True, xevent_mask_ptr, + GrabModeAsync, GrabModeAsync, w, None, CurrentTime); + } + if(0!=xevent_mask_key) { + XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); + } + + } + + // Periodically take a break + while( XPending(dpy)>0 ) { + XEvent evt; + KeySym keySym; + char keyChar; + char text[255]; + + XNextEvent(dpy, &evt); + + switch(evt.type) { + case ButtonPress: + case ButtonRelease: + case MotionNotify: + if( ! ( eventMask & EVENT_MOUSE ) ) { + continue; + } + break; + case KeyPress: + case KeyRelease: + if( ! ( eventMask & EVENT_KEY ) ) { + continue; + } + break; + case FocusIn: + case FocusOut: + case DestroyNotify: + case CreateNotify: + case VisibilityNotify: + if( ! ( eventMask & EVENT_WINDOW ) ) { + continue; + } + break; + } + + switch(evt.type) { + case ButtonPress: + if(evt.xbutton.window==w) { + (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (jint) evt.xbutton.state, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button); + } + break; + case ButtonRelease: + if(evt.xbutton.window==w) { + (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + (jint) evt.xbutton.state, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button); + } + break; + case MotionNotify: + if(evt.xmotion.window==w) { + (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + (jint) evt.xmotion.state, + (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0); + } + break; + case KeyPress: + if(evt.xkey.window==w) { + if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) { + keyChar=text[0]; + } else { + keyChar=0; + } + (*env)->CallVoidMethod(env, obj, sendKeyEventID, (jint) EVENT_KEY_PRESSED, + (jint) evt.xkey.state, + (jint) keySym, (jchar) keyChar); + } + break; + case KeyRelease: + if(evt.xkey.window==w) { + if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) { + keyChar=text[0]; + } else { + keyChar=0; + } + (*env)->CallVoidMethod(env, obj, sendKeyEventID, (jint) EVENT_KEY_RELEASED, + (jint) evt.xkey.state, + (jint) keySym, (jchar) keyChar); + } + break; + case FocusIn: + case FocusOut: + if(evt.xfocus.window==w) { + } + break; + case DestroyNotify: + if(evt.xdestroywindow.window==w) { + (*env)->CallVoidMethod(env, obj, windowDestroyedID); + } + break; + case CreateNotify: + if(evt.xcreatewindow.window==w) { + (*env)->CallVoidMethod(env, obj, windowCreatedID); + } + break; + case VisibilityNotify: + if(evt.xvisibility.window==w) { + } + break; + } + } +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: setSize0 + * Signature: (JJII)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setSize0 + (JNIEnv *env, jobject obj, jlong display, jlong window, jint width, jint height) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + XResizeWindow(dpy, w, (unsigned)width, (unsigned)height); + (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: setPosition0 + * Signature: (JJII)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setPosition0 + (JNIEnv *env, jobject obj, jlong display, jlong window, jint x, jint y) +{ + Display * dpy = (Display *) (intptr_t) display; + Window w = (Window)window; + XMoveWindow(dpy, w, (unsigned)x, (unsigned)y); + // (*env)->CallVoidMethod(env, obj, positionChangedID, (jint) width, (jint) height); +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: getDisplayWidth0 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_x11_X11Window_getDisplayWidth0 + (JNIEnv *env, jobject obj, jlong display, jint scrn_idx) +{ + Display * dpy = (Display *) (intptr_t) display; + return (jint) XDisplayWidth( dpy, scrn_idx); +} + +/* + * Class: com_sun_javafx_newt_x11_X11Window + * Method: getDisplayHeight0 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_x11_X11Window_getDisplayHeight0 + (JNIEnv *env, jobject obj, jlong display, jint scrn_idx) +{ + Display * dpy = (Display *) (intptr_t) display; + return (jint) XDisplayHeight( dpy, scrn_idx); +} + + |