aboutsummaryrefslogtreecommitdiffstats
path: root/src/native/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2008-06-25 05:50:55 +0000
committerSven Gothel <[email protected]>2008-06-25 05:50:55 +0000
commitb02adebb3213e19aecfe84e6966e52976e5c09cf (patch)
tree6435fdac5e3ccad90ae1e96b684e56d79fb57bcf /src/native/newt
parent800c7da4656277810d579e76b74558434bb6467c (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.h9
-rw-r--r--src/native/newt/KeyEvent.h10
-rw-r--r--src/native/newt/MouseEvent.h13
-rwxr-xr-xsrc/native/newt/WindowsWindow.c479
-rwxr-xr-xsrc/native/newt/X11Window.c530
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);
+}
+
+