Import Waterfall under the directory pluggable-jvm.

git-svn-id: svn://10.0.0.236/trunk@94499 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
edburns%acm.org
2001-05-10 18:12:45 +00:00
parent 6e6831a636
commit f3221c6814
189 changed files with 32534 additions and 0 deletions

View File

@@ -0,0 +1,668 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: host.cpp,v 1.1.1.1 2001-05-10 18:12:33 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include <stdio.h>
#include <jvmp.h>
#include <string.h>
#include <stdlib.h> // to getenv()
#include <gtk/gtk.h>
#ifdef XP_UNIX
#include <unistd.h> // to sleep()
#include <pthread.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <gdk/gdkx.h>
#define MUTEX_T pthread_mutex_t
#define MUTEX_CREATE(m) m = (MUTEX_T*)malloc(sizeof(MUTEX_T)); pthread_mutex_init(m, NULL)
#define MUTEX_LOCK(m) pthread_mutex_lock(m)
#define MUTEX_UNLOCK(m) pthread_mutex_unlock(m)
#define COND_T pthread_cond_t
#define COND_CREATE(c) c = (COND_T*)malloc(sizeof(COND_T)); pthread_cond_init(c, NULL)
#define dll_t void*
#define DL_MODE RTLD_NOW
#define FILE_SEPARATOR "/"
#define PATH_SEPARATOR ":"
#define DL_MODE RTLD_NOW
// gcc specific
#define DEBUG(x...) fprintf(stderr, "host: "x)
#endif
#ifdef XP_WIN32
#include <windows.h>
#include <gdk\win32\gdkwin32.h>
#define MUTEX_T CRITICAL_SECTION
#define dll_t HINSTANCE
#define DL_MODE 0
#define FILE_SEPARATOR "\\"
#define PATH_SEPARATOR ";"
#define DL_MODE 0
#define DEBUG
#endif
JVMP_GetPlugin_t fJVMP_GetPlugin;
// XXX: JVMP_CallingContext is per-thread structure, but almost all calls here
// goes from the "main" GTK thread.
JVMP_CallingContext* ctx = NULL;
JavaVM* jvm = NULL;
JNIEnv* env = NULL;
JavaVMInitArgs vm_args;
GtkWidget* topLevel = NULL;
JVMP_RuntimeContext* jvmp_context = NULL;
jint g_wid = 0; // ID of topLevel inside JVM
jint g_oid = 0; // ID of Java peer object
jint g_eid = 0; // ID of test extension
jint g_mid = 0; // ID of monitor object
char g_errbuf[JVMP_MAXERRORLENGTH];
#ifdef XP_UNIX // yet
MUTEX_T* g_mutex = NULL;
COND_T* g_cond = NULL;
JVMP_Monitor* g_mon = NULL;
#endif
#ifdef XP_UNIX
dll_t LoadDLL(const char* filename, int mode)
{
return dlopen(filename, mode);
}
void* FindSymbol(dll_t dll, const char* sym)
{
return dlsym(dll, sym);
}
int UnloadDLL(dll_t dll)
{
return dlclose(dll);
}
const char* LastDLLErrorString()
{
return dlerror();
}
#endif
#ifdef XP_WIN32
dll_t LoadDLL(const char* filename, int mode)
{
return LoadLibrary(filename);
}
void* FindSymbol(dll_t dll, const char* sym)
{
return GetProcAddress(dll, sym);
}
int UnloadDLL(dll_t dll)
{
// XXX: fix me
return 0;
}
const char* LastDLLErrorString()
{
static LPVOID lpMsgBuf = NULL;
free(lpMsgBuf);
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
return (const char*)lpMsgBuf;
}
#endif
jint loadPluginLibrary(void** h) {
dll_t handle;
char *path, *home;
#ifdef XP_UNIX
#ifdef JVMP_USE_SHM
char* filename="libjvmp_shm.so";
#else
char* filename="libjvmp.so";
#endif
#endif
#ifdef XP_WIN32
char* filename="jvmp.dll";
#endif
home = getenv("WFHOME");
if (!home) return JNI_FALSE;
path = (char*)malloc(strlen(home)+strlen(filename)+2);
sprintf(path, "%s"FILE_SEPARATOR"%s", home, filename);
handle = LoadDLL(path, DL_MODE);
if (!handle) {
fprintf(stderr, "dlopen: %s\n", LastDLLErrorString());
return JNI_FALSE;
};
fJVMP_GetPlugin =
(JVMP_GetPlugin_t)FindSymbol(handle, "JVMP_GetPlugin");
if (!fJVMP_GetPlugin) {
fprintf(stderr, "dlsym:%s\n", LastDLLErrorString());
return JNI_FALSE;
};
if ((*fJVMP_GetPlugin)(&jvmp_context) != JNI_TRUE)
{
fprintf(stderr, "JVMP_GetPlugin failed\n");
return JNI_FALSE;
}
(*h) = handle;
return JNI_TRUE;
}
jint initJVM(JavaVM** jvm, JNIEnv** env, JavaVMInitArgs* pvm_args) {
pvm_args->version = JNI_VERSION_1_2;
jint res = (jvmp_context->JVMP_GetRunningJVM)(&ctx, pvm_args, JNI_TRUE);
if (res == JNI_TRUE) {
*env = ctx->env;
*jvm = jvmp_context->jvm;
fprintf(stderr, "++++++JVM successfully obtained.\n");
return JNI_TRUE;
} else {
fprintf(stderr, "------Failed to obtain JVM.\n");
return JNI_FALSE;
};
};
void b1_handler(GtkWidget *widget)
{
void* handle;
if (!loadPluginLibrary(&handle)) return;
memset(&vm_args, 0, sizeof(vm_args));
if (!initJVM(&jvm, &env, &vm_args)) {
return;
};
};
void b2_handler(GtkWidget *widget) {
if (!jvmp_context) return;
if (g_eid) (jvmp_context->JVMP_UnregisterExtension)(ctx, g_eid);
(jvmp_context->JVMP_StopJVM)(ctx);
};
void b4_handler(GtkWidget *widget) {
JVMP_DrawingSurfaceInfo w;
if (!jvmp_context) return;
jint containerWindowID = (jint) GDK_WINDOW_XWINDOW(topLevel->window);
w.window = (JPluginWindow *)containerWindowID;
#ifdef XP_UNIX
gdk_flush();
#endif
w.x = 0;
w.y = 0;
w.width = topLevel->allocation.width;
w.height = topLevel->allocation.height;
if ((jvmp_context->JVMP_RegisterWindow)(ctx, &w, &g_wid) != JNI_TRUE) {
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr, "Can\'t register window: %s\n", g_errbuf);
return;
};
fprintf(stderr, "Registed our GTK window with ID %d\n", (int)g_wid);
}
void b5_handler(GtkWidget *widget) {
if (!jvmp_context || !g_oid) return;
if ((jvmp_context->JVMP_SendEvent)
(ctx, g_oid, 20, (jlong) g_wid, JVMP_PRIORITY_NORMAL) == JNI_FALSE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr, "cannot send event to %d: %s\n",
(int)g_oid, g_errbuf);
return;
}
fprintf(stderr, "Event sent to %d\n", (int)g_oid);
}
void b6_handler(GtkWidget *widget) {
if (!jvmp_context) return;
if ((jvmp_context->JVMP_UnregisterWindow)(ctx, g_wid) != JNI_TRUE) {
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr, "Can\'t unregister window: %s\n", g_errbuf);
return;
};
fprintf(stderr, "Unregisted our GTK window with ID %d\n", (int)g_wid);
}
void b9_handler(GtkWidget *widget) {
if (!jvmp_context) return;
JVMP_PluginDescription* d;
if ((jvmp_context->JVMP_GetDescription)(&d) != JNI_TRUE)
{
fprintf(stderr, "Cannot get description\n");
return;
}
fprintf(stderr,
"Waterfall plugin info:\n"
"JVM vendor=\"%s\"\n"
"JVM version=\"%s\"\n"
"JVM kind=\"%s\"\n"
"JVMP version=\"%s\"\n"
"platform=\"%s\"\n"
"arch=\"%s\"\n"
"vendor data=\"%p\"\n",
d->vendor, d->jvm_version, d->jvm_kind, d->jvmp_version,
d->platform, d->arch, d->vendor_data);
}
#ifdef XP_UNIX
void* thread_func(void* arg) {
jint id;
JVMP_CallingContext* myctx;
if ((jvmp_context->JVMP_GetCallingContext)(&myctx) != JNI_TRUE)
return NULL;
if ((jvmp_context->JVMP_AttachCurrentThread)(myctx, &id) != JNI_TRUE)
fprintf(stderr, "Can\'t attach thread\n");
else
fprintf(stderr, "Attached with ID %d\n", (int)id);
sleep(10);
// this function MUST be called by any function performed JVMP_GetCallingContext
// or JVMP_AttachCurrentThread. as otherwise structures inside of Waterfall
// not cleaned up. Also it destroys myctx
(jvmp_context->JVMP_DetachCurrentThread)(myctx);
return NULL;
}
#endif
void b8_handler(GtkWidget *widget) {
#ifdef XP_UNIX
pthread_t tid;
if (!jvmp_context) return;
// allocate in heap to prevent invalid deallocation
pthread_create(&tid, NULL, &thread_func, NULL);
pthread_detach(tid);
#endif
}
void registerMyExtension()
{
#ifdef XP_UNIX
const char* ext = "./libwf_test.so";
#endif
#ifdef XP_WIN32
const char* ext = "wf_test.dll";
#endif
if ((jvmp_context->JVMP_RegisterExtension)
(ctx, ext, &g_eid, 0) != JNI_TRUE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr, "extension not registred: %s\n", g_errbuf);
return;
}
fprintf(stderr, "Registered extension with ID: %d\n", (int)g_eid);
if ((jvmp_context->JVMP_SendExtensionEvent)(ctx, g_eid,
13, 0, JVMP_PRIORITY_NORMAL) == JNI_FALSE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr, "cannot send extension event: %s\n", g_errbuf);
return;
}
fprintf(stderr, "sent event 13 to newly registred extension\n");
}
void b10_handler(GtkWidget *widget) {
if (!jvmp_context) return;
registerMyExtension();
}
int newPrincipalsFromStrings(jbyte** *resprin, jint* *reslen, jint num, ...)
{
jint* prins_len;
jbyte* *prins;
char* str;
jint i, len;
va_list ap;
prins_len = (jint*)malloc(num*sizeof(jint));
if (!prins_len) return 0;
prins = (jbyte**)malloc(num*sizeof(jbyte**));
if (!prins) return 0;
va_start(ap, num);
for (i=0; i<num; i++)
{
str = va_arg(ap, char*);
len = str ? strlen(str) : 0;
prins[i] = (jbyte*)malloc(len);
if (!prins[i]) return 0;
prins_len[i] = len;
/* not copy last 0 */
memcpy(prins[i], str, len);
}
va_end(ap);
*resprin = prins;
*reslen = prins_len;
return 1;
}
int deletePrincipals(jbyte** prins, jint* plen, jint len)
{
int i;
for (i=0; i<len; i++)
free(prins[i]);
free(prins);
free(plen);
return 1;
}
void b12_handler(GtkWidget *widget) {
#ifdef XP_UNIX
static int registered = 0;
int millis = 20000;
jlong end;
struct timeval tv, tv1;
struct timespec ts;
long diff;
if (!jvmp_context) return;
if (!registered)
{
if ((jvmp_context->JVMP_RegisterMonitorObject)(ctx, g_mon, &g_mid) != JNI_TRUE)
{
DEBUG("couldn\'t register monitor object\n");
return;
}
registered = 1;
}
if (g_oid) {
// now post message to Java peer with request to start thread that will
// try to acquire the same mutex and wake up us on common native monitor.
// Not perfect, as possible race condition -
// if event handled too fast, but OK for testing
(jvmp_context->JVMP_PostEvent)
(ctx, g_oid, 666, (jlong)g_mid, JVMP_PRIORITY_HIGH);
}
DEBUG("locking mutex\n");
MUTEX_LOCK(g_mutex);
DEBUG("LOCKED. Sleeping no more %d millis, waiting until Java thread will wake up us\n", millis);
gettimeofday(&tv, 0);
end = ((jlong)tv.tv_sec)*1000 + ((jlong)tv.tv_usec)/1000 + millis;
ts.tv_sec = end / 1000;
ts.tv_nsec = (end % 1000) * 1000000;
/* pthread_cond_timedwait() reacquires mutex, so just changing
millis on Java side to value greater than millis wouldn't
force this call to complete earlier. */
pthread_cond_timedwait(g_cond, g_mutex, &ts);
gettimeofday(&tv1, 0);
MUTEX_UNLOCK(g_mutex);
diff = (tv1.tv_sec-tv.tv_sec)*1000 + (tv1.tv_usec-tv.tv_usec)/1000;
DEBUG("mutex unlocked after %ld millis\n", diff);
#endif
}
void b11_handler(GtkWidget *widget) {
static int onoff = 0;
if (!jvmp_context) return;
onoff = !onoff;
if (onoff)
{
if ((jvmp_context->JVMP_CreatePeer)(ctx,
"@sun.com/wf/tests/testextension;1",
0,
&g_oid) != JNI_TRUE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr,
"Cannot create new peer using this extension: %s\n",
g_errbuf);
return;
}
fprintf(stderr, "created peer witd id %d\n", (int)g_oid);
}
else
{
if ((jvmp_context->JVMP_DestroyPeer)(ctx, g_oid) != JNI_TRUE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr,
"Cannot remove peer: %s\n", g_errbuf);
return;
}
fprintf(stderr, "removed peer witd id %d\n", (int)g_oid);
}
}
void b13_handler(GtkWidget *widget) {
static int onoff = 0;
if (!jvmp_context) return;
onoff = (onoff == 0) ? 1 : 0;
if ((jvmp_context->JVMP_PostSysEvent)
(ctx, JVMP_CMD_CTL_CONSOLE, (jlong)onoff, JVMP_PRIORITY_NORMAL) == JNI_FALSE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr,
"Cannot send system event: %s\n", g_errbuf);
return;
}
}
void b7_handler(GtkWidget *widget) {
JVMP_SecurityCap cap;
static int onoff = 0;
if (!jvmp_context) return;
onoff = !onoff;
JVMP_FORBID_ALL_CAPS(cap);
JVMP_ALLOW_CAP(cap, JVMP_CAP_SYS_SYSTEM);
JVMP_ALLOW_CAP(cap, JVMP_CAP_SYS_EVENT);
JVMP_ALLOW_CAP(cap, JVMP_CAP_SYS_SYSEVENT);
if (onoff)
{
jbyte** prins;
jint pnum = 2;
jint* plen;
if (!newPrincipalsFromStrings(&prins, &plen,
pnum, "CAPS", "DUMMY"))
return;
if ((jvmp_context->JVMP_EnableCapabilities)
(ctx, &cap, pnum, plen, prins) != JNI_TRUE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr, "Can\'t enable caps: %s\n", g_errbuf);
return;
};
deletePrincipals(prins, plen, pnum);
}
else
{
if ((jvmp_context->JVMP_DisableCapabilities)
(ctx, &cap) != JNI_TRUE)
{
jvmp_context->JVMP_GetLastErrorString(ctx, g_errbuf);
fprintf(stderr, "Can\'t disable cap: %s\n", g_errbuf);
return;
};
}
fprintf(stderr, "Capabilities JVMP_CAP_SYS_SYSTEM and JVMP_CAP_SYS_EVENT triggered to %s\n",
onoff ? "ON" : "OFF");
}
GtkWidget* initGTKStuff(int *argc, char ***argv) {
// fprintf(stderr,"explicit threads init %d\n", XInitThreads());
gtk_init(argc, argv);
/* Create a new window */
GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Java Plugin Host");
/* Here we connect the "destroy" event to a signal handler */
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
gtk_widget_set_usize(window, 300, 400);
/* Sets the border width of the window. */
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Create a Frame */
GtkWidget* frame = gtk_frame_new(NULL);
/* Set the style of the frame */
gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
gtk_container_add(GTK_CONTAINER(window), frame);
/////////
gtk_signal_connect(GTK_OBJECT(window), "destroy",
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);
gtk_signal_connect(GTK_OBJECT(window), "delete-event",
GTK_SIGNAL_FUNC(gtk_false),
NULL);
/* Button initialization */
GtkWidget* button1 = gtk_button_new_with_label ("Start JVM");
GtkWidget* button2 = gtk_button_new_with_label ("Stop JVM");
GtkWidget* button3 = gtk_button_new_with_label ("Close application");
GtkWidget* button4 = gtk_button_new_with_label ("Register native window");
GtkWidget* button5 = gtk_button_new_with_label ("Test registered window");
GtkWidget* button6 = gtk_button_new_with_label ("Unregister window");
GtkWidget* button7 = gtk_button_new_with_label ("Enable/Disable system capabilities");
GtkWidget* button8 = gtk_button_new_with_label ("Attach new native thread");
GtkWidget* button9 = gtk_button_new_with_label ("Get WF description");
GtkWidget* button10 = gtk_button_new_with_label ("Register test extension");
GtkWidget* button11 = gtk_button_new_with_label ("Create/Remove test peer");
GtkWidget* button12 = gtk_button_new_with_label ("Test Java/native locking ability");
GtkWidget* button13 = gtk_button_new_with_label ("Show/hide Java console");
gtk_signal_connect (GTK_OBJECT (button1), "clicked",
GTK_SIGNAL_FUNC (b1_handler), NULL);
gtk_signal_connect (GTK_OBJECT (button2), "clicked",
GTK_SIGNAL_FUNC (b2_handler), NULL);
gtk_signal_connect_object (GTK_OBJECT (button3), "clicked",
GTK_SIGNAL_FUNC (gtk_main_quit),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button4), "clicked",
GTK_SIGNAL_FUNC (b4_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button5), "clicked",
GTK_SIGNAL_FUNC (b5_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button6), "clicked",
GTK_SIGNAL_FUNC (b6_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button7), "clicked",
GTK_SIGNAL_FUNC (b7_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button8), "clicked",
GTK_SIGNAL_FUNC (b8_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button9), "clicked",
GTK_SIGNAL_FUNC (b9_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button10), "clicked",
GTK_SIGNAL_FUNC (b10_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button11), "clicked",
GTK_SIGNAL_FUNC (b11_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button12), "clicked",
GTK_SIGNAL_FUNC (b12_handler),
GTK_OBJECT (window));
gtk_signal_connect_object (GTK_OBJECT (button13), "clicked",
GTK_SIGNAL_FUNC (b13_handler),
GTK_OBJECT (window));
GtkWidget* vbox1 = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox1), button1, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button2, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button13, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button10, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button4, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button6, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button7, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button11, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button5, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button8, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button9, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button12, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox1), button3, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(frame), vbox1);
///////////
gtk_widget_show(button1);
gtk_widget_show(button2);
gtk_widget_show(button3);
gtk_widget_show(button4);
gtk_widget_show(button5);
gtk_widget_show(button6);
gtk_widget_show(button7);
gtk_widget_show(button8);
gtk_widget_show(button9);
gtk_widget_show(button10);
gtk_widget_show(button11);
gtk_widget_show(button12);
gtk_widget_show(button13);
gtk_widget_show(vbox1);
gtk_widget_show(frame);
/* Display the window */
gtk_widget_show (window);
/* another window to play with JDK */
GtkWidget* window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize(window1, 300, 300);
GtkWidget* frame1 = gtk_frame_new(NULL);
gtk_frame_set_shadow_type( GTK_FRAME(frame1), GTK_SHADOW_ETCHED_OUT);
gtk_container_add(GTK_CONTAINER(window1), frame1);
gtk_widget_show (frame1);
gtk_widget_show (window1);
topLevel = window1;
return window1;
}
int main(int argc, char** argv) {
initGTKStuff(&argc, &argv);
// this stuff works only on unix yet
#ifdef XP_UNIX
MUTEX_CREATE(g_mutex);
COND_CREATE(g_cond);
JVMP_Monitor mon = JVMP_MONITOR_INITIALIZER(g_mutex, g_cond);
g_mon = &mon;
#endif
gtk_main();
return 0;
};

View File

@@ -0,0 +1,114 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: test_extension.c,v 1.1.1.1 2001-05-10 18:12:34 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include "jvmp.h"
#include <stdlib.h>
#include <string.h>
/* Extension parameters */
static const char* WFCID = "@sun.com/wf/tests/testextension;1";
static const jint WFExtVersion = 1;
static JVMP_SecurityCap g_moz_caps;
static JVMP_SecurityCap g_moz_cap_mask;
/* range of used capabilities */
#define MOZ_CAPS_LOW 101
#define MOZ_CAPS_HIGH 105
static JVMP_ExtDescription g_Description =
{
"Sun", /* vendor */
"1.0", /* version */
"Waterfall test extension", /* description */
PLATFORM, /* platform */
ARCH, /* architecture */
"GPL", /* license */
NULL /* vendor data */
};
/* extension API implementation */
static jint JNICALL JVMPExt_Init(jint side)
{
int i;
JVMP_FORBID_ALL_CAPS(g_moz_caps);
JVMP_ALLOW_ALL_CAPS(g_moz_cap_mask);
for (i=MOZ_CAPS_LOW; i <= MOZ_CAPS_HIGH; i++)
JVMP_ALLOW_CAP(g_moz_caps, i);
return JNI_TRUE;
}
static jint JNICALL JVMPExt_Shutdown()
{
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetExtInfo(const char* *pCID,
jint *pVersion,
JVMP_ExtDescription* *pDesc)
{
*pCID = WFCID;
*pVersion = WFExtVersion;
if (pDesc) *pDesc = &g_Description;
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetBootstrapClass(char* *bootstrapClassPath,
char* *bootstrapClassName)
{
/* should be defined at installation time */
*bootstrapClassPath = "";
*bootstrapClassName = "sun.jvmp.test.TestPeerFactory";
return JNI_TRUE;
}
static jint JNICALL JVMPExt_ScheduleRequest(JVMP_ShmRequest* req, jint local)
{
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetCapsRange(JVMP_SecurityCap* caps,
JVMP_SecurityCap* sh_mask)
{
if ((caps == NULL) || (sh_mask == NULL)) return JNI_FALSE;
memcpy(caps, &g_moz_caps, sizeof(JVMP_SecurityCap));
memcpy(sh_mask, &g_moz_cap_mask, sizeof(JVMP_SecurityCap));
return JNI_TRUE;
}
static JVMP_Extension JVMP_Ext =
{
&JVMPExt_Init,
&JVMPExt_Shutdown,
&JVMPExt_GetExtInfo,
&JVMPExt_GetBootstrapClass,
&JVMPExt_ScheduleRequest,
&JVMPExt_GetCapsRange
};
JNIEXPORT jint JNICALL JVMP_GetExtension(JVMP_Extension** ext)
{
*ext = &JVMP_Ext;
return JNI_TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: jpthreads.c,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include "jpthreads.h"
#include <stdlib.h>
#ifdef _JVMP_PTHREADS
static pthread_key_t tid_key = (pthread_key_t) -1;
static int inited = 0;
static void cleanup(JVMP_Thread* thr)
{
pthread_t tid;
tid = pthread_self();
if (!thr || (pthread_t)(thr->handle) != tid)
{
fprintf(stderr, "ERROR: tid mismatch!!!!\n");
return;
}
free(thr);
}
JVMP_Thread* ThreadInfoFromPthread()
{
JVMP_Thread* thr = NULL;
if (!inited)
{
pthread_key_create(&tid_key, NULL);
inited = 1;
}
thr = pthread_getspecific(tid_key);
if (thr) return thr;
thr = (JVMP_Thread*)malloc(sizeof(JVMP_Thread));
thr->handle = (long)pthread_self();
thr->id = 0; /* not yet attached */
thr->state = 0; /* XXX: find out state using pthread calls */
thr->cleanup = &cleanup;
thr->data = NULL;
thr->ctx = NULL;
pthread_setspecific(tid_key, thr);
return thr;
}
#endif
#ifdef _JVMP_WIN32THREADS
static int inited = 0;
/* some ideas from JVM Win32 code - I have not so much experience
with low level Windows programming :( */
#define TLS_INVALID_INDEX 0xffffffffUL
static unsigned long tls_index = TLS_INVALID_INDEX;
static void cleanup(JVMP_Thread* thr)
{
unsigned long tid;
tid = (unsigned long)GetCurrentThread();
if (!thr || (unsigned long)(thr->handle) != tid)
{
fprintf(stderr, "ERROR: tid mismatch!!!!\n");
return;
}
free(thr);
}
JVMP_Thread* ThreadInfoFromWthread()
{
JVMP_Thread* thr = NULL;
if (!inited)
{
tls_index = TlsAlloc();
if (tls_index == TLS_INVALID_INDEX) {
fprintf(stderr, "ERROR: cannot create TLS\n");
return NULL;
}
inited = 1;
}
thr = TlsGetValue(tls_index);
if (thr) return thr;
thr = (JVMP_Thread*)malloc(sizeof(JVMP_Thread));
thr->handle = (long)GetCurrentThread();
thr->id = 0; /* not yet attached */
thr->state = 0; /* XXX: find out state using Win32 calls */
thr->cleanup = &cleanup;
thr->data = NULL;
thr->ctx = NULL;
TlsSetValue(tls_index, thr);
return thr;
}
#endif
#ifdef XP_UNIX
dll_t JVMP_LoadDLL(const char* filename, int mode)
{
return dlopen(filename, mode);
}
void* JVMP_FindSymbol(dll_t dll, const char* sym)
{
return dlsym(dll, sym);
}
int JVMP_UnloadDLL(dll_t dll)
{
return dlclose(dll);
}
const char* JVMP_LastDLLErrorString()
{
return dlerror();
}
#endif
#ifdef XP_WIN32
dll_t JVMP_LoadDLL(const char* filename, int mode)
{
return LoadLibrary(filename);
}
void* JVMP_FindSymbol(dll_t dll, const char* sym)
{
return GetProcAddress(dll, sym);
}
int JVMP_UnloadDLL(dll_t dll)
{
// XXX: fix me
return 0;
}
const char* JVMP_LastDLLErrorString()
{
static LPVOID lpMsgBuf = NULL;
free(lpMsgBuf);
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
return lpMsgBuf;
}
#endif

View File

@@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: jpthreads.h,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include "jvmp.h"
#ifdef XP_WIN32
#include <windows.h>
#endif
#ifdef XP_UNIX
#include <dlfcn.h>
#endif
#ifdef _JVMP_PTHREADS
#include <pthread.h>
JVMP_Thread* ThreadInfoFromPthread();
#define THIS_THREAD() ThreadInfoFromPthread()
#define MUTEX_T pthread_mutex_t
/* arguments are pointers */
#define MUTEX_CREATE(m) m = (MUTEX_T*)malloc(sizeof(MUTEX_T)); pthread_mutex_init(m, NULL)
#define MUTEX_LOCK(m) pthread_mutex_lock(m)
#define MUTEX_UNLOCK(m) pthread_mutex_unlock(m)
#define MUTEX_DESTROY(m) pthread_mutex_destroy(m); free(m)
#endif /* of #ifdef _JVMP_PTHREADS */
#ifdef _JVMP_WIN32THREADS
JVMP_Thread* ThreadInfoFromWthread();
#define THIS_THREAD() ThreadInfoFromWthread()
#define MUTEX_T CRITICAL_SECTION
/* arguments are pointers */
#define MUTEX_CREATE(m) m = (MUTEX_T*)malloc(sizeof(MUTEX_T)); InitializeCriticalSection(m)
#define MUTEX_LOCK(m) EnterCriticalSection(m)
#define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
#define MUTEX_DESTROY(m) free(m);
#endif /* of #ifdef _JVMP_WIN32THREADS */
#ifdef XP_UNIX
#define dll_t void*
#define DL_MODE RTLD_NOW
#define FILE_SEPARATOR "/"
#define PATH_SEPARATOR ":"
#endif
#ifdef XP_WIN32
#define dll_t HINSTANCE
#define DL_MODE 0
#define FILE_SEPARATOR "\\"
#define PATH_SEPARATOR ";"
#endif
/* DLL handling here */
dll_t JVMP_LoadDLL(const char* filename, int mode);
void* JVMP_FindSymbol(dll_t dll, const char* sym);
int JVMP_UnloadDLL(dll_t dll);
const char* JVMP_LastDLLErrorString();

View File

@@ -0,0 +1,145 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: XmHelper.c,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
/*
Note: this tiny DLL overrides some symbols to allow libXm to be
dynamically loaded _after_ libXt.
The only thing you should care about is proper alignment:
"struct dummy_struct_t" should have the same binary layout as
VendorShellClassRec - i.e. use the same alignments as X uses.
On Solaris libawt.so does explicit check of name of library
where vendorShellWidgetClass defined, so this DLL should be called smth like
Helper.libXm.so.4. Stupid dog.....
Dedicated to Lyola.
Compile
gcc -D_GNU_SOURCE -O2 -fPIC -shared XmHelper.c -o Helper.libXm.so.4 -ldl
then
export LD_PRELOAD=<path_to_the_Helper.libXm.so.4>
in script running Mozilla.
*/
struct dummy_struct_t
{
void* reserved1;
void* reserved2;
/* typedef unsigned int Cardinal; */
unsigned int len;
char data[1024];
};
struct dummy_struct_t* vendorShellWidgetClass = NULL;
struct dummy_struct_t vendorShellClassRec =
{
NULL, NULL, 0, ""
};
static int is_our(const char* filename)
{
if (strstr(filename, "libawt.so") || strstr(filename, "libmawt.so") ||
strstr(filename, "libawt_g.so") || strstr(filename, "libmawt_g.so"))
return 1;
return 0;
};
void *dlopen (const char *filename, int flag)
{
typedef void* (*dlopen_t)(const char *filename, int flag);
static dlopen_t real = (void*)0;
void* result;
struct dummy_struct_t* s = (void*)0;
static int done = 0;
int size_core, size_total;
//fprintf(stderr, "opening %s\n", filename);
if (!real)
real = (dlopen_t)dlsym(RTLD_NEXT, "dlopen");
result = (*real)(filename, flag);
if (done || !filename || !result)
return result;
/* hate long ifs */
if (!is_our(filename) && vendorShellWidgetClass)
return result;
s = (struct dummy_struct_t*)dlsym(result, "vendorShellClassRec");
if (s) {
size_core = s->len;
size_total = size_core /* CoreClassPart */ +
5*sizeof(void*) /* CompositeClassPart */ +
sizeof(void*) /* ShellClassPart */ +
sizeof(void*) /* WMShellClassPart */ +
sizeof(void*) /* VendorShellClassPart */;
if (size_total > sizeof(struct dummy_struct_t))
{
fprintf(stderr, "Cannot override vendorShellClassRec: %d > %d\n",
size_total, sizeof(struct dummy_struct_t));
}
else
{
if (is_our(filename))
{
memcpy(&vendorShellClassRec, s, size_total);
vendorShellWidgetClass = &vendorShellClassRec;
done = 1;
}
else if (!vendorShellWidgetClass)
{
memcpy(&vendorShellClassRec, s, size_total);
vendorShellWidgetClass = &vendorShellClassRec;
}
}
}
/*
to clean up possible dlsym() errors.
dlopen() errors won't be lost, as it already succeed
*/
dlerror();
return result;
}
/* awfully dirty hack to allow JVM loading into browser on Solaris,
see src/solaris/hpi/native_threads/src/threads_solaris.c in JDK tree
for explanations. Need help from JDK people. */
#ifdef __sun
#include <thread.h>
ulong_t __gettsp(thread_t thr)
{
typedef ulong_t (*__gettsp_t)(thread_t thr);
static __gettsp_t real = (void*)0;
if (!real)
real = (__gettsp_t)dlsym(RTLD_NEXT, " __gettsp");
return (*real)(thr);
}
#endif

View File

@@ -0,0 +1,274 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: wf_moz6_common.h,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#ifndef __wf_moz6_common_h
#define __wf_moz6_common_h
/** Ideology behind this file:
* To keep generic binary compatibility, and be independent from Mozilla
* build system for Mozilla extension (not very good idea, but currently
* it's more convinient) we need some kind of fixed API/ABI between
* extension and Java service in browser. This file is _only_ (beside
* jvmp.h) common header between Java component and extension. It's written
* in pure C and has no Mozilla dependencies. So JVM service in browser fills
* propers callbacks and the extension, if wishes to perform some call to
* Mozilla uses those callbacks (and maybe even in another direction, but
* it's not recommened - use JVMP_Direct*Call for such purposes).
* Here described structures for
* - common browser configuration callbacks (show status, show document,
* get proxy config, add anything you want)
* - LiveConnect calls and security
* JavaObjectWrapper is wrapper for java-driven objects on browser side,
* usually lifetime coincides with lifetime of web page.
* If underlying native object is dead, proper field is 1.
* SecurityContextWrapper is wrapper for security context is
* LiveConnect calls, lifetime coincide with lifetime
* of LiveConnect call.
* BrowserSupportWrapper is wrapper for global JVM service object,
* exist always until JVM service is loaded, can be
* used for global operations not related to browser
* NB: If any other browser will implement those callbacks and be kind enough
* to follow Mozilla protocol in inline plugin handling, it will have
* Java + applets + LiveConnect for free. For example MSIE code can be written
* in such a manner.
**/
struct SecurityContextWrapper {
void* info;
int (*Implies) (void* handle, const char* target,
const char* action, int *bAllowedAccess);
int (*GetOrigin)(void* handle, char *buffer, int len);
int (*GetCertificateID)(void* handle, char *buffer, int len);
int dead;
};
typedef struct SecurityContextWrapper SecurityContextWrapper;
struct JavaObjectWrapper;
typedef struct JavaObjectWrapper JavaObjectWrapper;
#define WF_APPLETPEER_CID "@sun.com/wf/mozilla/appletpeer;1"
enum JSCallType { // Possible JS call type
JS_Unknown = 0,
JS_GetWindow = 1,
JS_ToString,
JS_Eval,
JS_Call,
JS_GetMember,
JS_SetMember,
JS_RemoveMember,
JS_GetSlot,
JS_SetSlot,
JS_Finalize
};
struct JSObject_CallInfo
{
const char* pszUrl; // URL of the CodeSource object in the Java call
jobjectArray jCertArray; // Certificate array of the CodeSource object
jintArray jCertLengthArray; // Certificate length array of the CodeSource object
int iNumOfCerts; // Number of certificates in the cert and cert length array
jobject jAccessControlContext; // AccessControlContext object that represents the Java callstack
enum JSCallType type; // Type of JSObject call
jthrowable jException; // Java exception object as the result of the call
JavaObjectWrapper* pWrapper; // native-Java glueing object
union {
struct __GetWindow {
void* pPlugin; // Plug-in instance corresponded to the JSObject call
jint iNativeJSObject; // Native JS object as the result of the GetWindow call
} __getWindow;
struct __Finalize {
jint iNativeJSObject; // Native JS object that needs to be finalized
} __finalize;
struct __ToString {
jint iNativeJSObject; // Native JS object that corresponded to the JSObject.toString
jstring jResult; // Result of JSObject.toString
} __toString;
struct __Call {
const jchar* pszMethodName; // Method name
int iMethodNameLen; // Length of method name
jobjectArray jArgs; // Argument for the JSObject.Call
jint iNativeJSObject; // Native JS object corresponded to the JSObject.call
jobject jResult; // Result of JSObject.call
} __call;
struct __Eval {
const jchar* pszEval; // String to be evaluated
int iEvalLen; // Length of the evaluatation string
jint iNativeJSObject; // Native JS object corresponded to the JSObject.eval
jobject jResult; // Result of JSObject.eval
} __eval;
struct __GetMember {
const jchar* pszName; // Member name
int iNameLen; // Length of member name
jint iNativeJSObject; // Native JS object corresponded to the JSObject.getMember
jobject jResult; // Result of JSObject.getMember
} __getMember;
struct __SetMember {
const jchar* pszName; // Member name
int iNameLen; // Length of member name
jint iNativeJSObject; // Native JS object corresponded to the JSObject.setMember
jobject jValue; // Result of JSObject.setMember
} __setMember;
struct __RemoveMember {
const jchar* pszName; // Member name
int iNameLen; // Length of member name
jint iNativeJSObject; // Native JS object corresponded to the JSObject.removeMember
} __removeMember;
struct __GetSlot {
int iIndex; // Slot number
jint iNativeJSObject; // Native JS object corresponded to the JSObject.getSlot
jobject jResult; // Result of JSObject.getSlot
} __getSlot;
struct __SetSlot {
int iIndex; // Slot number
jobject jValue; // Value to set in the slot
jint iNativeJSObject; // Native JS object corresponded to the JSObject.setSlot
} __setSlot;
} data;
};
enum JavaCallType {
Java_Unknown = 0,
Java_WrapJSObject,
Java_CreateObject,
Java_CallMethod,
Java_CallStaticMethod,
Java_CallNonvirtualMethod,
Java_SetField,
Java_SetStaticField,
Java_GetField,
Java_GetStaticField,
Java_UnwrapJObject
};
/* just a copy of enum jni_type from nsISecureEnv, as I have to get
it from somewhere - values are the same, so can convert flawlessly */
enum jvmp_jni_type
{
jvmp_jobject_type = 0,
jvmp_jboolean_type,
jvmp_jbyte_type,
jvmp_jchar_type,
jvmp_jshort_type,
jvmp_jint_type,
jvmp_jlong_type,
jvmp_jfloat_type,
jvmp_jdouble_type,
jvmp_jvoid_type
};
struct Java_CallInfo
{
enum JavaCallType type;
jthrowable jException;
SecurityContextWrapper* security;
union {
struct __WrapJSObject {
jint jsObject;
jint jstid;
jobject jObject ;
} __wrapJSObject;
struct __CreateObject {
jclass clazz;
jmethodID methodID;
jvalue *args;
jobject result;
} __createObject;
struct __CallMethod {
enum jvmp_jni_type type;
jobject obj;
jmethodID methodID;
jvalue *args;
jvalue result;
} __callMethod;
struct __CallStaticMethod {
enum jvmp_jni_type type;
jclass clazz;
jmethodID methodID;
jvalue *args;
jvalue result;
} __callStaticMethod;
struct __CallNonvirtualMethod {
enum jvmp_jni_type type;
jobject obj;
jclass clazz;
jmethodID methodID;
jvalue *args;
jvalue result;
} __callNonvirtualMethod;
struct __GetField {
enum jvmp_jni_type type;
jobject obj;
jfieldID fieldID;
jvalue result;
} __getField;
struct __GetStaticField {
enum jvmp_jni_type type;
jclass clazz;
jfieldID fieldID;
jvalue result;
} __getStaticField;
struct __SetField {
enum jvmp_jni_type type;
jobject obj;
jfieldID fieldID;
jvalue value;
} __setField;
struct __SetStaticField {
enum jvmp_jni_type type;
jclass clazz;
jfieldID fieldID;
jvalue value;
} __setStaticField;
struct __UnwrapJObject {
jobject jObject;
jint jstid;
jint jsObject ;
} __unwrapJObject;
} data;
};
struct JavaObjectWrapper
{
void* info;
void* plugin;
int (*GetParameters)(void* handle, char ***keys,
char ***values, int *count);
int (*ShowDocument)(void* handle, char* url, char* target);
int (*ShowStatus)(void* handle, char* status);
int (*GetJSThread)(void* handle, jint* jstid);
int dead;
};
struct BrowserSupportWrapper
{
void* info;
int (*GetProxyForURL)(void* handle, char* url, char** proxy);
int (*JSCall)(void* handle, jint jstid,
struct JSObject_CallInfo** jscall);
};
typedef struct BrowserSupportWrapper BrowserSupportWrapper;
#endif

View File

@@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: wfe_mozilla.c,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include "jvmp.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "wf_moz6_common.h"
/* Extension parameters */
static const char* WFCID = WF_APPLETPEER_CID;
static const jint WFExtVersion = 1;
static JVMP_SecurityCap g_moz_caps;
static JVMP_SecurityCap g_moz_cap_mask;
/* range of used capabilities */
#define MOZ_CAPS_LOW 16
#define MOZ_CAPS_HIGH 100
static JVMP_ExtDescription g_Description =
{
"Sun", /* vendor */
"1.0", /* version */
"Mozilla applet viewer Waterfall extension", /* description */
PLATFORM, /* platform */
ARCH, /* architecture */
"GPL", /* license */
NULL /* vendor data */
};
/* extension API implementation */
static jint JNICALL JVMPExt_Init(jint side)
{
int i;
JVMP_FORBID_ALL_CAPS(g_moz_caps);
JVMP_ALLOW_ALL_CAPS(g_moz_cap_mask);
for (i=MOZ_CAPS_LOW; i <= MOZ_CAPS_HIGH; i++)
JVMP_ALLOW_CAP(g_moz_caps, i);
return JNI_TRUE;
}
static jint JNICALL JVMPExt_Shutdown()
{
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetExtInfo(const char* *pCID,
jint *pVersion,
JVMP_ExtDescription* *pDesc)
{
*pCID = WFCID;
*pVersion = WFExtVersion;
if (pDesc) *pDesc = &g_Description;
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetBootstrapClass(char* *bootstrapClassPath,
char* *bootstrapClassName)
{
const char* home;
char* classpath;
/* XXX: incorrect, should be separate place for extensions */
home = getenv("WFHOME");
if (home == NULL) {
fprintf(stderr, "Env variable WFHOME not set");
return JNI_FALSE;
}
classpath = (char*)malloc(strlen(home)+20);
sprintf(classpath, "file://%s/classes/", home);
/* should be defined in installation time */
*bootstrapClassPath = classpath;
*bootstrapClassName = "sun.jvmp.mozilla.MozillaPeerFactory";
return JNI_TRUE;
}
static jint JNICALL JVMPExt_ScheduleRequest(JVMP_ShmRequest* req, jint local)
{
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetCapsRange(JVMP_SecurityCap* caps,
JVMP_SecurityCap* sh_mask)
{
if ((caps == NULL) || (sh_mask == NULL)) return JNI_FALSE;
memcpy(caps, &g_moz_caps, sizeof(JVMP_SecurityCap));
memcpy(sh_mask, & g_moz_cap_mask, sizeof(JVMP_SecurityCap));
return JNI_TRUE;
}
static JVMP_Extension JVMP_Ext =
{
&JVMPExt_Init,
&JVMPExt_Shutdown,
&JVMPExt_GetExtInfo,
&JVMPExt_GetBootstrapClass,
&JVMPExt_ScheduleRequest,
&JVMPExt_GetCapsRange
};
JNIEXPORT jint JNICALL JVMP_GetExtension(JVMP_Extension** ext)
{
*ext = &JVMP_Ext;
return JNI_TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: Aptest.java,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.text.*;
import java.net.*;
public class Aptest extends Applet implements Runnable {
Thread timer; // The thread that displays clock
int lastxs, lastys, lastxm,
lastym, lastxh, lastyh; // Dimensions used to draw hands
SimpleDateFormat formatter; // Formats the date displayed
String lastdate; // String to hold date displayed
Font clockFaceFont; // Font for number display on clock
Date currentDate; // Used to get date to display
Color handColor; // Color of main hands and dial
Color numberColor; // Color of second hand and numbers
public void init() {
Button b1 = new Button("Show status");
b1.setBounds(0, 0, 40, 40);
b1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
AppletContext ctx = getAppletContext();
ctx.showStatus("DONE SHOW STATUS");
}
});
Button b2 = new Button("Show document");
b2.setBounds(0, 0, 40, 40);
b2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
AppletContext ctx = getAppletContext();
try {
ctx.showDocument(new URL("http://www.sun.com"));
} catch (Exception ex) {}
}
});
setLayout(new FlowLayout(FlowLayout.CENTER));
add(b1);
add(b2);
resize(300,300); // Set clock window size
}
public void start() {
timer = new Thread(this);
timer.start();
}
public void stop() {
timer = null;
}
public void run() {
Thread me = Thread.currentThread();
while (timer == me) {
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
}
}
}
public void update(Graphics g) {
paint(g);
}
public String getAppletInfo() {
return "Title: A Clock \nAuthor: Rachel Gollub, 1995 \nAn analog clock.";
}
public String[][] getParameterInfo() {
String[][] info = {
{"bgcolor", "hexadecimal RGB number", "The background color. Default is the color of your browser."},
{"fgcolor1", "hexadecimal RGB number", "The color of the hands and dial. Default is blue."},
{"fgcolor2", "hexadecimal RGB number", "The color of the seconds hand and numbers. Default is dark gray."}
};
return info;
}
}

View File

@@ -0,0 +1,722 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: JavaPlugin.c,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/******************************************************************************
* Copyright (c) 1996 Netscape Communications. All rights reserved.
******************************************************************************/
/*
* UnixShell.c
*
* Netscape Client Plugin API
* - Function that need to be implemented by plugin developers
*
* This file defines a "Template" plugin that plugin developers can use
* as the basis for a real plugin. This shell just provides empty
* implementations of all functions that the plugin can implement
* that will be called by Netscape (the NPP_xxx methods defined in
* npapi.h).
*
* dp Suresh <dp@netscape.com>
*
*/
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include "jvmp.h"
#include "common.h"
#include "shmtran.h"
#define MAX_INSTANCES 200
#define ADD_INST(inst) for(_idx=0; _idx<MAX_INSTANCES; _idx++) \
if (!g_instances[_idx]) { g_instances[_idx] = inst; break; } \
if (_idx == MAX_INSTANCES) fprintf(stderr, "Leaking PluginInsances?\n");
#define DEL_INST(inst) for(_idx=0; _idx<MAX_INSTANCES; _idx++) \
if (g_instances[_idx] == inst) { g_instances[_idx] = NULL; break; }
static JVMP_RuntimeContext* g_jvmp_context = NULL;
static void* g_dll = NULL;
static JavaVM* g_jvm = NULL;
static JVMP_CallingContext* g_ctx;
static GlobalData g_data;
static PluginInstance* g_instances[MAX_INSTANCES];
static int _idx;
static int g_stopped = 0;
static int g_inited = 0;
#ifdef XP_UNIX
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <Xm/VendorS.h> /* really bad */
static Atom g_request_handler_atom;
#endif
/*
* Protypes of utility functions
*/
static NPError DoDirtyInit();
static jint loadPluginDLL();
static jint initJVM(JavaVM** jvm, JVMP_CallingContext** ctx,
JavaVMInitArgs* vm_args);
static jint PutParams(jint id, char** buf, int* argc, int* len);
static PluginInstance* GetInstance(jint id);
static void SetDocBase(PluginInstance* inst, char* buf, int len);
static int GetProxyForURL(void* handle, char* url, char** proxy)
{
PluginInstance* inst = (PluginInstance*)handle;
return JNI_TRUE;
}
static int ShowDocument(jint id, char* url, char* target)
{
PluginInstance* inst;
inst = GetInstance(id);
if (!inst) return JNI_FALSE;
NPN_GetURL(inst->m_peer, url, target);
return JNI_TRUE;
}
static int ShowStatus(jint id, char* status)
{
PluginInstance* inst;
inst = GetInstance(id);
if (!inst) return JNI_FALSE;
NPN_Status(inst->m_peer, status);
return JNI_TRUE;
}
/***********************************************************************
*
* Implementations of plugin API functions
*
***********************************************************************/
char*
NPP_GetMIMEDescription(void)
{
printf("NPP_GetMIMEDescription\n");
return
"application/x-java-vm::Java(tm) Plug-in"
";application/x-java-applet::Java(tm) Plug-in";
}
NPError
NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
NPError err = NPERR_NO_ERROR;
switch (variable) {
case NPPVpluginNameString:
*((char **)value) = "Java plugin";
break;
case NPPVpluginDescriptionString:
*((char **)value) =
"Flexible Java plugin based on Waterfall API";
break;
default:
err = NPERR_GENERIC_ERROR;
}
return err;
}
NPError
NPP_Initialize(void)
{
JavaVMInitArgs vm_args;
jint ext_id;
if (g_inited)
return NPERR_NO_ERROR;
if (g_jvmp_context != NULL)
return NPERR_NO_ERROR;
JVMP_ShmInit(1);
if (loadPluginDLL() != JNI_TRUE)
return NPERR_GENERIC_ERROR;
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_2;
(g_jvmp_context->JVMP_GetDefaultJavaVMInitArgs)(&vm_args);
if (initJVM(&g_jvm, &g_ctx, &vm_args) != JNI_TRUE)
return NPERR_GENERIC_ERROR;
if ((g_jvmp_context->JVMP_RegisterExtension)
(g_ctx,
"/ws/wf/build/unix/libwf_netscape4.so",
&ext_id) != JNI_TRUE)
return NPERR_GENERIC_ERROR;
return DoDirtyInit();
}
void
NPP_Shutdown(void)
{
g_stopped = 1;
}
NPError
NPP_New(NPMIMEType pluginType,
NPP instance,
uint16 mode,
int16 argc,
char* argn[],
char* argv[],
NPSavedData* saved)
{
PluginInstance* This;
int i;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
instance->pdata = malloc(sizeof(PluginInstance));
This = (PluginInstance*) instance->pdata;
if (This == NULL)
return NPERR_OUT_OF_MEMORY_ERROR;
This->m_argn = (char**)malloc(sizeof(char*)*(argc+1));
This->m_argv = (char**)malloc(sizeof(char*)*(argc+1));
This->m_peer = instance;
for(i=0; i<argc; i++)
{
(This->m_argn)[i] = strdup(argn[i]);
(This->m_argv)[i] = strdup(argv[i]);
};
//NPN_GetURL(This->m_peer, "javascript:document.location",
// NULL);
This->m_argn[i] = strdup("docbase");
This->m_argv[i] = strdup("http://java.sun.com");
argc++;
This->m_argc = argc;
This->m_wid = 0;
ADD_INST(This);
if ((g_jvmp_context->JVMP_CreatePeer)(g_ctx,
PV_MOZILLA4,
0,
&(This->m_id)) != JNI_TRUE)
return NPERR_GENERIC_ERROR;
if ((g_jvmp_context->JVMP_SendEvent)(g_ctx,
This->m_id,
(jint)PE_SETTYPE,
(jlong)PT_APPLET) != JNI_TRUE)
return NPERR_GENERIC_ERROR;
/* async as it calls browser back */
if ((g_jvmp_context->JVMP_PostEvent)(g_ctx,
This->m_id,
(jint)PE_NEWPARAMS,
(jlong)0) != JNI_TRUE)
return NPERR_GENERIC_ERROR;
return NPERR_NO_ERROR;
}
NPError
NPP_Destroy(NPP instance, NPSavedData** save)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
/* PLUGIN DEVELOPERS:
* If desired, call NP_MemAlloc to create a
* NPSavedDate structure containing any state information
* that you want restored if this plugin instance is later
* recreated.
*/
if (This != NULL) {
g_jvmp_context->JVMP_SendEvent(g_ctx,
This->m_id,
(jint)PE_STOP,
0);
g_jvmp_context->JVMP_UnregisterWindow(g_ctx,
This->m_wid);
/*g_jvmp_context->JVMP_SendEvent(g_ctx,
This->m_id,
(jint)PE_DESTROY,
0); */
g_jvmp_context->JVMP_DestroyPeer(g_ctx,
This->m_id);
// XXX: leak, create DestroyInstance() function
DEL_INST(This);
free(instance->pdata);
instance->pdata = NULL;
}
return NPERR_NO_ERROR;
}
NPError
NPP_SetWindow(NPP instance, NPWindow* rwin)
{
PluginInstance* This;
JVMP_DrawingSurfaceInfo w;
jint ID;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
if (rwin == NULL)
return NPERR_NO_ERROR;
This = (PluginInstance*) instance->pdata;
w.window = (struct JPluginWindow*)rwin->window;
w.x = rwin->x;
w.y = rwin->y;
w.width = rwin->width;
w.height = rwin->height;
#ifdef XP_UNIX
XSync(g_data.m_dpy, 0); /* otherwise JDK display connection won't see it */
#endif
if ((g_jvmp_context->JVMP_RegisterWindow)(g_ctx, &w, &ID) != JNI_TRUE)
return NPERR_GENERIC_ERROR;
if ((g_jvmp_context->JVMP_SendEvent)(g_ctx,
This->m_id,
(jint)PE_SETWINDOW,
(jlong)ID) != JNI_TRUE)
return NPERR_GENERIC_ERROR;
return NPERR_NO_ERROR;
}
NPError
NPP_NewStream(NPP instance,
NPMIMEType type,
NPStream *stream,
NPBool seekable,
uint16 *stype)
{
NPByteRange range;
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
return NPERR_NO_ERROR;
}
/* PLUGIN DEVELOPERS:
* These next 2 functions are directly relevant in a plug-in which
* handles the data in a streaming manner. If you want zero bytes
* because no buffer space is YET available, return 0. As long as
* the stream has not been written to the plugin, Navigator will
* continue trying to send bytes. If the plugin doesn't want them,
* just return some large number from NPP_WriteReady(), and
* ignore them in NPP_Write(). For a NP_ASFILE stream, they are
* still called but can safely be ignored using this strategy.
*/
int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
* mode so we can take any size stream in our
* write call (since we ignore it) */
int32
NPP_WriteReady(NPP instance, NPStream *stream)
{
PluginInstance* This;
if (instance != NULL)
This = (PluginInstance*) instance->pdata;
return STREAMBUFSIZE;
}
int32
NPP_Write(NPP instance, NPStream *stream,
int32 offset, int32 len, void *buffer)
{
fprintf(stderr, "NPP_WRITE %d\n", (int)len);
if (instance != NULL)
{
PluginInstance* This = (PluginInstance*) instance->pdata;
SetDocBase(This, (char*)buffer, len);
fprintf(stderr, "got base notification: %s", This->m_docbase);
}
return len; /* The number of bytes accepted */
}
NPError
NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
return NPERR_NO_ERROR;
}
void
NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
{
PluginInstance* This;
if (instance != NULL)
This = (PluginInstance*) instance->pdata;
}
void NPP_URLNotify(NPP instance,
const char* url,
NPReason reason,
void* notifyData)
{
fprintf(stderr, "URLNotify\n");
}
void
NPP_Print(NPP instance, NPPrint* printInfo)
{
if(printInfo == NULL)
return;
if (instance != NULL) {
PluginInstance* This = (PluginInstance*) instance->pdata;
if (printInfo->mode == NP_FULL) {
/*
* PLUGIN DEVELOPERS:
* If your plugin would like to take over
* printing completely when it is in full-screen mode,
* set printInfo->pluginPrinted to TRUE and print your
* plugin as you see fit. If your plugin wants Netscape
* to handle printing in this case, set
* printInfo->pluginPrinted to FALSE (the default) and
* do nothing. If you do want to handle printing
* yourself, printOne is true if the print button
* (as opposed to the print menu) was clicked.
* On the Macintosh, platformPrint is a THPrint; on
* Windows, platformPrint is a structure
* (defined in npapi.h) containing the printer name, port,
* etc.
*/
void* platformPrint =
printInfo->print.fullPrint.platformPrint;
NPBool printOne =
printInfo->print.fullPrint.printOne;
/* Do the default*/
printInfo->print.fullPrint.pluginPrinted = FALSE;
}
else { /* If not fullscreen, we must be embedded */
/*
* PLUGIN DEVELOPERS:
* If your plugin is embedded, or is full-screen
* but you returned false in pluginPrinted above, NPP_Print
* will be called with mode == NP_EMBED. The NPWindow
* in the printInfo gives the location and dimensions of
* the embedded plugin on the printed page. On the
* Macintosh, platformPrint is the printer port; on
* Windows, platformPrint is the handle to the printing
* device context.
*/
NPWindow* printWindow =
&(printInfo->print.embedPrint.window);
void* platformPrint =
printInfo->print.embedPrint.platformPrint;
}
}
}
/* here our private functions */
char* GetDlLibraryName(const char* path,
const char* name)
{
char* result =
(char*)malloc(strlen(path) + strlen(name) + 10);
/* XXX: Unix implementation */
sprintf(result, "%s/lib%s.so", path, name);
return result;
}
void* LoadDlLibrary(char* name)
{
/* XXX: Unix implementation */
return dlopen(name, RTLD_LAZY);
}
void GetDlErrorText(char* buf)
{
char* err;
int len;
err = dlerror();
if (err)
memcpy(buf, err, strlen(err));
}
void* FindDlSymbol(void* handle, const char* name)
{
return dlsym(handle, name);
}
static jint loadPluginDLL()
{
const char* plugin_home;
char errorMsg[1024] = "<unknown; can't get error>";
char* plugin_dll;
JVMP_GetPlugin_t fJVMP_GetPlugin;
plugin_home = getenv("JAVA_PLUGIN_HOME");
if (plugin_home == NULL) {
fprintf(stderr, "Env variable JAVA_PLUGIN_HOME not set");
return JNI_FALSE;
}
plugin_dll = GetDlLibraryName(plugin_home, "jvmp_shm");
g_dll = LoadDlLibrary(plugin_dll);
free(plugin_dll);
if (!g_dll)
{
GetDlErrorText(errorMsg);
fprintf(stderr, "Cannot load plugin DLL: %s", errorMsg);
return JNI_FALSE;
}
fJVMP_GetPlugin =
(JVMP_GetPlugin_t) FindDlSymbol(g_dll, "JVMP_GetPlugin");
if (!fJVMP_GetPlugin)
{
GetDlErrorText(errorMsg);
fprintf(stderr, "Cannot load plugin DLL: %s", errorMsg);
return JNI_FALSE;
}
(*fJVMP_GetPlugin)(&g_jvmp_context);
return JNI_TRUE;
}
static jint initJVM(JavaVM** jvm, JVMP_CallingContext** ctx,
JavaVMInitArgs* vm_args)
{
jint res =
(g_jvmp_context->JVMP_GetRunningJVM)(jvm, ctx, vm_args, JNI_FALSE);
if (res == JNI_TRUE)
{
//fprintf(stderr, "Got JVM!!!\n");
return JNI_TRUE;
}
else
{
fprintf(stderr, "BAD - NO JVM!!!!");
return JNI_FALSE;
}
}
/* this one is called only on Netscape side */
int JVMP_ExecuteShmRequest(JVMP_ShmRequest* req)
{
int vendor, funcno, id, *pid;
char sign[40], *buf, *status, *url, *target;
int len, argc, *pargc;
if (!req) return 0;
vendor = JVMP_GET_VENDOR(req->func_no);
if (vendor != WFNetscape4VendorID) return 0;
funcno = JVMP_GET_EXT_FUNCNO(req->func_no);
switch(funcno)
{
case 2:
sprintf(sign, "Iia[0]");
len = 0; pargc = &argc;
JVMP_DecodeRequest(req, 0, sign, &id, &pargc, &buf);
pargc = &argc;
PutParams(id, &buf, pargc, &len);
sprintf(sign, "Iia[%d]", len);
JVMP_EncodeRequest(req, sign, id, pargc, buf);
free(buf);
break;
case 3:
sprintf(sign, "IS");
JVMP_DecodeRequest(req, 1, sign, &id, &status);
req->retval = ShowStatus(id, status);
free(status);
break;
case 4:
sprintf(sign, "ISS");
JVMP_DecodeRequest(req, 1, sign, &id, &url, &target);
req->retval = ShowDocument(id, url, target);
free(url); free(target);
default:
return 0;
}
return 1;
}
#ifdef XP_UNIX
static void
request_handler(Widget w, XtPointer data,
XEvent *raw_evt, Boolean *cont)
{
JVMP_ShmRequest* req;
XPropertyEvent *evt = (XPropertyEvent *) raw_evt;
if (evt->atom == g_request_handler_atom)
{
while (JVMP_RecvShmRequest(g_data.m_msgid1, 0, &req))
{
if (!req) break;
JVMP_ExecuteShmRequest(req);
JVMP_ConfirmShmRequest(req);
JVMP_DeleteShmReq(req);
req = NULL;
}
}
// fprintf(stderr, "leaving request_handler\n");
}
static int AllocateEventWidget(Display* dpy, XID* pxid)
{
Arg args[40];
int argc;
Widget w;
if (!dpy || !pxid) return 0;
argc = 0;
XtSetArg(args[argc], XmNallowShellResize, True); argc++;
XtSetArg(args[argc], XmNwidth, 100); argc++;
XtSetArg(args[argc], XmNheight, 100); argc++;
XtSetArg(args[argc], XmNmappedWhenManaged, False); argc++;
w = NULL;
w = XtAppCreateShell("WF","XApplication",
vendorShellWidgetClass,
dpy,
args,
argc);
if (w == NULL) return 0;
XtRealizeWidget(w);
XtAddEventHandler(w, PropertyChangeMask, FALSE,
request_handler, NULL);
g_request_handler_atom =
XInternAtom(dpy, "WF atom", FALSE);
*pxid = XtWindow(w);
XFlush(dpy);
return 1;
}
#endif
NPError
DoDirtyInit()
{
#ifdef XP_UNIX
JVMP_ShmRequest* req = NULL;
int* pmsg_id;
char* npname;
Dl_info nfo;
g_data.m_msgid = (int)g_ctx->reserved0;
g_data.m_dpy = NULL;
NPN_GetValue(NULL, NPNVxDisplay, &(g_data.m_dpy));
if (!AllocateEventWidget(g_data.m_dpy, &(g_data.m_xid)))
{
fprintf(stderr, "Cannot allocate event widget\n");
return NPERR_GENERIC_ERROR;
}
req = JVMP_NewShmReq(g_data.m_msgid,
JVMP_NEW_EXT_FUNCNO(WFNetscape4VendorID, 1));
JVMP_EncodeRequest(req, "Ii", g_data.m_xid, &(g_data.m_msgid1));
if (!JVMP_SendShmRequest(req, 1)) return NPERR_GENERIC_ERROR;
JVMP_WaitConfirmShmRequest(req);
if (!req->retval) return NPERR_GENERIC_ERROR;
pmsg_id = &(g_data.m_msgid1);
JVMP_DecodeRequest(req, 0, "Ii", &g_data.m_xid, &pmsg_id);
/* just to increment refcount and forbid to unload plugin DLL */
if (dladdr(&DoDirtyInit, &nfo) != 0)
LoadDlLibrary(nfo.dli_fname);
g_inited = 1;
#endif
return NPERR_NO_ERROR;
}
static jint PutParams(jint id, char** pbuf, int* pargc, int* plen)
{
PluginInstance* inst;
int len, argc, i, pos;
char* buf;
inst = GetInstance(id);
if (!inst) {
fprintf(stderr, "instance %d not found\n", (int)id);
*plen = *pargc = 0; *pbuf = NULL;
return JNI_FALSE;
}
argc = inst->m_argc; len = 0;
for (i=0; i<argc; i++)
{
len += strlen(inst->m_argn[i]) + 1 + strlen(inst->m_argv[i]) + 1;
}
buf = (char*)malloc(len);
*plen = len;
pos = 0;
for (i=0; i<argc; i++)
{
len = strlen(inst->m_argn[i]) + 1;
memcpy(buf+pos, inst->m_argn[i], len);
pos += len;
len = strlen(inst->m_argv[i]) + 1;
memcpy(buf+pos, inst->m_argv[i], len);
pos += len;
}
*pbuf = buf;
*pargc = argc;
return JNI_TRUE;
}
static PluginInstance* GetInstance(jint id)
{
int i;
for(i=0; i<MAX_INSTANCES; i++)
{
if (g_instances[i] && (g_instances[i]->m_id == id))
return g_instances[i];
}
return NULL;
}
static void SetDocBase(PluginInstance* inst, char* buf, int len)
{
JVMP_ShmRequest* req;
if (!inst) return;
inst->m_docbase = strdup(buf);
}

View File

@@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: Makefile,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#!make
################################################################################
# Copyright (c) 1996 Netscape Communications. All rights reserved.
################################################################################
#
# Simple Sample plugin makefile
#
# Platform: Linux 1.2 (ELF)
#
# This makefile contains some of our defines for the compiler:
#
# XP_UNIX This needs to get defined for npapi.h on unix platforms.
# PLUGIN_TRACE Enable this define to get debug prints whenever the plugin
# api gets control.
#
# WARNING: Motif libraries are built static into the navigator and cannot
# be accessed from the plugin.
#
PLUGIN_DEFINES= -DXP_UNIX -DJVMP_USE_SHM
#PLUGIN_DEFINES= -DXP_UNIX -DPLUGIN_TRACE -DJVMP_USE_SHM
#PLUGIN_DEFINES= -DXP_UNIX -I../../../include -I../Source/_gen
CC= gcc
OPTIMIZER= -g
CFLAGS= -Wall -Wno-unused $(OPTIMIZER) $(PLUGIN_DEFINES) -I. -I../../../public/
SRC=JavaPlugin.c npunix.c
OBJ=JavaPlugin.o npunix.o
SHAREDTARGET=npjvmp.so
default all: $(SHAREDTARGET)
$(SHAREDTARGET): $(OBJ) ../../../build/unix/shmtran.o
$(CC) -shared -o $(SHAREDTARGET) $(OBJ) ../../../build/unix/shmtran.o $(LDFLAGS) -ldl
npsimple.o: ../Source/npsimple.c
$(CC) -c $(CFLAGS) ../Source/npsimple.c
stubs.o: ../Source/stubs.c
$(CC) -c $(CFLAGS) ../Source/stubs.c
clean:
$(RM) $(OBJ) $(SHAREDTARGET)

View File

@@ -0,0 +1,329 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: UnixShell.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/******************************************************************************
* Copyright (c) 1996 Netscape Communications. All rights reserved.
******************************************************************************/
/*
* UnixShell.c
*
* Netscape Client Plugin API
* - Function that need to be implemented by plugin developers
*
* This file defines a "Template" plugin that plugin developers can use
* as the basis for a real plugin. This shell just provides empty
* implementations of all functions that the plugin can implement
* that will be called by Netscape (the NPP_xxx methods defined in
* npapi.h).
*
* dp Suresh <dp@netscape.com>
*
*/
#include <stdio.h>
#include "npapi.h"
/***********************************************************************
* Instance state information about the plugin.
*
* PLUGIN DEVELOPERS:
* Use this struct to hold per-instance information that you'll
* need in the various functions in this file.
***********************************************************************/
typedef struct _PluginInstance
{
int nothing;
} PluginInstance;
/***********************************************************************
*
* Empty implementations of plugin API functions
*
* PLUGIN DEVELOPERS:
* You will need to implement these functions as required by your
* plugin.
*
***********************************************************************/
char*
NPP_GetMIMEDescription(void)
{
return("mime/type:sample:Template Only");
}
NPError
NPP_GetValue(void *future, NPPVariable variable, void *value)
{
NPError err = NPERR_NO_ERROR;
switch (variable) {
case NPPVpluginNameString:
*((char **)value) = "Template plugin";
break;
case NPPVpluginDescriptionString:
*((char **)value) =
"This plugins handles nothing. This is only"
" a template.";
break;
default:
err = NPERR_GENERIC_ERROR;
}
return err;
}
NPError
NPP_Initialize(void)
{
return NPERR_NO_ERROR;
}
jref
NPP_GetJavaClass()
{
return NULL;
}
void
NPP_Shutdown(void)
{
}
NPError
NPP_New(NPMIMEType pluginType,
NPP instance,
uint16 mode,
int16 argc,
char* argn[],
char* argv[],
NPSavedData* saved)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
This = (PluginInstance*) instance->pdata;
if (This != NULL)
return NPERR_NO_ERROR;
else
return NPERR_OUT_OF_MEMORY_ERROR;
}
NPError
NPP_Destroy(NPP instance, NPSavedData** save)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
/* PLUGIN DEVELOPERS:
* If desired, call NP_MemAlloc to create a
* NPSavedDate structure containing any state information
* that you want restored if this plugin instance is later
* recreated.
*/
if (This != NULL) {
NPN_MemFree(instance->pdata);
instance->pdata = NULL;
}
return NPERR_NO_ERROR;
}
NPError
NPP_SetWindow(NPP instance, NPWindow* window)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
if (window == NULL)
return NPERR_NO_ERROR;
This = (PluginInstance*) instance->pdata;
/*
* PLUGIN DEVELOPERS:
* Before setting window to point to the
* new window, you may wish to compare the new window
* info to the previous window (if any) to note window
* size changes, etc.
*/
return NPERR_NO_ERROR;
}
NPError
NPP_NewStream(NPP instance,
NPMIMEType type,
NPStream *stream,
NPBool seekable,
uint16 *stype)
{
NPByteRange range;
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
return NPERR_NO_ERROR;
}
/* PLUGIN DEVELOPERS:
* These next 2 functions are directly relevant in a plug-in which
* handles the data in a streaming manner. If you want zero bytes
* because no buffer space is YET available, return 0. As long as
* the stream has not been written to the plugin, Navigator will
* continue trying to send bytes. If the plugin doesn't want them,
* just return some large number from NPP_WriteReady(), and
* ignore them in NPP_Write(). For a NP_ASFILE stream, they are
* still called but can safely be ignored using this strategy.
*/
int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
* mode so we can take any size stream in our
* write call (since we ignore it) */
int32
NPP_WriteReady(NPP instance, NPStream *stream)
{
PluginInstance* This;
if (instance != NULL)
This = (PluginInstance*) instance->pdata;
return STREAMBUFSIZE;
}
int32
NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
{
if (instance != NULL)
{
PluginInstance* This = (PluginInstance*) instance->pdata;
}
return len; /* The number of bytes accepted */
}
NPError
NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
return NPERR_NO_ERROR;
}
void
NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
{
PluginInstance* This;
if (instance != NULL)
This = (PluginInstance*) instance->pdata;
}
void
NPP_Print(NPP instance, NPPrint* printInfo)
{
if(printInfo == NULL)
return;
if (instance != NULL) {
PluginInstance* This = (PluginInstance*) instance->pdata;
if (printInfo->mode == NP_FULL) {
/*
* PLUGIN DEVELOPERS:
* If your plugin would like to take over
* printing completely when it is in full-screen mode,
* set printInfo->pluginPrinted to TRUE and print your
* plugin as you see fit. If your plugin wants Netscape
* to handle printing in this case, set
* printInfo->pluginPrinted to FALSE (the default) and
* do nothing. If you do want to handle printing
* yourself, printOne is true if the print button
* (as opposed to the print menu) was clicked.
* On the Macintosh, platformPrint is a THPrint; on
* Windows, platformPrint is a structure
* (defined in npapi.h) containing the printer name, port,
* etc.
*/
void* platformPrint =
printInfo->print.fullPrint.platformPrint;
NPBool printOne =
printInfo->print.fullPrint.printOne;
/* Do the default*/
printInfo->print.fullPrint.pluginPrinted = FALSE;
}
else { /* If not fullscreen, we must be embedded */
/*
* PLUGIN DEVELOPERS:
* If your plugin is embedded, or is full-screen
* but you returned false in pluginPrinted above, NPP_Print
* will be called with mode == NP_EMBED. The NPWindow
* in the printInfo gives the location and dimensions of
* the embedded plugin on the printed page. On the
* Macintosh, platformPrint is the printer port; on
* Windows, platformPrint is the handle to the printing
* device context.
*/
NPWindow* printWindow =
&(printInfo->print.embedPrint.window);
void* platformPrint =
printInfo->print.embedPrint.platformPrint;
}
}
}

View File

@@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: common.h,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#ifndef _common_h
#define _common_h
#include "npapi.h"
/***********************************************************************
* Instance state information about the plugin.
*
* PLUGIN DEVELOPERS:
* Use this struct to hold per-instance information that you'll
* need in the various functions in this file.
***********************************************************************/
typedef struct _PluginInstance
{
void* info; /* really "this" */
NPP m_peer;
jint m_id;
jint m_wid;
int16 m_argc;
char** m_argn;
char** m_argv;
char* m_docbase;
} PluginInstance;
typedef struct _GlobalData
{
#ifdef XP_UNIX
Display* m_dpy;
/* message queue ID of shared memory transport in host -> JVM direction */
int m_msgid;
/* message queue ID of shared memory transport in JVM -> host direction */
int m_msgid1;
/* XID of widget used to notify browser about our requests */
XID m_xid;
#endif
} GlobalData;
#define PE_NOPE 0
#define PE_CREATE 1
#define PE_SETWINDOW 2
#define PE_DESTROY 3
#define PE_START 4
#define PE_STOP 5
#define PE_NEWPARAMS 6
#define PE_SETTYPE 7
#define PV_UNKNOWN 0
#define PV_MOZILLA6 1
#define PV_MOZILLA4 2
#define PT_UNKNOWN 0
#define PT_EMBED 1
#define PT_OBJECT 2
#define PT_APPLET 3
#define PT_PLUGLET 4
#define WFNetscape4VendorID 2 /* Netscape 4 */
#define WFNetscape4ExtVersion 1
#endif

View File

@@ -0,0 +1,667 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: jri.h,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/*******************************************************************************
* Java Runtime Interface
* Copyright (c) 1996 Netscape Communications Corporation. All rights reserved.
******************************************************************************/
#ifndef JRI_H
#define JRI_H
#include "jritypes.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*******************************************************************************
* JRIEnv
******************************************************************************/
/* The type of the JRIEnv interface. */
typedef struct JRIEnvInterface JRIEnvInterface;
/* The type of a JRIEnv instance. */
typedef const JRIEnvInterface* JRIEnv;
/*******************************************************************************
* JRIEnv Operations
******************************************************************************/
#define JRI_DefineClass(env, classLoader, buf, bufLen) \
(((*(env))->DefineClass)(env, JRI_DefineClass_op, classLoader, buf, bufLen))
#define JRI_FindClass(env, name) \
(((*(env))->FindClass)(env, JRI_FindClass_op, name))
#define JRI_Throw(env, obj) \
(((*(env))->Throw)(env, JRI_Throw_op, obj))
#define JRI_ThrowNew(env, clazz, message) \
(((*(env))->ThrowNew)(env, JRI_ThrowNew_op, clazz, message))
#define JRI_ExceptionOccurred(env) \
(((*(env))->ExceptionOccurred)(env, JRI_ExceptionOccurred_op))
#define JRI_ExceptionDescribe(env) \
(((*(env))->ExceptionDescribe)(env, JRI_ExceptionDescribe_op))
#define JRI_ExceptionClear(env) \
(((*(env))->ExceptionClear)(env, JRI_ExceptionClear_op))
#define JRI_NewGlobalRef(env, ref) \
(((*(env))->NewGlobalRef)(env, JRI_NewGlobalRef_op, ref))
#define JRI_DisposeGlobalRef(env, gref) \
(((*(env))->DisposeGlobalRef)(env, JRI_DisposeGlobalRef_op, gref))
#define JRI_GetGlobalRef(env, gref) \
(((*(env))->GetGlobalRef)(env, JRI_GetGlobalRef_op, gref))
#define JRI_SetGlobalRef(env, gref, ref) \
(((*(env))->SetGlobalRef)(env, JRI_SetGlobalRef_op, gref, ref))
#define JRI_IsSameObject(env, a, b) \
(((*(env))->IsSameObject)(env, JRI_IsSameObject_op, a, b))
#define JRI_NewObject(env) ((*(env))->NewObject)
#define JRI_NewObjectV(env, clazz, methodID, args) \
(((*(env))->NewObjectV)(env, JRI_NewObject_op_va_list, clazz, methodID, args))
#define JRI_NewObjectA(env, clazz, method, args) \
(((*(env))->NewObjectA)(env, JRI_NewObject_op_array, clazz, methodID, args))
#define JRI_GetObjectClass(env, obj) \
(((*(env))->GetObjectClass)(env, JRI_GetObjectClass_op, obj))
#define JRI_IsInstanceOf(env, obj, clazz) \
(((*(env))->IsInstanceOf)(env, JRI_IsInstanceOf_op, obj, clazz))
#define JRI_GetMethodID(env, clazz, name, sig) \
(((*(env))->GetMethodID)(env, JRI_GetMethodID_op, clazz, name, sig))
#define JRI_CallMethod(env) ((*(env))->CallMethod)
#define JRI_CallMethodV(env, obj, methodID, args) \
(((*(env))->CallMethodV)(env, JRI_CallMethod_op_va_list, obj, methodID, args))
#define JRI_CallMethodA(env, obj, methodID, args) \
(((*(env))->CallMethodA)(env, JRI_CallMethod_op_array, obj, methodID, args))
#define JRI_CallMethodBoolean(env) ((*(env))->CallMethodBoolean)
#define JRI_CallMethodBooleanV(env, obj, methodID, args) \
(((*(env))->CallMethodBooleanV)(env, JRI_CallMethodBoolean_op_va_list, obj, methodID, args))
#define JRI_CallMethodBooleanA(env, obj, methodID, args) \
(((*(env))->CallMethodBooleanA)(env, JRI_CallMethodBoolean_op_array, obj, methodID, args))
#define JRI_CallMethodByte(env) ((*(env))->CallMethodByte)
#define JRI_CallMethodByteV(env, obj, methodID, args) \
(((*(env))->CallMethodByteV)(env, JRI_CallMethodByte_op_va_list, obj, methodID, args))
#define JRI_CallMethodByteA(env, obj, methodID, args) \
(((*(env))->CallMethodByteA)(env, JRI_CallMethodByte_op_array, obj, methodID, args))
#define JRI_CallMethodChar(env) ((*(env))->CallMethodChar)
#define JRI_CallMethodCharV(env, obj, methodID, args) \
(((*(env))->CallMethodCharV)(env, JRI_CallMethodChar_op_va_list, obj, methodID, args))
#define JRI_CallMethodCharA(env, obj, methodID, args) \
(((*(env))->CallMethodCharA)(env, JRI_CallMethodChar_op_array, obj, methodID, args))
#define JRI_CallMethodShort(env) ((*(env))->CallMethodShort)
#define JRI_CallMethodShortV(env, obj, methodID, args) \
(((*(env))->CallMethodShortV)(env, JRI_CallMethodShort_op_va_list, obj, methodID, args))
#define JRI_CallMethodShortA(env, obj, methodID, args) \
(((*(env))->CallMethodShortA)(env, JRI_CallMethodShort_op_array, obj, methodID, args))
#define JRI_CallMethodInt(env) ((*(env))->CallMethodInt)
#define JRI_CallMethodIntV(env, obj, methodID, args) \
(((*(env))->CallMethodIntV)(env, JRI_CallMethodInt_op_va_list, obj, methodID, args))
#define JRI_CallMethodIntA(env, obj, methodID, args) \
(((*(env))->CallMethodIntA)(env, JRI_CallMethodInt_op_array, obj, methodID, args))
#define JRI_CallMethodLong(env) ((*(env))->CallMethodLong)
#define JRI_CallMethodLongV(env, obj, methodID, args) \
(((*(env))->CallMethodLongV)(env, JRI_CallMethodLong_op_va_list, obj, methodID, args))
#define JRI_CallMethodLongA(env, obj, methodID, args) \
(((*(env))->CallMethodLongA)(env, JRI_CallMethodLong_op_array, obj, methodID, args))
#define JRI_CallMethodFloat(env) ((*(env))->CallMethodFloat)
#define JRI_CallMethodFloatV(env, obj, methodID, args) \
(((*(env))->CallMethodFloatV)(env, JRI_CallMethodFloat_op_va_list, obj, methodID, args))
#define JRI_CallMethodFloatA(env, obj, methodID, args) \
(((*(env))->CallMethodFloatA)(env, JRI_CallMethodFloat_op_array, obj, methodID, args))
#define JRI_CallMethodDouble(env) ((*(env))->CallMethodDouble)
#define JRI_CallMethodDoubleV(env, obj, methodID, args) \
(((*(env))->CallMethodDoubleV)(env, JRI_CallMethodDouble_op_va_list, obj, methodID, args))
#define JRI_CallMethodDoubleA(env, obj, methodID, args) \
(((*(env))->CallMethodDoubleA)(env, JRI_CallMethodDouble_op_array, obj, methodID, args))
#define JRI_GetFieldID(env, clazz, name, sig) \
(((*(env))->GetFieldID)(env, JRI_GetFieldID_op, clazz, name, sig))
#define JRI_GetField(env, obj, fieldID) \
(((*(env))->GetField)(env, JRI_GetField_op, obj, fieldID))
#define JRI_GetFieldBoolean(env, obj, fieldID) \
(((*(env))->GetFieldBoolean)(env, JRI_GetFieldBoolean_op, obj, fieldID))
#define JRI_GetFieldByte(env, obj, fieldID) \
(((*(env))->GetFieldByte)(env, JRI_GetFieldByte_op, obj, fieldID))
#define JRI_GetFieldChar(env, obj, fieldID) \
(((*(env))->GetFieldChar)(env, JRI_GetFieldChar_op, obj, fieldID))
#define JRI_GetFieldShort(env, obj, fieldID) \
(((*(env))->GetFieldShort)(env, JRI_GetFieldShort_op, obj, fieldID))
#define JRI_GetFieldInt(env, obj, fieldID) \
(((*(env))->GetFieldInt)(env, JRI_GetFieldInt_op, obj, fieldID))
#define JRI_GetFieldLong(env, obj, fieldID) \
(((*(env))->GetFieldLong)(env, JRI_GetFieldLong_op, obj, fieldID))
#define JRI_GetFieldFloat(env, obj, fieldID) \
(((*(env))->GetFieldFloat)(env, JRI_GetFieldFloat_op, obj, fieldID))
#define JRI_GetFieldDouble(env, obj, fieldID) \
(((*(env))->GetFieldDouble)(env, JRI_GetFieldDouble_op, obj, fieldID))
#define JRI_SetField(env, obj, fieldID, value) \
(((*(env))->SetField)(env, JRI_SetField_op, obj, fieldID, value))
#define JRI_SetFieldBoolean(env, obj, fieldID, value) \
(((*(env))->SetFieldBoolean)(env, JRI_SetFieldBoolean_op, obj, fieldID, value))
#define JRI_SetFieldByte(env, obj, fieldID, value) \
(((*(env))->SetFieldByte)(env, JRI_SetFieldByte_op, obj, fieldID, value))
#define JRI_SetFieldChar(env, obj, fieldID, value) \
(((*(env))->SetFieldChar)(env, JRI_SetFieldChar_op, obj, fieldID, value))
#define JRI_SetFieldShort(env, obj, fieldID, value) \
(((*(env))->SetFieldShort)(env, JRI_SetFieldShort_op, obj, fieldID, value))
#define JRI_SetFieldInt(env, obj, fieldID, value) \
(((*(env))->SetFieldInt)(env, JRI_SetFieldInt_op, obj, fieldID, value))
#define JRI_SetFieldLong(env, obj, fieldID, value) \
(((*(env))->SetFieldLong)(env, JRI_SetFieldLong_op, obj, fieldID, value))
#define JRI_SetFieldFloat(env, obj, fieldID, value) \
(((*(env))->SetFieldFloat)(env, JRI_SetFieldFloat_op, obj, fieldID, value))
#define JRI_SetFieldDouble(env, obj, fieldID, value) \
(((*(env))->SetFieldDouble)(env, JRI_SetFieldDouble_op, obj, fieldID, value))
#define JRI_IsSubclassOf(env, a, b) \
(((*(env))->IsSubclassOf)(env, JRI_IsSubclassOf_op, a, b))
#define JRI_GetStaticMethodID(env, clazz, name, sig) \
(((*(env))->GetStaticMethodID)(env, JRI_GetStaticMethodID_op, clazz, name, sig))
#define JRI_CallStaticMethod(env) ((*(env))->CallStaticMethod)
#define JRI_CallStaticMethodV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodV)(env, JRI_CallStaticMethod_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodA)(env, JRI_CallStaticMethod_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodBoolean(env) ((*(env))->CallStaticMethodBoolean)
#define JRI_CallStaticMethodBooleanV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodBooleanV)(env, JRI_CallStaticMethodBoolean_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodBooleanA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodBooleanA)(env, JRI_CallStaticMethodBoolean_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodByte(env) ((*(env))->CallStaticMethodByte)
#define JRI_CallStaticMethodByteV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodByteV)(env, JRI_CallStaticMethodByte_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodByteA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodByteA)(env, JRI_CallStaticMethodByte_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodChar(env) ((*(env))->CallStaticMethodChar)
#define JRI_CallStaticMethodCharV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodCharV)(env, JRI_CallStaticMethodChar_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodCharA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodCharA)(env, JRI_CallStaticMethodChar_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodShort(env) ((*(env))->CallStaticMethodShort)
#define JRI_CallStaticMethodShortV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodShortV)(env, JRI_CallStaticMethodShort_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodShortA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodShortA)(env, JRI_CallStaticMethodShort_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodInt(env) ((*(env))->CallStaticMethodInt)
#define JRI_CallStaticMethodIntV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodIntV)(env, JRI_CallStaticMethodInt_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodIntA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodIntA)(env, JRI_CallStaticMethodInt_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodLong(env) ((*(env))->CallStaticMethodLong)
#define JRI_CallStaticMethodLongV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodLongV)(env, JRI_CallStaticMethodLong_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodLongA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodLongA)(env, JRI_CallStaticMethodLong_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodFloat(env) ((*(env))->CallStaticMethodFloat)
#define JRI_CallStaticMethodFloatV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodFloatV)(env, JRI_CallStaticMethodFloat_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodFloatA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodFloatA)(env, JRI_CallStaticMethodFloat_op_array, clazz, methodID, args))
#define JRI_CallStaticMethodDouble(env) ((*(env))->CallStaticMethodDouble)
#define JRI_CallStaticMethodDoubleV(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodDoubleV)(env, JRI_CallStaticMethodDouble_op_va_list, clazz, methodID, args))
#define JRI_CallStaticMethodDoubleA(env, clazz, methodID, args) \
(((*(env))->CallStaticMethodDoubleA)(env, JRI_CallStaticMethodDouble_op_array, clazz, methodID, args))
#define JRI_GetStaticFieldID(env, clazz, name, sig) \
(((*(env))->GetStaticFieldID)(env, JRI_GetStaticFieldID_op, clazz, name, sig))
#define JRI_GetStaticField(env, clazz, fieldID) \
(((*(env))->GetStaticField)(env, JRI_GetStaticField_op, clazz, fieldID))
#define JRI_GetStaticFieldBoolean(env, clazz, fieldID) \
(((*(env))->GetStaticFieldBoolean)(env, JRI_GetStaticFieldBoolean_op, clazz, fieldID))
#define JRI_GetStaticFieldByte(env, clazz, fieldID) \
(((*(env))->GetStaticFieldByte)(env, JRI_GetStaticFieldByte_op, clazz, fieldID))
#define JRI_GetStaticFieldChar(env, clazz, fieldID) \
(((*(env))->GetStaticFieldChar)(env, JRI_GetStaticFieldChar_op, clazz, fieldID))
#define JRI_GetStaticFieldShort(env, clazz, fieldID) \
(((*(env))->GetStaticFieldShort)(env, JRI_GetStaticFieldShort_op, clazz, fieldID))
#define JRI_GetStaticFieldInt(env, clazz, fieldID) \
(((*(env))->GetStaticFieldInt)(env, JRI_GetStaticFieldInt_op, clazz, fieldID))
#define JRI_GetStaticFieldLong(env, clazz, fieldID) \
(((*(env))->GetStaticFieldLong)(env, JRI_GetStaticFieldLong_op, clazz, fieldID))
#define JRI_GetStaticFieldFloat(env, clazz, fieldID) \
(((*(env))->GetStaticFieldFloat)(env, JRI_GetStaticFieldFloat_op, clazz, fieldID))
#define JRI_GetStaticFieldDouble(env, clazz, fieldID) \
(((*(env))->GetStaticFieldDouble)(env, JRI_GetStaticFieldDouble_op, clazz, fieldID))
#define JRI_SetStaticField(env, clazz, fieldID, value) \
(((*(env))->SetStaticField)(env, JRI_SetStaticField_op, clazz, fieldID, value))
#define JRI_SetStaticFieldBoolean(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldBoolean)(env, JRI_SetStaticFieldBoolean_op, clazz, fieldID, value))
#define JRI_SetStaticFieldByte(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldByte)(env, JRI_SetStaticFieldByte_op, clazz, fieldID, value))
#define JRI_SetStaticFieldChar(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldChar)(env, JRI_SetStaticFieldChar_op, clazz, fieldID, value))
#define JRI_SetStaticFieldShort(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldShort)(env, JRI_SetStaticFieldShort_op, clazz, fieldID, value))
#define JRI_SetStaticFieldInt(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldInt)(env, JRI_SetStaticFieldInt_op, clazz, fieldID, value))
#define JRI_SetStaticFieldLong(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldLong)(env, JRI_SetStaticFieldLong_op, clazz, fieldID, value))
#define JRI_SetStaticFieldFloat(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldFloat)(env, JRI_SetStaticFieldFloat_op, clazz, fieldID, value))
#define JRI_SetStaticFieldDouble(env, clazz, fieldID, value) \
(((*(env))->SetStaticFieldDouble)(env, JRI_SetStaticFieldDouble_op, clazz, fieldID, value))
#define JRI_NewString(env, unicode, len) \
(((*(env))->NewString)(env, JRI_NewString_op, unicode, len))
#define JRI_GetStringLength(env, string) \
(((*(env))->GetStringLength)(env, JRI_GetStringLength_op, string))
#define JRI_GetStringChars(env, string) \
(((*(env))->GetStringChars)(env, JRI_GetStringChars_op, string))
#define JRI_NewStringUTF(env, utf, len) \
(((*(env))->NewStringUTF)(env, JRI_NewStringUTF_op, utf, len))
#define JRI_GetStringUTFLength(env, string) \
(((*(env))->GetStringUTFLength)(env, JRI_GetStringUTFLength_op, string))
#define JRI_GetStringUTFChars(env, string) \
(((*(env))->GetStringUTFChars)(env, JRI_GetStringUTFChars_op, string))
#define JRI_NewScalarArray(env, length, elementSig, initialElements) \
(((*(env))->NewScalarArray)(env, JRI_NewScalarArray_op, length, elementSig, initialElements))
#define JRI_GetScalarArrayLength(env, array) \
(((*(env))->GetScalarArrayLength)(env, JRI_GetScalarArrayLength_op, array))
#define JRI_GetScalarArrayElements(env, array) \
(((*(env))->GetScalarArrayElements)(env, JRI_GetScalarArrayElements_op, array))
#define JRI_NewObjectArray(env, length, elementClass, initialElement) \
(((*(env))->NewObjectArray)(env, JRI_NewObjectArray_op, length, elementClass, initialElement))
#define JRI_GetObjectArrayLength(env, array) \
(((*(env))->GetObjectArrayLength)(env, JRI_GetObjectArrayLength_op, array))
#define JRI_GetObjectArrayElement(env, array, index) \
(((*(env))->GetObjectArrayElement)(env, JRI_GetObjectArrayElement_op, array, index))
#define JRI_SetObjectArrayElement(env, array, index, value) \
(((*(env))->SetObjectArrayElement)(env, JRI_SetObjectArrayElement_op, array, index, value))
#define JRI_RegisterNatives(env, clazz, nameAndSigArray, nativeProcArray) \
(((*(env))->RegisterNatives)(env, JRI_RegisterNatives_op, clazz, nameAndSigArray, nativeProcArray))
#define JRI_UnregisterNatives(env, clazz) \
(((*(env))->UnregisterNatives)(env, JRI_UnregisterNatives_op, clazz))
/*******************************************************************************
* JRIEnv Interface
******************************************************************************/
struct java_lang_ClassLoader;
struct java_lang_Class;
struct java_lang_Throwable;
struct java_lang_Object;
struct java_lang_String;
struct JRIEnvInterface {
void* reserved0;
void* reserved1;
void* reserved2;
void* reserved3;
struct java_lang_Class* (*FindClass)(JRIEnv* env, jint op, const char* a);
void (*Throw)(JRIEnv* env, jint op, struct java_lang_Throwable* a);
void (*ThrowNew)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b);
struct java_lang_Throwable* (*ExceptionOccurred)(JRIEnv* env, jint op);
void (*ExceptionDescribe)(JRIEnv* env, jint op);
void (*ExceptionClear)(JRIEnv* env, jint op);
jglobal (*NewGlobalRef)(JRIEnv* env, jint op, void* a);
void (*DisposeGlobalRef)(JRIEnv* env, jint op, jglobal a);
void* (*GetGlobalRef)(JRIEnv* env, jint op, jglobal a);
void (*SetGlobalRef)(JRIEnv* env, jint op, jglobal a, void* b);
jbool (*IsSameObject)(JRIEnv* env, jint op, void* a, void* b);
void* (*NewObject)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
void* (*NewObjectV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
void* (*NewObjectA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
struct java_lang_Class* (*GetObjectClass)(JRIEnv* env, jint op, void* a);
jbool (*IsInstanceOf)(JRIEnv* env, jint op, void* a, struct java_lang_Class* b);
jint (*GetMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c);
void* (*CallMethod)(JRIEnv* env, jint op, void* a, jint b, ...);
void* (*CallMethodV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
void* (*CallMethodA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jbool (*CallMethodBoolean)(JRIEnv* env, jint op, void* a, jint b, ...);
jbool (*CallMethodBooleanV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jbool (*CallMethodBooleanA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jbyte (*CallMethodByte)(JRIEnv* env, jint op, void* a, jint b, ...);
jbyte (*CallMethodByteV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jbyte (*CallMethodByteA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jchar (*CallMethodChar)(JRIEnv* env, jint op, void* a, jint b, ...);
jchar (*CallMethodCharV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jchar (*CallMethodCharA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jshort (*CallMethodShort)(JRIEnv* env, jint op, void* a, jint b, ...);
jshort (*CallMethodShortV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jshort (*CallMethodShortA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jint (*CallMethodInt)(JRIEnv* env, jint op, void* a, jint b, ...);
jint (*CallMethodIntV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jint (*CallMethodIntA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jlong (*CallMethodLong)(JRIEnv* env, jint op, void* a, jint b, ...);
jlong (*CallMethodLongV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jlong (*CallMethodLongA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jfloat (*CallMethodFloat)(JRIEnv* env, jint op, void* a, jint b, ...);
jfloat (*CallMethodFloatV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jfloat (*CallMethodFloatA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jdouble (*CallMethodDouble)(JRIEnv* env, jint op, void* a, jint b, ...);
jdouble (*CallMethodDoubleV)(JRIEnv* env, jint op, void* a, jint b, va_list c);
jdouble (*CallMethodDoubleA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c);
jint (*GetFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c);
void* (*GetField)(JRIEnv* env, jint op, void* a, jint b);
jbool (*GetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b);
jbyte (*GetFieldByte)(JRIEnv* env, jint op, void* a, jint b);
jchar (*GetFieldChar)(JRIEnv* env, jint op, void* a, jint b);
jshort (*GetFieldShort)(JRIEnv* env, jint op, void* a, jint b);
jint (*GetFieldInt)(JRIEnv* env, jint op, void* a, jint b);
jlong (*GetFieldLong)(JRIEnv* env, jint op, void* a, jint b);
jfloat (*GetFieldFloat)(JRIEnv* env, jint op, void* a, jint b);
jdouble (*GetFieldDouble)(JRIEnv* env, jint op, void* a, jint b);
void (*SetField)(JRIEnv* env, jint op, void* a, jint b, void* c);
void (*SetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b, jbool c);
void (*SetFieldByte)(JRIEnv* env, jint op, void* a, jint b, jbyte c);
void (*SetFieldChar)(JRIEnv* env, jint op, void* a, jint b, jchar c);
void (*SetFieldShort)(JRIEnv* env, jint op, void* a, jint b, jshort c);
void (*SetFieldInt)(JRIEnv* env, jint op, void* a, jint b, jint c);
void (*SetFieldLong)(JRIEnv* env, jint op, void* a, jint b, jlong c);
void (*SetFieldFloat)(JRIEnv* env, jint op, void* a, jint b, jfloat c);
void (*SetFieldDouble)(JRIEnv* env, jint op, void* a, jint b, jdouble c);
jbool (*IsSubclassOf)(JRIEnv* env, jint op, struct java_lang_Class* a, struct java_lang_Class* b);
jint (*GetStaticMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c);
void* (*CallStaticMethod)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
void* (*CallStaticMethodV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
void* (*CallStaticMethodA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jbool (*CallStaticMethodBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jbool (*CallStaticMethodBooleanV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jbool (*CallStaticMethodBooleanA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jbyte (*CallStaticMethodByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jbyte (*CallStaticMethodByteV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jbyte (*CallStaticMethodByteA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jchar (*CallStaticMethodChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jchar (*CallStaticMethodCharV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jchar (*CallStaticMethodCharA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jshort (*CallStaticMethodShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jshort (*CallStaticMethodShortV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jshort (*CallStaticMethodShortA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jint (*CallStaticMethodInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jint (*CallStaticMethodIntV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jint (*CallStaticMethodIntA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jlong (*CallStaticMethodLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jlong (*CallStaticMethodLongV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jlong (*CallStaticMethodLongA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jfloat (*CallStaticMethodFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jfloat (*CallStaticMethodFloatV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jfloat (*CallStaticMethodFloatA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jdouble (*CallStaticMethodDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...);
jdouble (*CallStaticMethodDoubleV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c);
jdouble (*CallStaticMethodDoubleA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c);
jint (*GetStaticFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c);
void* (*GetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jbool (*GetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jbyte (*GetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jchar (*GetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jshort (*GetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jint (*GetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jlong (*GetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jfloat (*GetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
jdouble (*GetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b);
void (*SetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, void* c);
void (*SetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbool c);
void (*SetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbyte c);
void (*SetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jchar c);
void (*SetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jshort c);
void (*SetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jint c);
void (*SetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jlong c);
void (*SetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jfloat c);
void (*SetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jdouble c);
struct java_lang_String* (*NewString)(JRIEnv* env, jint op, const jchar* a, jint b);
jint (*GetStringLength)(JRIEnv* env, jint op, struct java_lang_String* a);
const jchar* (*GetStringChars)(JRIEnv* env, jint op, struct java_lang_String* a);
struct java_lang_String* (*NewStringUTF)(JRIEnv* env, jint op, const jbyte* a, jint b);
jint (*GetStringUTFLength)(JRIEnv* env, jint op, struct java_lang_String* a);
const jbyte* (*GetStringUTFChars)(JRIEnv* env, jint op, struct java_lang_String* a);
void* (*NewScalarArray)(JRIEnv* env, jint op, jint a, const char* b, const jbyte* c);
jint (*GetScalarArrayLength)(JRIEnv* env, jint op, void* a);
jbyte* (*GetScalarArrayElements)(JRIEnv* env, jint op, void* a);
void* (*NewObjectArray)(JRIEnv* env, jint op, jint a, struct java_lang_Class* b, void* c);
jint (*GetObjectArrayLength)(JRIEnv* env, jint op, void* a);
void* (*GetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b);
void (*SetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b, void* c);
void (*RegisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a, char** b, void** c);
void (*UnregisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a);
struct java_lang_Class* (*DefineClass)(JRIEnv* env, jint op, struct java_lang_ClassLoader* a, jbyte* b, jsize bLen);
};
/*******************************************************************************
* JRIEnv Operation IDs
******************************************************************************/
typedef enum JRIEnvOperations {
JRI_Reserved0_op,
JRI_Reserved1_op,
JRI_Reserved2_op,
JRI_Reserved3_op,
JRI_FindClass_op,
JRI_Throw_op,
JRI_ThrowNew_op,
JRI_ExceptionOccurred_op,
JRI_ExceptionDescribe_op,
JRI_ExceptionClear_op,
JRI_NewGlobalRef_op,
JRI_DisposeGlobalRef_op,
JRI_GetGlobalRef_op,
JRI_SetGlobalRef_op,
JRI_IsSameObject_op,
JRI_NewObject_op,
JRI_NewObject_op_va_list,
JRI_NewObject_op_array,
JRI_GetObjectClass_op,
JRI_IsInstanceOf_op,
JRI_GetMethodID_op,
JRI_CallMethod_op,
JRI_CallMethod_op_va_list,
JRI_CallMethod_op_array,
JRI_CallMethodBoolean_op,
JRI_CallMethodBoolean_op_va_list,
JRI_CallMethodBoolean_op_array,
JRI_CallMethodByte_op,
JRI_CallMethodByte_op_va_list,
JRI_CallMethodByte_op_array,
JRI_CallMethodChar_op,
JRI_CallMethodChar_op_va_list,
JRI_CallMethodChar_op_array,
JRI_CallMethodShort_op,
JRI_CallMethodShort_op_va_list,
JRI_CallMethodShort_op_array,
JRI_CallMethodInt_op,
JRI_CallMethodInt_op_va_list,
JRI_CallMethodInt_op_array,
JRI_CallMethodLong_op,
JRI_CallMethodLong_op_va_list,
JRI_CallMethodLong_op_array,
JRI_CallMethodFloat_op,
JRI_CallMethodFloat_op_va_list,
JRI_CallMethodFloat_op_array,
JRI_CallMethodDouble_op,
JRI_CallMethodDouble_op_va_list,
JRI_CallMethodDouble_op_array,
JRI_GetFieldID_op,
JRI_GetField_op,
JRI_GetFieldBoolean_op,
JRI_GetFieldByte_op,
JRI_GetFieldChar_op,
JRI_GetFieldShort_op,
JRI_GetFieldInt_op,
JRI_GetFieldLong_op,
JRI_GetFieldFloat_op,
JRI_GetFieldDouble_op,
JRI_SetField_op,
JRI_SetFieldBoolean_op,
JRI_SetFieldByte_op,
JRI_SetFieldChar_op,
JRI_SetFieldShort_op,
JRI_SetFieldInt_op,
JRI_SetFieldLong_op,
JRI_SetFieldFloat_op,
JRI_SetFieldDouble_op,
JRI_IsSubclassOf_op,
JRI_GetStaticMethodID_op,
JRI_CallStaticMethod_op,
JRI_CallStaticMethod_op_va_list,
JRI_CallStaticMethod_op_array,
JRI_CallStaticMethodBoolean_op,
JRI_CallStaticMethodBoolean_op_va_list,
JRI_CallStaticMethodBoolean_op_array,
JRI_CallStaticMethodByte_op,
JRI_CallStaticMethodByte_op_va_list,
JRI_CallStaticMethodByte_op_array,
JRI_CallStaticMethodChar_op,
JRI_CallStaticMethodChar_op_va_list,
JRI_CallStaticMethodChar_op_array,
JRI_CallStaticMethodShort_op,
JRI_CallStaticMethodShort_op_va_list,
JRI_CallStaticMethodShort_op_array,
JRI_CallStaticMethodInt_op,
JRI_CallStaticMethodInt_op_va_list,
JRI_CallStaticMethodInt_op_array,
JRI_CallStaticMethodLong_op,
JRI_CallStaticMethodLong_op_va_list,
JRI_CallStaticMethodLong_op_array,
JRI_CallStaticMethodFloat_op,
JRI_CallStaticMethodFloat_op_va_list,
JRI_CallStaticMethodFloat_op_array,
JRI_CallStaticMethodDouble_op,
JRI_CallStaticMethodDouble_op_va_list,
JRI_CallStaticMethodDouble_op_array,
JRI_GetStaticFieldID_op,
JRI_GetStaticField_op,
JRI_GetStaticFieldBoolean_op,
JRI_GetStaticFieldByte_op,
JRI_GetStaticFieldChar_op,
JRI_GetStaticFieldShort_op,
JRI_GetStaticFieldInt_op,
JRI_GetStaticFieldLong_op,
JRI_GetStaticFieldFloat_op,
JRI_GetStaticFieldDouble_op,
JRI_SetStaticField_op,
JRI_SetStaticFieldBoolean_op,
JRI_SetStaticFieldByte_op,
JRI_SetStaticFieldChar_op,
JRI_SetStaticFieldShort_op,
JRI_SetStaticFieldInt_op,
JRI_SetStaticFieldLong_op,
JRI_SetStaticFieldFloat_op,
JRI_SetStaticFieldDouble_op,
JRI_NewString_op,
JRI_GetStringLength_op,
JRI_GetStringChars_op,
JRI_NewStringUTF_op,
JRI_GetStringUTFLength_op,
JRI_GetStringUTFChars_op,
JRI_NewScalarArray_op,
JRI_GetScalarArrayLength_op,
JRI_GetScalarArrayElements_op,
JRI_NewObjectArray_op,
JRI_GetObjectArrayLength_op,
JRI_GetObjectArrayElement_op,
JRI_SetObjectArrayElement_op,
JRI_RegisterNatives_op,
JRI_UnregisterNatives_op,
JRI_DefineClass_op
} JRIEnvOperations;
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* JRI_H */
/******************************************************************************/

View File

@@ -0,0 +1,196 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: jri_md.h,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/*******************************************************************************
* Java Runtime Interface - Machine Dependent Types
* Copyright (c) 1996 Netscape Communications Corporation. All rights reserved.
******************************************************************************/
#ifndef JRI_MD_H
#define JRI_MD_H
#include <assert.h>
#include "jni.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* WHAT'S UP WITH THIS FILE?
*
* This is where we define the mystical JRI_PUBLIC_API macro that works on all
* platforms. If you're running with Visual C++, Symantec C, or Borland's
* development environment on the PC, you're all set. Or if you're on the Mac
* with Metrowerks, Symantec or MPW with SC you're ok too. For UNIX it shouldn't
* matter.
*
* On UNIX though you probably care about a couple of other symbols though:
* IS_LITTLE_ENDIAN must be defined for little-endian systems
* HAVE_LONG_LONG must be defined on systems that have 'long long' integers
* HAVE_ALIGNED_LONGLONGS must be defined if long-longs must be 8 byte aligned
* HAVE_ALIGNED_DOUBLES must be defined if doubles must be 8 byte aligned
* IS_64 must be defined on 64-bit machines (like Dec Alpha)
******************************************************************************/
/* DLL Entry modifiers... */
/* PC */
#if defined(XP_PC) || defined(_WINDOWS) || defined(WIN32) || defined(_WIN32)
# include <windows.h>
# if defined(_MSC_VER)
# if defined(WIN32) || defined(_WIN32)
# define JRI_PUBLIC_API(ResultType) _declspec(dllexport) ResultType
# define JRI_CALLBACK
# else /* !_WIN32 */
# if defined(_WINDLL)
# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export __loadds
# define JRI_CALLBACK __loadds
# else /* !WINDLL */
# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export
# define JRI_CALLBACK __export
# endif /* !WINDLL */
# endif /* !_WIN32 */
# elif defined(__BORLANDC__)
# if defined(WIN32) || defined(_WIN32)
# define JRI_PUBLIC_API(ResultType) __export ResultType
# define JRI_CALLBACK
# else /* !_WIN32 */
# define JRI_PUBLIC_API(ResultType) ResultType _cdecl _export _loadds
# define JRI_CALLBACK _loadds
# endif
# else
# error Unsupported PC development environment.
# endif
# ifndef IS_LITTLE_ENDIAN
# define IS_LITTLE_ENDIAN
# endif
/* Mac */
#elif macintosh || Macintosh || THINK_C
# if defined(__MWERKS__) /* Metrowerks */
# if !__option(enumsalwaysint)
# error You need to define 'Enums Always Int' for your project.
# endif
# if defined(GENERATING68K) && !GENERATINGCFM
# if !__option(fourbyteints)
# error You need to define 'Struct Alignment: 68k' for your project.
# endif
# endif /* !GENERATINGCFM */
# elif defined(__SC__) /* Symantec */
# error What are the Symantec defines? (warren@netscape.com)
# elif macintosh && applec /* MPW */
# error Please upgrade to the latest MPW compiler (SC).
# else
# error Unsupported Mac development environment.
# endif
# define JRI_PUBLIC_API(ResultType) ResultType
# define JRI_CALLBACK
/* Unix or else */
#else
# define JRI_PUBLIC_API(ResultType) ResultType
# define JRI_CALLBACK
#endif
#ifndef FAR /* for non-Win16 */
#define FAR
#endif
/******************************************************************************/
/* Java Scalar Types */
typedef unsigned char jbool;
#ifdef IS_64 /* XXX ok for alpha, but not right on all 64-bit architectures */
typedef unsigned int juint;
typedef int jint;
#else
typedef unsigned long juint;
#endif
/******************************************************************************/
/*
** JDK Stuff -- This stuff is still needed while we're using the JDK
** dynamic linking strategy to call native methods.
*/
typedef union JRI_JDK_stack_item {
/* Non pointer items */
jint i;
jfloat f;
jint o;
/* Pointer items */
void *h;
void *p;
unsigned char *addr;
#ifdef IS_64
double d;
long l; /* == 64bits! */
#endif
} JRI_JDK_stack_item;
typedef union JRI_JDK_Java8Str {
jint x[2];
jdouble d;
jlong l;
void *p;
float f;
} JRI_JDK_Java8;
#ifdef HAVE_ALIGNED_LONGLONGS
#define JRI_GET_INT64(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \
((_t).x[1] = ((jint*)(_addr))[1]), \
(_t).l )
#define JRI_SET_INT64(_t, _addr, _v) ( (_t).l = (_v), \
((jint*)(_addr))[0] = (_t).x[0], \
((jint*)(_addr))[1] = (_t).x[1] )
#else
#define JRI_GET_INT64(_t,_addr) (*(jlong*)(_addr))
#define JRI_SET_INT64(_t, _addr, _v) (*(jlong*)(_addr) = (_v))
#endif
/* If double's must be aligned on doubleword boundaries then define this */
#ifdef HAVE_ALIGNED_DOUBLES
#define JRI_GET_DOUBLE(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \
((_t).x[1] = ((jint*)(_addr))[1]), \
(_t).d )
#define JRI_SET_DOUBLE(_t, _addr, _v) ( (_t).d = (_v), \
((jint*)(_addr))[0] = (_t).x[0], \
((jint*)(_addr))[1] = (_t).x[1] )
#else
#define JRI_GET_DOUBLE(_t,_addr) (*(jdouble*)(_addr))
#define JRI_SET_DOUBLE(_t, _addr, _v) (*(jdouble*)(_addr) = (_v))
#endif
/******************************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* JRI_MD_H */
/******************************************************************************/

View File

@@ -0,0 +1,193 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: jritypes.h,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/*******************************************************************************
* Java Runtime Interface
* Copyright (c) 1996 Netscape Communications Corporation. All rights reserved.
******************************************************************************/
#ifndef JRITYPES_H
#define JRITYPES_H
#include "jri_md.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Types
******************************************************************************/
struct JRIEnvInterface;
typedef void* JRIRef;
typedef void* JRIGlobalRef;
typedef jint JRIInterfaceID[4];
typedef jint JRIFieldID;
typedef jint JRIMethodID;
/* synonyms: */
typedef JRIGlobalRef jglobal;
typedef JRIRef jref;
typedef union JRIValue {
jbool z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong l;
jfloat f;
jdouble d;
jref r;
} JRIValue;
typedef enum JRIBoolean {
JRIFalse = 0,
JRITrue = 1
} JRIBoolean;
typedef enum JRIConstant {
JRIUninitialized = -1
} JRIConstant;
/* convenience types: */
#define JRIConstructorMethodName "<init>"
/*******************************************************************************
* Signature Construction Macros
******************************************************************************/
/*
** These macros can be used to construct signature strings. Hopefully their names
** are a little easier to remember than the single character they correspond to.
** For example, to specify the signature of the method:
**
** public int read(byte b[], int off, int len);
**
** you could write something like this in C:
**
** char* readSig = JRISigMethod(JRISigArray(JRISigByte)
** JRISigInt
** JRISigInt) JRISigInt;
**
** Of course, don't put commas between the types.
*/
#define JRISigArray(T) "[" T
#define JRISigByte "B"
#define JRISigChar "C"
#define JRISigClass(name) "L" name ";"
#define JRISigFloat "F"
#define JRISigDouble "D"
#define JRISigMethod(args) "(" args ")"
#define JRISigNoArgs ""
#define JRISigInt "I"
#define JRISigLong "J"
#define JRISigShort "S"
#define JRISigVoid "V"
#define JRISigBoolean "Z"
/*******************************************************************************
* Environments
******************************************************************************/
extern JRI_PUBLIC_API(const struct JRIEnvInterface**)
JRI_GetCurrentEnv(void);
/*******************************************************************************
* Specific Scalar Array Types
******************************************************************************/
/*
** The JRI Native Method Interface does not support boolean arrays. This
** is to allow Java runtime implementations to optimize boolean array
** storage. Using the ScalarArray operations on boolean arrays is bound
** to fail, so convert any boolean arrays to byte arrays in Java before
** passing them to a native method.
*/
#define JRI_NewByteArray(env, length, initialValues) \
JRI_NewScalarArray(env, length, JRISigByte, (jbyte*)(initialValues))
#define JRI_GetByteArrayLength(env, array) \
JRI_GetScalarArrayLength(env, array)
#define JRI_GetByteArrayElements(env, array) \
JRI_GetScalarArrayElements(env, array)
#define JRI_NewCharArray(env, length, initialValues) \
JRI_NewScalarArray(env, ((length) * sizeof(jchar)), JRISigChar, (jbyte*)(initialValues))
#define JRI_GetCharArrayLength(env, array) \
JRI_GetScalarArrayLength(env, array)
#define JRI_GetCharArrayElements(env, array) \
((jchar*)JRI_GetScalarArrayElements(env, array))
#define JRI_NewShortArray(env, length, initialValues) \
JRI_NewScalarArray(env, ((length) * sizeof(jshort)), JRISigShort, (jbyte*)(initialValues))
#define JRI_GetShortArrayLength(env, array) \
JRI_GetScalarArrayLength(env, array)
#define JRI_GetShortArrayElements(env, array) \
((jshort*)JRI_GetScalarArrayElements(env, array))
#define JRI_NewIntArray(env, length, initialValues) \
JRI_NewScalarArray(env, ((length) * sizeof(jint)), JRISigInt, (jbyte*)(initialValues))
#define JRI_GetIntArrayLength(env, array) \
JRI_GetScalarArrayLength(env, array)
#define JRI_GetIntArrayElements(env, array) \
((jint*)JRI_GetScalarArrayElements(env, array))
#define JRI_NewLongArray(env, length, initialValues) \
JRI_NewScalarArray(env, ((length) * sizeof(jlong)), JRISigLong, (jbyte*)(initialValues))
#define JRI_GetLongArrayLength(env, array) \
JRI_GetScalarArrayLength(env, array)
#define JRI_GetLongArrayElements(env, array) \
((jlong*)JRI_GetScalarArrayElements(env, array))
#define JRI_NewFloatArray(env, length, initialValues) \
JRI_NewScalarArray(env, ((length) * sizeof(jfloat)), JRISigFloat, (jbyte*)(initialValues))
#define JRI_GetFloatArrayLength(env, array) \
JRI_GetScalarArrayLength(env, array)
#define JRI_GetFloatArrayElements(env, array) \
((jfloat*)JRI_GetScalarArrayElements(env, array))
#define JRI_NewDoubleArray(env, length, initialValues) \
JRI_NewScalarArray(env, ((length) * sizeof(jdouble)), JRISigDouble, (jbyte*)(initialValues))
#define JRI_GetDoubleArrayLength(env, array) \
JRI_GetScalarArrayLength(env, array)
#define JRI_GetDoubleArrayElements(env, array) \
((jdouble*)JRI_GetScalarArrayElements(env, array))
/******************************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* JRITYPES_H */
/******************************************************************************/

View File

@@ -0,0 +1,438 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: npapi.h,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/*
* npapi.h $Revision: 1.1.1.1 $
* Netscape client plug-in API spec
*/
#ifndef _NPAPI_H_
#define _NPAPI_H_
#ifdef _WINDOWS
# ifndef XP_PC
# define XP_PC 1
# endif /* XP_PC */
#endif /* _WINDOWS */
#ifdef __MWERKS__
# define _declspec __declspec
# ifdef macintosh
# ifndef XP_MAC
# define XP_MAC 1
# endif /* XP_MAC */
# endif /* macintosh */
# ifdef __INTEL__
# undef NULL
# ifndef XP_PC
# define XP_PC 1
# endif /* __INTEL__ */
# endif /* XP_PC */
#endif /* __MWERKS__ */
#include "jri.h" /* Java Runtime Interface */
/*----------------------------------------------------------------------*/
/* Plugin Version Constants */
/*----------------------------------------------------------------------*/
#define NP_VERSION_MAJOR 0
#define NP_VERSION_MINOR 9
/*----------------------------------------------------------------------*/
/* Definition of Basic Types */
/*----------------------------------------------------------------------*/
#ifndef _UINT16
typedef unsigned short uint16;
#endif
#ifndef _UINT32
#if defined(__alpha)
typedef unsigned int uint32;
#else /* __alpha */
typedef unsigned long uint32;
#endif /* __alpha */
#endif
#ifndef _INT16
typedef short int16;
#endif
#ifndef _INT32
#if defined(__alpha)
typedef int int32;
#else /* __alpha */
typedef long int32;
#endif /* __alpha */
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef NULL
#define NULL (0L)
#endif
typedef unsigned char NPBool;
typedef void* NPEvent;
typedef int16 NPError;
typedef int16 NPReason;
typedef char* NPMIMEType;
/*----------------------------------------------------------------------*/
/* Structures and definitions */
/*----------------------------------------------------------------------*/
/*
* NPP is a plug-in's opaque instance handle
*/
typedef struct _NPP
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
} NPP_t;
typedef NPP_t* NPP;
typedef struct _NPStream
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
const char* url;
uint32 end;
uint32 lastmodified;
void* notifyData;
} NPStream;
typedef struct _NPByteRange
{
int32 offset; /* negative offset means from the end */
uint32 length;
struct _NPByteRange* next;
} NPByteRange;
typedef struct _NPSavedData
{
int32 len;
void* buf;
} NPSavedData;
typedef struct _NPRect
{
uint16 top;
uint16 left;
uint16 bottom;
uint16 right;
} NPRect;
#ifdef XP_UNIX
/*
* Unix specific structures and definitions
*/
#include <X11/Xlib.h>
/*
* Callback Structures.
*
* These are used to pass additional platform specific information.
*/
enum {
NP_SETWINDOW = 1,
NP_PRINT
};
typedef struct
{
int32 type;
} NPAnyCallbackStruct;
typedef struct
{
int32 type;
Display* display;
Visual* visual;
Colormap colormap;
unsigned int depth;
} NPSetWindowCallbackStruct;
typedef struct
{
int32 type;
FILE* fp;
} NPPrintCallbackStruct;
/*
* List of variable names for which NPP_GetValue shall be implemented
*/
typedef enum {
NPPVpluginNameString = 1,
NPPVpluginDescriptionString
} NPPVariable;
/*
* List of variable names for which NPN_GetValue is implemented by Mozilla
*/
typedef enum {
NPNVxDisplay = 1,
NPNVxtAppContext
} NPNVariable;
#endif /* XP_UNIX */
typedef struct _NPWindow
{
void* window; /* Platform specific window handle */
uint32 x; /* Position of top left corner relative */
uint32 y; /* to a netscape page. */
uint32 width; /* Maximum window size */
uint32 height;
NPRect clipRect; /* Clipping rectangle in port coordinates */
/* Used by MAC only. */
#ifdef XP_UNIX
void * ws_info; /* Platform-dependent additonal data */
#endif /* XP_UNIX */
} NPWindow;
typedef struct _NPFullPrint
{
NPBool pluginPrinted; /* Set TRUE if plugin handled fullscreen */
/* printing */
NPBool printOne; /* TRUE if plugin should print one copy */
/* to default printer */
void* platformPrint; /* Platform-specific printing info */
} NPFullPrint;
typedef struct _NPEmbedPrint
{
NPWindow window;
void* platformPrint; /* Platform-specific printing info */
} NPEmbedPrint;
typedef struct _NPPrint
{
uint16 mode; /* NP_FULL or NP_EMBED */
union
{
NPFullPrint fullPrint; /* if mode is NP_FULL */
NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
} print;
} NPPrint;
#ifdef XP_MAC
/*
* Mac-specific structures and definitions.
*/
#include <Quickdraw.h>
#include <Events.h>
typedef struct NP_Port
{
CGrafPtr port; /* Grafport */
int32 portx; /* position inside the topmost window */
int32 porty;
} NP_Port;
/*
* Non-standard event types that can be passed to HandleEvent
*/
#define getFocusEvent (osEvt + 16)
#define loseFocusEvent (osEvt + 17)
#define adjustCursorEvent (osEvt + 18)
#endif /* XP_MAC */
/*
* Values for mode passed to NPP_New:
*/
#define NP_EMBED 1
#define NP_FULL 2
/*
* Values for stream type passed to NPP_NewStream:
*/
#define NP_NORMAL 1
#define NP_SEEK 2
#define NP_ASFILE 3
#define NP_ASFILEONLY 4
#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
/*----------------------------------------------------------------------*/
/* Error and Reason Code definitions */
/*----------------------------------------------------------------------*/
/*
* Values of type NPError:
*/
#define NPERR_BASE 0
#define NPERR_NO_ERROR (NPERR_BASE + 0)
#define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
#define NPERR_INVALID_PARAM (NPERR_BASE + 9)
#define NPERR_INVALID_URL (NPERR_BASE + 10)
#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
#define NPERR_NO_DATA (NPERR_BASE + 12)
#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
/*
* Values of type NPReason:
*/
#define NPRES_BASE 0
#define NPRES_DONE (NPRES_BASE + 0)
#define NPRES_NETWORK_ERR (NPRES_BASE + 1)
#define NPRES_USER_BREAK (NPRES_BASE + 2)
/*
* Don't use these obsolete error codes any more.
*/
#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
/*
* Version feature information
*/
#define NPVERS_HAS_STREAMOUTPUT 8
#define NPVERS_HAS_NOTIFICATION 9
#define NPVERS_HAS_LIVECONNECT 9
#define NPVERS_WIN16_HAS_LIVECONNECT 10
/*----------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------*/
#if defined(_WINDOWS) && !defined(WIN32)
#define NP_LOADDS _loadds
#else
#define NP_LOADDS
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* NPP_* functions are provided by the plugin and called by the navigator.
*/
#ifdef XP_UNIX
char* NPP_GetMIMEDescription(void);
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
NPError NPN_SetValue(void* foo, void *val, void* value);
#endif /* XP_UNIX */
NPError NPP_Initialize(void);
void NPP_Shutdown(void);
NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
uint16 mode, int16 argc, char* argn[],
char* argv[], NPSavedData* saved);
NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
NPStream* stream, NPBool seekable,
uint16* stype);
NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset,
int32 len, void* buffer);
void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
const char* fname);
void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
int16 NP_LOADDS NPP_HandleEvent(NPP instance, void* event);
void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
NPReason reason, void* notifyData);
jref NP_LOADDS NPP_GetJavaClass(void);
/*
* NPN_* functions are provided by the navigator and called by the plugin.
*/
#ifdef XP_UNIX
NPError NPN_GetValue(NPP instance, NPNVariable variable,
void *value);
#endif /* XP_UNIX */
void NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor);
NPError NPN_GetURLNotify(NPP instance, const char* url,
const char* target, void* notifyData);
NPError NPN_GetURL(NPP instance, const char* url,
const char* target);
NPError NPN_PostURLNotify(NPP instance, const char* url,
const char* target, uint32 len,
const char* buf, NPBool file,
void* notifyData);
NPError NPN_PostURL(NPP instance, const char* url,
const char* target, uint32 len,
const char* buf, NPBool file);
NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
NPError NPN_NewStream(NPP instance, NPMIMEType type,
const char* target, NPStream** stream);
int32 NPN_Write(NPP instance, NPStream* stream, int32 len,
void* buffer);
NPError NPN_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
void NPN_Status(NPP instance, const char* message);
const char* NPN_UserAgent(NPP instance);
void* NPN_MemAlloc(uint32 size);
void NPN_MemFree(void* ptr);
uint32 NPN_MemFlush(uint32 size);
void NPN_ReloadPlugins(NPBool reloadPages);
JRIEnv* NPN_GetJavaEnv(void);
jref NPN_GetJavaPeer(NPP instance);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* _NPAPI_H_ */

View File

@@ -0,0 +1,420 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: npapi.h.my,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/*
* npapi.h $Revision: 1.1.1.1 $
* Netscape client plug-in API spec
*/
#ifndef _NPAPI_H_
#define _NPAPI_H_
/*#include "jri.h" */ /* Java Runtime Interface */
/* XXX this needs to get out of here */
#if defined(__MWERKS__)
#ifndef XP_MAC
#define XP_MAC
#endif
#endif
/*----------------------------------------------------------------------*/
/* Plugin Version Constants */
/*----------------------------------------------------------------------*/
#define NP_VERSION_MAJOR 0
#define NP_VERSION_MINOR 9
/*----------------------------------------------------------------------*/
/* Definition of Basic Types */
/*----------------------------------------------------------------------*/
#ifndef _UINT16
typedef unsigned short uint16;
#endif
#ifndef _UINT32
#if defined(__alpha)
typedef unsigned int uint32;
#else /* __alpha */
typedef unsigned long uint32;
#endif /* __alpha */
#endif
#ifndef _INT16
typedef short int16;
#endif
#ifndef _INT32
#if defined(__alpha)
typedef int int32;
#else /* __alpha */
typedef long int32;
#endif /* __alpha */
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef NULL
#define NULL (0L)
#endif
typedef unsigned char NPBool;
typedef void* NPEvent;
typedef int16 NPError;
typedef int16 NPReason;
typedef char* NPMIMEType;
/*----------------------------------------------------------------------*/
/* Structures and definitions */
/*----------------------------------------------------------------------*/
/*
* NPP is a plug-in's opaque instance handle
*/
typedef struct _NPP
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
} NPP_t;
typedef NPP_t* NPP;
typedef struct _NPStream
{
void* pdata; /* plug-in private data */
void* ndata; /* netscape private data */
const char* url;
uint32 end;
uint32 lastmodified;
void* notifyData;
} NPStream;
typedef struct _NPByteRange
{
int32 offset; /* negative offset means from the end */
uint32 length;
struct _NPByteRange* next;
} NPByteRange;
typedef struct _NPSavedData
{
int32 len;
void* buf;
} NPSavedData;
typedef struct _NPRect
{
uint16 top;
uint16 left;
uint16 bottom;
uint16 right;
} NPRect;
#ifdef XP_UNIX
/*
* Unix specific structures and definitions
*/
#include <X11/Xlib.h>
/*
* Callback Structures.
*
* These are used to pass additional platform specific information.
*/
enum {
NP_SETWINDOW = 1
};
typedef struct
{
int32 type;
} NPAnyCallbackStruct;
typedef struct
{
int32 type;
Display* display;
Visual* visual;
Colormap colormap;
unsigned int depth;
} NPSetWindowCallbackStruct;
/*
* List of variable names for which NPP_GetValue shall be implemented
*/
typedef enum {
NPPVpluginNameString = 1,
NPPVpluginDescriptionString
} NPPVariable;
/*
* List of variable names for which NPN_GetValue is implemented by Mozilla
*/
typedef enum {
NPNVxDisplay = 1,
NPNVxtAppContext
} NPNVariable;
#endif /* XP_UNIX */
typedef struct _NPWindow
{
void* window; /* Platform specific window handle */
uint32 x; /* Position of top left corner relative */
uint32 y; /* to a netscape page. */
uint32 width; /* Maximum window size */
uint32 height;
NPRect clipRect; /* Clipping rectangle in port coordinates */
/* Used by MAC only. */
#ifdef XP_UNIX
void * ws_info; /* Platform-dependent additonal data */
#endif /* XP_UNIX */
} NPWindow;
typedef struct _NPFullPrint
{
NPBool pluginPrinted; /* Set TRUE if plugin handled fullscreen */
/* printing */
NPBool printOne; /* TRUE if plugin should print one copy */
/* to default printer */
void* platformPrint; /* Platform-specific printing info */
} NPFullPrint;
typedef struct _NPEmbedPrint
{
NPWindow window;
void* platformPrint; /* Platform-specific printing info */
} NPEmbedPrint;
typedef struct _NPPrint
{
uint16 mode; /* NP_FULL or NP_EMBED */
union
{
NPFullPrint fullPrint; /* if mode is NP_FULL */
NPEmbedPrint embedPrint; /* if mode is NP_EMBED */
} print;
} NPPrint;
#ifdef XP_MAC
/*
* Mac-specific structures and definitions.
*/
#include <Quickdraw.h>
#include <Events.h>
typedef struct NP_Port
{
CGrafPtr port; /* Grafport */
int32 portx; /* position inside the topmost window */
int32 porty;
} NP_Port;
/*
* Non-standard event types that can be passed to HandleEvent
*/
#define getFocusEvent (osEvt + 16)
#define loseFocusEvent (osEvt + 17)
#define adjustCursorEvent (osEvt + 18)
#endif /* XP_MAC */
/*
* Values for mode passed to NPP_New:
*/
#define NP_EMBED 1
#define NP_FULL 2
/*
* Values for stream type passed to NPP_NewStream:
*/
#define NP_NORMAL 1
#define NP_SEEK 2
#define NP_ASFILE 3
#define NP_ASFILEONLY 4
#define NP_MAXREADY (((unsigned)(~0)<<1)>>1)
/*----------------------------------------------------------------------*/
/* Error and Reason Code definitions */
/*----------------------------------------------------------------------*/
/*
* Values of type NPError:
*/
#define NPERR_BASE 0
#define NPERR_NO_ERROR (NPERR_BASE + 0)
#define NPERR_GENERIC_ERROR (NPERR_BASE + 1)
#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2)
#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3)
#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4)
#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5)
#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6)
#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7)
#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8)
#define NPERR_INVALID_PARAM (NPERR_BASE + 9)
#define NPERR_INVALID_URL (NPERR_BASE + 10)
#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11)
#define NPERR_NO_DATA (NPERR_BASE + 12)
#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13)
/*
* Values of type NPReason:
*/
#define NPRES_BASE 0
#define NPRES_DONE (NPRES_BASE + 0)
#define NPRES_NETWORK_ERR (NPRES_BASE + 1)
#define NPRES_USER_BREAK (NPRES_BASE + 2)
/*
* Don't use these obsolete error codes any more.
*/
#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR
#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR
#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK
/*
* Version feature information
*/
#define NPVERS_HAS_STREAMOUTPUT 8
#define NPVERS_HAS_NOTIFICATION 9
#define NPVERS_HAS_LIVECONNECT 9
/*----------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------*/
#if defined(_WINDOWS) && !defined(WIN32)
#define NP_LOADDS _loadds
#else
#define NP_LOADDS
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* NPP_* functions are provided by the plugin and called by the navigator.
*/
#ifdef XP_UNIX
char* NPP_GetMIMEDescription(void);
NPError NPP_GetValue(void *instance, NPPVariable variable,
void *value);
#endif /* XP_UNIX */
NPError NPP_Initialize(void);
void NPP_Shutdown(void);
NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
uint16 mode, int16 argc, char* argn[],
char* argv[], NPSavedData* saved);
NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save);
NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window);
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
NPStream* stream, NPBool seekable,
uint16* stype);
NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream);
int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset,
int32 len, void* buffer);
void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
const char* fname);
void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint);
int16 NPP_HandleEvent(NPP instance, void* event);
void NPP_URLNotify(NPP instance, const char* url,
NPReason reason, void* notifyData);
/* it IS void* really */
void* NPP_GetJavaClass(void);
/*
* NPN_* functions are provided by the navigator and called by the plugin.
*/
#ifdef XP_UNIX
NPError NPN_GetValue(NPP instance, NPNVariable variable,
void *value);
#endif /* XP_UNIX */
void NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor);
NPError NPN_GetURLNotify(NPP instance, const char* url,
const char* target, void* notifyData);
NPError NPN_GetURL(NPP instance, const char* url,
const char* target);
NPError NPN_PostURLNotify(NPP instance, const char* url,
const char* target, uint32 len,
const char* buf, NPBool file,
void* notifyData);
NPError NPN_PostURL(NPP instance, const char* url,
const char* target, uint32 len,
const char* buf, NPBool file);
NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList);
NPError NPN_NewStream(NPP instance, NPMIMEType type,
const char* target, NPStream** stream);
int32 NPN_Write(NPP instance, NPStream* stream, int32 len,
void* buffer);
NPError NPN_DestroyStream(NPP instance, NPStream* stream,
NPReason reason);
void NPN_Status(NPP instance, const char* message);
const char* NPN_UserAgent(NPP instance);
void* NPN_MemAlloc(uint32 size);
void NPN_MemFree(void* ptr);
uint32 NPN_MemFlush(uint32 size);
void NPN_ReloadPlugins(NPBool reloadPages);
/* don't need it */
/*JRIEnv* NPN_GetJavaEnv(void);*/
void* NPN_GetJavaPeer(NPP instance);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* _NPAPI_H_ */

View File

@@ -0,0 +1,436 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: npunix.c,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/*
* npunix.c
*
* Netscape Client Plugin API
* - Wrapper function to interface with the Netscape Navigator
*
* dp Suresh <dp@netscape.com>
*
*----------------------------------------------------------------------
* PLUGIN DEVELOPERS:
* YOU WILL NOT NEED TO EDIT THIS FILE.
*----------------------------------------------------------------------
*/
#define XP_UNIX 1
#include <stdio.h>
#include "npapi.h"
#include "npupp.h"
/*
* Define PLUGIN_TRACE to have the wrapper functions print
* messages to stderr whenever they are called.
*/
#ifdef PLUGIN_TRACE
#include <stdio.h>
#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s\n", msg)
#else
#define PLUGINDEBUGSTR(msg)
#endif
/***********************************************************************
*
* Globals
*
***********************************************************************/
static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */
/***********************************************************************
*
* Wrapper functions : plugin calling Netscape Navigator
*
* These functions let the plugin developer just call the APIs
* as documented and defined in npapi.h, without needing to know
* about the function table and call macros in npupp.h.
*
***********************************************************************/
void
NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor)
{
*plugin_major = NP_VERSION_MAJOR;
*plugin_minor = NP_VERSION_MINOR;
/* Major version is in high byte */
*netscape_major = gNetscapeFuncs.version >> 8;
/* Minor version is in low byte */
*netscape_minor = gNetscapeFuncs.version & 0xFF;
}
NPError
NPN_GetValue(NPP instance, NPNVariable variable, void *r_value)
{
return CallNPN_GetValueProc(gNetscapeFuncs.getvalue,
instance, variable, r_value);
}
NPError
NPN_GetURL(NPP instance, const char* url, const char* window)
{
return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window);
}
NPError
NPN_GetURLNotify(NPP instance, const char *url,
const char *target, void* notifyData)
{
return CallNPN_GetURLNotifyProc(gNetscapeFuncs.geturlnotify,
instance, url, target, notifyData);
}
NPError
NPN_PostURL(NPP instance, const char* url, const char* window,
uint32 len, const char* buf, NPBool file)
{
return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance,
url, window, len, buf, file);
}
NPError
NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
{
return CallNPN_RequestReadProc(gNetscapeFuncs.requestread,
stream, rangeList);
}
NPError
NPN_NewStream(NPP instance, NPMIMEType type, const char *window,
NPStream** stream_ptr)
{
return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance,
type, window, stream_ptr);
}
int32
NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
{
return CallNPN_WriteProc(gNetscapeFuncs.write, instance,
stream, len, buffer);
}
NPError
NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream,
instance, stream, reason);
}
void
NPN_Status(NPP instance, const char* message)
{
CallNPN_StatusProc(gNetscapeFuncs.status, instance, message);
}
const char*
NPN_UserAgent(NPP instance)
{
return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance);
}
void*
NPN_MemAlloc(uint32 size)
{
return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size);
}
void NPN_MemFree(void* ptr)
{
CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr);
}
uint32 NPN_MemFlush(uint32 size)
{
return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size);
}
void NPN_ReloadPlugins(NPBool reloadPages)
{
CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages);
}
JRIEnv* NPN_GetJavaEnv()
{
return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv);
}
jref NPN_GetJavaPeer(NPP instance)
{
return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer,
instance);
}
/***********************************************************************
*
* Wrapper functions : Netscape Navigator -> plugin
*
* These functions let the plugin developer just create the APIs
* as documented and defined in npapi.h, without needing to
* install those functions in the function table or worry about
* setting up globals for 68K plugins.
*
***********************************************************************/
NPError
Private_New(NPMIMEType pluginType, NPP instance, uint16 mode,
int16 argc, char* argn[], char* argv[], NPSavedData* saved)
{
NPError ret;
PLUGINDEBUGSTR("New");
ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
return ret;
}
NPError
Private_Destroy(NPP instance, NPSavedData** save)
{
PLUGINDEBUGSTR("Destroy");
return NPP_Destroy(instance, save);
}
NPError
Private_SetWindow(NPP instance, NPWindow* window)
{
NPError err;
PLUGINDEBUGSTR("SetWindow");
err = NPP_SetWindow(instance, window);
return err;
}
NPError
Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16* stype)
{
NPError err;
PLUGINDEBUGSTR("NewStream");
err = NPP_NewStream(instance, type, stream, seekable, stype);
return err;
}
int32
Private_WriteReady(NPP instance, NPStream* stream)
{
unsigned int result;
PLUGINDEBUGSTR("WriteReady");
result = NPP_WriteReady(instance, stream);
return result;
}
int32
Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
void* buffer)
{
unsigned int result;
PLUGINDEBUGSTR("Write");
result = NPP_Write(instance, stream, offset, len, buffer);
return result;
}
void
Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
{
PLUGINDEBUGSTR("StreamAsFile");
NPP_StreamAsFile(instance, stream, fname);
}
NPError
Private_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
NPError err;
PLUGINDEBUGSTR("DestroyStream");
err = NPP_DestroyStream(instance, stream, reason);
return err;
}
void
Private_Print(NPP instance, NPPrint* platformPrint)
{
PLUGINDEBUGSTR("Print");
NPP_Print(instance, platformPrint);
}
void*
Private_GetJavaClass(void)
{
return NULL;
}
/***********************************************************************
*
* These functions are located automagically by netscape.
*
***********************************************************************/
/*
* NP_GetMIMEDescription
* - Netscape needs to know about this symbol
* - Netscape uses the return value to identify when an object instance
* of this plugin should be created.
*/
char *
NP_GetMIMEDescription(void)
{
return NPP_GetMIMEDescription();
}
/*
* NP_GetValue [optional]
* - Netscape needs to know about this symbol.
* - Interfaces with plugin to get values for predefined variables
* that the navigator needs.
*/
NPError
NP_GetValue(void *future, NPPVariable variable, void *value)
{
return NPP_GetValue(future, variable, value);
}
/*
* NP_Initialize
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol before it
* is about to create the first ever object of this kind.
*
* PARAMETERS
* nsTable - The netscape function table. If developers just use these
* wrappers, they dont need to worry about all these function
* tables.
* RETURN
* pluginFuncs
* - This functions needs to fill the plugin function table
* pluginFuncs and return it. Netscape Navigator plugin
* library will use this function table to call the plugin.
*
*/
NPError
NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs)
{
NPError err = NPERR_NO_ERROR;
PLUGINDEBUGSTR("NP_Initialize");
/* validate input parameters */
if ((nsTable == NULL) || (pluginFuncs == NULL))
err = NPERR_INVALID_FUNCTABLE_ERROR;
/*
* Check the major version passed in Netscape's function table.
* We won't load if the major version is newer than what we expect.
* Also check that the function tables passed in are big enough for
* all the functions we need (they could be bigger, if Netscape added
* new APIs, but that's OK with us -- we'll just ignore them).
*
*/
if (err == NPERR_NO_ERROR) {
if ((nsTable->version >> 8) > NP_VERSION_MAJOR)
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
if (nsTable->size < sizeof(NPNetscapeFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
if (pluginFuncs->size < sizeof(NPPluginFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
}
if (err == NPERR_NO_ERROR) {
/*
* Copy all the fields of Netscape function table into our
* copy so we can call back into Netscape later. Note that
* we need to copy the fields one by one, rather than assigning
* the whole structure, because the Netscape function table
* could actually be bigger than what we expect.
*/
gNetscapeFuncs.version = nsTable->version;
gNetscapeFuncs.size = nsTable->size;
gNetscapeFuncs.posturl = nsTable->posturl;
gNetscapeFuncs.geturl = nsTable->geturl;
gNetscapeFuncs.geturlnotify = nsTable->geturlnotify;
gNetscapeFuncs.requestread = nsTable->requestread;
gNetscapeFuncs.newstream = nsTable->newstream;
gNetscapeFuncs.write = nsTable->write;
gNetscapeFuncs.destroystream = nsTable->destroystream;
gNetscapeFuncs.status = nsTable->status;
gNetscapeFuncs.uagent = nsTable->uagent;
gNetscapeFuncs.memalloc = nsTable->memalloc;
gNetscapeFuncs.memfree = nsTable->memfree;
gNetscapeFuncs.memflush = nsTable->memflush;
gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
gNetscapeFuncs.getvalue = nsTable->getvalue;
/*
* Set up the plugin function table that Netscape will use to
* call us. Netscape needs to know about our version and size
* and have a UniversalProcPointer for every function we
* implement.
*/
pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
pluginFuncs->size = sizeof(NPPluginFuncs);
pluginFuncs->newp = NewNPP_NewProc(Private_New);
pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy);
pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow);
pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream);
pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream);
pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile);
pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady);
pluginFuncs->write = NewNPP_WriteProc(Private_Write);
pluginFuncs->print = NewNPP_PrintProc(Private_Print);
pluginFuncs->event = NULL;
pluginFuncs->javaClass = Private_GetJavaClass();
err = NPP_Initialize();
}
return err;
}
/*
* NP_Shutdown [optional]
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol after
* the last object of this kind has been destroyed.
*
*/
NPError
NP_Shutdown(void)
{
PLUGINDEBUGSTR("NP_Shutdown");
NPP_Shutdown();
return NPERR_NO_ERROR;
}

View File

@@ -0,0 +1,436 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: npunix.c.my,v 1.1.1.1 2001-05-10 18:12:36 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/*
* npunix.c
*
* Netscape Client Plugin API
* - Wrapper function to interface with the Netscape Navigator
*
* dp Suresh <dp@netscape.com>
*
*----------------------------------------------------------------------
* PLUGIN DEVELOPERS:
* YOU WILL NOT NEED TO EDIT THIS FILE.
*----------------------------------------------------------------------
*/
#define XP_UNIX 1
#include <stdio.h>
#include "npapi.h"
#include "npupp.h"
/*
* Define PLUGIN_TRACE to have the wrapper functions print
* messages to stderr whenever they are called.
*/
#ifdef PLUGIN_TRACE
#include <stdio.h>
#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s\n", msg)
#else
#define PLUGINDEBUGSTR(msg)
#endif
/***********************************************************************
*
* Globals
*
***********************************************************************/
static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */
/***********************************************************************
*
* Wrapper functions : plugin calling Netscape Navigator
*
* These functions let the plugin developer just call the APIs
* as documented and defined in npapi.h, without needing to know
* about the function table and call macros in npupp.h.
*
***********************************************************************/
void
NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor)
{
*plugin_major = NP_VERSION_MAJOR;
*plugin_minor = NP_VERSION_MINOR;
/* Major version is in high byte */
*netscape_major = gNetscapeFuncs.version >> 8;
/* Minor version is in low byte */
*netscape_minor = gNetscapeFuncs.version & 0xFF;
}
NPError
NPN_GetValue(NPP instance, NPNVariable variable, void *r_value)
{
return CallNPN_GetValueProc(gNetscapeFuncs.getvalue,
instance, variable, r_value);
}
NPError
NPN_GetURL(NPP instance, const char* url, const char* window)
{
return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window);
}
NPError
NPN_GetURLNotify(NPP instance, const char *url,
const char *target, void* notifyData)
{
return CallNPN_GetURLNotifyProc(gNetscapeFuncs.geturlnotify,
instance, url, target, notifyData);
}
NPError
NPN_PostURL(NPP instance, const char* url, const char* window,
uint32 len, const char* buf, NPBool file)
{
return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance,
url, window, len, buf, file);
}
NPError
NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
{
return CallNPN_RequestReadProc(gNetscapeFuncs.requestread,
stream, rangeList);
}
NPError
NPN_NewStream(NPP instance, NPMIMEType type, const char *window,
NPStream** stream_ptr)
{
return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance,
type, window, stream_ptr);
}
int32
NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
{
return CallNPN_WriteProc(gNetscapeFuncs.write, instance,
stream, len, buffer);
}
NPError
NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream,
instance, stream, reason);
}
void
NPN_Status(NPP instance, const char* message)
{
CallNPN_StatusProc(gNetscapeFuncs.status, instance, message);
}
const char*
NPN_UserAgent(NPP instance)
{
return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance);
}
void*
NPN_MemAlloc(uint32 size)
{
return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size);
}
void NPN_MemFree(void* ptr)
{
CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr);
}
uint32 NPN_MemFlush(uint32 size)
{
return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size);
}
void NPN_ReloadPlugins(NPBool reloadPages)
{
CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages);
}
void* NPN_GetJavaEnv()
{
return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv);
}
void* NPN_GetJavaPeer(NPP instance)
{
return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer,
instance);
}
/***********************************************************************
*
* Wrapper functions : Netscape Navigator -> plugin
*
* These functions let the plugin developer just create the APIs
* as documented and defined in npapi.h, without needing to
* install those functions in the function table or worry about
* setting up globals for 68K plugins.
*
***********************************************************************/
NPError
Private_New(NPMIMEType pluginType, NPP instance, uint16 mode,
int16 argc, char* argn[], char* argv[], NPSavedData* saved)
{
NPError ret;
PLUGINDEBUGSTR("New");
ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
return ret;
}
NPError
Private_Destroy(NPP instance, NPSavedData** save)
{
PLUGINDEBUGSTR("Destroy");
return NPP_Destroy(instance, save);
}
NPError
Private_SetWindow(NPP instance, NPWindow* window)
{
NPError err;
PLUGINDEBUGSTR("SetWindow");
err = NPP_SetWindow(instance, window);
return err;
}
NPError
Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16* stype)
{
NPError err;
PLUGINDEBUGSTR("NewStream");
err = NPP_NewStream(instance, type, stream, seekable, stype);
return err;
}
int32
Private_WriteReady(NPP instance, NPStream* stream)
{
unsigned int result;
PLUGINDEBUGSTR("WriteReady");
result = NPP_WriteReady(instance, stream);
return result;
}
int32
Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
void* buffer)
{
unsigned int result;
PLUGINDEBUGSTR("Write");
result = NPP_Write(instance, stream, offset, len, buffer);
return result;
}
void
Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
{
PLUGINDEBUGSTR("StreamAsFile");
NPP_StreamAsFile(instance, stream, fname);
}
NPError
Private_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
NPError err;
PLUGINDEBUGSTR("DestroyStream");
err = NPP_DestroyStream(instance, stream, reason);
return err;
}
void
Private_Print(NPP instance, NPPrint* platformPrint)
{
PLUGINDEBUGSTR("Print");
NPP_Print(instance, platformPrint);
}
void*
Private_GetJavaClass(void)
{
return NULL;
}
/***********************************************************************
*
* These functions are located automagically by netscape.
*
***********************************************************************/
/*
* NP_GetMIMEDescription
* - Netscape needs to know about this symbol
* - Netscape uses the return value to identify when an object instance
* of this plugin should be created.
*/
char *
NP_GetMIMEDescription(void)
{
return NPP_GetMIMEDescription();
}
/*
* NP_GetValue [optional]
* - Netscape needs to know about this symbol.
* - Interfaces with plugin to get values for predefined variables
* that the navigator needs.
*/
NPError
NP_GetValue(void *future, NPPVariable variable, void *value)
{
return NPP_GetValue(future, variable, value);
}
/*
* NP_Initialize
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol before it
* is about to create the first ever object of this kind.
*
* PARAMETERS
* nsTable - The netscape function table. If developers just use these
* wrappers, they dont need to worry about all these function
* tables.
* RETURN
* pluginFuncs
* - This functions needs to fill the plugin function table
* pluginFuncs and return it. Netscape Navigator plugin
* library will use this function table to call the plugin.
*
*/
NPError
NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs)
{
NPError err = NPERR_NO_ERROR;
PLUGINDEBUGSTR("NP_Initialize");
/* validate input parameters */
if ((nsTable == NULL) || (pluginFuncs == NULL))
err = NPERR_INVALID_FUNCTABLE_ERROR;
/*
* Check the major version passed in Netscape's function table.
* We won't load if the major version is newer than what we expect.
* Also check that the function tables passed in are big enough for
* all the functions we need (they could be bigger, if Netscape added
* new APIs, but that's OK with us -- we'll just ignore them).
*
*/
if (err == NPERR_NO_ERROR) {
if ((nsTable->version >> 8) > NP_VERSION_MAJOR)
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
if (nsTable->size < sizeof(NPNetscapeFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
if (pluginFuncs->size < sizeof(NPPluginFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
}
if (err == NPERR_NO_ERROR) {
/*
* Copy all the fields of Netscape function table into our
* copy so we can call back into Netscape later. Note that
* we need to copy the fields one by one, rather than assigning
* the whole structure, because the Netscape function table
* could actually be bigger than what we expect.
*/
gNetscapeFuncs.version = nsTable->version;
gNetscapeFuncs.size = nsTable->size;
gNetscapeFuncs.posturl = nsTable->posturl;
gNetscapeFuncs.geturl = nsTable->geturl;
gNetscapeFuncs.geturlnotify = nsTable->geturlnotify;
gNetscapeFuncs.requestread = nsTable->requestread;
gNetscapeFuncs.newstream = nsTable->newstream;
gNetscapeFuncs.write = nsTable->write;
gNetscapeFuncs.destroystream = nsTable->destroystream;
gNetscapeFuncs.status = nsTable->status;
gNetscapeFuncs.uagent = nsTable->uagent;
gNetscapeFuncs.memalloc = nsTable->memalloc;
gNetscapeFuncs.memfree = nsTable->memfree;
gNetscapeFuncs.memflush = nsTable->memflush;
gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
gNetscapeFuncs.getvalue = nsTable->getvalue;
/*
* Set up the plugin function table that Netscape will use to
* call us. Netscape needs to know about our version and size
* and have a UniversalProcPointer for every function we
* implement.
*/
pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
pluginFuncs->size = sizeof(NPPluginFuncs);
pluginFuncs->newp = NewNPP_NewProc(Private_New);
pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy);
pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow);
pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream);
pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream);
pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile);
pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady);
pluginFuncs->write = NewNPP_WriteProc(Private_Write);
pluginFuncs->print = NewNPP_PrintProc(Private_Print);
pluginFuncs->event = NULL;
pluginFuncs->javaClass = Private_GetJavaClass();
err = NPP_Initialize();
}
return err;
}
/*
* NP_Shutdown [optional]
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol after
* the last object of this kind has been destroyed.
*
*/
NPError
NP_Shutdown(void)
{
PLUGINDEBUGSTR("NP_Shutdown");
NPP_Shutdown();
return NPERR_NO_ERROR;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: stubs.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* -*- Mode: C; tab-width: 4; -*- */
/*******************************************************************************
* Simple LiveConnect Sample Plugin
* Copyright (c) 1996 Netscape Communications. All rights reserved.
******************************************************************************/
/*
** Ok, so we don't usually include .c files (only .h files) but we're
** doing it here to avoid some fancy make rules. First pull in the common
** glue code:
*/
#ifdef XP_UNIX
#include "../../../common/npunix.c"
#endif

View File

@@ -0,0 +1,412 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: wfe_netscape4.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include "jvmp.h"
#include "common.h"
#include "shmtran.h"
/* Extension parameters */
static jint g_side = 0;
#ifdef XP_UNIX
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdlib.h>
/* PART 1 - application specific host callbacks */
static XID g_xid = 0;
static int g_msgid1 = -1;
static Display* GetDisplay()
{
char* dname;
static Display* dpy = NULL;
if (dpy) return dpy;
dname = getenv("DISPLAY");
if (!dname) return NULL;
dpy = XOpenDisplay(dname);
return dpy;
}
static int SetTransport(int xid, int* pmsg_id)
{
int msg_id;
g_xid = xid;
/* create msg queue used by extension to recieve messages */
if ((msg_id =
JVMP_msgget (0, IPC_CREAT | IPC_PRIVATE | IPC_EXCL | 0770)) == -1)
{
perror("host: msgget");
return 0;
}
*pmsg_id = msg_id;
return 1;
}
#endif
int NotifyHost()
{
#ifdef XP_UNIX
static Atom atom = 0;
static Display* dpy;
if (g_side != 2 || !g_xid) return 0; /* has sense only on JVM side
and after init message has come */
dpy = GetDisplay();
if (!dpy) return 0;
if (!atom) atom = XInternAtom(dpy, "WF atom", FALSE);
XChangeProperty(dpy, g_xid, atom, XA_STRING, 8,
PropModeReplace, NULL, 0);
XFlush(dpy);
return 1;
#endif
}
/* PART 2 - Extension API implementation and related functions */
/* this is a dummy method to make linker happy */
int JVMP_ExecuteShmRequest(JVMP_ShmRequest* req)
{
fprintf(stderr, "NEVER CALL ME\n");
return 1;
}
/* this one is called only on JVM side and handle extension spec*/
static int JVMP_ExecuteExtShmRequest(JVMP_ShmRequest* req)
{
int vendor, funcno, xid;
char sign[40], *docbase;
int* pmsg_id;
jint *pid;
if (!req) return 0;
vendor = JVMP_GET_VENDOR(req->func_no);
if (vendor != WFNetscape4VendorID) return 0;
funcno = JVMP_GET_EXT_FUNCNO(req->func_no);
switch(funcno)
{
case 1:
/* XID setter on Unix, HANDLE setter on Win32 */
sprintf(sign, "Ii");
pmsg_id = &g_msgid1;
JVMP_DecodeRequest(req, 0, sign, &xid, &pmsg_id);
/* kinda tricky to allow msg queue clean up */
req->retval = SetTransport(xid, &g_msgid1);
JVMP_EncodeRequest(req, sign, xid, pmsg_id);
break;
case 5:
/* doc base setter - stupid Netscape */
sprintf(sign, "IS");
pid = NULL;
JVMP_DecodeRequest(req, 1, sign, pid, &docbase);
fprintf(stderr, "got docbase %s for id %ld\n", docbase, *pid);
free(pid); free(docbase);
break;
default:
fprintf(stderr, "JVM got func %d\n", funcno);
return 0;
}
return 1;
}
/* extension API implementation */
static jint JNICALL JVMPExt_Init(jint side)
{
g_side = side;
if (g_side == 0) return JNI_TRUE; /* in-proc case. Do nothing yet */
if (g_side == 1)
{
/* host side - create event widget and custom message queue,
and send their XID and msg_id to JVM side using
SHM transport. Sync is OK, as this Init methods are called in right
order - host side first, JVM side next. Really I'll do it
in JavaPlugin.c due current design it's more acceptable. */
}
else
{
/* JVM side - add extention callback to handle XID when it'll come.
Then use this XID as notificator after putting smth into this
extension's SHM queue. It's also not required as now callback
is JVMPExt_ScheduleRequest and called by JVMP automatically on every
non system request.
*/
}
return JNI_TRUE;
}
static jint JNICALL JVMPExt_Shutdown()
{
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetExtInfo(jint *pID, jint *pVersion)
{
*pID = WFNetscape4VendorID;
*pVersion = WFNetscape4ExtVersion;
return JNI_TRUE;
}
static jint JNICALL JVMPExt_GetBootstrapClass(char* *bootstrapClassPath,
char* *bootstrapClassName)
{
/* should be defined at installation time */
*bootstrapClassPath =
"file:///ws/M2308/mozilla/modules/jvmp/build/unix/classes/";
*bootstrapClassName =
"sun.jvmp.netscape4.NetscapePeerFactory";
return JNI_TRUE;
}
static jint JNICALL JVMPExt_ScheduleRequest(JVMP_ShmRequest* req,
jint local)
{
if (local == JNI_TRUE)
return JVMP_ExecuteExtShmRequest(req);
if (g_side == 1)
{
/* host side */
JVMP_SendShmRequest(req, 1);
JVMP_WaitConfirmShmRequest(req);
}
else
{
/* JVM side */
JVMP_SendShmRequest(req, 1);
if (NotifyHost()) JVMP_WaitConfirmShmRequest(req);
}
return JNI_TRUE;
}
static JVMP_Extension JVMP_Ext =
{
&JVMPExt_Init,
&JVMPExt_Shutdown,
&JVMPExt_GetExtInfo,
&JVMPExt_GetBootstrapClass,
&JVMPExt_ScheduleRequest
};
jint JNICALL JVMP_GetExtension(JVMP_Extension** ext)
{
*ext = &JVMP_Ext;
return JNI_TRUE;
}
/* PART3 - Java native methods implementation */
jint getID(JNIEnv* env, jobject jobj)
{
jint id;
static jfieldID peerFID = NULL;
if (!peerFID)
{
peerFID = (*env)->GetFieldID(env,
(*env)->GetObjectClass(env, jobj),
"m_id","I");
if (!peerFID) return 0;
}
id = (*env)->GetIntField(env, jobj, peerFID);
return id;
}
static jint GetParameters(jint id, char*** pkeys, char*** pvals, int *plen)
{
JVMP_ShmRequest* req;
int *pres, *pid, i, len, argc, pos;
char* buf, sign[20];
char **keys, **vals;
#define EXTRACT_STRING(res) \
len = strlen(buf+pos)+1; \
res = (char*)malloc(len); \
memcpy(res, buf+pos, len); \
pos += len;
req = JVMP_NewShmReq(g_msgid1,
JVMP_NEW_EXT_FUNCNO(WFNetscape4VendorID, 2));
pres = NULL;
pid = NULL;
buf = NULL;
sprintf(sign, "Iia[0]");
JVMP_EncodeRequest(req, sign, id, pres, buf);
JVMPExt_ScheduleRequest(req, JNI_FALSE);
JVMP_DecodeRequest(req, 1, sign, pid, &pres, &buf);
/* here we hopefully got all our parameters in one huge buffer
now is time to make strings arrays from 'em */
argc = *pres;
keys = (char**)malloc(argc*sizeof(char*));
vals = (char**)malloc(argc*sizeof(char*));
for (i=0, pos=0; i<argc; i++)
{
EXTRACT_STRING(keys[i]);
EXTRACT_STRING(vals[i]);
}
free(buf); free(pres); free(pid);
JVMP_DeleteShmReq(req);
*pkeys = keys;
*pvals = vals;
*plen = argc;
return JNI_TRUE;
}
static jint ShowStatus(jint id, char* status)
{
JVMP_ShmRequest* req;
char sign[40];
req = JVMP_NewShmReq(g_msgid1,
JVMP_NEW_EXT_FUNCNO(WFNetscape4VendorID, 3));
sprintf(sign, "IS");
JVMP_EncodeRequest(req, sign, id, status);
JVMPExt_ScheduleRequest(req, JNI_FALSE);
JVMP_DeleteShmReq(req);
return req->retval;
}
static jint ShowDocument(jint id, char* url, char* status)
{
JVMP_ShmRequest* req;
char sign[40];
req = JVMP_NewShmReq(g_msgid1,
JVMP_NEW_EXT_FUNCNO(WFNetscape4VendorID, 4));
sprintf(sign, "ISS");
JVMP_EncodeRequest(req, sign, id, url, status);
JVMPExt_ScheduleRequest(req, JNI_FALSE);
JVMP_DeleteShmReq(req);
return req->retval;
}
JNIEXPORT jobjectArray JNICALL
Java_sun_jvmp_netscape4_MozillaAppletPeer_getParams(JNIEnv* env, jobject jobj)
{
char **keys, **vals;
unsigned int i, len;
jclass StringClass, StringArrayClass;
jobjectArray jkeys, jvals, result;
jint id;
id = getID(env, jobj);
if (!GetParameters(id, &keys, &vals, &len)) return NULL;
// hopefully here runtime is inited so those classes resolved
// without problems - maybe cache it
StringClass = (*env)->FindClass(env, "java/lang/String");
StringArrayClass = (*env)->FindClass(env, "[Ljava/lang/String;");
result = (*env)->NewObjectArray(env, 2, StringArrayClass, NULL);
jkeys = (*env)->NewObjectArray(env, len, StringClass, NULL);
jvals = (*env)->NewObjectArray(env, len, StringClass, NULL);
for (i=0; i<len; i++)
{
(*env)->SetObjectArrayElement(env, jkeys, i,
(*env)->NewStringUTF(env, keys[i]));
(*env)->SetObjectArrayElement(env, jvals, i,
(*env)->NewStringUTF(env, vals[i]));
free(keys[i]); free(vals[i]);
}
free(keys); free(vals);
(*env)->SetObjectArrayElement(env, result, 0, jkeys);
(*env)->SetObjectArrayElement(env, result, 1, jvals);
(*env)->DeleteLocalRef(env, jkeys);
(*env)->DeleteLocalRef(env, jvals);
return result;
}
#if 0
JNIEXPORT jstring JNICALL
Java_sun_jvmp_netscape4_MozillaAppletPeer_getProxyForURL(JNIEnv * env,
jobject jobj,
jstring jurl)
{
jstring jresult;
jint res;
char *url, *result;
PluginInstance *wrapper;
if (!(wrapper = getWrapper(env, jobj))) return NULL;
url = (char*)(*env)->GetStringUTFChars(env, jurl, NULL);
res = wrapper->GetProxyForURL(wrapper->info, url, &result);
(*env)->ReleaseStringUTFChars(env, jurl, url);
if (res != 0) return NULL;
jresult = (*env)->NewStringUTF(env, result);
return jresult;
}
#endif
/*
* Class: sun_jvmp_netscape4_MozillaAppletPeer
* Method: nativeShowStatus
* Signature: (Ljava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL
Java_sun_jvmp_netscape4_MozillaAppletPeer_nativeShowStatus
(JNIEnv * env, jobject jobj, jstring jstatus)
{
jint res;
char *status;
jint id;
if (!(id = getID(env, jobj))) return JNI_FALSE;
status = (char*)(*env)->GetStringUTFChars(env, jstatus, NULL);
res = ShowStatus(id, status);
(*env)->ReleaseStringUTFChars(env, jstatus, status);
return (res == 0);
}
/*
* Class: sun_jvmp_netscape4_MozillaAppletPeer
* Method: nativeShowDocument
* Signature: (Ljava/lang/String;Ljava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL
Java_sun_jvmp_netscape4_MozillaAppletPeer_nativeShowDocument
(JNIEnv *env, jobject jobj, jstring jurl, jstring jtarget)
{
int res;
char *url, *target;
jint id;
if (!(id = getID(env, jobj))) return JNI_FALSE;
url = (char*)(*env)->GetStringUTFChars(env, jurl, NULL);
target = (char*)(*env)->GetStringUTFChars(env, jtarget, NULL);
res = ShowDocument(id, url, target);
(*env)->ReleaseStringUTFChars(env, jurl, url);
(*env)->ReleaseStringUTFChars(env, jtarget, target);
return (res == 0);
}

View File

@@ -0,0 +1,32 @@
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is The Waterfall Java Plugin Module
#
# The Initial Developer of the Original Code is Sun Microsystems Inc
# Portions created by Sun Microsystems Inc are Copyright (C) 2001
# All Rights Reserved.
#
# $Id: Makefile,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
#
#
# Contributor(s):
#
# Nikolay N. Igotti <inn@sparc.spb.su>
CFLAGS=-Wall -g -I../../../public/ -DJVMP_USE_SHM
all: shmtran.o jvmp_exec host
jvmp_exec: jvmp_exec.o shmtran.o
gcc -o jvmp_exec jvmp_exec.o shmtran.o
host: host.o shmtran.o
gcc -o host host.o shmtran.o
clean:
rm -rf *.o jvmp_exec host core

View File

@@ -0,0 +1,590 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: java_plugin_shm.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/*
all methods here but JVMP_GetPlugin() declared "static", as only access to
them is via structure returned by JVMP_GetPlugin(), so why to add needless
records to export table of plugin DLL. Also it looks like JNI approach.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dlfcn.h>
#include "jvmp.h"
#include "shmtran.h"
//#define PLUGIN_DEBUG 1
static JavaVM* JVMP_JVM_running = NULL;
//static jobject JVMP_PluginInstance = NULL;
//static jclass JVMP_PluginClass = NULL;
static char* JVMP_plugin_home = NULL;
static char* global_libpath = NULL;
static int g_msgid;
#ifdef PLUGIN_DEBUG
#define PLUGIN_LOG(s1) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1); fprintf(stderr, "\n"); }
#define PLUGIN_LOG2(s1, s2) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1, s2); fprintf(stderr, "\n"); }
#define PLUGIN_LOG3(s1, s2, s3) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1, s2, s3); fprintf(stderr, "\n"); }
#define PLUGIN_LOG4(s1, s2, s3, s4) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1, s2, s3 ,s4); fprintf(stderr, "\n"); }
#else
#define PLUGIN_LOG(s1)
#define PLUGIN_LOG2(s1, s2)
#define PLUGIN_LOG3(s1, s2, s3)
#define PLUGIN_LOG4(s1, s2, s3, s4)
#endif
#define JVMP_EXEC "jvmp_exec"
static char* getPluginLibPath(char* home) {
static char* result = NULL;
if (result != NULL) return result;
result = (char*) malloc(3*strlen(home)+200);
/* FIXME !! */
sprintf(result,
#ifdef _JVMP_SUNJVM
"%s/java/jre/lib/"ARCH"/hotspot:%s/java/jre/lib/"ARCH":%s"
#endif
#ifdef _JVMP_IBMJVM
"%s:%s/java/jre/bin:%s/java/jre/bin/classic"
#endif
, home, home, home);
return result;
}
static jint startSHM() {
static int started = 0;
char *libpath, *newlibpath, *pluginlibpath;
char *java_home, *jre_home;
char *jvmp_exec;
pid_t pid;
char* str;
struct stat sbuf;
int tmplen;
if (started) return JNI_TRUE;
/* find out JAVA_PLUGIN_HOME */
JVMP_plugin_home = getenv("JAVA_PLUGIN_HOME");
if (JVMP_plugin_home == NULL) {
PLUGIN_LOG("Env variable JAVA_PLUGIN_HOME not set");
return JNI_FALSE;
}
if ((stat(JVMP_plugin_home, &sbuf) < 0) || !S_ISDIR(sbuf.st_mode)) {
PLUGIN_LOG2("Bad value %s of JAVA_PLUGIN_HOME", JVMP_plugin_home);
return JNI_FALSE;
}
/* LD_LIBRARY_PATH correction */
pluginlibpath = getPluginLibPath(JVMP_plugin_home);
libpath = getenv("LD_LIBRARY_PATH");
if (!libpath) libpath = "";
tmplen = strlen(libpath) + strlen(pluginlibpath);
global_libpath = (char*) malloc(tmplen + 2);
newlibpath = (char*) malloc(tmplen + 22);
sprintf(global_libpath, "%s:%s", pluginlibpath, libpath);
sprintf(newlibpath, "LD_LIBRARY_PATH=%s", global_libpath);
putenv(newlibpath);
java_home = (char*) malloc(strlen(JVMP_plugin_home)+40);
jre_home = (char*) malloc(strlen(JVMP_plugin_home)+40);
#ifdef _JVMP_IBMJVM
sprintf(java_home, "JAVAHOME=%s/java/jre", JVMP_plugin_home);
sprintf(jre_home, "JREHOME=%s/java/jre", JVMP_plugin_home);
#endif
#ifdef _JVMP_SUNJVM
sprintf(java_home, "JAVA_HOME=%s/java/jre/", JVMP_plugin_home);
sprintf(jre_home, "JREHOME=%s/java/jre/", JVMP_plugin_home);
#endif
putenv(java_home);
putenv(jre_home);
JVMP_ShmInit(1); /* init transport on host side */
if ((g_msgid = JVMP_msgget (0, IPC_CREAT | IPC_PRIVATE | 0770)) == -1)
{
perror("host: msgget");
return JNI_FALSE;
}
if ((pid = fork()) == 0)
{
/* child */
str = (char*)malloc(20);
jvmp_exec = (char*)malloc(strlen(JVMP_EXEC)+
strlen(JVMP_plugin_home)+2);
sprintf(jvmp_exec, "%s/%s", JVMP_plugin_home, JVMP_EXEC);
sprintf(str, "%d", g_msgid);
execlp(jvmp_exec, "jvmp_exec", str, NULL);
perror("exec");
exit(1);
}
started = 1;
return JNI_TRUE;
}
static jint JVMP_SetCap(JVMP_CallingContext *ctx, jint cap_no)
{
JVMP_ALLOW_CAP(ctx->caps, cap_no);
return JNI_TRUE;
}
static jint JVMP_SetCaps(JVMP_CallingContext *ctx,
JVMP_SecurityCap *new_caps)
{
if (!new_caps) return JNI_FALSE;
memcpy(&(ctx->caps), new_caps, sizeof(JVMP_SecurityCap));
return JNI_TRUE;
}
static jint JVMP_GetCap(JVMP_CallingContext *ctx, jint cap_no)
{
return JVMP_IS_CAP_ALLOWED(ctx->caps, cap_no);
}
static jint JVMP_IsActionAllowed(JVMP_CallingContext *ctx,
JVMP_SecurityAction *caps)
{
int i, r;
for(i=0, r=1; i < JVMP_MAX_CAPS_BYTES; i++)
{
r =
r && ((!(caps->bits)[i]) |
(((ctx->caps).bits)[i] & (caps->bits)[i]));
if (!r) return JNI_FALSE;
}
return JNI_TRUE;
}
static JVMP_CallingContext* NewCallingContext()
{
JVMP_CallingContext* ctx_new = NULL;
ctx_new = (JVMP_CallingContext *) malloc(sizeof(JVMP_CallingContext));
if (!ctx_new) return NULL;
ctx_new->source_thread = NULL; /* must be current thread */
ctx_new->env = NULL;
ctx_new->source = NULL;
ctx_new->reserved0 = (void*)g_msgid;
JVMP_FORBID_ALL_CAPS(ctx_new->caps);
ctx_new->AllowCap = &JVMP_SetCap;
ctx_new->GetCap = &JVMP_GetCap;
ctx_new->SetCaps = &JVMP_SetCaps;
ctx_new->IsActionAllowed = &JVMP_IsActionAllowed;
return ctx_new;
}
/* prototype for this function */
static jint JVMP_GetCallingContext(JavaVM *jvm,
JVMP_CallingContext **pctx,
jint version,
JVMP_ThreadInfo* target);
/* Arguments are taken into account only if JVM isn't already created.
No clear what to do with JVM reusing - just ignore for now.
*/
static jint JNICALL JVMP_GetRunningJVM(JavaVM **pjvm,
JVMP_CallingContext **pctx,
void *args, jint allow_reuse)
{
JavaVM* jvm_new = NULL;
JVMP_CallingContext* ctx_new = NULL;
JVMP_ShmRequest* req;
jint retval;
if (JVMP_JVM_running == NULL) {
ctx_new = NewCallingContext();
if (!ctx_new) return JNI_FALSE;
*pctx = ctx_new;
jvm_new = (JavaVM*)malloc(sizeof(JavaVM));
if (!jvm_new) return JNI_FALSE;
memset(jvm_new, 0, sizeof(JavaVM));
req = JVMP_NewShmReq(g_msgid, 1);
if (!JVMP_EncodeRequest(req, "")
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DeleteShmReq(req);
} else {
(*pjvm) = JVMP_JVM_running;
/* XXX: FIXME version */
return JVMP_GetCallingContext(JVMP_JVM_running,
pctx,
JNI_VERSION_1_2,
NULL);
};
return retval;
}
static jint JNICALL JVMP_StopJVM(JVMP_CallingContext* ctx) {
JVMP_ShmRequest* req;
jint retval;
if (JVMP_JVM_running == NULL) return JNI_TRUE;
req = JVMP_NewShmReq(g_msgid, 2);
if (!JVMP_EncodeRequest(req, "")
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DeleteShmReq(req);
return retval;
}
static jint JNICALL JVMP_GetDefaultJavaVMInitArgs(void *args)
{
return JNI_TRUE;
}
static jint JNICALL JVMP_RegisterWindow(JVMP_CallingContext* ctx,
JVMP_DrawingSurfaceInfo *win,
jint *pID)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
PLUGIN_LOG("JVMP_RegisterWindow");
if (win == NULL) return JNI_FALSE;
sprintf(sign, "A[%d]i", sizeof(JVMP_DrawingSurfaceInfo));
req = JVMP_NewShmReq(g_msgid, 4);
if (!JVMP_EncodeRequest(req, sign, win, pID)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DecodeRequest(req, 0/* not alloc references */, sign,
&win, &pID);
JVMP_DeleteShmReq(req);
return retval;
}
static jint JNICALL JVMP_UnregisterWindow(JVMP_CallingContext* ctx,
jint ID)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
PLUGIN_LOG("JVMP_UnregisterWindow");
sprintf(sign, "I");
req = JVMP_NewShmReq(g_msgid, 5);
if (!JVMP_EncodeRequest(req, sign, ID)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DeleteShmReq(req);
return retval;
}
static jint JVMP_GetCallingContext(JavaVM *jvm,
JVMP_CallingContext* *pctx,
jint version,
JVMP_ThreadInfo* target)
{
JVMP_CallingContext* ctx_new = NewCallingContext();
if (!ctx_new) return JNI_FALSE;
if (!target)
ctx_new->dest_thread = ctx_new->source_thread;
else
ctx_new->dest_thread = target;
ctx_new->reserved0 = (void*)g_msgid;
*pctx = ctx_new;
return JNI_TRUE;
}
static jint JNICALL JVMP_RegisterMonitor(JVMP_CallingContext* ctx,
JVMP_MonitorInfo *monitor,
jint *pID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_UnregisterMonitor(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorEnter(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorExit(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorWait(JVMP_CallingContext* ctx,
jint ID, jlong milli)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorNotify(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorNotifyAll(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_CreatePeer(JVMP_CallingContext* ctx,
jint hostApp,
jint version,
jint *target)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
PLUGIN_LOG("JVMP_CreatePeer");
sprintf(sign, "IIi");
req = JVMP_NewShmReq(g_msgid, 14);
if (!JVMP_EncodeRequest(req, sign, hostApp, hostApp, target)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DecodeRequest(req, 0/* not alloc references */, sign,
NULL, NULL, &target);
JVMP_DeleteShmReq(req);
return retval;
}
static jint JNICALL JVMP_SendEvent(JVMP_CallingContext* ctx,
jint target,
jint event,
jlong data)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
PLUGIN_LOG("JVMP_SendEvent");
sprintf(sign, "IIA[%d]", sizeof(jlong));
req = JVMP_NewShmReq(g_msgid, 15);
if (!JVMP_EncodeRequest(req, sign, target, event, &data)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DeleteShmReq(req);
return retval;
}
static jint JNICALL JVMP_PostEvent(JVMP_CallingContext* ctx,
jint target,
jint event,
jlong data)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
PLUGIN_LOG("JVMP_PostEvent");
sprintf(sign, "IIA[%d]", sizeof(jlong));
req = JVMP_NewShmReq(g_msgid, 16);
if (!JVMP_EncodeRequest(req, sign, target, event, &data)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DeleteShmReq(req);
return retval;
}
static jint JNICALL JVMP_DestroyPeer(JVMP_CallingContext* ctx,
jint target)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
PLUGIN_LOG("JVMP_DestroyPeer");
sprintf(sign, "I");
req = JVMP_NewShmReq(g_msgid, 17);
if (!JVMP_EncodeRequest(req, sign, target)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DeleteShmReq(req);
return retval;
}
static jint JNICALL JVMP_RegisterExtension(JVMP_CallingContext* ctx,
const char* extPath,
jint *pID)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
void* handle;
JVMP_GetExtension_t JVMP_GetExtension;
JVMP_Extension* ext;
jint vendorID, version;
PLUGIN_LOG("JVMP_RegisterExtension - Netscape");
/* firstly, load it into the host */
handle = dlopen(extPath, RTLD_NOW);
if (!handle) {
PLUGIN_LOG2("extension dlopen: %s", dlerror());
return JNI_FALSE;
};
JVMP_GetExtension =
(JVMP_GetExtension_t)dlsym(handle, "JVMP_GetExtension");
if (handle == NULL)
{
PLUGIN_LOG2("extension dlsym: %s", dlerror());
return JNI_FALSE;
}
/* to implement JVMP_UnregisterExtension we should support
GHashTable of opened extensions, but later */
if (((*JVMP_GetExtension)(&ext) != JNI_TRUE))
{
PLUGIN_LOG2("Cannot obtain extension from %s", extPath);
return JNI_FALSE;
}
(ext->JVMPExt_GetExtInfo)(&vendorID, &version);
/* init it on host side */
if ((ext->JVMPExt_Init)(1) != JNI_TRUE) return JNI_FALSE;
/* then ask slave to do it */
sprintf(sign, "Si");
req = JVMP_NewShmReq(g_msgid, 18);
if (!JVMP_EncodeRequest(req, sign, extPath, pID)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DecodeRequest(req, 0/* not alloc references */, sign,
NULL, &pID);
JVMP_DeleteShmReq(req);
return retval;
}
static jint JNICALL JVMP_UnregisterExtension(JVMP_CallingContext* ctx,
jint ID)
{
JVMP_ShmRequest* req;
jint retval;
char sign[50];
PLUGIN_LOG("JVMP_UnregisterExtension");
sprintf(sign, "I");
req = JVMP_NewShmReq(g_msgid, 19);
if (!JVMP_EncodeRequest(req, sign, ID)
|| !JVMP_SendShmRequest(req, 1))
{
return JNI_FALSE;
}
JVMP_WaitConfirmShmRequest(req);
retval = req->retval;
JVMP_DeleteShmReq(req);
return retval;
}
/* Here main structure is initialized */
static JVMP_RuntimeContext JVMP_PluginContext = {
&JVMP_GetRunningJVM,
&JVMP_StopJVM,
&JVMP_GetDefaultJavaVMInitArgs,
&JVMP_RegisterWindow,
&JVMP_UnregisterWindow,
&JVMP_RegisterMonitor,
&JVMP_UnregisterMonitor,
&JVMP_MonitorEnter,
&JVMP_MonitorExit,
&JVMP_MonitorWait,
&JVMP_MonitorNotify,
&JVMP_MonitorNotifyAll,
&JVMP_GetCallingContext,
&JVMP_CreatePeer,
&JVMP_SendEvent,
&JVMP_PostEvent,
&JVMP_DestroyPeer,
&JVMP_RegisterExtension,
&JVMP_UnregisterExtension
};
jint JNICALL JVMP_GetPlugin(JVMP_RuntimeContext** cx) {
if (cx == NULL) return JNI_FALSE;
if (!startSHM()) {
PLUGIN_LOG("BAD - SHM not started");
return JNI_FALSE;
}
PLUGIN_LOG("OK - SHM started");
(*cx) = &JVMP_PluginContext;
return JNI_TRUE;
}
#ifdef _JVMP_PTHREADS
JVMP_ThreadInfo* ThreadInfoFromPthread(pthread_t thr)
{
JVMP_ThreadInfo* res =
(JVMP_ThreadInfo*)malloc(sizeof(JVMP_ThreadInfo));
/* pthread_t is unsigned int on Linux and Solaris :) */
res->handle = (void*)thr;
return res;
}
#endif /* of pthread case */

View File

@@ -0,0 +1,947 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: java_plugin_shm_host.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/*
all methods here but JVMP_GetPlugin() declared "static", as only access to
them is via structure returned by JVMP_GetPlugin(), so why to add needless
records to export table of plugin DLL. Also it looks like JNI approach.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <dlfcn.h>
#include "jvmp.h"
#include "shmtran.h"
#define PLUGIN_DEBUG 1
#define MAX_EXT 50
static int g_msg_id;
static JVMP_CallingContext* g_ctx = NULL;
static JVMP_Extension* g_extensions[MAX_EXT];
struct JVM_Methods {
jint JNICALL (*JNI_GetDefaultJavaVMInitArgs)(void *args);
jint JNICALL (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
jint JNICALL (*JNI_GetCreatedJavaVMs)(JavaVM **, jsize, jsize *);
};
typedef struct JVM_Methods JVM_Methods;
static JavaVM* JVMP_JVM_running = NULL;
static jobject JVMP_PluginInstance = NULL;
static jclass JVMP_PluginClass = NULL;
static JVM_Methods JVMP_JVMMethods;
static char* JVMP_plugin_home = NULL;
static char* global_libpath = NULL;
#ifdef PLUGIN_DEBUG
#define PLUGIN_LOG(s1) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1); fprintf(stderr, "\n"); }
#define PLUGIN_LOG2(s1, s2) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1, s2); fprintf(stderr, "\n"); }
#define PLUGIN_LOG3(s1, s2, s3) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1, s2, s3); fprintf(stderr, "\n"); }
#define PLUGIN_LOG4(s1, s2, s3, s4) { fprintf (stderr, "Java Plugin: "); \
fprintf(stderr, s1, s2, s3 ,s4); fprintf(stderr, "\n"); }
#else
#define PLUGIN_LOG(s1)
#define PLUGIN_LOG2(s1, s2)
#define PLUGIN_LOG3(s1, s2, s3)
#define PLUGIN_LOG4(s1, s2, s3, s4)
#endif
#define LIBJVM "libjvm.so"
static jint __JVMP_addOption(JavaVMInitArgs* opt, char* str, void* extra) {
jint numOp;
numOp = opt->nOptions + 1;
opt->options = realloc(opt->options, numOp * sizeof(JavaVMOption));
if (!opt->options)
{
PLUGIN_LOG("cannot realloc() memory for JVM options");
return JNI_FALSE;
};
opt->options[numOp-1].optionString = str;
opt->options[numOp-1].extraInfo = extra;
opt->nOptions = numOp;
return JNI_TRUE;
}
static char* getPluginLibPath(char* home) {
static char* result = NULL;
if (result != NULL) return result;
result = (char*) malloc(3*strlen(home)+200);
/* FIXME !! */
sprintf(result,
#ifdef _JVMP_SUNJVM
"%s/java/jre/lib/"ARCH"/hotspot:%s/java/jre/lib/"ARCH":%s"
#endif
#ifdef _JVMP_IBMJVM
"%s:%s/java/jre/bin:%s/java/jre/bin/classic"
#endif
, home, home, home);
return result;
}
static jint loadJVM(const char* name) {
void* handle;
char* error;
char *libpath, *newlibpath, *pluginlibpath;
char *libjvm, *java_home, *jre_home;
int tmplen;
struct stat sbuf;
static int loaded = 0;
typedef jint JNICALL (*JNI_GetDefaultJavaVMInitArgs_t)(void *args);
typedef jint JNICALL (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
typedef jint JNICALL (*JNI_GetCreatedJavaVMs_t)(JavaVM **, jsize, jsize *);
typedef jint JNICALL (*JNI_OnLoad_t)(JavaVM *vm, void *reserved);
typedef void JNICALL (*JNI_OnUnload_t)(JavaVM *vm, void *reserved);
#define JVM_RESOLVE(method) JVMP_JVMMethods.##method = \
(method##_t) dlsym(handle, #method); \
if ((error = dlerror()) != NULL) { \
PLUGIN_LOG2("dlsym: %s", error); \
return JNI_FALSE; \
}
if (loaded) return JNI_TRUE;
/* bzero() ? */
memset(&JVMP_JVMMethods, 0, sizeof(JVMP_JVMMethods));
/* find out JAVA_PLUGIN_HOME */
JVMP_plugin_home = getenv("JAVA_PLUGIN_HOME");
if (JVMP_plugin_home == NULL) {
PLUGIN_LOG("Env variable JAVA_PLUGIN_HOME not set");
return JNI_FALSE;
}
if ((stat(JVMP_plugin_home, &sbuf) < 0) || !S_ISDIR(sbuf.st_mode)) {
PLUGIN_LOG2("Bad value %s of JAVA_PLUGIN_HOME", JVMP_plugin_home);
return JNI_FALSE;
}
/* LD_LIBRARY_PATH correction */
pluginlibpath = getPluginLibPath(JVMP_plugin_home);
libpath = getenv("LD_LIBRARY_PATH");
if (!libpath) libpath = "";
tmplen = strlen(libpath) + strlen(pluginlibpath);
global_libpath = (char*) malloc(tmplen + 2);
newlibpath = (char*) malloc(tmplen + 22);
sprintf(global_libpath, "%s:%s", pluginlibpath, libpath);
sprintf(newlibpath, "LD_LIBRARY_PATH=%s", global_libpath);
//putenv(newlibpath);
java_home = (char*) malloc(strlen(JVMP_plugin_home)+41);
jre_home = (char*) malloc(strlen(JVMP_plugin_home)+41);
libjvm = (char*) malloc(strlen(JVMP_plugin_home)+strlen(name)+50);
#ifdef _JVMP_IBMJVM
sprintf(java_home, "JAVAHOME=%s/java/jre", JVMP_plugin_home);
sprintf(jre_home, "JREHOME=%s/java/jre", JVMP_plugin_home);
sprintf(libjvm, "%s/java/jre/bin/classic/%s", JVMP_plugin_home,
name);
#endif
#ifdef _JVMP_SUNJVM
sprintf(java_home, "JAVA_HOME=%s/java/jre/", JVMP_plugin_home);
sprintf(jre_home, "JREHOME=%s/java/jre/", JVMP_plugin_home);
sprintf(libjvm, "%s/java/jre/lib/"ARCH"/hotspot/%s", JVMP_plugin_home,
name);
#endif
//putenv(java_home);
//putenv(jre_home);
PLUGIN_LOG2("loading JVM from %s", libjvm);
handle = dlopen (libjvm, RTLD_NOW);
free (libjvm);
if (!handle) {
PLUGIN_LOG2("dlopen: %s", dlerror());
return JNI_FALSE;
};
JVM_RESOLVE(JNI_GetDefaultJavaVMInitArgs);
JVM_RESOLVE(JNI_CreateJavaVM);
JVM_RESOLVE(JNI_GetCreatedJavaVMs);
loaded = 1;
return JNI_TRUE;
}
/* join Plugin's classpaths to the arguments passed to JVM */
static jint JVMP_initClassPath(void* args) {
JavaVMInitArgs* opt;
char *classpath, *newclasspath, *pluginclasspath, *bootclasspath;
char *java_libpath, *java_home;
char* str;
int i;
opt = (JavaVMInitArgs*) args;
for (i=0; i < (int)opt->nOptions; i++)
PLUGIN_LOG3("before option[%d]=%s", i, opt->options[i].optionString);
/* add javaplugin classpath to standard classpath */
classpath = getenv("CLASSPATH");
if (!classpath) classpath = "";
pluginclasspath = (char*) malloc(2*strlen(JVMP_plugin_home)+50);
/* XXX: FIX ME - use both JARS and dirs */
sprintf(pluginclasspath,
"%s/classes:"
/* #ifdef _JVMP_IBMJVM */
/* "%s/java/jre/lib/rt.jar:" */
/* #endif */
/* #ifdef _JVMP_SUNJVM */
/* "%s/java/jre/lib/classes:" */
/* #endif */
, JVMP_plugin_home);
newclasspath = (char*) malloc(strlen(classpath) +
strlen(pluginclasspath) + 1);
strcpy(newclasspath, pluginclasspath);
if (classpath != NULL)
strcat(newclasspath, classpath);
str = (char*) malloc(strlen(newclasspath)+30);
sprintf(str, "-Djava.class.path=%s", newclasspath);
if (!__JVMP_addOption(opt, str, NULL)) return JNI_FALSE;
java_libpath = (char*) malloc(strlen(global_libpath) + 30);
sprintf(java_libpath, "-Djava.library.path=%s", global_libpath);
if (!__JVMP_addOption(opt, java_libpath, NULL)) return JNI_FALSE;
java_home = (char*) malloc(strlen(JVMP_plugin_home)+30);
sprintf(java_home, "-Djava.home=%s/java/jre", JVMP_plugin_home);
if (!__JVMP_addOption(opt, java_home, NULL)) return JNI_FALSE;
free(pluginclasspath);
bootclasspath = (char*) malloc(3*strlen(JVMP_plugin_home)+180);
sprintf(bootclasspath, "-Xbootclasspath:"
"%s/java/jre/classes:"
"%s/java/jre/lib/rt.jar:"
"%s/java/jre/lib/i18n.jar",
JVMP_plugin_home, JVMP_plugin_home, JVMP_plugin_home
);
if (!__JVMP_addOption(opt, bootclasspath, NULL)) return JNI_FALSE;
for (i=0; i < (int)opt->nOptions; i++)
PLUGIN_LOG3("JVM option[%d]=%s", i, opt->options[i].optionString);
return JNI_TRUE;
}
static jint JNICALL JVMP_initJavaClasses(JavaVM* jvm, JNIEnv* env) {
jclass clz;
jmethodID meth;
jboolean trace = JNI_TRUE;
jobject inst;
(*env)->ExceptionClear(env);
/* Find main plugin's class */
clz = (*env)->FindClass(env, "sun/jvmp/generic/motif/Plugin");
if (clz == 0) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
/* Find its "startJVM" method */
meth = (*env)->GetStaticMethodID(env, clz, "startJVM",
"(Z)Lsun/jvmp/PluggableJVM;");
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
inst = (*env)->CallStaticObjectMethod(env, clz, meth, trace);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
JVMP_PluginInstance = (*env)->NewWeakGlobalRef(env, inst);
JVMP_PluginClass = (*env)->NewWeakGlobalRef(env, clz);
return JNI_TRUE;
}
/* prototype for this function */
static jint JVMP_GetCallingContext(JavaVM *jvm,
JVMP_CallingContext **pctx,
jint version,
JVMP_ThreadInfo* target);
static jint JVMP_SetCap(JVMP_CallingContext *ctx, jint cap_no)
{
JVMP_ALLOW_CAP(ctx->caps, cap_no);
return JNI_TRUE;
}
static jint JVMP_SetCaps(JVMP_CallingContext *ctx,
JVMP_SecurityCap *new_caps)
{
if (!new_caps) return JNI_FALSE;
memcpy(&(ctx->caps), new_caps, sizeof(JVMP_SecurityCap));
return JNI_TRUE;
}
static jint JVMP_GetCap(JVMP_CallingContext *ctx, jint cap_no)
{
return JVMP_IS_CAP_ALLOWED(ctx->caps, cap_no);
}
static jint JVMP_IsActionAllowed(JVMP_CallingContext *ctx,
JVMP_SecurityAction *caps)
{
int i, r;
for(i=0, r=1; i < JVMP_MAX_CAPS_BYTES; i++)
{
r =
r && ((!(caps->bits)[i]) |
(((ctx->caps).bits)[i] & (caps->bits)[i]));
if (!r) return JNI_FALSE;
}
return JNI_TRUE;
}
static JVMP_CallingContext* NewCallingContext()
{
JVMP_CallingContext* ctx_new = NULL;
ctx_new = (JVMP_CallingContext *) malloc(sizeof(JVMP_CallingContext));
if (!ctx_new) return NULL;
ctx_new->source_thread = NULL; /* must be current thread */
ctx_new->env = NULL;
ctx_new->source = NULL;
JVMP_FORBID_ALL_CAPS(ctx_new->caps);
ctx_new->AllowCap = &JVMP_SetCap;
ctx_new->GetCap = &JVMP_GetCap;
ctx_new->SetCaps = &JVMP_SetCaps;
ctx_new->IsActionAllowed = &JVMP_IsActionAllowed;
return ctx_new;
}
/* arguments are taken into account only if JVM isn't already created */
/* XXX: fix possible race conditions when different threads calls
this method in the same time, as JNI_CreateJavaVM() is long.
I've skipped it yet, as haven't decided which thread library to
use. I can't use MonitorEnter/MonitorExit yet, as there is no
JNIEnv yet.
*/
static jint JNICALL JVMP_GetRunningJVM(JavaVM **pjvm,
JVMP_CallingContext **pctx,
void *args, jint allow_reuse)
{
JavaVM* jvm_new = NULL;
JVMP_CallingContext* ctx_new = NULL;
JNIEnv* env_new = NULL;
jint jvm_err;
if (JVMP_JVM_running == NULL) {
if (!JVMP_initClassPath(args)) return JNI_FALSE;
ctx_new = NewCallingContext();
if (!ctx_new) return JNI_FALSE;
if ((jvm_err = JVMP_JVMMethods.JNI_CreateJavaVM
(&jvm_new, (void*)&(ctx_new->env), args)) != JNI_OK)
{
PLUGIN_LOG2("JVMP: JNI_CreateJavaVM failed due %d", (int)jvm_err);
return jvm_err;
}
env_new = ctx_new->env;
} else {
(*pjvm) = JVMP_JVM_running;
/* XXX: FIXME version */
return JVMP_GetCallingContext(JVMP_JVM_running,
pctx,
JNI_VERSION_1_2,
NULL);
};
if (env_new) {
if (!JVMP_initJavaClasses(jvm_new, env_new)) {
PLUGIN_LOG("Problems with Java classes of JVMP. Exiting...");
return JNI_FALSE;
};
JVMP_JVM_running = jvm_new;
(*pjvm) = JVMP_JVM_running;
(*pctx) = ctx_new;
(*env_new)->ExceptionClear(env_new);
return JNI_TRUE;
}
else {
return JNI_FALSE;
};
}
static jint JNICALL JVMP_StopJVM(JVMP_CallingContext* ctx) {
jmethodID myMethod;
JNIEnv* env = ctx->env;
if (JVMP_JVM_running == NULL) return JNI_TRUE;
myMethod = (*env)->GetMethodID(env, JVMP_PluginClass,
"stopPlugin", "()V");
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
(*env)->CallVoidMethod(env, JVMP_PluginInstance, myMethod);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
/* FIXME: I don't know how to completly destroy JVM.
Current code waits until only one thread left - but how to kill 'em?
Host application should be able to control such stuff as execution of
JVM, even if there are some java threads running
*/
(*JVMP_JVM_running)->DestroyJavaVM(JVMP_JVM_running);
JVMP_JVM_running = NULL;
return JNI_TRUE;
}
static jint JNICALL JVMP_GetDefaultJavaVMInitArgs(void *args)
{
if (JVMP_JVMMethods.JNI_GetDefaultJavaVMInitArgs)
{
return JVMP_JVMMethods.JNI_GetDefaultJavaVMInitArgs(args);
}
return JNI_FALSE;
}
static jint JNICALL JVMP_RegisterWindow(JVMP_CallingContext* ctx,
JVMP_DrawingSurfaceInfo *win,
jint *pID)
{
jlong handle;
jint ID;
jmethodID myMethod;
JNIEnv* env = ctx->env;
PLUGIN_LOG("JVMP_RegisterWindow");
if (win == NULL) return JNI_FALSE;
handle = (jlong)(jint)(win->window);
myMethod = (*env)->GetMethodID(env, JVMP_PluginClass,
"RegisterWindow", "(JII)I");
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
}
/* fprintf(stderr, "calling RegisterWindow()\n"); */
ID = (*env)->CallIntMethod(env, JVMP_PluginInstance, myMethod,
handle, win->width, win->height);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
}
if (ID == 0)
{
PLUGIN_LOG("ID == 0");
return JNI_FALSE;
};
if (pID) *pID = ID;
return JNI_TRUE;
}
static jint JNICALL JVMP_UnregisterWindow(JVMP_CallingContext* ctx,
jint ID)
{
jmethodID myMethod;
jint result;
JNIEnv* env = ctx->env;
if (ID <= 0) return JNI_FALSE;
myMethod = (*env)->GetMethodID(env, JVMP_PluginClass,
"UnregisterWindow", "(I)I");
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
result = (*env)->CallIntMethod(env, JVMP_PluginInstance, myMethod,
ID);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
if (result != ID) return JNI_FALSE;
return JNI_TRUE;
}
static jint JVMP_GetCallingContext(JavaVM *jvm,
JVMP_CallingContext* *pctx,
jint version,
JVMP_ThreadInfo* target)
{
jint ret;
JVMP_CallingContext* ctx_new = NewCallingContext();
if (!ctx_new) return JNI_FALSE;
g_ctx = ctx_new;
ret = (*jvm)->GetEnv(jvm, (void*)&(ctx_new->env), version);
return (ret == JNI_OK ? JNI_TRUE : JNI_FALSE);
}
static jint JNICALL JVMP_RegisterMonitor(JVMP_CallingContext* ctx,
JVMP_MonitorInfo *monitor,
jint *pID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_UnregisterMonitor(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorEnter(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorExit(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorWait(JVMP_CallingContext* ctx,
jint ID, jlong milli)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorNotify(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_MonitorNotifyAll(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_FALSE;
}
static jint JNICALL JVMP_CreatePeer(JVMP_CallingContext* ctx,
jint hostApp,
jint version,
jint *target)
{
jmethodID myMethod = NULL;
jint result = 0;
JNIEnv* env = ctx->env;
myMethod = (*env)->GetMethodID(env, JVMP_PluginClass,
"createPeer", "(II)I");
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
result = (*env)->CallIntMethod(env, JVMP_PluginInstance, myMethod,
hostApp, version);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
if (result == 0) return JNI_FALSE;
*target = result;
return JNI_TRUE;
}
static jint JNICALL JVMP_SendEvent(JVMP_CallingContext* ctx,
jint target,
jint event,
jlong data)
{
jmethodID myMethod;
jint result;
JNIEnv* env = ctx->env;
myMethod = (*env)->GetMethodID(env, JVMP_PluginClass,
"sendEvent", "(IIJ)I");
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
result = (*env)->CallIntMethod(env, JVMP_PluginInstance, myMethod,
target, event, data);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
if (result == 0) return JNI_FALSE;
return JNI_TRUE;
}
static jint JNICALL JVMP_PostEvent(JVMP_CallingContext* ctx,
jint target,
jint event,
jlong data)
{
jmethodID myMethod;
jint result;
JNIEnv* env = ctx->env;
myMethod = (*env)->GetMethodID(env, JVMP_PluginClass,
"postEvent", "(IIJ)I");
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
result = (*env)->CallIntMethod(env, JVMP_PluginInstance, myMethod,
target, event, data);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
if (result == 0) return JNI_FALSE;
return JNI_TRUE;
}
static jint JNICALL JVMP_DestroyPeer(JVMP_CallingContext* ctx,
jint target)
{
jmethodID myMethod = NULL;
jint result = 0;
JNIEnv* env = ctx->env;
myMethod = (*env)->GetMethodID(env, JVMP_PluginClass,
"removePeer", "(I)I");
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
result = (*env)->CallIntMethod(env, JVMP_PluginInstance, myMethod,
target);
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
if (result != target) return JNI_FALSE;
return JNI_TRUE;
}
static jint JNICALL JVMP_RegisterExtension(JVMP_CallingContext* ctx,
const char* extPath,
jint *pID)
{
void* handle;
char* error;
JVMP_GetExtension_t JVMP_GetExtension;
JVMP_Extension* ext;
jint vendorID, version, result;
jmethodID myMethod = NULL;
char *classpath, *classname;
jstring jclasspath, jclassname;
static int ext_idx = 0;
JNIEnv* env = ctx->env;
PLUGIN_LOG("JVMP_RegisterExtension - JVM");
handle = dlopen(extPath, RTLD_NOW);
if (!handle) {
PLUGIN_LOG2("extension dlopen: %s", dlerror());
return JNI_FALSE;
};
JVMP_GetExtension =
(JVMP_GetExtension_t)dlsym(handle, "JVMP_GetExtension");
if ((error = dlerror()) != NULL)
{
PLUGIN_LOG2("extension dlsym: %s", error);
return JNI_FALSE;
}
/* to implement JVMP_UnregisterExtension we should support
GHashTable of opened extensions, but later */
if (((*JVMP_GetExtension)(&ext) != JNI_TRUE))
{
PLUGIN_LOG2("Cannot obtain extension from %s", extPath);
return JNI_FALSE;
}
(ext->JVMPExt_GetExtInfo)(&vendorID, &version);
/* init it on JVM side */
if ((ext->JVMPExt_Init)(2) != JNI_TRUE) return JNI_FALSE;
g_extensions[ext_idx++] = ext;
myMethod =
(*env)->GetMethodID(env, JVMP_PluginClass,
"registerExtension",
"(IILjava/lang/String;Ljava/lang/String;)I");
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
(ext->JVMPExt_GetBootstrapClass)(&classpath, &classname);
jclasspath = (*env)->NewStringUTF(env, classpath);
jclassname = (*env)->NewStringUTF(env, classname);
if (jclasspath == NULL || jclassname == NULL) return JNI_FALSE;
result = (*env)->CallIntMethod(env, JVMP_PluginInstance, myMethod,
vendorID, version,
jclasspath, jclassname);
/* XXX: maybe leak of jclasspath, jclassname - ReleaseStringUTFChars*/
if ((*env)->ExceptionOccurred(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
return JNI_FALSE;
};
*pID = result;
return JNI_TRUE;
}
static jint JNICALL JVMP_UnregisterExtension(JVMP_CallingContext* ctx,
jint ID)
{
return JNI_TRUE;
}
/* Here main structure is initialized */
static JVMP_RuntimeContext JVMP_PluginContext = {
&JVMP_GetRunningJVM,
&JVMP_StopJVM,
&JVMP_GetDefaultJavaVMInitArgs,
&JVMP_RegisterWindow,
&JVMP_UnregisterWindow,
&JVMP_RegisterMonitor,
&JVMP_UnregisterMonitor,
&JVMP_MonitorEnter,
&JVMP_MonitorExit,
&JVMP_MonitorWait,
&JVMP_MonitorNotify,
&JVMP_MonitorNotifyAll,
&JVMP_GetCallingContext,
&JVMP_CreatePeer,
&JVMP_SendEvent,
&JVMP_PostEvent,
&JVMP_DestroyPeer,
&JVMP_RegisterExtension,
&JVMP_UnregisterExtension
};
jint JNICALL JVMP_GetPlugin(JVMP_RuntimeContext** cx) {
if (cx == NULL) return JNI_FALSE;
if (!loadJVM(LIBJVM)) {
PLUGIN_LOG("BAD - JVM loading failed");
return JNI_FALSE;
}
PLUGIN_LOG("OK - JVM dll at least loaded");
(*cx) = &JVMP_PluginContext;
return JNI_TRUE;
}
#ifdef _JVMP_PTHREADS
JVMP_ThreadInfo* ThreadInfoFromPthread(pthread_t thr)
{
JVMP_ThreadInfo* res =
(JVMP_ThreadInfo*)malloc(sizeof(JVMP_ThreadInfo));
/* pthread_t is unsigned int on Linux and Solaris :) */
res->handle = (void*)thr;
return res;
}
#endif /* of pthread case */
static int JVMP_ExecuteExtReq(JVMP_ShmRequest* req)
{
int i;
for (i=0; i<MAX_EXT; i++)
{
if (g_extensions[i] != NULL &&
((g_extensions[i])->JVMPExt_ScheduleRequest)(req, JNI_TRUE))
break;
}
return 1;
}
int JVMP_ExecuteShmRequest(JVMP_ShmRequest* req)
{
JavaVMInitArgs vm_args;
JVMP_DrawingSurfaceInfo win, *pwin;
jint ID, *pID;
char* extPath;
char sign[100];
jint vendorID, version, *ptarget, target, event;
jlong data, *pdata;
if (!req) return 0;
switch(req->func_no)
{
case 1:
// JVMP_GetRunningJVM(JavaVM **jvm,
// JVMP_CallingContext* *pctx, void *args)
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_2;
JVMP_GetDefaultJavaVMInitArgs((void*)&vm_args);
req->retval = JVMP_GetRunningJVM(&JVMP_JVM_running,
&g_ctx, &vm_args, JNI_FALSE);
break;
case 2:
// JVMP_StopJVM(JVMP_CallingContext* ctx)
req->retval = JVMP_StopJVM(g_ctx);
break;
case 3:
// jint JNICALL (*JVMP_GetDefaultJavaVMInitArgs)(void *args);
req->retval = JNI_TRUE;
break;
case 4:
/* jint JNICALL (*JVMP_RegisterWindow)(JVMP_CallingContext* ctx,
JVMP_DrawingSurfaceInfo *win,
jint *pID);
*/
pwin = &win;
pID = &ID;
sprintf(sign, "A[%d]i", sizeof(JVMP_DrawingSurfaceInfo));
JVMP_DecodeRequest(req, 0, sign, &pwin, &pID);
req->retval = JVMP_RegisterWindow(g_ctx, pwin, pID);
JVMP_EncodeRequest(req, sign, pwin, pID);
break;
case 5:
/* jint JNICALL (*JVMP_UnregisterWindow)(JVMP_CallingContext* ctx,
jint ID);
*/
sprintf(sign, "I");
JVMP_DecodeRequest(req, 0, sign, &ID);
req->retval = JVMP_UnregisterWindow(g_ctx, ID);
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
req->retval = JNI_FALSE;
break;
case 14:
/* jint JNICALL (*JVMP_CreatePeer)(JVMP_CallingContext* ctx,
jint vendorID,
jint version,
jint *target); */
sprintf(sign, "IIi");
ptarget = &target;
JVMP_DecodeRequest(req, 0, sign, &vendorID, &version, &ptarget);
req->retval = JVMP_CreatePeer(g_ctx, vendorID, version, ptarget);
JVMP_EncodeRequest(req, sign, vendorID, version, ptarget);
break;
case 15:
/* jint JNICALL (*JVMP_SendEvent)(JVMP_CallingContext* ctx,
jint target,
jint event,
jlong data); */
sprintf(sign, "IIA[%d]", sizeof(jlong));
pdata = &data;
JVMP_DecodeRequest(req, 0, sign, &target, &event, &pdata);
req->retval = JVMP_SendEvent(g_ctx, target, event, data);
break;
case 16:
/* jint JNICALL (*JVMP_PostEvent)(JVMP_CallingContext* ctx,
jint target,
jint event,
jlong data); */
sprintf(sign, "IIA[%d]", sizeof(jlong));
pdata = &data;
JVMP_DecodeRequest(req, 0, sign, &target, &event, &pdata);
req->retval = JVMP_PostEvent(g_ctx, target, event, data);
break;
case 17:
/* jint JNICALL (*JVMP_DestroyPeer)(JVMP_CallingContext* ctx,
jint target); */
sprintf(sign, "I");
JVMP_DecodeRequest(req, 0, sign, &target);
req->retval = JVMP_DestroyPeer(g_ctx, target);
break;
case 18:
/* jint JNICALL (*JVMP_RegisterExtension)(JVMP_CallingContext* ctx,
const char* extPath,
jint *pID); */
sprintf(sign, "Si");
JVMP_DecodeRequest(req, 1, sign, &extPath, &pID);
req->retval = JVMP_RegisterExtension(g_ctx, extPath, pID);
JVMP_EncodeRequest(req, sign, NULL, pID);
free(extPath);
free(pID);
break;
case 19:
/* jint JNICALL (*JVMP_UnregisterExtension)(JVMP_CallingContext* ctx,
jint ID); */
sprintf(sign, "I");
JVMP_DecodeRequest(req, 0, sign, &ID);
req->retval = JVMP_UnregisterExtension(g_ctx, ID);
break;
default:
return JVMP_ExecuteExtReq(req);
}
return 1;
}
int main(int argc, char** argv)
{
int id = 0;
JVMP_RuntimeContext* cx = NULL;
/* one and only argument should be message queue id used to communicate
with host application */
if (argc != 2) return 1;
id = atoi(argv[1]);
g_msg_id = id;
//sleep(30);
JVMP_ShmInit(2); /* init it on JVM side */
memset(g_extensions, 0, MAX_EXT*sizeof(JVMP_Extension*));
if (!JVMP_GetPlugin(&cx) || !cx) return 1;
JVMP_ShmMessageLoop(g_msg_id);
return 0;
}

View File

@@ -0,0 +1,89 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: jvmp_exec.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "shmtran.h"
#include "string.h"
int g_msg_id;
static int test(int i, char* s, void* ptr);
int JVMP_ExecuteShmRequest(JVMP_ShmRequest* req)
{
char* string_val;
jpointer jpointer_val;
int int_val;
char sign[20];
char* buf;
if (!req) return 0;
switch(req->func_no)
{
case 1:
strcpy(sign, "ISA[8]a[0]");
JVMP_DecodeRequest(req, 1, sign,
&int_val, &string_val, &jpointer_val, &buf);
buf = malloc(100000);
strcpy(buf, "Privet");
sprintf(sign, "ISA[8]a[%d]", 100000);
req->retval = test(int_val, string_val, jpointer_val);
JVMP_EncodeRequest(req, sign, int_val, string_val, jpointer_val, buf);
break;
default:
printf("no such function\n");
return 0;
break;
}
return 1;
}
static int test(int i, char* s, void* ptr)
{
printf("called with i=%d s=\"%s\" ptr[5]=%c \n", i, s, ((char*)ptr)[5]
);
((char*)ptr)[5] = 'B';
return 19;
}
int main(int argc, char** argv)
{
int id = 0;
/* one and only argument should be message queue id used to communicate
with host application */
if (argc != 2) return 1;
id = atoi(argv[1]);
g_msg_id = id;
JVMP_ShmInit();
JVMP_ShmMessageLoop(g_msg_id);
return 0;
}

View File

@@ -0,0 +1,344 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: native.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
/* Waterfall headers */
#include "jvmp.h"
#include "jvmp_threading.h"
/* some native methods implemented here */
#include "sun_jvmp_generic_motif_Plugin.h"
#include "sun_jvmp_generic_motif_PthreadSynchroObject.h"
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stropts.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <Xm/VendorS.h>
#include <dlfcn.h>
#include <sys/param.h>
/* AWT glueing code */
#include "awt_Plugin.h"
/* code resolved from AWT DLL */
static void (* LockIt)(JNIEnv *) = NULL;
static void (* UnLockIt)(JNIEnv *) = NULL;
static void (* NoFlushUnlockIt)(JNIEnv *) = NULL;
/* AWT X server connection */
static Display *display;
/* AWT DLL handle */
static void *awtDLL = NULL;
#define AWTDLL "libawt.so"
/* those functions exported from AWT DLL ... */
typedef void (*getAwtLockFunctions_t)(void (**AwtLock)(JNIEnv *),
void (**AwtUnlock)(JNIEnv *),
void (**AwtNoFlushUnlock)(JNIEnv *),
void *reserved);
typedef void (*getAwtData_t) (int *awt_depth,
Colormap *awt_cmap,
Visual* *awt_visual,
int *awt_num_colors,
void* pReserved);
typedef Display* (*getAwtDisplay_t)(void);
/* ...and written to this table */
struct awt_callbacks_t {
getAwtLockFunctions_t getAwtLockFunctions;
getAwtData_t getAwtData;
getAwtDisplay_t getAwtDisplay;
} awt =
{ NULL,
NULL,
NULL };
static WidgetClass getVendorShellWidgetClass() {
static WidgetClass *v = NULL;
if (v != NULL) return *v;
v = (WidgetClass *) dlsym(RTLD_DEFAULT , "vendorShellWidgetClass");
if (v != NULL) return *v;
/* I dunno why but it doesn't work on Linux
with statically linked Motif - so search it in libawt explicity */
v = (WidgetClass *) dlsym(awtDLL, "vendorShellWidgetClass");
if (v != NULL) return *v;
fprintf(stderr,
"Cannot resolve vendorShellWidgetClass now: %s\nAborting...\n",
dlerror());
/* XXX: maybe give up more nicely */
exit(1);
/* Not reached anyway */
return *v;
}
static int initAWTGlue()
{
#define AWT_RESOLVE(method) awt.##method = \
(method##_t) dlsym(awtDLL, #method); \
if (awt.##method == NULL) { \
fprintf(stderr, "dlsyn: %s", dlerror()); \
return 0; \
}
char awtPath[MAXPATHLEN];
/* JAVA_HOME/JAVAHOME set by Waterfall before, see java_plugin.c */
#ifdef _JVMP_SUNJVM
sprintf(awtPath, "%s/lib/" ARCH "/" AWTDLL,
getenv("JAVA_HOME"));
#endif
#ifdef _JVMP_IBMJVM
sprintf(awtPath, "%s/bin/" AWTDLL,
getenv("JAVAHOME"));
#endif
//fprintf(stderr,"loading %s\n", awtPath);
awtDLL = dlopen(awtPath, RTLD_NOW);
if (awtDLL == NULL)
{
fprintf(stderr,"cannot load AWT: %s\n", dlerror());
return 0;
}
AWT_RESOLVE(getAwtLockFunctions);
awt.getAwtLockFunctions(&LockIt, &UnLockIt, &NoFlushUnlockIt, NULL);
AWT_RESOLVE(getAwtData);
AWT_RESOLVE(getAwtDisplay);
return 1;
}
static void
checkPos(Widget w, XtPointer data, XEvent *event)
{
/* for reparent hack */
w->core.x = event->xcrossing.x_root - event->xcrossing.x;
w->core.y = event->xcrossing.y_root - event->xcrossing.y;
}
JNIEXPORT jlong JNICALL
Java_sun_jvmp_generic_motif_Plugin_getWidget(JNIEnv *env, jclass clz,
jint winid, jint width, jint height,
jint x, jint y)
{
Arg args[40];
int argc;
Widget w;
Window child, parent;
Visual *visual;
Colormap cmap;
int depth;
int ncolors;
Display **awt_display_ptr;
/*
* Create a top-level shell. Note that we need to use the
* AWT's own awt_display to initialize the widget. If we
* try to create a second X11 display connection the Java
* runtimes get very confused.
*/
(*LockIt)(env);
argc = 0;
XtSetArg(args[argc], XmNsaveUnder, False); argc++;
XtSetArg(args[argc], XmNallowShellResize, False); argc++;
/* the awt initialization should be done by now (awt_GraphicsEnv.c) */
awt.getAwtData(&depth,&cmap, &visual, &ncolors, NULL);
awt_display_ptr = (Display **) dlsym(awtDLL, "awt_display");
if (awt_display_ptr == NULL)
display = awt.getAwtDisplay();
else
display = *awt_display_ptr;
XtSetArg(args[argc], XmNvisual, visual); argc++;
XtSetArg(args[argc], XmNdepth, depth); argc++;
XtSetArg(args[argc], XmNcolormap, cmap); argc++;
XtSetArg(args[argc], XmNwidth, width); argc++;
XtSetArg(args[argc], XmNheight, height); argc++;
XtSetArg(args[argc], XmNx, 0); argc++;
XtSetArg(args[argc], XmNy, 0); argc++;
XtSetArg(args[argc], XmNmappedWhenManaged, False); argc++;
w = XtAppCreateShell("AWTapp","XApplication",
getVendorShellWidgetClass(),
display,
args,
argc);
XtRealizeWidget(w);
XtAddEventHandler(w, EnterWindowMask, FALSE,(XtEventHandler) checkPos, 0);
/*
* Now reparent our new Widget into our Navigator window
*/
parent = (Window) winid;
child = XtWindow(w);
XReparentWindow(display, child, parent, 0, 0);
XFlush(display);
XSync(display, False);
XtVaSetValues(w, XmNx, 0, XmNy, 0, NULL);
XFlush(display);
XSync(display, False);
(*UnLockIt)(env);
return PTR_TO_JLONG(w);
}
JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved)
{
if (!initAWTGlue()) return 0;
return JNI_VERSION_1_2;
}
static jlong getTimeMillis()
{
struct timeval t;
gettimeofday(&t, 0);
return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
}
JNIEXPORT jint JNICALL
Java_sun_jvmp_generic_motif_PthreadSynchroObject_checkHandle (JNIEnv *env,
jobject jobj,
jlong handle)
{
JVMP_Monitor* monitor = (JVMP_Monitor*)JLONG_TO_PTR(handle);
if (!monitor || monitor->magic != JVMP_MONITOR_MAGIC) return -1;
return 0;
}
JNIEXPORT jint JNICALL
Java_sun_jvmp_generic_motif_PthreadSynchroObject_doDestroy(JNIEnv *env,
jobject jobj,
jlong handle)
{
JVMP_Monitor* monitor = (JVMP_Monitor*)JLONG_TO_PTR(handle);
/* XXX: should this code destroy anything at all? */
pthread_cond_destroy((pthread_cond_t*)monitor->monitor);
pthread_mutex_destroy((pthread_mutex_t*)monitor->mutex);
return 0;
}
JNIEXPORT jint JNICALL
Java_sun_jvmp_generic_motif_PthreadSynchroObject_doLock(JNIEnv *env,
jobject jobj,
jlong handle)
{
JVMP_Monitor* monitor = (JVMP_Monitor*)JLONG_TO_PTR(handle);
int r;
if (monitor->mutex_state != JVMP_STATE_INITED)
return JVMP_ERROR_INCORRECT_MUTEX_STATE;
r = pthread_mutex_lock((pthread_mutex_t*)monitor->mutex);
if (r != 0) return r;
monitor->mutex_state = JVMP_STATE_LOCKED;
return 0;
}
JNIEXPORT jint JNICALL
Java_sun_jvmp_generic_motif_PthreadSynchroObject_doUnlock(JNIEnv *env,
jobject jobj,
jlong handle)
{
JVMP_Monitor* monitor = (JVMP_Monitor*)JLONG_TO_PTR(handle);
int r;
if (monitor->mutex_state != JVMP_STATE_LOCKED)
return JVMP_ERROR_MUTEX_NOT_LOCKED;
r = pthread_mutex_unlock((pthread_mutex_t*)monitor->mutex);
if (r != 0) return r;
monitor->mutex_state = JVMP_STATE_INITED;
return 0;
}
JNIEXPORT jint JNICALL
Java_sun_jvmp_generic_motif_PthreadSynchroObject_doNotify(JNIEnv *env,
jobject jobj,
jlong handle)
{
JVMP_Monitor* monitor = (JVMP_Monitor*)JLONG_TO_PTR(handle);
if (monitor->mutex_state != JVMP_STATE_LOCKED)
return JVMP_ERROR_MUTEX_NOT_LOCKED;
return pthread_cond_signal((pthread_cond_t*)monitor->monitor);
}
JNIEXPORT jint JNICALL
Java_sun_jvmp_generic_motif_PthreadSynchroObject_doNotifyAll(JNIEnv *env,
jobject jobj,
jlong handle)
{
JVMP_Monitor* monitor = (JVMP_Monitor*)JLONG_TO_PTR(handle);
if (monitor->mutex_state != JVMP_STATE_LOCKED)
return JVMP_ERROR_MUTEX_NOT_LOCKED;
return pthread_cond_broadcast((pthread_cond_t*)monitor->monitor);
}
JNIEXPORT jint JNICALL
Java_sun_jvmp_generic_motif_PthreadSynchroObject_doWait(JNIEnv *env,
jobject jobj,
jlong handle,
jint milli)
{
JVMP_Monitor* monitor = (JVMP_Monitor*)JLONG_TO_PTR(handle);
int r;
if (monitor->mutex_state != JVMP_STATE_LOCKED)
return JVMP_ERROR_MUTEX_NOT_LOCKED;
if (milli == 0)
r = pthread_cond_wait((pthread_cond_t*)monitor->monitor,
(pthread_mutex_t*)monitor->mutex);
else
{
struct timespec abstime;
jlong end;
end = getTimeMillis() + milli;
abstime.tv_sec = end / 1000;
abstime.tv_nsec = (end % 1000) * 1000000;
r = pthread_cond_timedwait((pthread_cond_t*)monitor->monitor,
(pthread_mutex_t*)monitor->mutex,
&abstime);
}
switch (r)
{
case 0:
return 0; /* OK */
case EINTR:
return -1; /* interrupted */
case ETIMEDOUT:
return 0; /* OK as far */
default:
return -2;
}
}

View File

@@ -0,0 +1,813 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: shmtran.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
#include "shmtran.h"
#include <stdlib.h>
#include <stdarg.h> /* for va_list */
#include <stdio.h>
#include <string.h>
#include <strings.h> /* for index() */
#include <signal.h>
#include <errno.h>
#include "jvmp_cap_vals.h"
/* XXX: int->jint, long->jlong */
static volatile int g_terminate = 0;
#define MAX_SHM_MSG 40
#define MAX_SHM_MEM 10
static int _msgs[MAX_SHM_MSG];
static int _shms[MAX_SHM_MEM];
static struct sigaction _sigs[NSIG];
#define JVMP_SHM_LIMIT 1000000
static int g_side = 0;
/* to break, or not to break */
#define ADD_MQ(_idx, msg) for(_idx=0; _idx<MAX_SHM_MSG; _idx++) \
if (_msgs[_idx] == -1) { _msgs[_idx] = msg; break; }
#define DEL_MQ(_idx, msg) for(_idx=0; _idx<MAX_SHM_MSG; _idx++) \
if (_msgs[_idx] == msg) { _msgs[_idx] = -1; break; }
#define ADD_SHM(_idx, shm) for(_idx=0; _idx<MAX_SHM_MEM; _idx++) {\
if (_shms[_idx] == -1) { _shms[_idx] = shm; break; } };\
if (_idx == MAX_SHM_MEM) \
fprintf(stderr, "Leaking SHM(_shms[2]=%d)?\n", _shms[2]);
#define DEL_SHM(_idx, shm) for(_idx=0; _idx<MAX_SHM_MEM; _idx++) \
if (_shms[_idx] == shm) { _shms[_idx] = -1;}
int JVMP_msgget(key_t key, int msgflg)
{
int rval, i;
rval = msgget (key, msgflg);
if (rval != -1) { ADD_MQ(i, rval); }
return rval;
}
int JVMP_shmget(key_t key, int size, int shmflg)
{
int rval, i;
rval = shmget (key, size, shmflg);
if (rval != -1) { ADD_SHM(i, rval); }
return rval;
}
void* JVMP_shmat(int shmid, const void *shmaddr, int shmflg)
{
void* rval;
int i;
rval = shmat(shmid, shmaddr, shmflg);
if (rval != (void*)-1) { ADD_SHM(i, shmid); }
return rval;
}
int JVMP_shmdt(const void *shmaddr, int shmid)
{
int rval, i;
DEL_SHM(i, shmid);
rval = shmdt(shmaddr);
return rval;
}
static int GetShmRealLen(int len)
{
int rlen;
#ifdef __linux
/* man shmget on Linux - page size is greater really */
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
rlen = (len + PAGE_SIZE) / PAGE_SIZE * PAGE_SIZE;
#else
rlen = len;
#endif
return rlen;
}
JVMP_ShmRequest* JVMP_NewShmReq(int msg_id, unsigned int func_no)
{
JVMP_ShmRequest* req;
req = (JVMP_ShmRequest*)malloc(sizeof(JVMP_ShmRequest));
if (!req) return NULL;
req->rid = 0;
req->argt = NULL;
req->argc = 0;
req->length = 0;
req->data = NULL;
req->func_no = func_no;
req->retval = 0; /* determined later in JVMP_WaitConfirmShmRequest*/
req->msg_id = msg_id;
req->shmid = 0;
req->shmdata = NULL;
req->nullmask = 0;
req->shmlen = 0;
JVMP_FORBID_ALL_CAPS(req->caps);
JVMP_ALLOW_CAP(req->caps, JVMP_CAP_SYS_PARITY); /* integrity bit */
return req;
}
int JVMP_EncodeRequest(JVMP_ShmRequest* req,
char* fmt, ...)
{
#define GET_AND_COPY(ap, type, pos, len) \
type##_val = va_arg(ap, type); \
size = sizeof(type); \
if (pos+size >= len) { len = step+pos+size; buf = realloc(buf, len); } \
memcpy(buf+pos, &type##_val, size); \
pos += size; argc++;
#define GET_AND_COPY_STRING(ap, pos, len) \
string_val = va_arg(ap, char*); \
if (!string_val) {nullmask |= (0x1 << argc); } else {\
size = strlen(string_val) + 1; \
if (pos+size >= len) { len = step+pos+size; buf = realloc(buf, len); } \
memcpy(buf+pos, string_val, size); \
pos += size; } argc++;
#define GET_AND_COPY_DATA(ap, pos, len, size) \
jpointer_val = va_arg(ap, void*); \
if (!jpointer_val) { nullmask |= (0x1 << argc); } else {\
if (pos+size >= len) { len = step+pos+size; buf = realloc(buf, len); } \
memcpy(buf+pos, jpointer_val, size); \
pos += size;} argc++;
char* buf = NULL;
char *next, lens[20];
int len, step, pos, size, argc, slen, nullmask;
int int_val;
char* string_val;
long long_val;
jpointer jpointer_val;
va_list ap;
if (!req || !fmt) return 0;
if (req->argt) free(req->argt);
req->argt = strdup(fmt);
nullmask = 0;
len = 0; step = 20; pos = 0; argc = 0; size = 0;
va_start(ap, fmt);
while(*fmt)
{
switch(*fmt++)
{
case 'I': /* integer */
GET_AND_COPY(ap, int, pos, len);
//printf("int %d of size %d\n", int_val, size);
break;
case 'i': /* integer ref */
GET_AND_COPY_DATA(ap, pos, len, sizeof(int));
//printf("int ref %d\n", (int)*(int*)jpointer_val);
break;
case 'J': /* long */
GET_AND_COPY(ap, long, pos, len);
//printf("long %ld of size %d\n", long_val, size);
break;
case 'j': /* long ref */
GET_AND_COPY_DATA(ap, pos, len, sizeof(long));
//printf("long ref %ld\n", (long)*(long*)jpointer_val);
break;
case 'P': /* pointer */
GET_AND_COPY(ap, jpointer, pos, len);
//printf("pointer %p of size %d\n", jpointer_val, size);
break;
case 'p': /* pointer ref */
GET_AND_COPY_DATA(ap, pos, len, sizeof(void*));
//printf("pointer ref %p\n", *(void**)jpointer_val);
break;
case 'C': /* char */
/* `char' is promoted to `int' when passed through `...' */
GET_AND_COPY(ap, int, pos, len);
//printf("char %c of size %d\n", int_val, size);
break;
case 'c': /* char ref - not string */
GET_AND_COPY_DATA(ap, pos, len, sizeof(void*));
break;
case 'S': /* zero terminated string */
case 's':
GET_AND_COPY_STRING(ap, pos, len);
//printf("string \"%s\" of size %d\n", string_val, size);
break;
case 'A': /* any data - length follows */
case 'a':
if (*fmt != '[') break; /* invalid description */
next = index(fmt, ']');
if (!next) break; /* invalid description */
slen = (int)(next - fmt);
if (slen > 20) break;
memset(lens, 0, slen);
memcpy(lens, fmt+1, slen-1);
slen = atoi(lens);
GET_AND_COPY_DATA(ap, pos, len, slen)
fmt = next + 1;
//fprintf(stderr, "data %p of size %d\n", jpointer_val, slen);
break;
default:
//printf("UNKNOWN\n");
break;
}
};
va_end(ap);
//printf("Total len is %d, argc=%d nullmask=0x%x\n", pos, argc, nullmask);
req->argc = argc;
req->length = pos;
if (req->data) free(req->data);
req->data = buf;
req->nullmask = nullmask;
return 1;
}
int JVMP_DecodeRequest(JVMP_ShmRequest* req, int alloc_ref,
char* sign, ...)
{
#define CHECK_SIGNATURE(sign1, sign2) \
if (strcmp(sign1, sign2)) { \
fprintf(stderr, "signature mismatch\n"); return 0; }
char* fmt;
char *buf, *next, lens[20];
int size, argc, slen, byval;
jpointer* ptr;
va_list ap;
if (!req || !sign) return 0;
//CHECK_SIGNATURE(req->argt, sign);
fmt = req->argt;
buf = req->data;
argc = 0;
va_start(ap, sign);
while(*fmt)
{
byval = 0;
switch(*fmt++)
{
case 'I': /* integer */
byval = 1;
case 'i':
size = sizeof(int);
break;
case 'J': /* long */
byval = 1;
case 'j':
size = sizeof(long);
break;
case 'P': /* pointer */
byval = 1;
case 'p':
size = sizeof(void*);
break;
case 'C': /* char */
byval = 1;
case 'c':
/* `char' is promoted to `int' when passed through `...' */
size = sizeof(int);
break;
case 'S': /* zero terminated string */
case 's':
size = strlen(buf)+1;
break;
case 'A':
case 'a': /* any data - length follows */
size = 0;
if (*fmt != '[') break; /* invalid description */
next = index(fmt, ']');
if (!next) break; /* invalid description */
slen = (int)(next - fmt);
memset(lens, 0, slen);
memcpy(lens, fmt+1, slen-1);
slen = atoi(lens);
size = slen;
fmt = next + 1;
break;
// not yet
#if 0
case 'Z':
case 'z': /* really special, but important case of char**
Z[10] means array of 10 strings, or z[0]
if you don't know length of returned value.
But another side must know, when calling
JVMP_EncodeRequest, and it should change
signature to smth meaningful.
Use with care. */
size = 0;
if (*fmt != '[') break; /* invalid description */
next = index(fmt, ']');
if (!next) break; /* invalid description */
slen = (int)(next - fmt);
if (slen > 20) break;
memset(lens, 0, slen);
memcpy(lens, fmt+1, slen-1);
slen = atoi(lens);
if (!slen) { size = -1; break; }
size = slen;
fmt = next + 1;
break;
#endif
default:
size = 0;
fprintf(stderr, "shmtran: UNKNOWN signature: %c\n",*(fmt-1));
break;
}
if (size != 0) argc++;
if (size == -1) size = 0;
ptr = va_arg(ap, jpointer*);
if (ptr)
{
if (IS_NULL_VAL(req, argc))
{
*ptr = NULL;
continue;
}
if (byval)
memcpy(ptr, buf, size);
else
{
if (alloc_ref) *ptr = malloc(size);
memcpy(*ptr, buf, size);
}
}
if (!IS_NULL_VAL(req, argc))
buf += size;
};
va_end(ap);
return 1;
}
int JVMP_GetArgSize(JVMP_ShmRequest* req, int argno)
{
char* fmt;
char *buf, *next, lens[40];
int size, argc, slen;
if (!req) return 0;
fmt = strdup(req->argt);
buf = req->data;
argc = 0;
while(*fmt)
{
switch(*fmt++)
{
case 'I': /* integer */
case 'i':
size = sizeof(int);
break;
case 'J': /* long */
case 'j':
size = sizeof(long);
break;
case 'P': /* pointer */
case 'p':
size = sizeof(void*);
break;
case 'C': /* char */
case 'c':
/* `char' is promoted to `int' when passed through `...' */
size = sizeof(int);
break;
case 'S': /* zero terminated string */
case 's':
size = strlen(buf)+1;
break;
case 'A':
case 'a': /* any data - length follows */
size = 0;
if (*fmt != '[') break; /* invalid description */
next = index(fmt, ']');
if (!next) break; /* invalid description */
slen = (int)(next - fmt);
if (slen > 20) break;
memset(lens, 0, slen);
memcpy(lens, fmt+1, slen-1);
slen = atoi(lens);
if (!slen) { size = -1; break; }
size = slen;
fmt = next + 1;
break;
default:
size = 0;
printf("UNKNOWN: %c\n",*(fmt-1));
break;
}
if (size != 0) argc++;
if (size == -1) size = 0;
if (argc == argno)
{
if (IS_NULL_VAL(req, argc))
{
return 0;
}
return size;
}
if (!IS_NULL_VAL(req, argc))
buf += size;
};
return -1;
}
int JVMP_DeleteShmReq(JVMP_ShmRequest* req)
{
JVMP_shmdt(req->shmdata, req->shmid);
/* XXX: this can be inefficient, but otherwise I'll get EINVAL
if this segment will be reused with greater size */
shmctl(req->shmid, IPC_RMID, NULL);
free(req->data);
free(req->argt);
free(req);
return 1;
}
// XXX: update when JVMP_ShmRequest changed
static int JVMP_MarshallShmReq(JVMP_ShmRequest* req,
char* *res, int *plen)
{
#define ADD_VAL(val) \
size = sizeof(val); \
if (pos+size >= len) { len = pos+size+step; buf = realloc(buf, len); } \
memcpy(buf+pos, &val, size); \
pos += size; argc++;
#define ADD_REF(ref, size) \
if (pos+size >= len) { len = pos+size+step; buf = realloc(buf, len); } \
memcpy(buf+pos, ref, size); \
pos += size; argc++;
int len=0, pos=0, size, step=20, argc=0;
char* buf = NULL;
if (!req) return 0;
ADD_VAL(req->rid);
ADD_VAL(req->msg_id);
ADD_VAL(req->func_no);
ADD_VAL(req->retval);
ADD_VAL(req->argc);
ADD_REF(req->argt, strlen(req->argt)+1);
ADD_VAL(req->nullmask);
ADD_VAL(req->length);
ADD_REF(req->data, req->length);
ADD_VAL(req->shmlen);
ADD_VAL(req->shmid);
ADD_VAL(req->caps);
// there's no ADD_REF(req->shmdata, req->length); as it's SHARED
*res = buf;
*plen = pos;
return 1;
}
static int JVMP_DemarshallShmReq(char* buf, int buf_len,
JVMP_ShmRequest* *preq)
{
#define EXTRACT_VAL(val) \
size = sizeof(val); \
memcpy(&(val), buf+pos, size); \
pos += size; argc++;
#define EXTRACT_REF(ref, size) \
ref = (char*)malloc(size); \
memcpy(ref, buf+pos, size); \
pos += size; argc++;
int pos=0, size, argc=0;
JVMP_ShmRequest* req;
req = JVMP_NewShmReq(0, 0);
if (!req) return 0;
EXTRACT_VAL(req->rid);
EXTRACT_VAL(req->msg_id);
EXTRACT_VAL(req->func_no);
EXTRACT_VAL(req->retval);
EXTRACT_VAL(req->argc);
EXTRACT_REF(req->argt, strlen(buf+pos)+1);
EXTRACT_VAL(req->nullmask);
EXTRACT_VAL(req->length);
EXTRACT_REF(req->data, req->length);
EXTRACT_VAL(req->shmlen);
EXTRACT_VAL(req->shmid);
EXTRACT_VAL(req->caps);
if (!JVMP_IS_CAP_ALLOWED(req->caps, JVMP_CAP_SYS_PARITY))
{
fprintf(stderr, "Parity cap is not set - probably WF bug\n");
return 0;
}
*preq = req;
return 1;
}
/* there's additional #if 0'ed handshake code for cases
when it desired to detach shared memory ASAP */
int JVMP_SendShmRequest(JVMP_ShmRequest* req, int sync)
{
char* buf = NULL;
int len = 0;
int shmid;
void* shmbuf;
static key_t key = 0;
JVMP_ShmMessage msg;
static unsigned long id = 0;
id += 2;
if (id >= JVMP_SHM_LIMIT) id = 0;
req->rid = id;
//if (!key) key = ftok(".", 's');
JVMP_MarshallShmReq(req, &buf, &len);
shmid = JVMP_shmget(key, len, IPC_CREAT | IPC_EXCL | IPC_PRIVATE | 0660);
if (shmid == -1)
{
perror("JVMP_SendShmRequest: shmget");
return 0;
}
if ((shmbuf = JVMP_shmat(shmid, NULL, 0)) == (void*)-1)
{
perror("JVMP_SendShmRequest: shmat");
return 0;
}
req->shmid = shmid;
req->shmdata = shmbuf;
req->shmlen = GetShmRealLen(len);
/* yes, double marshalling is stupid, but I dunno how to find out len */
free(buf);
JVMP_MarshallShmReq(req, &buf, &len);
memcpy(shmbuf, buf, len);
free(buf);
msg.mtype = id;
msg.message = sync ? 1 : 2; /* 1 - sync,
wait confirmtion
2 - async,
never wait confirmation */
msg.shm_len = req->shmlen;
msg.shm_id = shmid;
if ((msgsnd(req->msg_id, (struct msgbuf *)&msg,
sizeof(msg)-sizeof(long), 0)) ==-1)
{
perror("JVMP_SendShmRequest: msgsnd");
return 0;
}
return 1;
}
int JVMP_RecvShmRequest(int msg_id, int sync,
JVMP_ShmRequest* *preq)
{
int qflags = sync ? 0 : IPC_NOWAIT;
JVMP_ShmMessage msg;
char* buf;
void* shmbuf;
int len;
/* this msgrcv() won't recieve system messages */
restart:
if ((msgrcv(msg_id,
(struct msgbuf *)&msg,
sizeof(msg)-sizeof(long),
-JVMP_SHM_LIMIT, qflags)) ==-1)
{
if (errno == EINTR && !g_terminate) goto restart;
/* just to remove not needed output */
if (!(((errno == ENOMSG || errno == EAGAIN) && !sync) || g_terminate))
perror("JVMP_RecvShmRequest: msgrcv");
*preq = NULL;
return 0;
}
if ((shmbuf = JVMP_shmat(msg.shm_id, NULL, 0)) == (void*)-1)
{
perror("JVMP_RecvShmRequest: shmat");
return 0;
}
len = msg.shm_len;
buf = (char*)malloc(len);
memcpy(buf, shmbuf, len);
JVMP_DemarshallShmReq(buf, len, preq);
free(buf);
(*preq)->shmid = msg.shm_id;
(*preq)->shmdata = shmbuf;
return 1;
}
int JVMP_ConfirmShmRequest(JVMP_ShmRequest* req)
{
JVMP_ShmMessage msg;
char* buf;
int len;
msg.mtype = req->rid + JVMP_SHM_LIMIT + 1;
msg.message = req->retval;
msg.shm_id = req->shmid;
JVMP_MarshallShmReq(req, &buf, &len);
/* can optimize it, using knowledge, that really segment size is whole pages
number on some systems - see GetShmRealLen() */
if (req->shmlen < len)
{
JVMP_shmdt(req->shmdata, req->shmid);
req->shmid =
JVMP_shmget(0, len, IPC_CREAT | IPC_EXCL | IPC_PRIVATE | 0660);
if (req->shmid == -1)
{
perror("JVMP_ConfirmShmRequest: shmget");
return 0;
}
if ((req->shmdata
= JVMP_shmat(req->shmid, NULL, 0)) == (void*)-1)
{
perror("JVMP_ConfirmShmRequest: shmat");
return 0;
}
req->shmlen = GetShmRealLen(len);
if ((req->shmdata = JVMP_shmat(req->shmid, NULL, 0)) == (void*)-1)
{
perror("JVMP_WaitConfirmShmRequest: shmat");
return 0;
}
msg.shm_id = req->shmid;
}
msg.shm_len = req->shmlen;
memcpy(req->shmdata, buf, len);
if ((msgsnd(req->msg_id, (struct msgbuf *)&msg,
sizeof(msg)-sizeof(long), 0)) == -1)
{
perror("JVMP_ConfirmShmRequest: msgsnd");
return 0;
}
return 1;
}
int JVMP_WaitConfirmShmRequest(JVMP_ShmRequest* req)
{
JVMP_ShmMessage msg;
char* buf;
int len;
JVMP_ShmRequest* req1;
//fprintf(stderr, "Waiting confirm %ld\n", req->rid + JVMP_SHM_LIMIT + 1);
restart:
if ((msgrcv(req->msg_id,
(struct msgbuf *)&msg,
sizeof(msg)-sizeof(long),
req->rid + JVMP_SHM_LIMIT + 1, 0)) == -1)
{
/* I know, it's wrong, but what else I can do
to reliably restart after alarams? */
if (errno == EINTR && !g_terminate) goto restart;
if (!!g_terminate) perror("JVMP_WaitConfirmShmRequest: msgrcv");
return 0;
}
req->retval = msg.message;
req->shmlen = msg.shm_len;
if (req->shmid != msg.shm_id) /* SHM segment changed - reattach to new */
{
JVMP_shmdt(req->shmdata, req->shmid);
shmctl(req->shmid, IPC_RMID, NULL); /* nobody uses it */
req->shmid = msg.shm_id;
if ((req->shmdata = JVMP_shmat(req->shmid, NULL, 0)) == (void*)-1)
{
perror("JVMP_WaitConfirmShmRequest: shmat");
return 0;
}
}
len = req->shmlen;
buf = (char*)malloc(len);
memcpy(buf, req->shmdata, len);
JVMP_DemarshallShmReq(buf, len, &req1);
free(buf);
free(req->argt); req->argt = req1->argt;
req->length = req1->length;
free(req->data); req->data = req1->data;
req->nullmask = req1->nullmask;
/* update call capabilities, if changed on another side.
Higher level code can use it to update thread current capabilities,
if some caps changing call happened. Maybe not need, commented out yet. */
//memcpy(&req->caps, &req1->caps, sizeof(JVMP_SecurityCap));
free(req1);
//fprintf(stderr, "Got confirm %ld retval=%d\n",
// req->rid + JVMP_SHM_LIMIT + 1, req->retval);
return 1;
}
int JVMP_ShmMessageLoop(int msg_id)
{
JVMP_ShmRequest* req;
while (!g_terminate)
{
if (!JVMP_RecvShmRequest(msg_id, 1, &req)) break;
JVMP_ExecuteShmRequest(req);
JVMP_ConfirmShmRequest(req);
JVMP_DeleteShmReq(req);
}
JVMP_ShmShutdown();
return 1;
}
static void JVMP_SigHandler(int sig)
{
fprintf(stderr, "Got signal %d\n", sig);
g_terminate = 1;
JVMP_ShmShutdown();
raise(sig);
}
int JVMP_ShmInit(int side)
{
int i;
struct sigaction sigact;
for (i=0; i < MAX_SHM_MSG; i++) _msgs[i] = -1;
for (i=0; i < MAX_SHM_MEM; i++) _shms[i] = -1;
sigact.sa_handler = JVMP_SigHandler;
sigact.sa_flags = 0;
g_side = side;
/* interrupts chaining */
if (side == 1)
{
/* host side - all signal handlers setting are safe */
sigaction(SIGSEGV, &sigact, &(_sigs[SIGSEGV]));
sigaction(SIGCHLD, &sigact, &(_sigs[SIGCHLD]));
//sigaction(SIGILL, &sigact, &(_sigs[SIGILL]));
}
else
{
/* JVM side - some signal handlers unsafe to set */
#ifndef _JVMP_SUNJVM
/* Sun's JVM stupidly coredumps if change those handlers */
sigaction(SIGSEGV, &sigact, &(_sigs[SIGSEGV]));
sigaction(SIGCHLD, &sigact, &(_sigs[SIGCHLD]));
#endif
}
sigaction(SIGINT, &sigact, &(_sigs[SIGINT]));
sigaction(SIGKILL, &sigact, &(_sigs[SIGKILL]));
sigaction(SIGTERM, &sigact, &(_sigs[SIGTERM]));
atexit(&JVMP_ShmShutdown);
return 1;
}
void JVMP_ShmShutdown()
{
struct msqid_ds mctl;
struct shmid_ds sctl;
int i;
for (i=0; i < MAX_SHM_MSG; i++)
if (_msgs[i] != -1) {
msgctl(_msgs[i], IPC_RMID, &mctl);
_msgs[i] = -1;
}
for (i=0; i < MAX_SHM_MEM; i++)
if (_shms[i] != -1) {
shmctl(_shms[i], IPC_RMID, &sctl);
_shms[i] = -1;
}
if (g_side == 1)
{
sigaction(SIGSEGV, &(_sigs[SIGSEGV]), 0);
sigaction(SIGCHLD, &(_sigs[SIGCHLD]), 0);
}
else
{
/* Sun's JVM stupidly coredumps if change those handlers */
#ifndef _JVMP_SUNJVM
sigaction(SIGSEGV, &(_sigs[SIGSEGV]), 0);
sigaction(SIGCHLD, &(_sigs[SIGCHLD]), 0);
#endif
}
sigaction(SIGINT, &(_sigs[SIGINT]), 0);
sigaction(SIGKILL, &(_sigs[SIGKILL]), 0);
sigaction(SIGTERM, &(_sigs[SIGTERM]), 0);
//sigaction(SIGILL, &(_sigs[SIGILL]), 0);
}
/*
JVMP_ShmRequest* JVMP_NewEncodedShmReq(int msg_id, unsigned int func_no,
char* sign, ...)
{
JVMP_ShmRequest* req = JVMP_NewShmReq(msg_id, func_no);
if (!req || !JVMP_EncodeRequest(req, sign, ...)) return 0;
return 1;
}
*/

View File

@@ -0,0 +1,27 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is The Waterfall Java Plugin Module
*
* The Initial Developer of the Original Code is Sun Microsystems Inc
* Portions created by Sun Microsystems Inc are Copyright (C) 2001
* All Rights Reserved.
*
* $Id: native.c,v 1.1.1.1 2001-05-10 18:12:37 edburns%acm.org Exp $
*
*
* Contributor(s):
*
* Nikolay N. Igotti <inn@sparc.spb.su>
*/
// nothing here yet