summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:55 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:55 +0000
commitd017e93a6a22f6d4c2c7e76deec1cdeca632135e (patch)
tree7703052799dc65cee9eacf6f573fb5c4afcd3936
R6.6 is the Xorg base-lineXORG-MAINXORG-STABLE
-rw-r--r--cgi-bin/bitmap241
-rw-r--r--cgi-bin/dtcm281
-rw-r--r--cgi-bin/dtcm.sh7
-rw-r--r--cgi-bin/excel228
-rw-r--r--cgi-bin/xclock241
-rw-r--r--cgi-bin/xload241
-rw-r--r--helper/GetUrl.c296
-rw-r--r--helper/GetUrl.h36
-rw-r--r--helper/helper.c529
-rw-r--r--helper/xrx.man134
-rw-r--r--htdocs/bitmap12
-rw-r--r--htdocs/bitmap.html23
-rw-r--r--htdocs/dtcm12
-rw-r--r--htdocs/dtcm.html23
-rw-r--r--htdocs/excel11
-rw-r--r--htdocs/excel.html23
-rw-r--r--htdocs/xclock11
-rw-r--r--htdocs/xclock.html23
-rw-r--r--htdocs/xload11
-rw-r--r--htdocs/xload.html23
-rw-r--r--libxplugin/README6
-rw-r--r--plugin/Global.c97
-rw-r--r--plugin/Main.c630
-rw-r--r--plugin/NewNDest.c71
-rw-r--r--plugin/PProcess.c1017
-rw-r--r--plugin/RxPlugin.h171
-rw-r--r--plugin/SetWin.c213
-rw-r--r--plugin/common/npunix.c407
-rw-r--r--plugin/include/jri.h639
-rw-r--r--plugin/include/jri_md.h501
-rw-r--r--plugin/include/jritypes.h181
-rw-r--r--plugin/include/npapi.h393
-rw-r--r--plugin/include/npupp.h996
-rw-r--r--plugin/libxrx.man152
-rw-r--r--plugin/stubs.c15
-rw-r--r--rx/BuildReq.c150
-rw-r--r--rx/PParse.c460
-rw-r--r--rx/PRead.c274
-rw-r--r--rx/Prefs.c273
-rw-r--r--rx/Prefs.h56
-rw-r--r--rx/Rx.h129
-rw-r--r--rx/RxI.h95
-rw-r--r--rx/XAuth.c163
-rw-r--r--rx/XAuth.h39
-rw-r--r--rx/XDpyName.c513
-rw-r--r--rx/XDpyName.h39
-rw-r--r--rx/XUrls.c360
-rw-r--r--rx/XUrls.h37
-rw-r--r--testplugin/testplugin.c671
-rw-r--r--testplugin/testplugin.man66
-rw-r--r--xnest-plugin/NewNDest.c65
-rw-r--r--xnest-plugin/PProcess.c71
-rw-r--r--xnest-plugin/RxPlugin.h119
-rw-r--r--xnest-plugin/SetWin.c216
-rw-r--r--xnest-plugin/XnestDis.c106
55 files changed, 11797 insertions, 0 deletions
diff --git a/cgi-bin/bitmap b/cgi-bin/bitmap
new file mode 100644
index 0000000..246b1c8
--- /dev/null
+++ b/cgi-bin/bitmap
@@ -0,0 +1,241 @@
+#!/usr/local/bin/perl
+# $Xorg: bitmap,v 1.3 2000/08/17 19:54:57 cpqbld Exp $
+# CGI script to launch xclock
+#
+
+# define every program we are going to use
+$project_root = "XPROJECT_ROOT";
+$command = $project_root . "/bin/bitmap";
+$xfindproxy = $project_root . "/bin/xfindproxy";
+$xauth = $project_root . "/bin/xauth";
+
+# address of our proxy manager
+$proxymngr = "XPROXYMNGR";
+
+# make stderr and stdout unbuffered so nothing get lost
+select(STDERR); $| = 1;
+select(STDOUT); $| = 1;
+
+# print out header to content httpd no matter what happens later on
+print "Content-type: text/plain\r\n\r\n";
+
+# let's try not to leave any file behind us if things go really wrong
+sub handler { # 1st argument is signal name
+ local($sig) = @_;
+ # send error code first and error msg then
+ print "1\n";
+ print "Error: Caught a SIG$sig -- Oops!\n";
+ system "rm -f /tmp/*$$";
+ exit(0);
+}
+
+$SIG{'INT'} = 'handler';
+$SIG{'QUIT'} = 'handler';
+$SIG{'TERM'} = 'handler';
+$SIG{'KILL'} = 'handler';
+$SIG{'STOP'} = 'handler';
+# this one is perhaps the most important one, since this is what we should get
+# when the user interrupts the GET request.
+$SIG{'PIPE'} = 'handler';
+
+
+######################
+# sub procedures
+######################
+
+# parse an url param of the form: proto:display[;param]
+sub parse_url {
+ local($input, *proto_ret, *display_ret, *param_ret) = @_;
+
+ # extract param first
+ ($sub_url, $param_ret) = split(/;/, $input, 2);
+ # then extract proto and display
+ ($proto_ret, $display_ret) = split(/:/, $sub_url, 2);
+
+}
+
+# parse an auth param of the form: auth=name:key
+sub parse_auth {
+ local($input, *name_ret, *key_ret) = @_;
+
+ if ($input) {
+ ($param_name, $param_value) = split(/=/, $input, 2);
+ if ($param_name eq "auth") {
+ ($name_ret, $key_ret) = split(/:/, $param_value, 2);
+ }
+ }
+}
+
+# parse an LBX param of the form: either NO or YES[;auth=...]
+sub parse_lbx_param {
+ local($input, *lbx_ret, *lbx_auth_name_ret, *lbx_auth_key_ret) = @_;
+
+ ($lbx_ret, $lbxparam) = split(/;/, $input, 2);
+ if ($lbx_ret eq "YES") {
+ # look for an authentication auth in param
+ &parse_auth($lbxparam, *lbx_auth_name_ret, *lbx_auth_key_ret);
+ }
+}
+
+# setup proxy with possible auth, change display parameter when succeeding
+sub setup_lbx_proxy {
+ local(*display, $auth_name, $auth_key) = @_;
+
+ # setup auth file for xfindproxy
+ if ($auth_name && $auth_key) {
+ $proxy_input = "/tmp/xlbxauth.$$";
+ open(PROXYINPUT, ">$proxy_input");
+ print PROXYINPUT "$auth_name\n$auth_key\n";
+ close(PROXYINPUT);
+ $findproxy_param = " -auth <$proxy_input";
+ } else {
+ $findproxy_param = "";
+ }
+
+ # remove screen number specification if there is one
+ ($host, $tmp) = split(/:/, $display);
+ ($dpy, $screen) = split(/\./, $tmp);
+ $server = $host . ":" . $dpy;
+
+ # let's get an LBX proxy
+ open(PROXY, "$xfindproxy -manager $proxymngr -server $server -name LBX $findproxy_param|");
+ # get the proxy address from xfindproxy output
+ while (<PROXY>) {
+ chop;
+ ($proxy_dpy, $proxy_port) = split(/:/, $_);
+ if ($proxy_dpy && $proxy_port) {
+ # build up the new display name
+ $display = $proxy_dpy . ":" . $proxy_port;
+ if ($screen) {
+ $display .= "." . $screen;
+ }
+ last;
+ }
+ }
+ close(PROXY);
+
+ if ($proxy_input) {
+ system "rm -f $proxy_input";
+ }
+}
+
+# add entry in authority file
+sub add_auth {
+ local($display, $auth_name, $auth_key) = @_;
+
+ system "$xauth add $display $auth_name $auth_key";
+}
+
+
+######################
+# the main thing now
+######################
+
+
+# handle both ways of getting query
+if ($ENV{'QUERY_STRING'})
+{
+ $query = $ENV{'QUERY_STRING'};
+} else {
+ $query = $ARGV[0];
+}
+
+if ($query)
+{
+ $cleanup = "";
+
+ # parse params
+ %params = split(/\?/, $query);
+ foreach $param (split(/\?/, $query)) {
+
+ ($name, $value) = split(/=/, $param, 2);
+ if ($name eq "WIDTH") {
+ $width = $value;
+ } elsif ($name eq "HEIGHT") {
+ $height = $value;
+ } elsif ($name eq "UI") {
+ # look at what we got for the UI parameter, it should be of the
+ # form: x11:hostname:dpynum[.screen][;auth=...]
+ &parse_url($value, *proto, *display, *ui_param);
+ if ($proto eq 'x11') {
+ $xdisplay = $display;
+ } else {
+ # unknown UI protocol!!
+ }
+ # look for an authentication auth in param
+ &parse_auth($ui_param, *xui_auth_name, *xui_auth_key);
+
+ } elsif ($name eq "X-UI-LBX") {
+ &parse_lbx_param($value, *xui_lbx,
+ *xui_lbx_auth_name, *xui_lbx_auth_key);
+ }
+ }
+
+ # set authority file for X
+ $ENV{'XAUTHORITY'} = "/tmp/xauth.$$";
+ # and define its related cleanup command
+ $cleanup = "rm -f $ENV{'XAUTHORITY'}";
+
+ # process params
+ if ($xdisplay) {
+
+ if ($xui_lbx eq "YES") {
+ &setup_lbx_proxy(*xdisplay, $xui_lbx_auth_name, $xui_lbx_auth_key);
+ }
+ if ($xui_auth_name && $xui_auth_key) {
+ &add_auth($xdisplay, $xui_auth_name, $xui_auth_key);
+ }
+ # add display specification to the command line
+ $command .= " -display $xdisplay";
+ # and put it in the environment too for good measure.
+ $ENV{'DISPLAY'} = $xdisplay;
+ }
+ if ($width && $height) {
+ # add geometry specification to the command line
+ $command .= " -geometry ${width}x${height}";
+ }
+
+ # Start application followed by a cleanup command in the background.
+ # The ouput and input need to be redirected, otherwise the CGI process will
+ # be kept alive by the http server and the browser will keep waiting for
+ # the end of the stream...
+ # Catching application's failure is not easy since we want to run it in
+ # background and therefore we can't get its exit status. However, we can
+ # catch obvious errors by logging its output and after some time looking
+ # at whether the application is still running or not. This is determine
+ # based on some kind of "lock" file.
+ # This is quite complicated but it allows to get some error report without
+ # leaving any file behind us in any case.
+
+ $LOCK= "/tmp/lock.$$";
+ $LOG= "/tmp/log.$$";
+ $LOG2 = "/tmp/log2.$$";
+ system "(touch $LOCK; _s=true; $command >$LOG 2>&1 || _s=false; if \$_s; then rm $LOG; else rm $LOCK; fi; if [ -f $LOG2 ]; then rm $LOG2; fi; $cleanup) >/dev/null 2>&1 </dev/null &";
+
+ # sleep for a while to let the application start or fail
+ # it's up to you to decide how long it could for the application to fail...
+ sleep(5);
+
+ # now lets see if the application died
+ if (open(LOCK, "<$LOCK")) {
+ close(LOCK);
+ # the application seems to be running, remove lock and rename the log
+ # so that it gets removed no matter how the application exits later on
+ system "rm $LOCK; mv $LOG $LOG2";
+ # send success error code as reply
+ print "0\n";
+ } else {
+ # the lock file is gone, for sure the application has failed so send
+ # back error code and log
+ print "1\n";
+ system "cat $LOG; rm $LOG";
+ }
+
+} else {
+
+ # reply with an error message
+ print "This script requires to be given the proper RX arguments
+to run successfully.
+";
+
+}
diff --git a/cgi-bin/dtcm b/cgi-bin/dtcm
new file mode 100644
index 0000000..4a201ad
--- /dev/null
+++ b/cgi-bin/dtcm
@@ -0,0 +1,281 @@
+#!/usr/local/bin/perl
+# $Xorg: dtcm,v 1.3 2000/08/17 19:54:57 cpqbld Exp $
+# CGI script to launch dtcm
+#
+
+# define every program we are going to use
+$project_root = "XPROJECT_ROOT";
+$command = "CGIBINDIR/dtcm.sh";
+$xfindproxy = $project_root . "/bin/xfindproxy";
+$xauth = $project_root . "/bin/xauth";
+
+# address of our proxy manager
+$proxymngr = "XPROXYMNGR";
+
+# make stderr and stdout unbuffered so nothing get lost
+select(STDERR); $| = 1;
+select(STDOUT); $| = 1;
+
+# print out header to content httpd no matter what happens later on
+print "Content-type: text/plain\r\n\r\n";
+
+# let's try not to leave any file behind us if things go really wrong
+sub handler { # 1st argument is signal name
+ local($sig) = @_;
+ # send error code first and error msg then
+ print "1\n";
+ print "Error: Caught a SIG$sig -- Oops!\n";
+ system "rm -f /tmp/*$$";
+ exit(0);
+}
+
+$SIG{'INT'} = 'handler';
+$SIG{'QUIT'} = 'handler';
+$SIG{'TERM'} = 'handler';
+$SIG{'KILL'} = 'handler';
+$SIG{'STOP'} = 'handler';
+# this one is perhaps the most important one, since this is what we should get
+# when the user interrupts the GET request
+$SIG{'PIPE'} = 'handler';
+
+
+######################
+# sub procedures
+######################
+
+# parse an url param of the form: proto:display[;param]
+sub parse_url {
+ local($input, *proto_ret, *display_ret, *param_ret) = @_;
+
+ # extract param first
+ ($sub_url, $param_ret) = split(/;/, $input, 2);
+ # then extract proto and display
+ ($proto_ret, $display_ret) = split(/:/, $sub_url, 2);
+
+}
+
+# parse an auth param of the form: auth=name:key
+sub parse_auth {
+ local($input, *name_ret, *key_ret) = @_;
+
+ if ($input) {
+ ($param_name, $param_value) = split(/=/, $input, 2);
+ if ($param_name eq "auth") {
+ ($name_ret, $key_ret) = split(/:/, $param_value, 2);
+ }
+ }
+}
+
+# parse an LBX param of the form: either NO or YES[;auth=...]
+sub parse_lbx_param {
+ local($input, *lbx_ret, *lbx_auth_name_ret, *lbx_auth_key_ret) = @_;
+
+ ($lbx_ret, $lbxparam) = split(/;/, $input, 2);
+ if ($lbx_ret eq "YES") {
+ # look for an authentication auth in param
+ &parse_auth($lbxparam, *lbx_auth_name_ret, *lbx_auth_key_ret);
+ }
+}
+
+# setup proxy with possible auth, change display parameter when succeeding
+sub setup_lbx_proxy {
+ local(*display, $auth_name, $auth_key) = @_;
+
+ # setup auth file for xfindproxy
+ if ($auth_name && $auth_key) {
+ $proxy_input = "/tmp/xlbxauth.$$";
+ open(PROXYINPUT, ">$proxy_input");
+ print PROXYINPUT "$auth_name\n$auth_key\n";
+ close(PROXYINPUT);
+ $findproxy_param = " -auth <$proxy_input";
+ } else {
+ $findproxy_param = "";
+ }
+
+ # remove screen number specification if there is one
+ ($host, $tmp) = split(/:/, $display);
+ ($dpy, $screen) = split(/\./, $tmp);
+ $server = $host . ":" . $dpy;
+
+ # let's get an LBX proxy
+ open(PROXY, "$xfindproxy -manager $proxymngr -server $server -name LBX $findproxy_param|");
+ # get the proxy address from xfindproxy output
+ while (<PROXY>) {
+ chop;
+ ($proxy_dpy, $proxy_port) = split(/:/, $_);
+ if ($proxy_dpy && $proxy_port) {
+ # build up the new display name
+ $display = $proxy_dpy . ":" . $proxy_port;
+ if ($screen) {
+ $display .= "." . $screen;
+ }
+ last;
+ }
+ }
+ close(PROXY);
+
+ if ($proxy_input) {
+ system "rm -f $proxy_input";
+ }
+}
+
+# add entry in authority file
+sub add_auth {
+ local($display, $auth_name, $auth_key) = @_;
+
+ system "$xauth add $display $auth_name $auth_key";
+}
+
+
+######################
+# the main thing now
+######################
+
+
+# handle both ways of getting query
+if ($ENV{'QUERY_STRING'})
+{
+ $query = $ENV{'QUERY_STRING'};
+} else {
+ $query = $ARGV[0];
+}
+
+if ($query)
+{
+ $cleanup = "";
+
+ # parse params
+ %params = split(/\?/, $query);
+ foreach $param (split(/\?/, $query)) {
+
+ ($name, $value) = split(/=/, $param, 2);
+ if ($name eq "WIDTH") {
+ $width = $value;
+ } elsif ($name eq "HEIGHT") {
+ $height = $value;
+ } elsif ($name eq "UI") {
+ # look at what we got for the UI parameter, it should be of the
+ # form: x11:hostname:dpynum[.screen][;auth=...]
+ &parse_url($value, *proto, *display, *ui_param);
+ if ($proto eq 'x11') {
+ $xdisplay = $display;
+ } else {
+ # unknown UI protocol!!
+ }
+ # look for an authentication auth in param
+ &parse_auth($ui_param, *xui_auth_name, *xui_auth_key);
+
+ } elsif ($name eq "X-UI-LBX") {
+ &parse_lbx_param($value, *xui_lbx,
+ *xui_lbx_auth_name, *xui_lbx_auth_key);
+ } elsif ($name eq "PRINT") {
+ # look at what we got for the PRINT parameter, it should be of the
+ # form: xprint:[printer@]hostname:dpynum[;auth=...]
+
+ &parse_url($value, *proto, *display, *prt_param);
+ if ($proto eq 'xprint') {
+ $xprint = $display;
+ } else {
+ # unknown PRINT protocol!!
+ }
+ # look for an authentication auth in param
+ &parse_auth($prt_param, *xprt_auth_name, *xprt_auth_key);
+
+ } elsif ($name eq "X-PRINT-LBX") {
+ &parse_lbx_param($value, *xprt_lbx,
+ *xprt_lbx_auth_name, *xprt_lbx_auth_key);
+ }
+ }
+
+ # set a common authority file for X and XPrint
+ $ENV{'XAUTHORITY'} = "/tmp/xauth.$$";
+ # and define its related cleanup command
+ $cleanup = "rm -f $ENV{'XAUTHORITY'}";
+
+ # process params
+ # Note: we want to process printing first so if for some reason we end up
+ # with a conflict between the two authorizations, the display one wins
+ if ($xprint) {
+ # extract print server from printer specification (xpress@foo:0)
+ ($xprt_printer, $xprt_display) = split(/\@/, $xprint, 2);
+ if (! $xprt_display) {
+ # printer not specified
+ $xprt_display = $xprt_printer;
+ $xprt_printer = "";
+ }
+
+ if ($xprt_lbx eq "YES") {
+ &setup_lbx_proxy(*xprt_display,
+ $xprt_lbx_auth_name, $xprt_lbx_auth_key);
+ # rebuild printer specification with new xprt_display
+ $xprint = $xprt_printer . "@" . $xprt_display;
+ }
+ if ($xprt_auth_name && $xprt_auth_key) {
+ &add_auth($xprt_display, $xprt_auth_name, $xprt_auth_key);
+ }
+ # specify printer via the environment
+ $ENV{'XPRINTER'} = $xprint;
+ $ENV{'XPSERVERLIST'} = $xpr_display;
+ }
+ if ($xdisplay) {
+
+ if ($xui_lbx eq "YES") {
+ &setup_lbx_proxy(*xdisplay, $xui_lbx_auth_name, $xui_lbx_auth_key);
+ }
+ if ($xui_auth_name && $xui_auth_key) {
+ &add_auth($xdisplay, $xui_auth_name, $xui_auth_key);
+ }
+ # add display specification to the command line
+ $command .= " -display $xdisplay";
+ # and put it in the environment too for good measure.
+ $ENV{'DISPLAY'} = $xdisplay;
+ }
+ if ($width && $height) {
+ # add geometry specification to the command line
+ $command .= " -geometry ${width}x${height}";
+ }
+
+ # Start application followed by a cleanup command in the background.
+ # The ouput and input need to be redirected, otherwise the CGI process will
+ # be kept alive by the http server and the browser will keep waiting for
+ # the end of the stream...
+ # Catching application's failure is not easy since we want to run it in
+ # background and therefore we can't get its exit status. However, we can
+ # catch obvious errors by logging its output and after some time looking
+ # at whether the application is still running or not. This is determine
+ # based on some kind of "lock" file.
+ # This is quite complicated but it allows to get some error report without
+ # leaving any file behind us in any case.
+
+ $LOCK= "/tmp/lock.$$";
+ $LOG= "/tmp/log.$$";
+ $LOG2 = "/tmp/log2.$$";
+ system "(touch $LOCK; _s=true; $command >$LOG 2>&1 || _s=false; if \$_s; then rm $LOG; else rm $LOCK; fi; if [ -f $LOG2 ]; then rm $LOG2; fi; $cleanup) >/dev/null 2>&1 </dev/null &";
+
+ # sleep for a while to let the application start or fail
+ # it's up to you to decide how long it could for the application to fail...
+ sleep(5);
+
+ # now lets see if the application died
+ if (open(LOCK, "<$LOCK")) {
+ close(LOCK);
+ # the application seems to be running, remove lock and rename the log
+ # so that it gets removed no matter how the application exits later on
+ system "rm $LOCK; mv $LOG $LOG2";
+ # send success error code as reply
+ print "0\n";
+ } else {
+ # the lock file is gone, for sure the application has failed so send
+ # back error code and log
+ print "1\n";
+ system "cat $LOG; rm $LOG";
+ }
+
+} else {
+
+ # reply with an error message
+ print "This script requires to be given the proper RX arguments
+to run successfully.
+";
+
+}
diff --git a/cgi-bin/dtcm.sh b/cgi-bin/dtcm.sh
new file mode 100644
index 0000000..8e8a117
--- /dev/null
+++ b/cgi-bin/dtcm.sh
@@ -0,0 +1,7 @@
+#! /bin/csh -f
+#$Xorg: dtcm.sh,v 1.3 2000/08/17 19:54:57 cpqbld Exp $
+setenv SHELL /bin/csh
+setenv _RLD_ROOT /dev/null
+setenv LD_LIBRARY_PATH /tools/packages/cde/alpha/osf1/cde_cst8/dt/lib:/tools/packages/cde/alpha/osf1/cde_cst8/x11/lib:/usr/shlib:/usr/ccs/lib:/usr/lib/cmplrs/cxx:/usr/lib/cmplrs/cc:/usr/lib:/usr/local/lib:/var/shlib
+eval `/tools/packages/cde/alpha/osf1/cde_cst8/dt/bin/dtsearchpath | /usr/bin/sed -e 's^/usr/dt^/tools/packages/cde/alpha/osf1/cde_cst8/dt^g'`
+exec /tools/packages/cde/alpha/osf1/cde_cst8/dt/bin/dtcm $*
diff --git a/cgi-bin/excel b/cgi-bin/excel
new file mode 100644
index 0000000..3b68e1e
--- /dev/null
+++ b/cgi-bin/excel
@@ -0,0 +1,228 @@
+#!/usr/local/bin/perl
+# $Xorg: excel,v 1.3 2000/08/17 19:54:57 cpqbld Exp $
+# CGI script to launch excel
+#
+
+# define every program we are going to use
+$project_root = "XPROJECT_ROOT";
+$command = "/usr/bin/rsh WINCENTERHOST wincenter";
+$xfindproxy = $project_root . "/bin/xfindproxy";
+
+# address of our proxy manager
+$proxymngr = "XPROXYMNGR";
+
+# make stderr and stdout unbuffered so nothing get lost
+select(STDERR); $| = 1;
+select(STDOUT); $| = 1;
+
+# print out header to content httpd no matter what happens later on
+print "Content-type: text/plain\r\n\r\n";
+
+# let's try not to leave any file behind us if things go really wrong
+sub handler { # 1st argument is signal name
+ local($sig) = @_;
+ # send error code first and error msg then
+ print "1\n";
+ print "Error: Caught a SIG$sig -- Oops!\n";
+ system "rm -f /tmp/*$$";
+ exit(0);
+}
+
+$SIG{'INT'} = 'handler';
+$SIG{'QUIT'} = 'handler';
+$SIG{'TERM'} = 'handler';
+$SIG{'KILL'} = 'handler';
+$SIG{'STOP'} = 'handler';
+# this one is perhaps the most important one, since this is what we should get
+# when the user interrupts the GET request.
+$SIG{'PIPE'} = 'handler';
+
+
+######################
+# sub procedures
+######################
+
+# parse an url param of the form: proto:display[;param]
+sub parse_url {
+ local($input, *proto_ret, *display_ret, *param_ret) = @_;
+
+ # extract param first
+ ($sub_url, $param_ret) = split(/;/, $input, 2);
+ # then extract proto and display
+ ($proto_ret, $display_ret) = split(/:/, $sub_url, 2);
+
+}
+
+# parse an auth param of the form: auth=name:key
+sub parse_auth {
+ local($input, *name_ret, *key_ret) = @_;
+
+ if ($input) {
+ ($param_name, $param_value) = split(/=/, $input, 2);
+ if ($param_name eq "auth") {
+ ($name_ret, $key_ret) = split(/:/, $param_value, 2);
+ }
+ }
+}
+
+# parse an LBX param of the form: either NO or YES[;auth=...]
+sub parse_lbx_param {
+ local($input, *lbx_ret, *lbx_auth_name_ret, *lbx_auth_key_ret) = @_;
+
+ ($lbx_ret, $lbxparam) = split(/;/, $input, 2);
+ if ($lbx_ret eq "YES") {
+ # look for an authentication auth in param
+ &parse_auth($lbxparam, *lbx_auth_name_ret, *lbx_auth_key_ret);
+ }
+}
+
+# setup proxy with possible auth, change display parameter when succeeding
+sub setup_lbx_proxy {
+ local(*display, $auth_name, $auth_key) = @_;
+
+ # setup auth file for xfindproxy
+ if ($auth_name && $auth_key) {
+ $proxy_input = "/tmp/xlbxauth.$$";
+ open(PROXYINPUT, ">$proxy_input");
+ print PROXYINPUT "$auth_name\n$auth_key\n";
+ close(PROXYINPUT);
+ $findproxy_param = " -auth <$proxy_input";
+ } else {
+ $findproxy_param = "";
+ }
+
+ # remove screen number specification if there is one
+ ($host, $tmp) = split(/:/, $display);
+ ($dpy, $screen) = split(/\./, $tmp);
+ $server = $host . ":" . $dpy;
+
+ # let's get an LBX proxy
+ open(PROXY, "$xfindproxy -manager $proxymngr -server $server -name LBX $findproxy_param|");
+ # get the proxy address from xfindproxy output
+ while (<PROXY>) {
+ chop;
+ ($proxy_dpy, $proxy_port) = split(/:/, $_);
+ if ($proxy_dpy && $proxy_port) {
+ # build up the new display name
+ $display = $proxy_dpy . ":" . $proxy_port;
+ if ($screen) {
+ $display .= "." . $screen;
+ }
+ last;
+ }
+ }
+ close(PROXY);
+
+ if ($proxy_input) {
+ system "rm -f $proxy_input";
+ }
+}
+
+######################
+# the main thing now
+######################
+
+
+# handle both ways of getting query
+if ($ENV{'QUERY_STRING'})
+{
+ $query = $ENV{'QUERY_STRING'};
+} else {
+ $query = $ARGV[0];
+}
+
+if ($query)
+{
+ $cleanup = "";
+
+ # parse params
+ %params = split(/\?/, $query);
+ foreach $param (split(/\?/, $query)) {
+
+ ($name, $value) = split(/=/, $param, 2);
+ if ($name eq "WIDTH") {
+ $width = $value;
+ } elsif ($name eq "HEIGHT") {
+ $height = $value;
+ } elsif ($name eq "UI") {
+ # look at what we got for the UI parameter, it should be of the
+ # form: x11:hostname:dpynum[.screen][;auth=...]
+ &parse_url($value, *proto, *display, *ui_param);
+ if ($proto eq 'x11') {
+ $xdisplay = $display;
+ } else {
+ # unknown UI protocol!!
+ }
+ # look for an authentication auth in param
+ &parse_auth($ui_param, *xui_auth_name, *xui_auth_key);
+
+ } elsif ($name eq "X-UI-LBX") {
+ &parse_lbx_param($value, *xui_lbx,
+ *xui_lbx_auth_name, *xui_lbx_auth_key);
+ }
+ }
+
+ # process params
+ if ($xdisplay) {
+
+ if ($xui_lbx eq "YES") {
+ &setup_lbx_proxy(*xdisplay, $xui_lbx_auth_name, $xui_lbx_auth_key);
+ }
+ if ($xui_auth_name && $xui_auth_key) {
+ $command .= " -auth $xdisplay $xui_auth_name $xui_auth_key";
+ }
+ # add display specification to the command line
+ $command .= " -display $xdisplay";
+ # and put it in the environment too for good measure.
+ $ENV{'DISPLAY'} = $xdisplay;
+ }
+ if ($width && $height) {
+ # add geometry specification to the command line
+ $command .= " -geometry ${width}x${height}";
+ }
+ $command .= " -username IUSR_WINDY -password broadway -colors 16 -- C:/MSOffice/Excel/EXCEL.EXE C:/MSOffice/Excel/Examples/SAMPLES.XLS";
+
+ # Start application followed by a cleanup command in the background.
+ # The ouput and input need to be redirected, otherwise the CGI process will
+ # be kept alive by the http server and the browser will keep waiting for
+ # the end of the stream...
+ # Catching application's failure is not easy since we want to run it in
+ # background and therefore we can't get its exit status. However, we can
+ # catch obvious errors by logging its output and after some time looking
+ # at whether the application is still running or not. This is determine
+ # based on some kind of "lock" file.
+ # This is quite complicated but it allows to get some error report without
+ # leaving any file behind us in any case.
+
+ $LOCK= "/tmp/lock.$$";
+ $LOG= "/tmp/log.$$";
+ $LOG2 = "/tmp/log2.$$";
+ system "(touch $LOCK; _s=true; $command >$LOG 2>&1 || _s=false; if \$_s; then rm $LOG; else rm $LOCK; fi; if [ -f $LOG2 ]; then rm $LOG2; fi; $cleanup) >/dev/null 2>&1 </dev/null &";
+
+ # sleep for a while to let the application start or fail
+ # it's up to you to decide how long it could for the application to fail...
+ sleep(5);
+
+ # now lets see if the application died
+ if (open(LOCK, "<$LOCK")) {
+ close(LOCK);
+ # the application seems to be running, remove lock and rename the log
+ # so that it gets removed no matter how the application exits later on
+ system "rm $LOCK; mv $LOG $LOG2";
+ # send success error code as reply
+ print "0\n";
+ } else {
+ # the lock file is gone, for sure the application has failed so send
+ # back error code and log
+ print "1\n";
+ system "cat $LOG; rm $LOG";
+ }
+
+} else {
+
+ # reply with an error message
+ print "This script requires to be given the proper RX arguments
+to run successfully.
+";
+
+}
diff --git a/cgi-bin/xclock b/cgi-bin/xclock
new file mode 100644
index 0000000..cbc1b83
--- /dev/null
+++ b/cgi-bin/xclock
@@ -0,0 +1,241 @@
+#!/usr/local/bin/perl
+# $Xorg: xclock,v 1.3 2000/08/17 19:54:57 cpqbld Exp $
+# CGI script to launch xclock
+#
+
+# define every program we are going to use
+$project_root = "XPROJECT_ROOT";
+$command = $project_root . "/bin/xclock -update 1";
+$xfindproxy = $project_root . "/bin/xfindproxy";
+$xauth = $project_root . "/bin/xauth";
+
+# address of our proxy manager
+$proxymngr = "XPROXYMNGR";
+
+# make stderr and stdout unbuffered so nothing get lost
+select(STDERR); $| = 1;
+select(STDOUT); $| = 1;
+
+# print out header to content httpd no matter what happens later on
+print "Content-type: text/plain\r\n\r\n";
+
+# let's try not to leave any file behind us if things go really wrong
+sub handler { # 1st argument is signal name
+ local($sig) = @_;
+ # send error code first and error msg then
+ print "1\n";
+ print "Error: Caught a SIG$sig -- Oops!\n";
+ system "rm -f /tmp/*$$";
+ exit(0);
+}
+
+$SIG{'INT'} = 'handler';
+$SIG{'QUIT'} = 'handler';
+$SIG{'TERM'} = 'handler';
+$SIG{'KILL'} = 'handler';
+$SIG{'STOP'} = 'handler';
+# this one is perhaps the most important one, since this is what we should get
+# when the user interrupts the GET request.
+$SIG{'PIPE'} = 'handler';
+
+
+######################
+# sub procedures
+######################
+
+# parse an url param of the form: proto:display[;param]
+sub parse_url {
+ local($input, *proto_ret, *display_ret, *param_ret) = @_;
+
+ # extract param first
+ ($sub_url, $param_ret) = split(/;/, $input, 2);
+ # then extract proto and display
+ ($proto_ret, $display_ret) = split(/:/, $sub_url, 2);
+
+}
+
+# parse an auth param of the form: auth=name:key
+sub parse_auth {
+ local($input, *name_ret, *key_ret) = @_;
+
+ if ($input) {
+ ($param_name, $param_value) = split(/=/, $input, 2);
+ if ($param_name eq "auth") {
+ ($name_ret, $key_ret) = split(/:/, $param_value, 2);
+ }
+ }
+}
+
+# parse an LBX param of the form: either NO or YES[;auth=...]
+sub parse_lbx_param {
+ local($input, *lbx_ret, *lbx_auth_name_ret, *lbx_auth_key_ret) = @_;
+
+ ($lbx_ret, $lbxparam) = split(/;/, $input, 2);
+ if ($lbx_ret eq "YES") {
+ # look for an authentication auth in param
+ &parse_auth($lbxparam, *lbx_auth_name_ret, *lbx_auth_key_ret);
+ }
+}
+
+# setup proxy with possible auth, change display parameter when succeeding
+sub setup_lbx_proxy {
+ local(*display, $auth_name, $auth_key) = @_;
+
+ # setup auth file for xfindproxy
+ if ($auth_name && $auth_key) {
+ $proxy_input = "/tmp/xlbxauth.$$";
+ open(PROXYINPUT, ">$proxy_input");
+ print PROXYINPUT "$auth_name\n$auth_key\n";
+ close(PROXYINPUT);
+ $findproxy_param = " -auth <$proxy_input";
+ } else {
+ $findproxy_param = "";
+ }
+
+ # remove screen number specification if there is one
+ ($host, $tmp) = split(/:/, $display);
+ ($dpy, $screen) = split(/\./, $tmp);
+ $server = $host . ":" . $dpy;
+
+ # let's get an LBX proxy
+ open(PROXY, "$xfindproxy -manager $proxymngr -server $server -name LBX $findproxy_param|");
+ # get the proxy address from xfindproxy output
+ while (<PROXY>) {
+ chop;
+ ($proxy_dpy, $proxy_port) = split(/:/, $_);
+ if ($proxy_dpy && $proxy_port) {
+ # build up the new display name
+ $display = $proxy_dpy . ":" . $proxy_port;
+ if ($screen) {
+ $display .= "." . $screen;
+ }
+ last;
+ }
+ }
+ close(PROXY);
+
+ if ($proxy_input) {
+ system "rm -f $proxy_input";
+ }
+}
+
+# add entry in authority file
+sub add_auth {
+ local($display, $auth_name, $auth_key) = @_;
+
+ system "$xauth add $display $auth_name $auth_key";
+}
+
+
+######################
+# the main thing now
+######################
+
+
+# handle both ways of getting query
+if ($ENV{'QUERY_STRING'})
+{
+ $query = $ENV{'QUERY_STRING'};
+} else {
+ $query = $ARGV[0];
+}
+
+if ($query)
+{
+ $cleanup = "";
+
+ # parse params
+ %params = split(/\?/, $query);
+ foreach $param (split(/\?/, $query)) {
+
+ ($name, $value) = split(/=/, $param, 2);
+ if ($name eq "WIDTH") {
+ $width = $value;
+ } elsif ($name eq "HEIGHT") {
+ $height = $value;
+ } elsif ($name eq "UI") {
+ # look at what we got for the UI parameter, it should be of the
+ # form: x11:hostname:dpynum[.screen][;auth=...]
+ &parse_url($value, *proto, *display, *ui_param);
+ if ($proto eq 'x11') {
+ $xdisplay = $display;
+ } else {
+ # unknown UI protocol!!
+ }
+ # look for an authentication auth in param
+ &parse_auth($ui_param, *xui_auth_name, *xui_auth_key);
+
+ } elsif ($name eq "X-UI-LBX") {
+ &parse_lbx_param($value, *xui_lbx,
+ *xui_lbx_auth_name, *xui_lbx_auth_key);
+ }
+ }
+
+ # set authority file for X
+ $ENV{'XAUTHORITY'} = "/tmp/xauth.$$";
+ # and define its related cleanup command
+ $cleanup = "rm -f $ENV{'XAUTHORITY'}";
+
+ # process params
+ if ($xdisplay) {
+
+ if ($xui_lbx eq "YES") {
+ &setup_lbx_proxy(*xdisplay, $xui_lbx_auth_name, $xui_lbx_auth_key);
+ }
+ if ($xui_auth_name && $xui_auth_key) {
+ &add_auth($xdisplay, $xui_auth_name, $xui_auth_key);
+ }
+ # add display specification to the command line
+ $command .= " -display $xdisplay";
+ # and put it in the environment too for good measure.
+ $ENV{'DISPLAY'} = $xdisplay;
+ }
+ if ($width && $height) {
+ # add geometry specification to the command line
+ $command .= " -geometry ${width}x${height}";
+ }
+
+ # Start application followed by a cleanup command in the background.
+ # The ouput and input need to be redirected, otherwise the CGI process will
+ # be kept alive by the http server and the browser will keep waiting for
+ # the end of the stream...
+ # Catching application's failure is not easy since we want to run it in
+ # background and therefore we can't get its exit status. However, we can
+ # catch obvious errors by logging its output and after some time looking
+ # at whether the application is still running or not. This is determine
+ # based on some kind of "lock" file.
+ # This is quite complicated but it allows to get some error report without
+ # leaving any file behind us in any case.
+
+ $LOCK= "/tmp/lock.$$";
+ $LOG= "/tmp/log.$$";
+ $LOG2 = "/tmp/log2.$$";
+ system "(touch $LOCK; _s=true; $command >$LOG 2>&1 || _s=false; if \$_s; then rm $LOG; else rm $LOCK; fi; if [ -f $LOG2 ]; then rm $LOG2; fi; $cleanup) >/dev/null 2>&1 </dev/null &";
+
+ # sleep for a while to let the application start or fail
+ # it's up to you to decide how long it could for the application to fail...
+ sleep(5);
+
+ # now lets see if the application died
+ if (open(LOCK, "<$LOCK")) {
+ close(LOCK);
+ # the application seems to be running, remove lock and rename the log
+ # so that it gets removed no matter how the application exits later on
+ system "rm $LOCK; mv $LOG $LOG2";
+ # send success error code as reply
+ print "0\n";
+ } else {
+ # the lock file is gone, for sure the application has failed so send
+ # back error code and log
+ print "1\n";
+ system "cat $LOG; rm $LOG";
+ }
+
+} else {
+
+ # reply with an error message
+ print "This script requires to be given the proper RX arguments
+to run successfully.
+";
+
+}
diff --git a/cgi-bin/xload b/cgi-bin/xload
new file mode 100644
index 0000000..c0ab5c8
--- /dev/null
+++ b/cgi-bin/xload
@@ -0,0 +1,241 @@
+#!/usr/local/bin/perl
+# $Xorg: xload,v 1.3 2000/08/17 19:54:57 cpqbld Exp $
+# CGI script to launch xload
+#
+
+# define every program we are going to use
+$project_root = "XPROJECT_ROOT";
+$command = $project_root . "/bin/xload -update 1";
+$xfindproxy = $project_root . "/bin/xfindproxy";
+$xauth = $project_root . "/bin/xauth";
+
+# address of our proxy manager
+$proxymngr = "XPROXYMNGR";
+
+# make stderr and stdout unbuffered so nothing get lost
+select(STDERR); $| = 1;
+select(STDOUT); $| = 1;
+
+# print out header to content httpd no matter what happens later on
+print "Content-type: text/plain\r\n\r\n";
+
+# let's try not to leave any file behind us if things go really wrong
+sub handler { # 1st argument is signal name
+ local($sig) = @_;
+ # send error code first and error msg then
+ print "1\n";
+ print "Error: Caught a SIG$sig -- Oops!\n";
+ system "rm -f /tmp/*$$";
+ exit(0);
+}
+
+$SIG{'INT'} = 'handler';
+$SIG{'QUIT'} = 'handler';
+$SIG{'TERM'} = 'handler';
+$SIG{'KILL'} = 'handler';
+$SIG{'STOP'} = 'handler';
+# this one is perhaps the most important one, since this is what we should get
+# when the user interrupts the GET request.
+$SIG{'PIPE'} = 'handler';
+
+
+######################
+# sub procedures
+######################
+
+# parse an url param of the form: proto:display[;param]
+sub parse_url {
+ local($input, *proto_ret, *display_ret, *param_ret) = @_;
+
+ # extract param first
+ ($sub_url, $param_ret) = split(/;/, $input, 2);
+ # then extract proto and display
+ ($proto_ret, $display_ret) = split(/:/, $sub_url, 2);
+
+}
+
+# parse an auth param of the form: auth=name:key
+sub parse_auth {
+ local($input, *name_ret, *key_ret) = @_;
+
+ if ($input) {
+ ($param_name, $param_value) = split(/=/, $input, 2);
+ if ($param_name eq "auth") {
+ ($name_ret, $key_ret) = split(/:/, $param_value, 2);
+ }
+ }
+}
+
+# parse an LBX param of the form: either NO or YES[;auth=...]
+sub parse_lbx_param {
+ local($input, *lbx_ret, *lbx_auth_name_ret, *lbx_auth_key_ret) = @_;
+
+ ($lbx_ret, $lbxparam) = split(/;/, $input, 2);
+ if ($lbx_ret eq "YES") {
+ # look for an authentication auth in param
+ &parse_auth($lbxparam, *lbx_auth_name_ret, *lbx_auth_key_ret);
+ }
+}
+
+# setup proxy with possible auth, change display parameter when succeeding
+sub setup_lbx_proxy {
+ local(*display, $auth_name, $auth_key) = @_;
+
+ # setup auth file for xfindproxy
+ if ($auth_name && $auth_key) {
+ $proxy_input = "/tmp/xlbxauth.$$";
+ open(PROXYINPUT, ">$proxy_input");
+ print PROXYINPUT "$auth_name\n$auth_key\n";
+ close(PROXYINPUT);
+ $findproxy_param = " -auth <$proxy_input";
+ } else {
+ $findproxy_param = "";
+ }
+
+ # remove screen number specification if there is one
+ ($host, $tmp) = split(/:/, $display);
+ ($dpy, $screen) = split(/\./, $tmp);
+ $server = $host . ":" . $dpy;
+
+ # let's get an LBX proxy
+ open(PROXY, "$xfindproxy -manager $proxymngr -server $server -name LBX $findproxy_param|");
+ # get the proxy address from xfindproxy output
+ while (<PROXY>) {
+ chop;
+ ($proxy_dpy, $proxy_port) = split(/:/, $_);
+ if ($proxy_dpy && $proxy_port) {
+ # build up the new display name
+ $display = $proxy_dpy . ":" . $proxy_port;
+ if ($screen) {
+ $display .= "." . $screen;
+ }
+ last;
+ }
+ }
+ close(PROXY);
+
+ if ($proxy_input) {
+ system "rm -f $proxy_input";
+ }
+}
+
+# add entry in authority file
+sub add_auth {
+ local($display, $auth_name, $auth_key) = @_;
+
+ system "$xauth add $display $auth_name $auth_key";
+}
+
+
+######################
+# the main thing now
+######################
+
+
+# handle both ways of getting query
+if ($ENV{'QUERY_STRING'})
+{
+ $query = $ENV{'QUERY_STRING'};
+} else {
+ $query = $ARGV[0];
+}
+
+if ($query)
+{
+ $cleanup = "";
+
+ # parse params
+ %params = split(/\?/, $query);
+ foreach $param (split(/\?/, $query)) {
+
+ ($name, $value) = split(/=/, $param, 2);
+ if ($name eq "WIDTH") {
+ $width = $value;
+ } elsif ($name eq "HEIGHT") {
+ $height = $value;
+ } elsif ($name eq "UI") {
+ # look at what we got for the UI parameter, it should be of the
+ # form: x11:hostname:dpynum[.screen][;auth=...]
+ &parse_url($value, *proto, *display, *ui_param);
+ if ($proto eq 'x11') {
+ $xdisplay = $display;
+ } else {
+ # unknown UI protocol!!
+ }
+ # look for an authentication auth in param
+ &parse_auth($ui_param, *xui_auth_name, *xui_auth_key);
+
+ } elsif ($name eq "X-UI-LBX") {
+ &parse_lbx_param($value, *xui_lbx,
+ *xui_lbx_auth_name, *xui_lbx_auth_key);
+ }
+ }
+
+ # set authority file for X
+ $ENV{'XAUTHORITY'} = "/tmp/xauth.$$";
+ # and define its related cleanup command
+ $cleanup = "rm -f $ENV{'XAUTHORITY'}";
+
+ # process params
+ if ($xdisplay) {
+
+ if ($xui_lbx eq "YES") {
+ &setup_lbx_proxy(*xdisplay, $xui_lbx_auth_name, $xui_lbx_auth_key);
+ }
+ if ($xui_auth_name && $xui_auth_key) {
+ &add_auth($xdisplay, $xui_auth_name, $xui_auth_key);
+ }
+ # add display specification to the command line
+ $command .= " -display $xdisplay";
+ # and put it in the environment too for good measure.
+ $ENV{'DISPLAY'} = $xdisplay;
+ }
+ if ($width && $height) {
+ # add geometry specification to the command line
+ $command .= " -geometry ${width}x${height}";
+ }
+
+ # Start application followed by a cleanup command in the background.
+ # The ouput and input need to be redirected, otherwise the CGI process will
+ # be kept alive by the http server and the browser will keep waiting for
+ # the end of the stream...
+ # Catching application's failure is not easy since we want to run it in
+ # background and therefore we can't get its exit status. However, we can
+ # catch obvious errors by logging its output and after some time looking
+ # at whether the application is still running or not. This is determine
+ # based on some kind of "lock" file.
+ # This is quite complicated but it allows to get some error report without
+ # leaving any file behind us in any case.
+
+ $LOCK= "/tmp/lock.$$";
+ $LOG= "/tmp/log.$$";
+ $LOG2 = "/tmp/log2.$$";
+ system "(touch $LOCK; _s=true; $command >$LOG 2>&1 || _s=false; if \$_s; then rm $LOG; else rm $LOCK; fi; if [ -f $LOG2 ]; then rm $LOG2; fi; $cleanup) >/dev/null 2>&1 </dev/null &";
+
+ # sleep for a while to let the application start or fail
+ # it's up to you to decide how long it could for the application to fail...
+ sleep(5);
+
+ # now lets see if the application died
+ if (open(LOCK, "<$LOCK")) {
+ close(LOCK);
+ # the application seems to be running, remove lock and rename the log
+ # so that it gets removed no matter how the application exits later on
+ system "rm $LOCK; mv $LOG $LOG2";
+ # send success error code as reply
+ print "0\n";
+ } else {
+ # the lock file is gone, for sure the application has failed so send
+ # back error code and log
+ print "1\n";
+ system "cat $LOG; rm $LOG";
+ }
+
+} else {
+
+ # reply with an error message
+ print "This script requires to be given the proper RX arguments
+to run successfully.
+";
+
+}
diff --git a/helper/GetUrl.c b/helper/GetUrl.c
new file mode 100644
index 0000000..04b4c93
--- /dev/null
+++ b/helper/GetUrl.c
@@ -0,0 +1,296 @@
+/* $Xorg: GetUrl.c,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+/*
+ * This file is really split into two major parts where GetUrl is implemented
+ * in two completely different ways.
+ * The first one, which is used when XUSE_WWW is defined uses the standalone
+ * program "www" to perform the GET request.
+ * The second one, based on the xtrans layer, performs the GET request
+ * directly.
+ */
+
+#define Free(b) if (b) free(b)
+
+#ifdef XUSE_WWW
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xos.h> /* for strcmp() etc... */
+
+/*
+ * GetUrl first method, using www.
+ */
+
+int
+GetUrl(char *url, char **reply_ret, int *len_ret)
+{
+ char buf[BUFSIZ], *reply, *ptr;
+ FILE *fp;
+ int readbytes, size;
+
+ sprintf(buf, "www -source \"%s\"", url);
+ fp = popen(buf, "r");
+ if (fp == NULL)
+ return 1;
+
+ reply = NULL;
+ size = 0;
+ do {
+ readbytes = fread(buf, sizeof(char), BUFSIZ, fp);
+ if (readbytes != 0) {
+ /* malloc enough memory */
+ ptr = (char *) realloc(reply, sizeof(char) * size + readbytes);
+ if (ptr == NULL) { /* memory allocation failed */
+ Free(reply);
+ return 1;
+ }
+ reply = ptr;
+ memcpy(reply + size, buf, readbytes);
+ size += readbytes;
+ }
+ } while (readbytes == BUFSIZ);
+ pclose(fp);
+
+ *reply_ret = reply;
+ *len_ret = size;
+ return 0;
+}
+
+#else /* XUSE_WWW */
+
+/*
+ * GetUrl second method, using the xtrans layer.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+/* get definitions for the HTTP protocol */
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _HttpTrans##func
+#else
+#define TRANS(func) _HttpTrans/**/func
+#endif
+#include <X11/Xtrans.h>
+
+#define HTTP_CONNECTION_RETRIES 5
+
+static XtransConnInfo
+OpenConnection(char *hostname, int port)
+{
+ int retry; /* retry counter */
+ XtransConnInfo trans_conn = NULL; /* transport connection object */
+ int connect_stat;
+ char address[128]; /* address passed to the transport layer */
+ char protocol[] = "tcp"; /* hardcoded transport */
+
+ /* make the address of the form: protocol/host:port */
+ sprintf(address,"%s/%s:%d",
+ protocol ? protocol : "",
+ hostname ? hostname : "",
+ port);
+
+ /*
+ * Make the connection. Do retries in case server host has hit its
+ * backlog (which, unfortunately, isn't distinguishable from there not
+ * being a server listening at all, which is why we have to not retry
+ * too many times).
+ */
+ for(retry = HTTP_CONNECTION_RETRIES; retry >= 0; retry--) {
+ if ((trans_conn = _HttpTransOpenCOTSClient(address)) == NULL)
+ break;
+
+ if ((connect_stat = _HttpTransConnect(trans_conn, address)) < 0) {
+ _HttpTransClose(trans_conn);
+ trans_conn = NULL;
+
+ if (connect_stat == TRANS_TRY_CONNECT_AGAIN) {
+ sleep(1);
+ continue;
+ } else
+ break;
+ }
+ }
+
+ return trans_conn;
+}
+
+static void
+CloseConnection(XtransConnInfo trans_conn)
+{
+ _HttpTransDisconnect(trans_conn);
+ _HttpTransClose(trans_conn);
+}
+
+static void
+SendGetRequest(XtransConnInfo trans_conn, char *filename)
+{
+ char *request;
+ char request_format[] =
+ "GET %s HTTP/1.0\r\nUser-Agent: xrx\r\nAccept: */*\r\n\r\n";
+ int request_len = strlen(filename) + sizeof(request_format) + 1;
+
+ /* build request */
+ request = (char *)malloc(request_len);
+ sprintf(request, request_format, filename);
+ /* send it */
+ _HttpTransWrite(trans_conn, request, request_len);
+
+ Free(request);
+}
+
+static int
+ReadGetReply(XtransConnInfo trans_conn, char **reply_ret)
+{
+ char *reply = NULL;
+ char buf[BUFSIZ];
+ int len, nbytes;
+
+ len = 0;
+ do {
+ nbytes = _HttpTransRead(trans_conn, buf, BUFSIZ);
+ if (nbytes > 0) {
+ reply = (char *)realloc(reply, len + nbytes);
+ if (reply == NULL)
+ break;
+ memcpy(reply + len, buf, nbytes);
+ len += nbytes;
+ }
+ } while (nbytes != 0);
+
+ *reply_ret = reply;
+ return len;
+}
+
+/* per HTTP 1.0 spec */
+#define HTTP_DEFAULT_PORT 80
+
+/* Parse given http url and return hostname, port number and path.
+ * expected syntax: "http:" "//" host [ ":" port ] [ abs_path ]
+ * default port: 80
+ */
+static int
+ParseHttpUrl(char *url, char **hostname_ret, int *port_ret, char **path_ret)
+{
+ char HTTP[] = "http://";
+ char *hostname, *path;
+ int port;
+ char *ptr, *bos;
+ int status = 0;
+
+ /* check if it's an http url */
+ if (strncmp(HTTP, url, sizeof(HTTP) - 1))
+ return 1; /* this is not an http url */
+
+ /* parse hostname */
+ bos = ptr = url + sizeof(HTTP) - 1;
+ while (*ptr && *ptr != ':' && *ptr != '/')
+ ptr++;
+ if (bos == ptr)
+ return 1; /* doesn't have any hostname */
+
+ hostname = (char *)malloc(ptr - bos + 1);
+ if (hostname == NULL)
+ return 1; /* not enouch memory */
+ memcpy(hostname, bos, ptr - bos);
+ hostname[ptr - bos] = '\0';
+
+ /* make sure path is initialized in case of error */
+ path = NULL;
+
+ /* parse port */
+ if (*ptr != ':' || ! ptr[1])
+ port = HTTP_DEFAULT_PORT;
+ else {
+ ++ptr; /* skip ':' */
+ port = 0;
+ while (*ptr && *ptr != '/') {
+ if (isdigit((int) *ptr)) {
+ port *= 10;
+ port += *ptr - '0';
+ } else {
+ status = 1; /* bad port specification */
+ goto error;
+ }
+ ptr++;
+ }
+ }
+
+ /* the rest of the url is the path */
+ path = (char *)malloc(strlen(ptr) + 1);
+ if (path == NULL) {
+ status = 1; /* not enouch memory */
+ goto error;
+ }
+ strcpy(path, ptr);
+
+ /* set returned value */
+ *hostname_ret = hostname;
+ *port_ret = port;
+ *path_ret = path;
+ return 0;
+
+error:
+ Free(hostname);
+ Free(path);
+ return status;
+}
+
+int
+GetUrl(char *url, char **reply_ret, int *len_ret)
+{
+ char *hostname, *path;
+ int port;
+ XtransConnInfo trans;
+ int status = 0;
+
+ if (ParseHttpUrl(url, &hostname, &port, &path) != 0)
+ return 1; /* invalid URL */
+
+ trans = OpenConnection(hostname, port);
+ if (trans == NULL) {
+ status = 1; /* connection failed */
+ goto end;
+ }
+
+ SendGetRequest(trans, path);
+
+ *len_ret = ReadGetReply(trans, reply_ret);
+
+ CloseConnection(trans);
+
+end:
+ Free(hostname);
+ Free(path);
+ return status;
+}
+
+
+#endif /* XUSE_WWW */
diff --git a/helper/GetUrl.h b/helper/GetUrl.h
new file mode 100644
index 0000000..cb80b9c
--- /dev/null
+++ b/helper/GetUrl.h
@@ -0,0 +1,36 @@
+/* $Xorg: GetUrl.h,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifndef _GetUrl_h
+#define _GetUrl_h
+
+extern int
+GetUrl(char *url, char **reply_ret, int *len_ret);
+
+#endif /* _GetUrl_h */
diff --git a/helper/helper.c b/helper/helper.c
new file mode 100644
index 0000000..9842623
--- /dev/null
+++ b/helper/helper.c
@@ -0,0 +1,529 @@
+/* $Xorg: helper.c,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+#include <X11/extensions/security.h>
+#include <X11/Intrinsic.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <limits.h> /* for MAXHOSTNAMELEN */
+/* and in case we didn't get it from the headers above */
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN 256
+#endif
+
+#include "Rx.h"
+#include "RxI.h" /* for Strncasecmp */
+#include "XUrls.h"
+#include "GetUrl.h"
+#include "XAuth.h"
+#include "XDpyName.h"
+#include "Prefs.h"
+
+
+#define DEFAULT_TIMEOUT 300
+#define NO_TIMEOUT 0
+
+/* a few global */
+Display *pdpy;
+int security_event_type_base;
+XSecurityAuthorization ui_auth_id;
+XSecurityAuthorization print_auth_id;
+
+#define RevokedEventType \
+ (security_event_type_base + XSecurityAuthorizationRevoked)
+
+/* read file in memory and return character stream */
+static char *
+ReadFile(char *filename)
+{
+ int fd;
+ struct stat st;
+ char *stream;
+
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ return(0);
+ fstat(fd, &st);
+ stream = (char *)malloc(st.st_size+1);
+ if (stream == 0)
+ return(0);
+ if ((st.st_size = read(fd, stream, st.st_size)) < 0) {
+ free(stream);
+ return(0);
+ }
+ close(fd);
+ stream[st.st_size] = '\0';
+ return stream;
+}
+
+
+static Display *
+OpenXPrintDisplay(Display *dpy, char **printer_return)
+{
+ char *pdpy_name;
+ Display *pdpy;
+ pdpy_name = GetXPrintDisplayName(printer_return);
+ if (pdpy_name != NULL) {
+ pdpy = XOpenDisplay(pdpy_name);
+ free(pdpy_name);
+ } else {
+ /* no server specified,
+ let's see if the video server could do it */
+ int dummy;
+ if (XQueryExtension(dpy, "XpExtension", &dummy, &dummy, &dummy))
+ pdpy = dpy;
+ else
+ pdpy = NULL;
+ }
+ return pdpy;
+}
+
+static void
+CloseXPrintDisplay(Display *dpy, Display *pdpy)
+{
+ if (pdpy != NULL && pdpy != dpy)
+ XCloseDisplay(pdpy);
+}
+
+/* process the given RxParams and make the RxReturnParams */
+static int
+ProcessUIParams(Display *dpy,
+ Boolean trusted, Boolean use_fwp, Boolean use_lbx,
+ RxParams *in, RxReturnParams *out, char **x_ui_auth_ret)
+{
+ char *fwp_dpyname = NULL;
+ XSecurityAuthorization dum;
+ char *x_ui_auth = NULL;
+ Display *rdpy;
+ char *real_display;
+
+ if (in->x_ui_auth[0] != 0)
+ GetXAuth(dpy, in->x_ui_auth[0], in->x_ui_auth_data[0],
+ trusted, None, DEFAULT_TIMEOUT, True,
+ &x_ui_auth, &ui_auth_id, &security_event_type_base);
+ else if (in->x_auth[0] != 0)
+ GetXAuth(dpy, in->x_auth[0], in->x_auth_data[0],
+ trusted, None, DEFAULT_TIMEOUT, True,
+ &x_ui_auth, &ui_auth_id, &security_event_type_base);
+
+ /* make sure we use the server the user wants us to use */
+ rdpy = dpy;
+ real_display = getenv("XREALDISPLAY");
+ if (real_display != NULL) {
+ rdpy = XOpenDisplay(real_display);
+ if (rdpy == NULL)
+ rdpy = dpy;
+ }
+
+ /* let's see whether we have a firewall proxy */
+ if (use_fwp) {
+ fwp_dpyname = GetXFwpDisplayName(DisplayString(rdpy));
+ if (fwp_dpyname == NULL)
+ /*
+ * We were supposed to use the firewall proxy but we
+ * couldn't get a connection. There is no need to
+ * continue.
+ */
+ return 1;
+ }
+
+ if (fwp_dpyname != NULL) {
+ out->ui = GetXUrl(fwp_dpyname, x_ui_auth, in->action);
+ free(fwp_dpyname);
+ } else
+ out->ui = GetXUrl(DisplayString(rdpy), x_ui_auth, in->action);
+
+ if (in->x_ui_lbx == RxTrue) {
+ if (use_lbx == True) {
+ int dummy;
+ /* let's see whether the server supports LBX or not */
+ if (XQueryExtension(rdpy, "LBX", &dummy, &dummy, &dummy)) {
+ out->x_ui_lbx = RxTrue;
+
+ /* let's get a key for the proxy now */
+ if (in->x_ui_lbx_auth[0] != 0) {
+ GetXAuth(dpy, in->x_ui_lbx_auth[0],
+ in->x_ui_lbx_auth_data[0],
+ trusted, None, DEFAULT_TIMEOUT, False,
+ &out->x_ui_lbx_auth, &dum, &dummy);
+ } else if (in->x_auth[0] != 0)
+ GetXAuth(dpy, in->x_auth[0], in->x_auth_data[0],
+ trusted, None, DEFAULT_TIMEOUT, False,
+ &out->x_ui_lbx_auth, &dum, &dummy);
+ } else {
+ out->x_ui_lbx = RxFalse;
+ fprintf(stderr, "Warning: Cannot setup LBX as requested, \
+LBX extension not supported\n");
+ }
+ } else
+ out->x_ui_lbx = RxFalse;
+ } else /* it's either RxFalse or RxUndef */
+ out->x_ui_lbx = in->x_ui_lbx;
+
+ if (rdpy != dpy)
+ XCloseDisplay(rdpy);
+
+ *x_ui_auth_ret = x_ui_auth;
+
+ return 0;
+}
+
+
+static int
+ProcessPrintParams(Display *dpy,
+ Boolean trusted, Boolean use_fwp, Boolean use_lbx,
+ RxParams *in, RxReturnParams *out, char *x_ui_auth)
+{
+ char *printer = NULL;
+ char *auth = NULL;
+ XSecurityAuthorization dum;
+ char *pfwp_dpyname = NULL;
+ int dummy;
+
+ pdpy = OpenXPrintDisplay(dpy, &printer);
+ if (pdpy == NULL) {
+ fprintf(stderr, "Warning: Cannot setup X printer as requested, \
+no server found\n");
+ return 0;
+ }
+
+ /* create a key only when the video server is not the print
+ server or when we didn't create a key yet */
+ if (pdpy != dpy || x_ui_auth == NULL) {
+ /* if the application has a GUI we can't guess when it will really
+ connect to the print server so we need an auth which never expires,
+ on the other hand if the application happens not to have any GUI
+ we can expect it to connect to the print server pretty soon */
+ unsigned int timeout = ui_auth_id != 0 ? NO_TIMEOUT : DEFAULT_TIMEOUT;
+ if (in->x_print_auth[0] != 0)
+ GetXAuth(pdpy, in->x_print_auth[0], in->x_print_auth_data[0],
+ trusted, None, timeout, False,
+ &auth, &print_auth_id, &dummy);
+ else if (in->x_auth[0] != 0)
+ GetXAuth(pdpy, in->x_auth[0], in->x_auth_data[0],
+ trusted, None, timeout, False,
+ &auth, &print_auth_id, &dummy);
+ }
+ /* let's see whether we have a firewall proxy */
+ if (use_fwp) {
+ pfwp_dpyname = GetXFwpDisplayName(DisplayString(pdpy));
+ if (pfwp_dpyname == NULL)
+ /*
+ * We were supposed to use the firewall proxy but we
+ * couldn't get a connection. There is no need to
+ * continue.
+ */
+ return 1;
+ }
+
+ if (pfwp_dpyname != NULL) {
+ out->print = GetXPrintUrl(pfwp_dpyname, printer, auth, in->action);
+ free(pfwp_dpyname);
+ } else
+ out->print = GetXPrintUrl(DisplayString(pdpy), printer, auth, in->action);
+
+ if (auth != NULL)
+ free(auth);
+
+ if (in->x_print_lbx == RxTrue) {
+ if (use_lbx == True) {
+ if (pdpy == dpy && in->x_ui_lbx == RxTrue) {
+ /* the video server is the print server and we already
+ know whether it supports LBX or not */
+ out->x_print_lbx = out->x_ui_lbx;
+ } else {
+ /* let's see whether the server supports LBX or not */
+ if (XQueryExtension(pdpy, "LBX", &dummy, &dummy, &dummy)) {
+ out->x_print_lbx = RxTrue;
+
+ /* let's get a key for the proxy now */
+ if (in->x_print_lbx_auth[0] != 0) {
+ GetXAuth(pdpy, in->x_print_lbx_auth[0],
+ in->x_print_lbx_auth_data[0],
+ trusted, None, DEFAULT_TIMEOUT, False,
+ &out->x_print_lbx_auth, &dum, &dummy);
+ } else if (in->x_auth[0] != 0)
+ GetXAuth(pdpy, in->x_auth[0], in->x_auth_data[0],
+ trusted, None, DEFAULT_TIMEOUT, False,
+ &out->x_print_lbx_auth, &dum, &dummy);
+ } else {
+ out->x_print_lbx = RxFalse;
+ fprintf(stderr, "Warning: Cannot setup LBX as \
+requested, LBX extension not supported\n");
+ }
+ }
+ } else
+ out->x_print_lbx = RxFalse;
+ } else /* it's either RxFalse or RxUndef */
+ out->x_print_lbx = in->x_print_lbx;
+
+ if (printer != NULL)
+ free(printer);
+
+ return 0;
+}
+
+static int
+ProcessParams(Display *dpy, Preferences *prefs, RxParams *in,
+ RxReturnParams *out)
+{
+ char *x_ui_auth = NULL;
+ char webserver[MAXHOSTNAMELEN];
+ Boolean trusted, use_fwp, use_lbx;
+ int return_value = 0;
+
+ /* init return struture */
+ memset(out, 0, sizeof(RxReturnParams));
+ out->x_ui_lbx = RxUndef;
+ out->x_print_lbx = RxUndef;
+ out->action = in->action;
+
+ if (in->embedded != RxUndef)
+ out->embedded = RxFalse; /* we cannot perform embbeding from helper */
+ else
+ out->embedded = RxUndef;
+
+ out->width = in->width;
+ out->height = in->height;
+
+ ComputePreferences(prefs,
+ ParseHostname(in->action, webserver, MAXHOSTNAMELEN) ? webserver : NULL,
+ &trusted, &use_fwp, &use_lbx);
+
+ if (in->ui[0] == XUI) /* X display needed */
+ return_value = ProcessUIParams(dpy, trusted, use_fwp, use_lbx,
+ in, out, &x_ui_auth);
+
+ if (in->print[0] == XPrint) /* XPrint server needed */
+ return_value = ProcessPrintParams(dpy, trusted, use_fwp, use_lbx,
+ in, out, x_ui_auth);
+
+ if (x_ui_auth != NULL)
+ free(x_ui_auth);
+
+ return return_value;
+}
+
+#define CONTENT_TYPE "Content-type"
+#define TEXT_PLAIN "text/plain"
+
+/* parse CGI reply looking for error status line,
+ * and return following message
+ */
+int
+ParseReply(char *reply, int reply_len, char **reply_ret, int *reply_len_ret)
+{
+ char *ptr, *end;
+ int status = 0;
+
+ /* look for content-type field */
+ end = reply + reply_len;
+ ptr = reply;
+ while (Strncasecmp(ptr, CONTENT_TYPE, sizeof(CONTENT_TYPE) - 1) != 0 &&
+ ptr < end) {
+ /* goto the next line */
+ while (*ptr != '\n' && ptr < end)
+ ptr++;
+ if (ptr != end)
+ ptr++;
+ }
+
+ if (ptr < end) { /* if we found it */
+ /* skip to field value */
+ ptr += sizeof(CONTENT_TYPE);
+ while (isspace(*ptr) && ptr < end)
+ ptr++;
+ if (Strncasecmp(ptr, TEXT_PLAIN, sizeof(TEXT_PLAIN) - 1) == 0) {
+ /* go to the next line */
+ while (*ptr != '\n' && ptr < end)
+ ptr++;
+ if (ptr == end) /* input truncated */
+ goto exit;
+ ptr++;
+ /* skip the next line should be empty (except for \r) */
+ while (*ptr != '\n' && ptr < end)
+ ptr++;
+ if (ptr == end) /* input truncated */
+ goto exit;
+ ptr++;
+ /* now should be the error code */
+ if (isdigit(*ptr)) {
+ status = atoi(ptr);
+ /* go to the next line */
+ while (*ptr != '\n' && ptr < end)
+ ptr++;
+ if (ptr == end) /* input truncated */
+ goto exit;
+ ptr++;
+ goto exit;
+ } else /* input truncated */
+ goto exit;
+ }
+ }
+exit:
+ *reply_ret = ptr;
+ *reply_len_ret = reply_len - (ptr - reply);
+ return status;
+}
+
+
+/*
+ * The following event dispatcher is in charge of revoking the print
+ * authorization when the video authorization is (which means the application
+ * using it is gone).
+ * We can then exit since we do not have anything else to do.
+ */
+Boolean
+RevokeD(XEvent *xev)
+{
+ if (xev->type == RevokedEventType) { /* should always be true */
+ XSecurityAuthorizationRevokedEvent *ev;
+ ev = (XSecurityAuthorizationRevokedEvent *) xev;
+ if (ev->auth_id == ui_auth_id) { /* should always be true */
+ XSecurityRevokeAuthorization(pdpy, print_auth_id);
+ exit(0);
+ }
+ }
+ return True;
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *stream;
+ char **rx_argn, **rx_argv;
+ int rx_argc;
+ RxParams params;
+ RxReturnParams return_params;
+ char *query, *reply, *msg;
+ int reply_len, msg_len;
+ Widget toplevel;
+ XtAppContext app_context;
+ Preferences prefs;
+
+ /* init global variables */
+ pdpy = NULL;
+ security_event_type_base = 0;
+ ui_auth_id = 0;
+ print_auth_id = 0;
+
+ rx_argc = 0;
+
+ toplevel = XtAppInitialize(&app_context, "Xrx", 0, 0,
+#if XtSpecificationRelease > 4
+ &argc,
+#else
+ (Cardinal *)&argc,
+#endif
+ argv, 0, 0, 0);
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ exit(1);
+ }
+
+ if ((stream = ReadFile(argv[1])) == 0) {
+ fprintf(stderr, "%s: cannot open file %s\n", argv[0], argv[1]);
+ exit(1);
+ }
+
+ if (RxReadParams(stream, &rx_argn, &rx_argv, &rx_argc) != 0) {
+ fprintf(stderr, "%s: invalid file %s\n", argv[0], argv[1]);
+ exit(1);
+ }
+
+ RxInitializeParams(&params);
+
+ if (RxParseParams(rx_argn, rx_argv, rx_argc, &params, 0) != 0) {
+ fprintf(stderr, "%s: invalid params\n", argv[0]);
+ exit(1);
+ }
+ GetPreferences(toplevel, &prefs);
+
+ /* set up return parameters */
+ if (ProcessParams(XtDisplay(toplevel), &prefs,
+ &params, &return_params) != 0) {
+ fprintf(stderr, "%s: failed to process params\n", argv[0]);
+ exit(1);
+ }
+
+ /* make query */
+ query = RxBuildRequest(&return_params);
+ if (query == NULL) {
+ fprintf(stderr, "%s: failed to make query\n", argv[0]);
+ exit(1);
+ }
+
+ /* perform GET request */
+ if (GetUrl(query, &reply, &reply_len) != 0) {
+ fprintf(stderr, "%s: GET request failed\n", argv[0]);
+ exit(1);
+ }
+
+ if (reply) {
+ if (ParseReply(reply, reply_len, &msg, &msg_len) != 0) {
+ fprintf(stderr, "%s: Remote execution failed\n", argv[0]);
+ fwrite(msg, msg_len, 1, stderr);
+ }
+ }
+
+ /* if we didn't create any authorization for printing or
+ if the application is only using the print server, exit here */
+ if (print_auth_id == 0 || ui_auth_id == 0)
+ exit (0);
+
+ /* otherwise, free as much as we can now */
+ if (rx_argc != 0) {
+ int i;
+ for (i = 0; i < rx_argc; i++) {
+ free(rx_argn[i]);
+ free(rx_argv[i]);
+ }
+ free(rx_argn);
+ free(rx_argv);
+ }
+ RxFreeParams(&params);
+ RxFreeReturnParams(&return_params);
+
+ free(stream);
+ free(query);
+ if (reply)
+ free(reply);
+
+ FreePreferences(&prefs);
+
+ /* and setup event dispatcher so we catch the video key revocation */
+ XtSetEventDispatcher(XtDisplay(toplevel), RevokedEventType, RevokeD);
+
+ /* then wait for it... */
+ XtAppMainLoop(app_context);
+}
diff --git a/helper/xrx.man b/helper/xrx.man
new file mode 100644
index 0000000..fc5d90d
--- /dev/null
+++ b/helper/xrx.man
@@ -0,0 +1,134 @@
+.\" $Xorg: xrx.man,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $
+.\" Copyright 1996, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.\"
+.TH XRX 1 "Release 6.4" "X Version 11"
+.SH NAME
+xrx - RX helper program
+.SH SYNOPSIS
+\fBxrx\fP [\-\fItoolkitoption\fP ...] \fIfilename\fP
+.SH DESCRIPTION
+The helper program may be used with any Web browser to interpret documents
+in the RX MIME type format and start remote applications.
+.PP
+\fBxrx\fP reads in the RX document specified by its \fIfilename\fP, from
+which it gets the list of services the application wants to use. Based on
+this information, \fBxrx\fP sets the various requested services, including
+creating authorization keys if your X server supports the SECURITY
+extension. It then passes the relevant data, such as the X display name, to
+the application through an HTTP GET request of the associated CGI
+script. The Web server then executes the CGI script to start the
+application. The client runs on the web server host connected to your X
+server.
+.PP
+.SH INSTALLATION
+You need to configure your web browser to use \fBxrx\fP for RX documents.
+Generally the following line in your $HOME/.mailcap is enough:
+ application/x-rx; xrx %s
+.PP
+However, you may need to refer to your web browser's documentation for exact
+instructions on configuring helper applications.
+.PP
+Once correctly configured, your browser will activate the helper program
+whenever you retrieve any document of the MIME type \fIapplication/x-rx\fP.
+.PP
+.SH OPTIONS
+The \fIxrx\fP helper program accepts all of the standard X Toolkit command
+line options such as:
+.TP 8
+.B \-xrm \fIresourcestring\fP
+This option specifies a resource string to be used. There may be several
+instances of this option on the command line.
+.PP
+.SH RESOURCES
+The application class name of the \fIxrx\fP program is Xrx and it
+understands the following application resource names and classes:
+.\".in +1in
+.TP 8
+.B "xrxHasFirewallProxy (\fPclass\fB XrxHasFirewallProxy)"
+Specifies whether an X server firewall proxy (see xfwp) is running and
+should be used. Default is ``False.''
+.TP 8
+.B "xrxInternalWebServers (\fPclass\fB XrxInternalWebServers)"
+The web servers for which the X server firewall proxy should not be used
+(only relevant when \fBxrxHasFirewallProxy\fP is ``True''). Its value is a
+comma separated list of mask/value pairs to be used to filter internal
+web servers, based on their address. The mask part specifies which segments
+of the address are to be considered and the value part specifies what the
+result should match. For instance the following list:
+
+ 255.255.255.0/198.112.45.0, 255.255.255.0/198.112.46.0
+
+matches the address sets: 198.112.45.* and 198.112.46.*. More precisely,
+the test is (address & mask) == value.
+.TP 8
+.B "xrxFastWebServers (\fPclass\fB XrxFastWebServers)"
+The web servers for which LBX should not be used. The resource value is a
+list of address mask/value pairs, as previously described.
+.TP 8
+.B "xrxTrustedWebServers (\fPclass\fB XrxTrustedWebServers)"
+The web servers from which remote applications should be run as trusted
+clients. The default is to run remote applications as untrusted
+clients. The resource value is a list of address mask/value pairs, as
+previously described.
+.PP
+.SH ENVIRONMENT
+
+The \fIxrx\fP helper program uses the standard X environment variables
+such as ``DISPLAY'' to get the default X server host and display
+number. If the RX document requests X-UI-LBX service and the default X
+server does not advertise the LBX extension, \fIxrx\fP will look for the
+environment variable ``XREALDISPLAY'' to get a second address for your X
+server and look for the LBX extension there. When running your browser
+through \fIlbxproxy\fP you will need to set XREALDISPLAY to the actual
+address of your server if you wish remote applications to be able to use
+LBX across the Internet.
+.PP
+If the RX document requests XPRINT service, \fIxrx\fP looks for the
+variable ``XPRINTER'' to get the printer name and X Print server address to
+use. If the server address is not specified as part of XPRINTER, \fIxrx\fP
+uses the first one specified through the variable ``XPSERVERLIST'' when it
+is set. When it is not \fIxrx\fP then tries to use the video server as the
+print server. If the printer name is not specified via XPRINTER, \fIxrx\fP
+looks for it in the variables ``PDPRINTER'', then ``LPDEST'', and finally
+``PRINTER'',
+.PP
+Finally, if you are using a firewall proxy, \fIxrx\fP will look for
+``PROXY_MANAGER'' to get the address of your proxy manager (see
+proxymngr). When not specified it will use ":6500" as the default.
+.PP
+.SH KNOWN BUG
+When an authorization key is created for a remote application to use the X
+Print service, the helper program has to create the key with an infinite
+timeout since nobody knows when the application will actually connect to
+the X Print server. Therefore, in this case, the helper program stays
+around to revoke the key when the application goes away (that is when its
+video key expires). However, if the helper program dies unexpectedly the
+print authorization key will never get revoked.
+.PP
+.SH SEE ALSO
+libxrx (1), xfwp (1), lbxproxy (1), proxymngr (1),
+The RX Document specification
+.SH AUTHOR
+Arnaud Le Hors, X Consortium
diff --git a/htdocs/bitmap b/htdocs/bitmap
new file mode 100644
index 0000000..934fe47
--- /dev/null
+++ b/htdocs/bitmap
@@ -0,0 +1,12 @@
+<!-- $Xorg: bitmap,v 1.3 2000/08/17 19:54:58 cpqbld Exp $ -->
+<PARAM Name=VERSION Value=1.0>
+<PARAM Name=REQUIRED-SERVICES Value=UI>
+<PARAM Name=UI Value=X>
+<PARAM Name=ACTION Value=http://WEBSERVER/cgi-bin/bitmap.pl>
+<PARAM Name=WIDTH Value=200>
+<PARAM Name=HEIGHT Value=200>
+<PARAM Name=EMBEDDED Value=YES>
+<PARAM Name=AUTO_START Value=YES>
+<PARAM Name=X-UI-INPUT-METHOD VALUE=YES;foo>
+<PARAM Name=X-UI-LBX Value=YES>
+<PARAM Name=X-AUTH VALUE=MIT-MAGIC-COOKIE-1>
diff --git a/htdocs/bitmap.html b/htdocs/bitmap.html
new file mode 100644
index 0000000..242b867
--- /dev/null
+++ b/htdocs/bitmap.html
@@ -0,0 +1,23 @@
+<!--$Xorg: bitmap.html,v 1.3 2000/08/17 19:54:58 cpqbld Exp $-->
+<html>
+<head>
+ <title>X Applications on the Web - bitmap demo page. </title>
+</head>
+
+<body>
+<a name="begin">
+<h1> X Applications on the Web - bitmap <br> Demo page. </h1>
+
+<hr>
+
+Here is a simple demo of the RX plug-in used to launch the bitmap program
+over the web. In addition, if you are using Netscape Navigator with
+the embedding capabable plug-in, the bitmap program should appear embedded
+within this page.
+
+<p>
+When embedded, bitmap's window should be here:
+<EMBED version=1.0 type=application/x-rx src="bitmap.rx" width=420 height=570>
+
+</body>
+</html>
diff --git a/htdocs/dtcm b/htdocs/dtcm
new file mode 100644
index 0000000..9d617ce
--- /dev/null
+++ b/htdocs/dtcm
@@ -0,0 +1,12 @@
+<!-- $Xorg: dtcm,v 1.3 2000/08/17 19:54:58 cpqbld Exp $ -->
+<PARAM Name=VERSION Value=1.0>
+<PARAM Name=REQUIRED-SERVICES Value=UI>
+<PARAM Name=UI Value=X>
+<PARAM Name=PRINT Value=XPRINT>
+<PARAM Name=ACTION Value=http://WEBSERVER/cgi-bin/dtcm.pl>
+<PARAM Name=WIDTH Value=500>
+<PARAM Name=HEIGHT Value=300>
+<PARAM Name=EMBEDDED Value=YES>
+<PARAM Name=X-UI-LBX Value=YES>
+<PARAM Name=X-PRINT-LBX Value=NO>
+<PARAM Name=X-AUTH VALUE=MIT-MAGIC-COOKIE-1>
diff --git a/htdocs/dtcm.html b/htdocs/dtcm.html
new file mode 100644
index 0000000..6f9f450
--- /dev/null
+++ b/htdocs/dtcm.html
@@ -0,0 +1,23 @@
+<!--$Xorg: dtcm.html,v 1.3 2000/08/17 19:54:58 cpqbld Exp $-->
+<html>
+<head>
+ <title>X Applications on the Web - Demo page. </title>
+</head>
+
+<body>
+<a name="begin">
+<h1> X Applications on the Web - Dtcm <br> Demo page. </h1>
+
+<hr>
+
+Here is a simple demo of the RX plug-in used to launch the dtcm program
+over the web. In addition, if you are using Netscape Navigator with
+the embedding capabable plug-in, the dtcm program should appear embedded
+within this page.
+
+<p>
+When embedded, dtcm's window should be here:
+<EMBED version=1.0 type=application/x-rx src="dtcm.rx" width=500 height=300>
+
+</body>
+</html>
diff --git a/htdocs/excel b/htdocs/excel
new file mode 100644
index 0000000..2a453b0
--- /dev/null
+++ b/htdocs/excel
@@ -0,0 +1,11 @@
+<!-- $Xorg: excel,v 1.3 2000/08/17 19:54:58 cpqbld Exp $ -->
+<PARAM Name=VERSION Value=1.0>
+<PARAM Name=REQUIRED-SERVICES Value=UI>
+<PARAM Name=UI Value=X>
+<PARAM Name=ACTION Value=http://WEBSERVER/cgi-bin/excel.pl>
+<PARAM Name=WIDTH Value=640>
+<PARAM Name=HEIGHT Value=480>
+<PARAM Name=EMBEDDED Value=YES>
+<PARAM Name=X-UI-LBX Value=YES>
+<PARAM Name=X-UI-INPUT-METHOD VALUE=YES;foo>
+<PARAM Name=X-AUTH VALUE=MIT-MAGIC-COOKIE-1>
diff --git a/htdocs/excel.html b/htdocs/excel.html
new file mode 100644
index 0000000..d5ce718
--- /dev/null
+++ b/htdocs/excel.html
@@ -0,0 +1,23 @@
+<!--$Xorg: excel.html,v 1.3 2000/08/17 19:54:58 cpqbld Exp $-->
+<html>
+<head>
+ <title>X Applications on the Web - Excel demo page. </title>
+</head>
+
+<body>
+<a name="begin">
+<h1> X Applications on the Web - Excel <br> Demo page. </h1>
+
+<hr>
+
+Here is a simple demo of the RX plug-in used to launch Microsoft Excel
+over the web. In addition, if you are using Netscape Navigator with
+the embedding capabable plug-in, Excel should appear embedded
+within this page.
+
+<p>
+When embedded, Excel's window should be here:
+<EMBED version=1.0 type=application/x-rx src="excel.rx" width=640 height=480>
+
+</body>
+</html>
diff --git a/htdocs/xclock b/htdocs/xclock
new file mode 100644
index 0000000..86d21fa
--- /dev/null
+++ b/htdocs/xclock
@@ -0,0 +1,11 @@
+<!-- $Xorg: xclock,v 1.3 2000/08/17 19:54:58 cpqbld Exp $ -->
+<PARAM Name=VERSION Value=1.0>
+<PARAM Name=REQUIRED-SERVICES Value=UI>
+<PARAM Name=UI Value=X>
+<PARAM Name=ACTION Value=http://WEBSERVER/cgi-bin/xclock.pl>
+<PARAM Name=WIDTH Value=200>
+<PARAM Name=HEIGHT Value=200>
+<PARAM Name=EMBEDDED Value=YES>
+<PARAM Name=X-UI-INPUT-METHOD VALUE=YES;foo>
+<PARAM Name=X-UI-LBX Value=YES>
+<PARAM Name=X-AUTH VALUE=MIT-MAGIC-COOKIE-1>
diff --git a/htdocs/xclock.html b/htdocs/xclock.html
new file mode 100644
index 0000000..024ec25
--- /dev/null
+++ b/htdocs/xclock.html
@@ -0,0 +1,23 @@
+<!--$Xorg: xclock.html,v 1.3 2000/08/17 19:54:58 cpqbld Exp $-->
+<html>
+<head>
+ <title>X Applications on the Web - xclock demo page. </title>
+</head>
+
+<body>
+<a name="begin">
+<h1> X Applications on the Web - xclock <br> Demo page. </h1>
+
+<hr>
+
+Here is a simple demo of the RX plug-in used to launch the xclock program
+over the web. In addition, if you are using Netscape Navigator with
+the embedding capabable plug-in, the xclock program should appear embedded
+within this page.
+
+<p>
+When embedded, xclock's window should be here:
+<EMBED version=1.0 type=application/x-rx src="xclock.rx" width=200 height=200>
+
+</body>
+</html>
diff --git a/htdocs/xload b/htdocs/xload
new file mode 100644
index 0000000..8e01606
--- /dev/null
+++ b/htdocs/xload
@@ -0,0 +1,11 @@
+<!-- $Xorg: xload,v 1.3 2000/08/17 19:54:59 cpqbld Exp $ -->
+<PARAM Name=VERSION Value=1.0>
+<PARAM Name=REQUIRED-SERVICES Value=UI>
+<PARAM Name=UI Value=X>
+<PARAM Name=ACTION Value=http://WEBSERVER/cgi-bin/xload.pl>
+<PARAM Name=WIDTH Value=200>
+<PARAM Name=HEIGHT Value=150>
+<PARAM Name=EMBEDDED Value=YES>
+<PARAM Name=X-UI-INPUT-METHOD VALUE=YES;foo>
+<PARAM Name=X-UI-LBX Value=YES>
+<PARAM Name=X-AUTH VALUE=MIT-MAGIC-COOKIE-1>
diff --git a/htdocs/xload.html b/htdocs/xload.html
new file mode 100644
index 0000000..362c4b9
--- /dev/null
+++ b/htdocs/xload.html
@@ -0,0 +1,23 @@
+<!--$Xorg: xload.html,v 1.3 2000/08/17 19:54:59 cpqbld Exp $-->
+<html>
+<head>
+ <title>X Applications on the Web - Demo page. </title>
+</head>
+
+<body>
+<a name="begin">
+<h1> X Applications on the Web <br> Demo page. </h1>
+
+<hr>
+
+Here is a simple demo of the RX plug-in used to launch the xload program
+over the web. In addition, if you are using Netscape Navigator with
+the embedding capabable plug-in, the xload program should appear embedded
+within this page.
+
+<p>
+When embedded, xload's window should be here:
+<EMBED version=1.0 type=application/x-rx src="xload.rx" width=100 height=100>
+
+</body>
+</html>
diff --git a/libxplugin/README b/libxplugin/README
new file mode 100644
index 0000000..775db40
--- /dev/null
+++ b/libxplugin/README
@@ -0,0 +1,6 @@
+$Xorg: README,v 1.3 2000/08/17 19:54:59 cpqbld Exp $
+
+This library exists solely to get the new extensions linked into the
+Netscape Plug-in. Once vendors start shipping R7 versions of libXext.so
+then there will be no need for this library.
+
diff --git a/plugin/Global.c b/plugin/Global.c
new file mode 100644
index 0000000..3372f48
--- /dev/null
+++ b/plugin/Global.c
@@ -0,0 +1,97 @@
+/* $Xorg: Global.c,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxPlugin.h"
+
+#include <stdio.h>
+
+/* global variable to handle data global to all instances */
+PluginGlobal RxGlobal;
+
+
+NPError
+NPP_Initialize(void)
+{
+#ifdef PLUGIN_TRACE
+ (void) fprintf (stderr, "%s\n", "NPP_Initialize");
+#endif
+ RxGlobal.has_appgroup = RxUndef;
+ RxGlobal.has_real_server = RxUndef;
+ RxGlobal.has_ui_lbx = RxUndef;
+ RxGlobal.has_print_lbx = RxUndef;
+ RxGlobal.has_printer = RxUndef;
+ RxGlobal.has_ui_fwp = RxUndef;
+ RxGlobal.has_print_fwp = RxUndef;
+ RxGlobal.pdpy_name = NULL;
+ RxGlobal.printer_name = NULL;
+ RxGlobal.fwp_dpyname = NULL;
+ RxGlobal.pfwp_dpyname = NULL;
+ RxGlobal.ice_conn = NULL;
+ RxGlobal.pm_opcode = 0;
+ RxGlobal.get_prefs = True;
+ RxGlobal.dpy = NULL;
+ RxGlobal.pdpy = NULL;
+ RxGlobal.wm_delete_window = 0;
+ RxGlobal.wm_protocols = 0;
+ return NPERR_NO_ERROR;
+}
+
+void
+NPP_Shutdown(void)
+{
+#ifdef PLUGIN_TRACE
+ (void) fprintf (stderr, "%s\n", "NPP_Shutdown");
+#endif
+/*
+ * Netscape doesn't try to cache plug-ins at all, and it unloads
+ * the plug-in immediately after the last instance that uses it is
+ * gone. So if you load a page that uses the plug-in, and then reload
+ * the page, Netscape will unload the plug-in and call NPP_Shutdown.
+ * Then it will reload the plug-in and call NPP_Initialize. And when
+ * it reloads it, zeroes the plug-in's DATA segment so even if we
+ * tried to be smart in NPP_Initialize, Netscape would defeat us
+ * anyway.
+ */
+ if (RxGlobal.pdpy_name != NULL)
+ NPN_MemFree(RxGlobal.pdpy_name);
+ if (RxGlobal.printer_name != NULL)
+ NPN_MemFree(RxGlobal.printer_name);
+ if (RxGlobal.fwp_dpyname != NULL)
+ NPN_MemFree(RxGlobal.fwp_dpyname);
+ if (RxGlobal.pfwp_dpyname != NULL)
+ NPN_MemFree(RxGlobal.pfwp_dpyname);
+ if (RxGlobal.get_prefs == False)
+ FreePreferences(&RxGlobal.prefs);
+ if (RxGlobal.pdpy != NULL && RxGlobal.pdpy != RxGlobal.dpy)
+ XCloseDisplay(RxGlobal.pdpy);
+ if (RxGlobal.ice_conn) {
+ IceProtocolShutdown (RxGlobal.ice_conn, RxGlobal.pm_opcode);
+ IceCloseConnection (RxGlobal.ice_conn);
+ }
+}
diff --git a/plugin/Main.c b/plugin/Main.c
new file mode 100644
index 0000000..913f235
--- /dev/null
+++ b/plugin/Main.c
@@ -0,0 +1,630 @@
+/* $Xorg: Main.c,v 1.5 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+/*
+ * RX plug-in module based on the UnixTemplate file provided by Netcape.
+ */
+
+/* -*- Mode: C; tab-width: 4; -*- */
+/******************************************************************************
+ * Copyright 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 <ctype.h>
+#include <stdlib.h>
+#include "RxPlugin.h"
+#include "X11/StringDefs.h"
+
+
+/***********************************************************************
+ * Utility functions to deal with list of arguments
+ ***********************************************************************/
+
+/* Free list of arguments */
+static void
+FreeArgs(char* argn[], char* argv[], int argc)
+{
+ int i;
+ if (argc != 0) {
+ for (i = 0; i < argc; i++) {
+ NPN_MemFree(argn[i]);
+ NPN_MemFree(argv[i]);
+ }
+ NPN_MemFree(argn);
+ NPN_MemFree(argv);
+ }
+}
+
+/* Copy list 2 to list 1 */
+static NPError
+CopyArgs(char** argn1[], char** argv1[], int16* argc1,
+ char* argn2[], char* argv2[], int16 argc2)
+{
+ char **argn, **argv;
+ int i;
+
+ argn = (char **)NPN_MemAlloc(sizeof(char *) * argc2);
+ if (!argn)
+ return NPERR_OUT_OF_MEMORY_ERROR;
+ argv = (char **)NPN_MemAlloc(sizeof(char *) * argc2);
+ if (!argv) {
+ NPN_MemFree(argn);
+ return NPERR_OUT_OF_MEMORY_ERROR;
+ }
+ memset(argn, 0, sizeof(char *) * argc2);
+ memset(argv, 0, sizeof(char *) * argc2);
+ for (i = 0; i < argc2; i++) {
+ char *name, *value;
+ name = (char *)NPN_MemAlloc(strlen(argn2[i]) + 1);
+ if (!name) {
+ FreeArgs(argn, argv, i - 1);
+ return NPERR_OUT_OF_MEMORY_ERROR;
+ }
+ strcpy(name, argn2[i]);
+ value = (char *)NPN_MemAlloc(strlen(argv2[i]) + 1);
+ if (!value) {
+ NPN_MemFree(name);
+ FreeArgs(argn, argv, i - 1);
+ return NPERR_OUT_OF_MEMORY_ERROR;
+ }
+ strcpy(value, argv2[i]);
+ argn[i] = name;
+ argv[i] = value;
+ }
+ *argc1 = argc2;
+ *argn1 = argn;
+ *argv1 = argv;
+
+ return NPERR_NO_ERROR;
+}
+
+
+char*
+NPP_GetMIMEDescription(void)
+{
+ return(PLUGIN_MIME_DESCRIPTION);
+}
+
+NPError
+NPP_GetValue(void *future, NPPVariable variable, void *value)
+{
+ NPError err = NPERR_NO_ERROR;
+
+ switch (variable) {
+ case NPPVpluginNameString:
+ *((char **)value) = PLUGIN_NAME;
+ break;
+ case NPPVpluginDescriptionString:
+ *((char **)value) = PLUGIN_DESCRIPTION;
+ break;
+ default:
+ err = NPERR_GENERIC_ERROR;
+ }
+ return err;
+}
+
+jref
+NPP_GetJavaClass()
+{
+ return NULL;
+}
+
+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_OUT_OF_MEMORY_ERROR;
+
+ This->instance = instance;
+ if (argc != 0) { /* copy the arguments list */
+ if (CopyArgs(&This->argn, &This->argv, &This->argc,
+ argn, argv, argc) == NPERR_OUT_OF_MEMORY_ERROR) {
+ NPN_MemFree(This);
+ return NPERR_OUT_OF_MEMORY_ERROR;
+ }
+ } else {
+ This->argc = 0;
+ This->argn = This->argv = NULL;
+ }
+ This->parse_reply = 0;
+ This->status = 0;
+ This->dont_reparent = RxUndef;
+ This->state = LOADING;
+ This->status_widget = NULL;
+ This->plugin_widget = NULL;
+ RxpNew(This);
+
+ 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) {
+ RxpDestroy(This);
+ if (This->argc != 0)
+ FreeArgs(This->argn, This->argv, This->argc);
+ if (This->query != NULL)
+ NPN_MemFree(This->query);
+ NPN_MemFree(instance->pdata);
+ instance->pdata = NULL;
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+
+/* private buffer structure */
+typedef struct {
+ char *buf;
+ uint32 size;
+} RxStreamBuf;
+
+NPError
+NPP_NewStream(NPP instance,
+ NPMIMEType type,
+ NPStream *stream,
+ NPBool seekable,
+ uint16 *stype)
+{
+ PluginInstance* This;
+ RxStreamBuf *streambuf;
+
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ This = (PluginInstance*) instance->pdata;
+
+ if (This->parse_reply != 0)
+ return NPERR_NO_ERROR;
+
+ /* malloc structure to store RX document */
+ streambuf = (RxStreamBuf *) NPN_MemAlloc(sizeof(RxStreamBuf));
+ if (streambuf == NULL)
+ return NPERR_OUT_OF_MEMORY_ERROR;
+
+ streambuf->buf = NULL;
+ streambuf->size = 0;
+ stream->pdata = (void *) streambuf;
+
+ 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 *buf)
+{
+ PluginInstance* This;
+
+ if (instance == NULL)
+ return len;
+
+ This = (PluginInstance*) instance->pdata;
+
+ if (This->parse_reply == 0) {
+ /* copy stream buffer to private storage, concatenating if necessary:
+ * since Netscape doesn't provide an NPN_MemRealloc we must do
+ * a new malloc, copy, and free :-(
+ */
+ RxStreamBuf *streambuf = (RxStreamBuf *) stream->pdata;
+ uint32 size = streambuf->size;
+ char *cbuf;
+
+ /* if first chunk add 1 for null terminating character */
+ if (size == 0)
+ size++;
+
+ size += len;
+ cbuf = (char *) NPN_MemAlloc(size);
+ if (cbuf == NULL)
+ return -1;
+ if (streambuf->size != 0) {
+ memcpy(cbuf, streambuf->buf, streambuf->size - 1);
+ memcpy(cbuf + streambuf->size - 1, ((char *)buf), len);
+ /* free old storage */
+ NPN_MemFree((void *) streambuf->buf);
+ } else
+ memcpy(cbuf, ((char *)buf), len);
+ cbuf[size - 1] = '\0';
+ /* store new buffer */
+ streambuf->buf = cbuf;
+ streambuf->size = size;
+#ifdef PLUGIN_TRACE
+ fprintf(stderr, "write %s:\n", PLUGIN_NAME);
+ fwrite(buf, len, 1, stderr);
+ fprintf(stderr, "\n");
+#endif
+ } else {
+ int l = len;
+ if (This->parse_reply == 1) {
+ /* look for status line */
+ char *ptr = strchr(buf, '\n');
+ if (ptr != NULL && isdigit(((char *)buf)[0])) {
+ This->status = (short) atoi((char *)buf);
+ /* skip status line */
+ l -= ptr - (char *)buf + 1;
+ buf = ptr + 1;
+ if (This->status != 0) {
+ fprintf(stderr,
+ "%s: Application failed to start properly\n",
+ PLUGIN_NAME);
+ }
+ }
+ This->parse_reply = 2;
+ }
+ /* simply prints out whatever we get, and let netscape display it
+ in a dialog */
+ fwrite(buf, l, 1, stderr);
+ }
+
+ return len; /* The number of bytes accepted */
+}
+
+void
+StartApplication(PluginInstance* This)
+{
+ NPError err;
+
+#ifndef NO_STARTING_STATE
+ RxpSetStatusWidget(This, STARTING);
+#else
+ RxpSetStatusWidget(This, RUNNING);
+#endif
+
+ /* perform GET request
+ * throwing away the response.
+ */
+ err = NPN_GetURL(This->instance, This->query, NULL);
+ This->parse_reply = 1; /* we want to print out the answer */
+}
+
+void
+StartCB(Widget widget, XtPointer client_data, XtPointer call_data)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+#if 0
+ XtUnmapWidget(widget);
+#endif
+ XtDestroyWidget(widget);
+ StartApplication(This);
+}
+
+#if defined(linux) || (defined(sun) && !defined(SVR4))
+/* deficient linux linker semantics */
+static WidgetClass xmLabelGadgetClass;
+static WidgetClass xmPushButtonGadgetClass;
+#else
+extern WidgetClass xmLabelGadgetClass;
+extern WidgetClass xmPushButtonGadgetClass;
+#endif
+
+void
+RxpSetStatusWidget(PluginInstance* This, PluginState state)
+{
+ Arg args[5];
+ int n;
+ XrmDatabase db;
+ char* return_type;
+ XrmValue return_value;
+
+ if (This->status_widget) {
+ XtDestroyWidget(This->status_widget);
+ This->status_widget = NULL;
+ }
+ if (This->plugin_widget == NULL)
+ return;
+
+ db = XtDatabase (XtDisplay (This->plugin_widget));
+
+ if (!XrmGetResource (db, "RxPlugin_BeenHere", "RxPlugin_BeenHere",
+ &return_type, &return_value)) {
+
+ XrmPutStringResource (&db, "*Rx_Loading.labelString", "Loading...");
+ XrmPutStringResource (&db, "*Rx_Starting.labelString", "Starting...");
+ XrmPutStringResource (&db, "*Rx_Start.labelString", "Start");
+ XrmPutStringResource (&db, "RxPlugin_BeenHere", "YES");
+ }
+#if defined(linux) || (defined(sun) && !defined(SVR4))
+ /*
+ lame loader semantics mean we have to go fishing around to
+ come up with widget class records so we can create some widgets.
+
+ Names of widgets changed in 4.x, so look for those names too
+ for linux.
+
+ If Microsoft ever does IE for Linux we'll have to figure out
+ those names too.
+ */
+ if (xmLabelGadgetClass == NULL) {
+ Widget w;
+
+ w = XtNameToWidget (This->toplevel_widget, "*topLeftArea.urlLabel");
+ if (w == NULL)
+ w = XtNameToWidget (This->toplevel_widget, "*urlBar.urlLocationLabel");
+ xmLabelGadgetClass = XtClass (w);
+ w = XtNameToWidget (This->toplevel_widget, "*toolBar.abort");
+ if (w == NULL)
+ w = XtNameToWidget (This->toplevel_widget, "*PopupMenu.openCustomUrl");
+ xmPushButtonGadgetClass = XtClass (w);
+ }
+#endif
+
+ n = 0;
+ XtSetArg(args[n], "shadowThickness", 1); n++;
+ XtSetArg(args[n], XtNwidth, This->width); n++;
+ XtSetArg(args[n], XtNheight, This->height); n++;
+ if (state == LOADING) {
+ /* create a label */
+ This->status_widget =
+ XtCreateManagedWidget("Rx_Loading", xmLabelGadgetClass,
+ This->plugin_widget, args, n);
+#ifndef NO_STARTING_STATE
+ } else if (state == STARTING) {
+ /* create a label */
+ This->status_widget =
+ XtCreateManagedWidget("Rx_Starting", xmLabelGadgetClass,
+ This->plugin_widget, args, n);
+#endif
+ } else if (state == WAITING) {
+ /* create a push button */
+ This->status_widget =
+ XtCreateManagedWidget("Rx_Start", xmPushButtonGadgetClass,
+ This->plugin_widget, args, n);
+ XtAddCallback(This->status_widget, "activateCallback", StartCB, This);
+ } else if (state == RUNNING) {
+ /* nothing else to be done */
+ }
+ This->state = state;
+}
+
+
+NPError
+NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
+{
+ PluginInstance* This;
+ RxStreamBuf *streambuf = (RxStreamBuf *) stream->pdata;
+ char **rx_argn, **rx_argv;
+ int rx_argc;
+ RxParams params;
+ RxReturnParams return_params;
+ NPError status = NPERR_NO_ERROR;
+
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ This = (PluginInstance*) instance->pdata;
+
+ if (This->parse_reply != 0) {
+ fflush(stderr);
+ if (This->status != 0) /* if error occured change widget status */
+ RxpSetStatusWidget(This, WAITING);
+ return NPRES_DONE;
+ }
+
+ memset(&params, 0, sizeof(RxParams));
+ memset(&return_params, 0, sizeof(RxReturnParams));
+ rx_argc = 0;
+
+ if (reason != NPRES_DONE) {
+ status = NPERR_GENERIC_ERROR;
+ goto exit;
+ }
+
+ /* read params from stream */
+ if (RxReadParams(streambuf->buf, &rx_argn, &rx_argv, &rx_argc) != 0) {
+ fprintf(stderr, "%s: invalid file %s\n", PLUGIN_NAME, stream->url);
+ status = NPERR_GENERIC_ERROR;
+ goto exit;
+ }
+
+ RxInitializeParams(&params);
+
+ /* parse RX params */
+ if (RxParseParams(rx_argn, rx_argv, rx_argc, &params, 0) != 0) {
+ fprintf(stderr, "%s: invalid RX params\n", PLUGIN_NAME);
+ status = NPERR_GENERIC_ERROR;
+ goto exit;
+ }
+
+ /* parse HTML params */
+ if (RxParseParams(This->argn, This->argv, This->argc, &params, 0) != 0) {
+ fprintf(stderr, "%s: invalid HTML params\n", PLUGIN_NAME);
+ status = NPERR_GENERIC_ERROR;
+ goto exit;
+ }
+
+ /* set up return parameters */
+ if (RxpProcessParams(This, &params, &return_params) != 0) {
+ fprintf(stderr, "%s: failed to process params\n", PLUGIN_NAME);
+ status = NPERR_GENERIC_ERROR;
+ goto exit;
+ }
+
+ /* make query */
+ This->query = RxBuildRequest(&return_params);
+ if (This->query == NULL) {
+ fprintf(stderr, "%s: failed to make query\n", PLUGIN_NAME);
+ status = NPERR_GENERIC_ERROR;
+ goto exit;
+ }
+
+ if (params.auto_start != RxFalse) /* default is auto start */
+ StartApplication(This);
+ else
+ RxpSetStatusWidget(This, WAITING);
+
+exit:
+ /* free all forms of params */
+ FreeArgs(rx_argn, rx_argv, rx_argc);
+ FreeArgs(This->argn, This->argv, This->argc);
+ This->argc = 0;
+ RxFreeParams(&params);
+ RxFreeReturnParams(&return_params);
+ /* free private storage */
+ if (streambuf->buf != NULL)
+ NPN_MemFree(streambuf->buf);
+ NPN_MemFree(stream->pdata);
+
+ return status;
+}
+
+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;
+ }
+ }
+}
diff --git a/plugin/NewNDest.c b/plugin/NewNDest.c
new file mode 100644
index 0000000..bee8bf3
--- /dev/null
+++ b/plugin/NewNDest.c
@@ -0,0 +1,71 @@
+/* $Xorg: NewNDest.c,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxPlugin.h"
+
+/***********************************************************************
+ * Functions to init and free private members
+ ***********************************************************************/
+
+void
+RxpNew(PluginInstance *This)
+{
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "RxpNew");
+#endif
+ This->x_ui_auth_id = 0;
+ This->x_print_auth_id = 0;
+ This->app_group = 0;
+ This->toplevel_widget = NULL;
+ This->client_windows = NULL;
+ This->nclient_windows = 0;
+}
+
+void
+RxpDestroy(PluginInstance *This)
+{
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "RxpDestroy");
+#endif
+ if (RxGlobal.dpy != NULL) {
+ RxpWmDelWinHandler (This->toplevel_widget, (XtPointer) This, NULL, NULL);
+ RxpRemoveDestroyCallback(This);
+ if (This->x_ui_auth_id != 0)
+ XSecurityRevokeAuthorization(RxGlobal.dpy, This->x_ui_auth_id);
+ if (This->app_group != None)
+ XagDestroyApplicationGroup (RxGlobal.dpy, This->app_group);
+ RxpTeardown (This);
+ }
+ if (RxGlobal.pdpy != NULL) {
+ if (This->x_print_auth_id != 0)
+ XSecurityRevokeAuthorization(RxGlobal.pdpy, This->x_print_auth_id);
+ }
+ if (This->client_windows) NPN_MemFree (This->client_windows);
+ RxpNew (This);
+}
diff --git a/plugin/PProcess.c b/plugin/PProcess.c
new file mode 100644
index 0000000..d2f2faf
--- /dev/null
+++ b/plugin/PProcess.c
@@ -0,0 +1,1017 @@
+/* $Xorg: PProcess.c,v 1.6 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxPlugin.h"
+#include "XUrls.h"
+#include "XAuth.h"
+#include "XDpyName.h"
+#include "Prefs.h"
+#include <X11/StringDefs.h>
+
+#include <limits.h> /* for MAXHOSTNAMELEN */
+/* and in case we didn't get it from the headers above */
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN 256
+#endif
+
+#ifdef XUSE_XTREGISTERWINDOW
+extern void _XtRegisterWindow (Window window, Widget widget);
+#define XtRegisterDrawable(d,win,wid) _XtRegisterWindow(win,wid)
+extern void _XtUnregisterWindow (Window window, Widget widget);
+#define UnregisterDrawable(win,wid) _XtUnregisterWindow(win,wid)
+#else
+#define UnregisterDrawable(win,wid) XtUnregisterDrawable(XtDisplay(wid),win)
+#endif
+
+/* timeout for authorizations */
+#define DEFAULT_TIMEOUT 300
+#define NO_TIMEOUT 0
+
+/***********************************************************************
+ * Try and do something sensible about window geometry
+ ***********************************************************************/
+static void
+GetWindowGeometry(
+ Display* dpy,
+ Window win,
+ Position* x,
+ Position* y,
+ Dimension* width,
+ Dimension* height,
+ Dimension* border_width,
+ /* the following doesn't really belong here but it saves us from doing
+ another XGetWindowAttributes later on */
+ Colormap *cmap)
+{
+ long mask;
+ XSizeHints* sizehints = XAllocSizeHints();
+ XWindowAttributes wattr;
+
+ if (XGetWindowAttributes (dpy, win, &wattr)) {
+ *x = wattr.x;
+ *y = wattr.y;
+ *width = wattr.width;
+ *height = wattr.height;
+ *border_width = wattr.border_width;
+ *cmap = wattr.colormap;
+ }
+ if (sizehints) {
+ XGetWMNormalHints (dpy, win, sizehints, &mask);
+
+ if (mask & USPosition|PPosition) {
+ *x = sizehints->x;
+ *y = sizehints->y;
+ *width = sizehints->width;
+ *height = sizehints->height;
+ XFree ((char*) sizehints);
+ return;
+ }
+ XFree ((char*) sizehints);
+ }
+ *x = 0;
+ *y = 0;
+ *width = 0;
+ *height = 0;
+}
+
+/***********************************************************************
+ * a set of utility functions to manipulate Windows lists
+ ***********************************************************************/
+static Bool
+IsInWinList(Window *list, int count, Window win)
+{
+ int i;
+ for (i = 0; i < count; i++, list++)
+ if (*list == win)
+ return True;
+ return False;
+}
+
+static void
+AppendToWinList(Window **new_list, int *new_count,
+ Window *list, int count, Window win)
+{
+ *new_count = count + 1;
+ *new_list = (Window*) malloc(sizeof(Window) * *new_count);
+ memcpy(*new_list, list, sizeof(Window) * count);
+ (*new_list)[count] = win;
+}
+
+static void
+PrependToWinList(Window **new_list, int *new_count,
+ Window *list, int count, Window win)
+{
+ *new_count = count + 1;
+ *new_list = (Window*) malloc(sizeof(Window) * *new_count);
+ (*new_list)[0] = win;
+ memcpy(*new_list + 1, list, sizeof(Window) * count);
+}
+
+/* rotate the list so the given window is at the beginning of it */
+static void
+SetFirstWinList(Window *list, int count, Window win)
+{
+ int i;
+
+ /* look for the given window starting from the end */
+ list += count - 1;
+ for (i = 0; i < count; i++, list--)
+ if (*list == win)
+ break;
+ if (i < count) { /* when we found it rotate from there */
+ /* shift every element to the right */
+ for (i++; i < count; i++) {
+ list--;
+ list[1] = list[0];
+ }
+ /* and set the first one */
+ *list = win;
+ }
+}
+
+/* rotate the list so the given window which should be the first item is
+ at the end of it */
+static void
+SetLastWinList(Window *list, int count, Window win)
+{
+ if (*list == win) {
+ int i;
+ /* shift every element to the left */
+ for (i = 0; i < count - 1; i++, list++)
+ list[0] = list[1];
+ /* and set the last one */
+ *list = win;
+ }
+}
+
+static void
+RemoveFromWinList(Window **wlist, int *count, Window win)
+{
+ Window *list = *wlist;
+ int i;
+ /* look for the window to remove */
+ for (i = 0; i < *count; i++, list++)
+ if (*list == win) {
+ (*count)--;
+ break;
+ }
+ /* then simply shift following elements to the left */
+ for (; i < *count; i++, list++)
+ list[0] = list[1];
+}
+
+static void
+ConcatWinLists(Window **list, int *count,
+ Window *list1, int count1,
+ Window *list2, int count2)
+{
+ *count = count1 + count2;
+ *list = (Window*) malloc(sizeof(Window) * *count);
+ memcpy(*list, list1, sizeof(Window) * count1);
+ memcpy(*list + count1, list2, sizeof(Window) * count2);
+}
+
+static void
+SubstractWinLists(Window **wlist, int *count,
+ Window *list1, int count1)
+{
+ Window *list = *wlist;
+ int i, j;
+ /* look for the beginning of the list to remove */
+ for (i = 0; i < *count; i++, list++)
+ if (*list == *list1)
+ break;
+ /* skip the list to remove stopping at the end of one of the lists
+ or at the first alien element */
+ for (j = 0; j < count1 && i + j < *count; j++, list1++)
+ if (list[j] != *list1)
+ break;
+ /* then shift following elements */
+ *count -= j;
+ for (; i < *count; i++, list++)
+ list[0] = list[j];
+}
+
+/***********************************************************************
+ * Add window to the WM_COLORMAP_WINDOWS property on the Netscape
+ * toplevel widget if necessary
+ ***********************************************************************/
+static void
+SetWMColormap(PluginInstance* This, Window win)
+{
+ int i;
+ Colormap top_cmap;
+ Arg arg;
+
+ /* get window's record */
+ for (i = 0; i < This->nclient_windows; i++)
+ if ((This->client_windows[i].win = win))
+ break;
+
+ if (i == This->nclient_windows)
+ return;
+
+ /* if window's colormap is different from toplevel's one set property */
+ XtSetArg(arg, XtNcolormap, &top_cmap);
+ XtGetValues(This->toplevel_widget, &arg, 1);
+ if (This->client_windows[i].colormap != top_cmap) {
+ Window *cur_list;
+ int cur_count = 0;
+
+ /* if there is already a non empty list we need to update it */
+ if (XGetWMColormapWindows(RxGlobal.dpy, XtWindow(This->toplevel_widget),
+ &cur_list, &cur_count) == True &&
+ cur_count != 0) {
+
+ if (IsInWinList(cur_list, cur_count, win)) {
+ /* window is already in the list just move it in first place */
+ SetFirstWinList(cur_list, cur_count, win);
+ XSetWMColormapWindows(RxGlobal.dpy,
+ XtWindow(This->toplevel_widget),
+ cur_list, cur_count);
+ } else {
+ /* window is not in the list add it in first place */
+ Window *new_list;
+ int new_count;
+
+ PrependToWinList(&new_list, &new_count,
+ cur_list, cur_count, win);
+ XSetWMColormapWindows(RxGlobal.dpy,
+ XtWindow(This->toplevel_widget),
+ new_list, new_count);
+ free(new_list);
+ }
+ } else { /* no list yet so lets make one */
+ Window list[2];
+
+ list[0] = win;
+ list[1] = XtWindow(This->toplevel_widget);
+ XSetWMColormapWindows(RxGlobal.dpy, XtWindow(This->toplevel_widget),
+ list, 2);
+ }
+ if (cur_count != 0)
+ XFree(cur_list);
+ }
+}
+
+/***********************************************************************
+ * Move window at the end of the WM_COLORMAP_WINDOWS property list on
+ * the Netscape toplevel widget
+ ***********************************************************************/
+static void
+UnsetWMColormap(PluginInstance* This, Window win)
+{
+ Window *list;
+ int count = 0;
+
+ if (XGetWMColormapWindows(RxGlobal.dpy, XtWindow(This->toplevel_widget),
+ &list, &count) == True && count != 0) {
+ SetLastWinList(list, count, win);
+ XSetWMColormapWindows(RxGlobal.dpy, XtWindow(This->toplevel_widget),
+ list, count);
+ }
+ if (count != 0)
+ XFree(list);
+}
+
+/***********************************************************************
+ * Remove window from the WM_COLORMAP_WINDOWS property on the Netscape
+ * toplevel widget
+ ***********************************************************************/
+static void
+ResetWMColormap(PluginInstance* This, Window win)
+{
+ Window *list;
+ int count = 0;
+
+ if (XGetWMColormapWindows(RxGlobal.dpy, XtWindow(This->toplevel_widget),
+ &list, &count) == True && count != 0) {
+ RemoveFromWinList(&list, &count, win);
+
+ if (count > 1)
+ XSetWMColormapWindows(RxGlobal.dpy, XtWindow(This->toplevel_widget),
+ list, count);
+ else { /* remove list when it becomes useless */
+ Atom prop;
+
+ prop = XInternAtom (RxGlobal.dpy, "WM_COLORMAP_WINDOWS", False);
+ XDeleteProperty(RxGlobal.dpy, XtWindow(This->toplevel_widget), prop);
+ }
+ }
+ if (count != 0)
+ XFree(list);
+}
+
+/***********************************************************************
+ * Event Handler to reparent client window under plugin window
+ ***********************************************************************/
+/* static */ void
+SubstructureRedirectHandler (
+ Widget widget,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean* cont)
+{
+ windowrec* new_list;
+ PluginInstance* This = (PluginInstance*) client_data;
+
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "SubstructureRedirectHandler");
+ fprintf (stderr, "This: 0x%x\n", This);
+#endif
+
+ switch (event->type) {
+ case ConfigureRequest:
+ {
+ XWindowChanges config;
+ config.x = event->xconfigurerequest.x;
+ config.y = event->xconfigurerequest.y;
+ config.width = event->xconfigurerequest.width;
+ config.height = event->xconfigurerequest.height;
+ config.border_width = event->xconfigurerequest.border_width;
+ config.sibling = event->xconfigurerequest.above;
+ config.stack_mode = event->xconfigurerequest.detail;
+#if 0
+ fprintf (stderr, "configuring at %dx%d+%d+%d\n",
+ config.width, config.height, config.x, config.y);
+#endif
+ XConfigureWindow (RxGlobal.dpy,
+ event->xconfigurerequest.window,
+ event->xconfigurerequest.value_mask,
+ &config);
+ }
+ break;
+
+ case MapRequest:
+
+ RxpSetStatusWidget(This, RUNNING);
+
+ {
+ Window for_win;
+ int i;
+
+ if (XGetTransientForHint (RxGlobal.dpy, event->xmaprequest.window,
+ &for_win)) {
+ for (i = 0; i < This->nclient_windows; i++)
+ if (for_win == This->client_windows[i].win)
+ XMapWindow (RxGlobal.dpy, event->xmaprequest.window);
+ return;
+ }
+ }
+ new_list = (windowrec*)
+ NPN_MemAlloc (sizeof (windowrec) * (This->nclient_windows + 1));
+ if (new_list) {
+ Position x, y;
+ Dimension width, height;
+ Dimension border_width;
+ Colormap cmap;
+ int n;
+ Atom* wm_proto;
+ windowrec* wp;
+ Window destwin = XtWindow (This->plugin_widget);
+
+ This->nclient_windows++;
+ if (This->nclient_windows > 1)
+ memcpy ((void*) new_list, (void*) This->client_windows,
+ (This->nclient_windows - 1) * sizeof (windowrec));
+ if (This->client_windows)
+ NPN_MemFree (This->client_windows);
+ This->client_windows = new_list;
+
+ x = y = 0;
+ width = height = border_width = 0;
+ GetWindowGeometry (RxGlobal.dpy, event->xmaprequest.window,
+ &x, &y, &width, &height, &border_width, &cmap);
+
+ wp = &This->client_windows[This->nclient_windows - 1];
+ wp->win = event->xmaprequest.window;
+ wp->x = x; wp->y = y;
+ wp->width = width; wp->height = height;
+ wp->border_width = border_width;
+ wp->flags = RxpMapped;
+ wp->colormap = cmap;
+
+ if (XGetWMProtocols (RxGlobal.dpy, wp->win, &wm_proto, &n)) {
+ int i;
+ Atom* ap;
+
+ for (i = 0, ap = wm_proto; i < n; i++, ap++) {
+ if (*ap == RxGlobal.wm_delete_window)
+ wp->flags |= RxpWmDelWin;
+ }
+ if (wm_proto) XFree ((char*) wm_proto);
+ }
+
+ XSelectInput(RxGlobal.dpy, wp->win,
+ EnterWindowMask | LeaveWindowMask);
+ XtRegisterDrawable (RxGlobal.dpy, wp->win, This->plugin_widget);
+ XReparentWindow (RxGlobal.dpy, wp->win, destwin, wp->x, wp->y);
+ XMapWindow (RxGlobal.dpy, wp->win);
+ }
+ break;
+ }
+}
+
+/***********************************************************************
+ * Event Handler to forward WM_DELETE_WINDOW events to the client windows
+ ***********************************************************************/
+void
+RxpWmDelWinHandler (
+ Widget widget,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean* cont)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+ int i;
+
+ if (event == NULL ||
+ (event->type == ClientMessage &&
+ event->xclient.message_type == RxGlobal.wm_protocols &&
+ event->xclient.data.l[0] == RxGlobal.wm_delete_window)) {
+ for (i = 0; i < This->nclient_windows; i++) {
+ if (This->client_windows[i].flags & RxpWmDelWin) {
+ XClientMessageEvent ev;
+
+ ev.type = ClientMessage;
+ ev.window = This->client_windows[i].win;
+ ev.message_type = RxGlobal.wm_protocols;
+ ev.format = 32;
+ ev.data.l[0] = RxGlobal.wm_delete_window;
+ ev.data.l[1] = XtLastTimestampProcessed (XtDisplay (widget));
+ XSendEvent (RxGlobal.dpy, ev.window, FALSE, 0L, (XEvent*) &ev);
+ }
+ }
+ }
+}
+
+/***********************************************************************
+ * Event Handler to forward ConfigureNotify events to the client windows
+ ***********************************************************************/
+static void
+StructureNotifyHandler (
+ Widget widget,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean* cont)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "StructureNotifyHandler");
+#endif
+
+ switch (event->type) {
+
+ /*
+ * For the testplugin, which uses a ScrolledWindow, the clipped
+ * window, i.e. This->plugin, is "configured" when the user pans
+ * around the ScrolledWindow. The Netscape scrolled-window is
+ * different. It moves-and-resizes the clip window, causing the
+ * child, i.e. This->plugin, to be "dragged" up by win-gravity.
+ */
+ case ConfigureNotify:
+ case GravityNotify:
+ if (This->plugin_widget == NULL)
+ return;
+
+ {
+ int i;
+ Position x, y;
+ XConfigureEvent sendev;
+
+ XtTranslateCoords (This->plugin_widget, 0, 0, &x, &y);
+ for (i = 0; i < This->nclient_windows; i++) {
+ sendev.type = ConfigureNotify;
+ sendev.send_event = True;
+ sendev.event = sendev.window = This->client_windows[i].win;
+ sendev.x = x + This->client_windows[i].x;
+ sendev.y = y + This->client_windows[i].y;
+ sendev.width = This->client_windows[i].width;
+ sendev.height = This->client_windows[i].height;
+ sendev.border_width = This->client_windows[i].border_width;
+ sendev.above = None;
+ sendev.override_redirect = False;
+ if (!XSendEvent (RxGlobal.dpy, This->client_windows[i].win,
+ False, StructureNotifyMask,
+ (XEvent*) &sendev))
+ (void) fprintf (stderr, "%s\n", "XSendEvent Failed");
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/***********************************************************************
+ * Event Handler to detect the destruction of a client window
+ ***********************************************************************/
+static void
+SubstructureNotifyHandler (
+ Widget widget,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean* cont)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "SubstructureNotifyHandler");
+#endif
+
+ if (event->type == DestroyNotify) {
+ int i;
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "DestroyNotify");
+#endif
+ for (i = 0; i < This->nclient_windows; i++)
+ if (This->client_windows[i].win == event->xdestroywindow.window) {
+ This->nclient_windows--;
+ if (This->nclient_windows > 0) {
+ /* remove this window from the list */
+ for (; i < This->nclient_windows; i++)
+ This->client_windows[i] = This->client_windows[i + 1];
+ } else { /* no more client windows! */
+ /* get back to user to restart the application */
+ RxpSetStatusWidget(This, WAITING);
+ }
+ ResetWMColormap(This, event->xdestroywindow.window);
+ UnregisterDrawable(event->xdestroywindow.window,
+ This->plugin_widget);
+ break;
+ }
+
+ }
+}
+
+/***********************************************************************
+ * Arrange to receive (synthetic) ConfigureNotify events on the proper
+ * windows of this instance and relay them to the embedded apps
+ ***********************************************************************/
+static void
+SetupStructureNotify (PluginInstance* This)
+{
+ /* Get ConfigureNotify when the browser is moved */
+ XtAddRawEventHandler (This->toplevel_widget,
+ StructureNotifyMask,
+ False,
+ StructureNotifyHandler,
+ (XtPointer) This);
+
+ XtAddRawEventHandler (This->toplevel_widget,
+ NoEventMask,
+ True,
+ RxpWmDelWinHandler,
+ (XtPointer) This);
+#if 0
+ XmAddWMProtocolCallback (This->toplevel_widget,
+ RxGlobal.wm_delete_window,
+ RxpWmDelWinHandler,
+ (XtPointer) This);
+#endif
+}
+
+/***********************************************************************
+ * Event Handler to deal with colormap settings
+ ***********************************************************************/
+static void
+CrossingHandler (
+ Widget widget,
+ XtPointer client_data,
+ XEvent* event,
+ Boolean* cont)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s: 0x%x\n", "CrossingHandler", event->xany.window);
+#endif
+
+ if (event->xany.window != XtWindow(This->plugin_widget) &&
+ event->xcrossing.detail != NotifyInferior) {
+ if (event->type == EnterNotify) {
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "EnterNotify");
+#endif
+ SetWMColormap(This, event->xany.window);
+ } else if (event->type == LeaveNotify) {
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "LeaveNotify");
+#endif
+ UnsetWMColormap(This, event->xany.window);
+ }
+ }
+}
+
+/***********************************************************************
+ * Setup various event handlers on the plugin widget
+ ***********************************************************************/
+void
+RxpSetupPluginEventHandlers (PluginInstance* This)
+{
+ int i;
+
+ /* Get ConfigureNotify and GravityNotify on the plugin */
+ XtAddEventHandler (This->plugin_widget,
+ StructureNotifyMask,
+ False,
+ StructureNotifyHandler,
+ (XtPointer) This);
+ /* Arrange to receive DestroyNotify events on the clients windows. */
+ XtAddEventHandler (This->plugin_widget,
+ SubstructureNotifyMask,
+ False,
+ SubstructureNotifyHandler,
+ (XtPointer) This);
+ /* Arrange to receive MapRequest and ConfigureRequest events on the
+ * netscape plug-in widget. */
+ XtAddRawEventHandler(This->plugin_widget,
+ SubstructureRedirectMask,
+ False,
+ SubstructureRedirectHandler,
+ (XtPointer) This);
+ XtRegisterDrawable (RxGlobal.dpy, This->app_group, This->plugin_widget);
+
+ /* Arrange to receive Enter and Leave Notify events on application's
+ toplevel windows */
+ XtAddRawEventHandler(This->plugin_widget,
+ EnterWindowMask | LeaveWindowMask,
+ False,
+ CrossingHandler,
+ (XtPointer) This);
+ for (i = 0; i < This->nclient_windows; i++) {
+ XtRegisterDrawable (RxGlobal.dpy,
+ This->client_windows[i].win, This->plugin_widget);
+ }
+}
+
+/***********************************************************************
+ * The instance is gone. Remove Event Handlers so that they aren't
+ * called with a reference to the old instance.
+ ***********************************************************************/
+void
+RxpTeardown (PluginInstance* This)
+{
+ if (This->toplevel_widget != NULL) {
+ /* ConfigureNotify on top level */
+ XtRemoveRawEventHandler (This->toplevel_widget,
+ StructureNotifyMask,
+ False,
+ StructureNotifyHandler,
+ (XtPointer) This);
+ XtRemoveRawEventHandler (This->toplevel_widget,
+ NoEventMask,
+ True,
+ RxpWmDelWinHandler,
+ (XtPointer) This);
+#if 0
+ XmRemoveWMProtocolCallback (This->toplevel_widget,
+ RxGlobal.wm_delete_window,
+ RxpWmDelWinHandler,
+ (XtPointer) This);
+#endif
+ }
+}
+
+/***********************************************************************
+ * Process the given RxParams and make the RxReturnParams
+ ***********************************************************************/
+
+static int
+ProcessUIParams(PluginInstance* This,
+ Boolean trusted, Boolean use_fwp, Boolean use_lbx,
+ RxParams *in, RxReturnParams *out, char **x_ui_auth_ret)
+{
+ XSecurityAuthorization dum;
+ int dummy;
+ char *display_name;
+
+ This->app_group = None;
+ if (out->embedded != RxFalse) { /* default is embedded */
+ /* let's see whether the server supports AppGroups or not */
+ if (RxGlobal.has_appgroup == RxUndef) {
+ if (XQueryExtension(RxGlobal.dpy, "XC-APPGROUP",
+ &dummy, &dummy, &dummy) &&
+ XagQueryVersion (RxGlobal.dpy, &dummy, &dummy))
+ RxGlobal.has_appgroup = RxTrue;
+ else
+ RxGlobal.has_appgroup = RxFalse;
+ }
+ if (RxGlobal.has_appgroup == RxTrue) {
+ Screen *scr;
+ Colormap cmap;
+ Arg arg;
+
+ /* use plugin's colormap as the default colormap */
+ XtSetArg(arg, XtNcolormap, &cmap);
+ XtGetValues(This->plugin_widget, &arg, 1);
+ scr = XtScreen(This->plugin_widget);
+ if (cmap == DefaultColormapOfScreen(scr)) {
+ XagCreateEmbeddedApplicationGroup (RxGlobal.dpy, None,
+ cmap,
+ BlackPixelOfScreen(scr),
+ WhitePixelOfScreen(scr),
+ &This->app_group);
+ } else {
+ XColor black, white;
+ Pixel pixels[2];
+
+ black.red = black.green = black.blue = 0;
+ XAllocColor(RxGlobal.dpy, cmap, &black);
+ white.red = white.green = white.blue = 65535;
+ XAllocColor(RxGlobal.dpy, cmap, &white);
+ XagCreateEmbeddedApplicationGroup (RxGlobal.dpy, None,
+ cmap,
+ pixels[0] = black.pixel,
+ pixels[1] = white.pixel,
+ &This->app_group);
+ XFreeColors(RxGlobal.dpy, cmap, pixels, 2, 0);
+ }
+ SetupStructureNotify (This);
+ RxpSetupPluginEventHandlers (This);
+ } else { /* too bad */
+ out->embedded = RxFalse;
+ fprintf(stderr, "Warning: Cannot perform embedding as \
+requested, APPGROUP extension not supported\n");
+ }
+ }
+
+ if (in->x_ui_auth[0] != 0) {
+ GetXAuth(RxGlobal.dpy, in->x_ui_auth[0], in->x_ui_auth_data[0],
+ trusted, This->app_group, False, DEFAULT_TIMEOUT,
+ x_ui_auth_ret, &This->x_ui_auth_id, &dummy);
+ } else if (in->x_auth[0] != 0)
+ GetXAuth(RxGlobal.dpy, in->x_auth[0], in->x_auth_data[0],
+ trusted, This->app_group, False, DEFAULT_TIMEOUT,
+ x_ui_auth_ret, &This->x_ui_auth_id, &dummy);
+
+ /* make sure we use the server the user wants us to use */
+ if (RxGlobal.has_real_server == RxUndef) {
+ Display *rdpy = RxGlobal.dpy;
+ char *real_display = getenv("XREALDISPLAY");
+ RxGlobal.has_real_server = RxFalse;
+ if (real_display != NULL) {
+ rdpy = XOpenDisplay(real_display);
+ if (rdpy == NULL)
+ rdpy = RxGlobal.dpy;
+ else
+ RxGlobal.has_real_server = RxTrue;
+ }
+ /* let's see now whether the server supports LBX or not */
+ if (XQueryExtension(rdpy, "LBX", &dummy, &dummy, &dummy))
+ RxGlobal.has_ui_lbx = RxTrue;
+ else
+ RxGlobal.has_ui_lbx = RxFalse;
+
+ if (rdpy != RxGlobal.dpy)
+ XCloseDisplay(rdpy);
+ }
+ if (RxGlobal.has_real_server == RxTrue)
+ display_name = getenv("XREALDISPLAY");
+ else
+ display_name = DisplayString(RxGlobal.dpy);
+
+ /* let's see whether we have a firewall proxy */
+ if (use_fwp == True && RxGlobal.has_ui_fwp == RxUndef) {
+ RxGlobal.fwp_dpyname = GetXFwpDisplayName(display_name);
+ if (RxGlobal.fwp_dpyname != NULL)
+ RxGlobal.has_ui_fwp = RxTrue;
+ else {
+ /*
+ * We were supposed to use the firewall proxy but we
+ * couldn't get a connection. There is no need to
+ * continue.
+ */
+ return 1;
+ }
+ }
+ if (use_fwp == True && RxGlobal.has_ui_fwp == RxTrue)
+ out->ui = GetXUrl(RxGlobal.fwp_dpyname, *x_ui_auth_ret, in->action);
+ else
+ out->ui = GetXUrl(display_name, *x_ui_auth_ret, in->action);
+
+ if (in->x_ui_lbx == RxTrue) {
+ if (use_lbx == True) {
+ if (RxGlobal.has_ui_lbx == RxTrue) {
+ out->x_ui_lbx = RxTrue;
+
+ /* let's get a key for the proxy now */
+ if (in->x_ui_lbx_auth[0] != 0) {
+ GetXAuth(RxGlobal.dpy, in->x_ui_lbx_auth[0],
+ in->x_ui_lbx_auth_data[0],
+ trusted, None, False, DEFAULT_TIMEOUT,
+ &out->x_ui_lbx_auth, &dum, &dummy);
+ } else if (in->x_auth[0] != 0)
+ GetXAuth(RxGlobal.dpy, in->x_auth[0], in->x_auth_data[0],
+ trusted, None, False, DEFAULT_TIMEOUT,
+ &out->x_ui_lbx_auth, &dum, &dummy);
+ } else {
+ out->x_ui_lbx = RxFalse;
+ fprintf(stderr, "Warning: Cannot setup LBX as requested, \
+LBX extension not supported\n");
+ }
+ } else
+ out->x_ui_lbx = RxFalse;
+ } else /* it's either RxFalse or RxUndef */
+ out->x_ui_lbx = in->x_ui_lbx;
+
+ return 0;
+}
+
+static int
+ProcessPrintParams(PluginInstance* This,
+ Boolean trusted, Boolean use_fwp, Boolean use_lbx,
+ RxParams *in, RxReturnParams *out, char *x_ui_auth)
+{
+ char *auth = NULL;
+ XSecurityAuthorization dum;
+ int dummy;
+
+ /* let's find out if we have a print server */
+ if (RxGlobal.has_printer == RxUndef) {
+ RxGlobal.pdpy_name = GetXPrintDisplayName(&RxGlobal.printer_name);
+ if (RxGlobal.pdpy_name != NULL) {
+ /* open connection to the print server */
+ RxGlobal.pdpy = XOpenDisplay(RxGlobal.pdpy_name);
+ if (RxGlobal.pdpy != NULL)
+ RxGlobal.has_printer = RxTrue;
+ else
+ RxGlobal.has_printer = RxFalse;
+ } else {
+ /* no server specified,
+ let's see if the video server could do it */
+ if (XQueryExtension(RxGlobal.dpy, "XpExtension",
+ &dummy, &dummy, &dummy)) {
+ RxGlobal.has_printer = RxTrue;
+ RxGlobal.pdpy = RxGlobal.dpy;
+ } else
+ RxGlobal.has_printer = RxFalse;
+ }
+ }
+ if (RxGlobal.has_printer == RxFalse) {
+ fprintf(stderr, "Warning: Cannot setup X printer as requested, \
+no server found\n");
+ return 0;
+ }
+
+ /* create a key only when the video server is not the print
+ server or when we didn't create a key yet */
+ if (RxGlobal.pdpy != RxGlobal.dpy || x_ui_auth == NULL) {
+ if (in->x_print_auth[0] != 0)
+ GetXAuth(RxGlobal.pdpy, in->x_print_auth[0],
+ in->x_print_auth_data[0],
+ trusted, None, False, NO_TIMEOUT,
+ &auth, &This->x_print_auth_id, &dummy);
+ else if (in->x_auth[0] != 0)
+ GetXAuth(RxGlobal.pdpy, in->x_auth[0], in->x_auth_data[0],
+ trusted, None, False, NO_TIMEOUT,
+ &auth, &This->x_print_auth_id, &dummy);
+ }
+
+ /* let's see whether we have a firewall proxy */
+ if (use_fwp == True && RxGlobal.has_print_fwp == RxUndef) {
+ RxGlobal.pfwp_dpyname = GetXFwpDisplayName(DisplayString(RxGlobal.pdpy));
+ if (RxGlobal.pfwp_dpyname != NULL)
+ RxGlobal.has_print_fwp = RxTrue;
+ else {
+ /*
+ * We were supposed to use the firewall proxy but we
+ * couldn't get a connection. There is no need to
+ * continue.
+ */
+ return 1;
+ }
+ }
+ if (use_fwp == True && RxGlobal.has_print_fwp == RxTrue)
+ out->print = GetXPrintUrl(RxGlobal.pfwp_dpyname,
+ RxGlobal.printer_name, auth,
+ in->action);
+ else
+ out->print = GetXPrintUrl(DisplayString(RxGlobal.pdpy),
+ RxGlobal.printer_name, auth,
+ in->action);
+
+ if (auth != NULL)
+ NPN_MemFree(auth);
+
+ if (in->x_print_lbx == RxTrue) {
+ if (use_lbx == True) {
+ /* let's see whether the server supports LBX or not */
+ if (RxGlobal.has_print_lbx == RxUndef) {
+ if (RxGlobal.pdpy == RxGlobal.dpy &&
+ RxGlobal.has_ui_lbx != RxUndef) {
+ /* the video server is the print server and we already
+ know whether it supports LBX or not */
+ RxGlobal.has_print_lbx = RxGlobal.has_ui_lbx;
+ } else {
+ if (XQueryExtension(RxGlobal.pdpy, "LBX",
+ &dummy, &dummy, &dummy))
+ RxGlobal.has_print_lbx = RxTrue;
+ else
+ RxGlobal.has_print_lbx = RxFalse;
+ }
+ }
+ if (RxGlobal.has_print_lbx == RxTrue) {
+ out->x_print_lbx = RxTrue;
+ if (RxGlobal.pdpy != RxGlobal.dpy) {
+ /* let's get a key for the proxy now */
+ if (in->x_print_lbx_auth[0] != 0) {
+ GetXAuth(RxGlobal.pdpy, in->x_print_lbx_auth[0],
+ in->x_print_lbx_auth_data[0],
+ trusted, None, False, DEFAULT_TIMEOUT,
+ &out->x_print_lbx_auth, &dum, &dummy);
+ } else if (in->x_auth[0] != 0)
+ GetXAuth(RxGlobal.pdpy, in->x_auth[0],
+ in->x_auth_data[0],
+ trusted, None, False, DEFAULT_TIMEOUT,
+ &out->x_print_lbx_auth, &dum, &dummy);
+ }
+ } else {
+ out->x_print_lbx = RxFalse;
+ fprintf(stderr, "Warning: Cannot setup LBX as \
+requested, LBX extension not supported\n");
+ }
+ } else
+ out->x_print_lbx = RxFalse;
+ } else /* it's either RxFalse or RxUndef */
+ out->x_print_lbx = in->x_print_lbx;
+
+ return 0;
+}
+
+int
+RxpProcessParams(PluginInstance* This, RxParams *in, RxReturnParams *out)
+{
+ char *x_ui_auth = NULL;
+ char webserver[MAXHOSTNAMELEN];
+ Boolean trusted, use_fwp, use_lbx;
+ int return_value = 0;
+
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "%s\n", "RxpProcessParams");
+ fprintf (stderr, "This: 0x%x\n", This);
+#endif
+
+ /* init return struture */
+ memset(out, 0, sizeof(RxReturnParams));
+ out->x_ui_lbx = RxUndef;
+ out->x_print_lbx = RxUndef;
+ out->action = in->action;
+
+ if (in->embedded != RxUndef)
+ out->embedded = in->embedded;
+ else
+ out->embedded = RxUndef;
+
+ out->width = in->width;
+ out->height = in->height;
+
+ if (RxGlobal.get_prefs == True) {
+ GetPreferences(This->toplevel_widget, &RxGlobal.prefs);
+ RxGlobal.get_prefs = False;
+ }
+ ComputePreferences(&RxGlobal.prefs,
+ ParseHostname(in->action, webserver, MAXHOSTNAMELEN) ? webserver : NULL,
+ &trusted, &use_fwp, &use_lbx);
+
+ if (in->ui[0] == XUI) /* X display needed */
+ return_value = ProcessUIParams(This, trusted, use_fwp, use_lbx,
+ in, out, &x_ui_auth);
+
+ if (in->print[0] == XPrint) /* XPrint server needed */
+ return_value = ProcessPrintParams(This, trusted, use_fwp, use_lbx,
+ in, out, x_ui_auth);
+
+ if (x_ui_auth != NULL)
+ NPN_MemFree(x_ui_auth);
+
+ return return_value;
+}
diff --git a/plugin/RxPlugin.h b/plugin/RxPlugin.h
new file mode 100644
index 0000000..9b97789
--- /dev/null
+++ b/plugin/RxPlugin.h
@@ -0,0 +1,171 @@
+/* $Xorg: RxPlugin.h,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+/*
+ * RX plug-in header file, based on the UnixTemplate file provided by Netcape.
+ */
+
+/* -*- Mode: C; tab-width: 4; -*- */
+/******************************************************************************
+ * Copyright 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>
+ *
+ */
+
+#ifndef _RxPlugin_h
+#define _RxPLugin_h
+
+#include "npapi.h"
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+#include <X11/extensions/Xag.h>
+#include <X11/extensions/security.h>
+#include <X11/ICE/ICElib.h>
+#include <stdio.h>
+#include "Rx.h"
+#include "Prefs.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 enum {
+ RxpNoflags = 0,
+ RxpWmDelWin = (1 << 0),
+ RxpMapped = (1 << 4)
+} WindowFlags;
+
+typedef struct {
+ Window win;
+ Position x,y;
+ Dimension width,height;
+ Dimension border_width;
+ WindowFlags flags;
+ Colormap colormap;
+} windowrec;
+
+typedef enum { LOADING, STARTING, WAITING, RUNNING } PluginState;
+
+typedef struct _PluginInstance
+{
+ NPP instance;
+ int16 argc; /* HTML arguments given by Netscape */
+ char **argn;
+ char **argv;
+ short parse_reply; /* 0 - no
+ 1 - look for status line
+ 2 - done */
+ short status; /* returned application status */
+ RxBool dont_reparent; /* whether client windows need reparent*/
+ char *query;
+ PluginState state;
+ Widget status_widget;
+ Widget plugin_widget;
+ Dimension width, height;
+ /* The following fields need to be taken care by RxpNew & RxpDestroy */
+ XSecurityAuthorization x_ui_auth_id;
+ XSecurityAuthorization x_print_auth_id;
+ XAppGroup app_group;
+ Widget toplevel_widget;
+ windowrec *client_windows;
+ int nclient_windows;
+} PluginInstance;
+
+typedef struct _PluginGlobal {
+ Boolean inited;
+ RxBool has_appgroup;
+ RxBool has_real_server;
+ RxBool has_ui_lbx;
+ RxBool has_print_lbx;
+ RxBool has_printer;
+ RxBool has_ui_fwp;
+ RxBool has_print_fwp;
+ char *pdpy_name;
+ char *printer_name;
+ char *fwp_dpyname;
+ char *pfwp_dpyname;
+ struct _IceConn* ice_conn;
+ int pm_opcode;
+ Preferences prefs;
+ Boolean get_prefs;
+ Display* dpy;
+ Display* pdpy;
+ Atom wm_delete_window;
+ Atom wm_protocols;
+} PluginGlobal;
+
+extern PluginGlobal RxGlobal;
+
+
+#define PLUGIN_NAME "RX Plug-in"
+#define PLUGIN_DESCRIPTION "X Remote Activation Plug-in"
+#define PLUGIN_MIME_DESCRIPTION \
+ "application/x-rx:xrx:X Remote Activation Plug-in"
+
+
+/* functions to init and free private members */
+extern void RxpNew(PluginInstance*);
+extern void RxpDestroy(PluginInstance*);
+
+extern int
+RxpProcessParams(PluginInstance*, RxParams*, RxReturnParams*);
+
+extern void
+RxpSetStatusWidget(PluginInstance*, PluginState);
+
+extern void
+RxpSetupPluginEventHandlers(PluginInstance*);
+
+extern void
+RxpTeardown (PluginInstance*);
+
+extern void
+RxpWmDelWinHandler (Widget, XtPointer, XEvent*, Boolean*);
+
+extern void
+RxpRemoveDestroyCallback (PluginInstance*);
+
+#endif
diff --git a/plugin/SetWin.c b/plugin/SetWin.c
new file mode 100644
index 0000000..3e60f75
--- /dev/null
+++ b/plugin/SetWin.c
@@ -0,0 +1,213 @@
+/* $Xorg: SetWin.c,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+/*
+ * RX plug-in module based on the UnixTemplate file provided by Netcape.
+ */
+
+/* -*- Mode: C; tab-width: 4; -*- */
+/******************************************************************************
+ * Copyright 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 "RxPlugin.h"
+#include <X11/StringDefs.h>
+
+/***********************************************************************
+ * Sometimes the plugin widget gets stupidly destroyed, that is whenever
+ * Netscape relayouts the page. This callback reparents the client
+ * windows to the root window so they do not get destroyed as well.
+ * Eventually the NPP_SetWindow function should be called and we'll
+ * reparent them back under the plugin.
+ ***********************************************************************/
+static void
+DestroyCB (Widget widget, XtPointer client_data, XtPointer call_data)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+ int i;
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "DestroyCB, This: 0x%x\n", This);
+#endif
+ if (widget == This->plugin_widget) {
+ This->plugin_widget = NULL;
+ This->status_widget = NULL;
+ }
+ if (This->dont_reparent == RxFalse) {
+ for (i = 0; i < This->nclient_windows; i++) {
+ XUnmapWindow (RxGlobal.dpy, This->client_windows[i].win);
+ This->client_windows[i].flags &= ~RxpMapped;
+
+ XReparentWindow (RxGlobal.dpy, This->client_windows[i].win,
+ (XtScreen (widget))->root, 0, 0);
+ }
+ This->dont_reparent = RxTrue;
+ } else
+ This->dont_reparent = RxFalse;
+ /*
+ * not worth removing event handlers on this widget since it's
+ * about to be destroyed anyway.
+ */
+}
+
+
+/***********************************************************************
+ * Sometimes the plugin widget gets stupidly resized, because of poor
+ * geometry when its child (that is the status widget) gets destroyed.
+ * So this callback resizes it back to the right size.
+ * Note that this could lead to an endless battle, but it appears that
+ * it doesn't so far...
+ ***********************************************************************/
+static void
+ResizeCB (Widget widget, XtPointer client_data, XtPointer call_data)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+ Arg args[5];
+ int n;
+
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "ResizeCB, This: 0x%x\n", This);
+#endif
+ /* make sure plugin widget gets the same size back */
+ n = 0;
+ XtSetArg(args[n], XtNwidth, This->width); n++;
+ XtSetArg(args[n], XtNheight, This->height); n++;
+ XtSetValues(This->plugin_widget, args, n);
+}
+
+static Widget
+FindToplevel(Widget widget)
+{
+ while (XtParent(widget) != NULL && !XtIsTopLevelShell(widget))
+ widget = XtParent(widget);
+
+ return widget;
+}
+
+/***********************************************************************
+ * This function gets called first when the plugin widget is created and
+ * then whenever the plugin is changed.
+ ***********************************************************************/
+NPError
+NPP_SetWindow(NPP instance, NPWindow* window)
+{
+ PluginInstance* This;
+ Widget netscape_widget;
+
+ if (instance == NULL)
+ return NPERR_INVALID_INSTANCE_ERROR;
+
+ if (window == NULL)
+ return NPERR_NO_ERROR;
+
+ /*
+ * 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.
+ */
+ This = (PluginInstance*) instance->pdata;
+#ifdef PLUGIN_TRACE
+ fprintf(stderr, "SetWindow 0x%x.\n", (Window) window->window);
+ fprintf(stderr, "This: 0x%x\n", This);
+ if (This->plugin_widget)
+ fprintf(stderr, "This->plugin_widget: 0x%x\n", This->plugin_widget);
+#endif
+ if (RxGlobal.dpy == NULL) {
+ RxGlobal.dpy = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
+ RxGlobal.wm_delete_window =
+ XInternAtom (RxGlobal.dpy, "WM_DELETE_WINDOW", TRUE);
+ RxGlobal.wm_protocols = XInternAtom (RxGlobal.dpy, "WM_PROTOCOLS", TRUE);
+ }
+ netscape_widget = XtWindowToWidget(RxGlobal.dpy, (Window) window->window);
+ if (This->toplevel_widget == NULL)
+ This->toplevel_widget = FindToplevel(netscape_widget);
+
+ if (This->plugin_widget != netscape_widget) {
+
+ /* We have a new widget store it */
+ This->plugin_widget = netscape_widget;
+ This->width = window->width;
+ This->height = window->height;
+
+ XtAddCallback (This->plugin_widget, XtNdestroyCallback,
+ DestroyCB, (XtPointer) This);
+ XtAddCallback (This->plugin_widget, "resizeCallback",
+ ResizeCB, (XtPointer) This);
+
+ if (This->app_group)
+ RxpSetupPluginEventHandlers (This);
+
+ if (This->nclient_windows > 0) {
+ int i;
+
+ /* We already have the client, so we need to reparent it to the
+ new window */
+ for (i = 0; i < This->nclient_windows; i++) {
+ XReparentWindow(RxGlobal.dpy, This->client_windows[i].win,
+ XtWindow(netscape_widget),
+ This->client_windows[i].x,
+ This->client_windows[i].y);
+ if (This->dont_reparent == RxTrue) {
+ XMapWindow (RxGlobal.dpy, This->client_windows[i].win);
+ This->client_windows[i].flags |= RxpMapped;
+ }
+ }
+ } else /* no client window, display status widget */
+ RxpSetStatusWidget(This, This->state);
+ if (This->dont_reparent != RxFalse) /* can be True or Undef */
+ This->dont_reparent = RxFalse;
+ else
+ This->dont_reparent = RxTrue;
+ }
+ return NPERR_NO_ERROR;
+}
+
+void
+RxpRemoveDestroyCallback(PluginInstance *This)
+{
+ if (This->plugin_widget != NULL)
+ XtRemoveCallback(This->plugin_widget, XtNdestroyCallback,
+ DestroyCB, (XtPointer) This);
+}
diff --git a/plugin/common/npunix.c b/plugin/common/npunix.c
new file mode 100644
index 0000000..bedd861
--- /dev/null
+++ b/plugin/common/npunix.c
@@ -0,0 +1,407 @@
+/* $Xorg: npunix.c,v 1.3 2000/08/17 19:54:59 cpqbld Exp $ */
+/*
+ * 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_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);
+}
+
+JRIGlobalRef
+Private_GetJavaClass(void)
+{
+ jref clazz = NPP_GetJavaClass();
+ if (clazz) {
+ JRIEnv* env = NPN_GetJavaEnv();
+ return JRI_NewGlobalRef(env, clazz);
+ }
+ 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.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;
+}
diff --git a/plugin/include/jri.h b/plugin/include/jri.h
new file mode 100644
index 0000000..4391455
--- /dev/null
+++ b/plugin/include/jri.h
@@ -0,0 +1,639 @@
+/* $Xorg: jri.h,v 1.3 2000/08/17 19:55:00 cpqbld Exp $ */
+/* -*- 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_LoadClass(env, buf, bufLen) \
+ (((*(env))->LoadClass)(env, JRI_LoadClass_op, 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_Class;
+struct java_lang_Throwable;
+struct java_lang_Object;
+struct java_lang_String;
+
+struct JRIEnvInterface {
+ void* reserved0;
+ void* reserved1;
+ void* reserved2;
+ struct java_lang_Class* (*LoadClass)(JRIEnv* env, jint op, jbyte* a, jsize aLen);
+ 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);
+};
+
+/*******************************************************************************
+ * JRIEnv Operation IDs
+ ******************************************************************************/
+
+typedef enum JRIEnvOperations {
+ JRI_Reserved0_op,
+ JRI_Reserved1_op,
+ JRI_Reserved2_op,
+ JRI_LoadClass_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
+} JRIEnvOperations;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* JRI_H */
+/******************************************************************************/
diff --git a/plugin/include/jri_md.h b/plugin/include/jri_md.h
new file mode 100644
index 0000000..1ba1c64
--- /dev/null
+++ b/plugin/include/jri_md.h
@@ -0,0 +1,501 @@
+/* $Xorg: jri_md.h,v 1.3 2000/08/17 19:55:01 cpqbld Exp $ */
+/* -*- 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>
+
+#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;
+typedef char jbyte;
+typedef short jchar;
+typedef short jshort;
+#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;
+typedef long jint;
+#endif
+typedef float jfloat;
+typedef double jdouble;
+
+typedef juint jsize;
+
+/*******************************************************************************
+ * jlong : long long (64-bit signed integer type) support.
+ ******************************************************************************/
+
+/*
+** Bit masking macros. (n must be <= 31 to be portable)
+*/
+#define JRI_BIT(n) ((juint)1 << (n))
+#define JRI_BITMASK(n) (JRI_BIT(n) - 1)
+
+#ifdef HAVE_LONG_LONG
+
+#if !(defined(WIN32) || defined(_WIN32))
+typedef long long jlong;
+typedef unsigned long long julong;
+
+#define jlong_MAXINT 0x7fffffffffffffffLL
+#define jlong_MININT 0x8000000000000000LL
+#define jlong_ZERO 0x0LL
+
+#else
+typedef LONGLONG jlong;
+typedef DWORDLONG julong;
+
+#define jlong_MAXINT 0x7fffffffffffffffi64
+#define jlong_MININT 0x8000000000000000i64
+#define jlong_ZERO 0x0i64
+
+#endif
+
+#define jlong_IS_ZERO(a) ((a) == 0)
+#define jlong_EQ(a, b) ((a) == (b))
+#define jlong_NE(a, b) ((a) != (b))
+#define jlong_GE_ZERO(a) ((a) >= 0)
+#define jlong_CMP(a, op, b) ((a) op (b))
+
+#define jlong_AND(r, a, b) ((r) = (a) & (b))
+#define jlong_OR(r, a, b) ((r) = (a) | (b))
+#define jlong_XOR(r, a, b) ((r) = (a) ^ (b))
+#define jlong_OR2(r, a) ((r) = (r) | (a))
+#define jlong_NOT(r, a) ((r) = ~(a))
+
+#define jlong_NEG(r, a) ((r) = -(a))
+#define jlong_ADD(r, a, b) ((r) = (a) + (b))
+#define jlong_SUB(r, a, b) ((r) = (a) - (b))
+
+#define jlong_MUL(r, a, b) ((r) = (a) * (b))
+#define jlong_DIV(r, a, b) ((r) = (a) / (b))
+#define jlong_MOD(r, a, b) ((r) = (a) % (b))
+
+#define jlong_SHL(r, a, b) ((r) = (a) << (b))
+#define jlong_SHR(r, a, b) ((r) = (a) >> (b))
+#define jlong_USHR(r, a, b) ((r) = (julong)(a) >> (b))
+#define jlong_ISHL(r, a, b) ((r) = ((jlong)(a)) << (b))
+
+#define jlong_L2I(i, l) ((i) = (int)(l))
+#define jlong_L2UI(ui, l) ((ui) =(unsigned int)(l))
+#define jlong_L2F(f, l) ((f) = (l))
+#define jlong_L2D(d, l) ((d) = (l))
+
+#define jlong_I2L(l, i) ((l) = (i))
+#define jlong_UI2L(l, ui) ((l) = (ui))
+#define jlong_F2L(l, f) ((l) = (f))
+#define jlong_D2L(l, d) ((l) = (d))
+
+#define jlong_UDIVMOD(qp, rp, a, b) \
+ (*(qp) = ((julong)(a) / (b)), \
+ *(rp) = ((julong)(a) % (b)))
+
+#else /* !HAVE_LONG_LONG */
+
+typedef struct {
+#ifdef IS_LITTLE_ENDIAN
+ juint lo, hi;
+#else
+ juint hi, lo;
+#endif
+} jlong;
+typedef jlong julong;
+
+extern jlong jlong_MAXINT, jlong_MININT, jlong_ZERO;
+
+#define jlong_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0))
+#define jlong_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo))
+#define jlong_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo))
+#define jlong_GE_ZERO(a) (((a).hi >> 31) == 0)
+
+/*
+ * NB: jlong_CMP and jlong_UCMP work only for strict relationals (<, >).
+ */
+#define jlong_CMP(a, op, b) (((int32)(a).hi op (int32)(b).hi) || \
+ (((a).hi == (b).hi) && ((a).lo op (b).lo)))
+#define jlong_UCMP(a, op, b) (((a).hi op (b).hi) || \
+ (((a).hi == (b).hi) && ((a).lo op (b).lo)))
+
+#define jlong_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \
+ (r).hi = (a).hi & (b).hi)
+#define jlong_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \
+ (r).hi = (a).hi | (b).hi)
+#define jlong_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \
+ (r).hi = (a).hi ^ (b).hi)
+#define jlong_OR2(r, a) ((r).lo = (r).lo | (a).lo, \
+ (r).hi = (r).hi | (a).hi)
+#define jlong_NOT(r, a) ((r).lo = ~(a).lo, \
+ (r).hi = ~(a).hi)
+
+#define jlong_NEG(r, a) ((r).lo = -(int32)(a).lo, \
+ (r).hi = -(int32)(a).hi - ((r).lo != 0))
+#define jlong_ADD(r, a, b) { \
+ jlong _a, _b; \
+ _a = a; _b = b; \
+ (r).lo = _a.lo + _b.lo; \
+ (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \
+}
+
+#define jlong_SUB(r, a, b) { \
+ jlong _a, _b; \
+ _a = a; _b = b; \
+ (r).lo = _a.lo - _b.lo; \
+ (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \
+} \
+
+/*
+ * Multiply 64-bit operands a and b to get 64-bit result r.
+ * First multiply the low 32 bits of a and b to get a 64-bit result in r.
+ * Then add the outer and inner products to r.hi.
+ */
+#define jlong_MUL(r, a, b) { \
+ jlong _a, _b; \
+ _a = a; _b = b; \
+ jlong_MUL32(r, _a.lo, _b.lo); \
+ (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
+}
+
+/* XXX _jlong_lo16(a) = ((a) << 16 >> 16) is better on some archs (not on mips) */
+#define _jlong_lo16(a) ((a) & JRI_BITMASK(16))
+#define _jlong_hi16(a) ((a) >> 16)
+
+/*
+ * Multiply 32-bit operands a and b to get 64-bit result r.
+ * Use polynomial expansion based on primitive field element (1 << 16).
+ */
+#define jlong_MUL32(r, a, b) { \
+ juint _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
+ _a1 = _jlong_hi16(a), _a0 = _jlong_lo16(a); \
+ _b1 = _jlong_hi16(b), _b0 = _jlong_lo16(b); \
+ _y0 = _a0 * _b0; \
+ _y1 = _a0 * _b1; \
+ _y2 = _a1 * _b0; \
+ _y3 = _a1 * _b1; \
+ _y1 += _jlong_hi16(_y0); /* can't carry */ \
+ _y1 += _y2; /* might carry */ \
+ if (_y1 < _y2) _y3 += 1 << 16; /* propagate */ \
+ (r).lo = (_jlong_lo16(_y1) << 16) + _jlong_lo16(_y0); \
+ (r).hi = _y3 + _jlong_hi16(_y1); \
+}
+
+/*
+ * Divide 64-bit unsigned operand a by 64-bit unsigned operand b, setting *qp
+ * to the 64-bit unsigned quotient, and *rp to the 64-bit unsigned remainder.
+ * Minimize effort if one of qp and rp is null.
+ */
+#define jlong_UDIVMOD(qp, rp, a, b) jlong_udivmod(qp, rp, a, b)
+
+extern JRI_PUBLIC_API(void)
+jlong_udivmod(julong *qp, julong *rp, julong a, julong b);
+
+#define jlong_DIV(r, a, b) { \
+ jlong _a, _b; \
+ juint _negative = (int32)(a).hi < 0; \
+ if (_negative) { \
+ jlong_NEG(_a, a); \
+ } else { \
+ _a = a; \
+ } \
+ if ((int32)(b).hi < 0) { \
+ _negative ^= 1; \
+ jlong_NEG(_b, b); \
+ } else { \
+ _b = b; \
+ } \
+ jlong_UDIVMOD(&(r), 0, _a, _b); \
+ if (_negative) \
+ jlong_NEG(r, r); \
+}
+
+#define jlong_MOD(r, a, b) { \
+ jlong _a, _b; \
+ juint _negative = (int32)(a).hi < 0; \
+ if (_negative) { \
+ jlong_NEG(_a, a); \
+ } else { \
+ _a = a; \
+ } \
+ if ((int32)(b).hi < 0) { \
+ jlong_NEG(_b, b); \
+ } else { \
+ _b = b; \
+ } \
+ jlong_UDIVMOD(0, &(r), _a, _b); \
+ if (_negative) \
+ jlong_NEG(r, r); \
+}
+
+/*
+ * NB: b is a juint, not jlong or julong, for the shift ops.
+ */
+#define jlong_SHL(r, a, b) { \
+ if (b) { \
+ jlong _a; \
+ _a = a; \
+ if ((b) < 32) { \
+ (r).lo = _a.lo << (b); \
+ (r).hi = (_a.hi << (b)) | (_a.lo >> (32 - (b))); \
+ } else { \
+ (r).lo = 0; \
+ (r).hi = _a.lo << ((b) & 31); \
+ } \
+ } else { \
+ (r) = (a); \
+ } \
+}
+
+/* a is an int32, b is int32, r is jlong */
+#define jlong_ISHL(r, a, b) { \
+ if (b) { \
+ jlong _a; \
+ _a.lo = (a); \
+ _a.hi = 0; \
+ if ((b) < 32) { \
+ (r).lo = (a) << (b); \
+ (r).hi = ((a) >> (32 - (b))); \
+ } else { \
+ (r).lo = 0; \
+ (r).hi = (a) << ((b) & 31); \
+ } \
+ } else { \
+ (r).lo = (a); \
+ (r).hi = 0; \
+ } \
+}
+
+#define jlong_SHR(r, a, b) { \
+ if (b) { \
+ jlong _a; \
+ _a = a; \
+ if ((b) < 32) { \
+ (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \
+ (r).hi = (int32)_a.hi >> (b); \
+ } else { \
+ (r).lo = (int32)_a.hi >> ((b) & 31); \
+ (r).hi = (int32)_a.hi >> 31; \
+ } \
+ } else { \
+ (r) = (a); \
+ } \
+}
+
+#define jlong_USHR(r, a, b) { \
+ if (b) { \
+ jlong _a; \
+ _a = a; \
+ if ((b) < 32) { \
+ (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \
+ (r).hi = _a.hi >> (b); \
+ } else { \
+ (r).lo = _a.hi >> ((b) & 31); \
+ (r).hi = 0; \
+ } \
+ } else { \
+ (r) = (a); \
+ } \
+}
+
+#define jlong_L2I(i, l) ((i) = (l).lo)
+#define jlong_L2UI(ui, l) ((ui) = (l).lo)
+#define jlong_L2F(f, l) { double _d; jlong_L2D(_d, l); (f) = (float) _d; }
+
+#define jlong_L2D(d, l) { \
+ int32 _negative; \
+ jlong _absval; \
+ \
+ _negative = (l).hi >> 31; \
+ if (_negative) { \
+ jlong_NEG(_absval, l); \
+ } else { \
+ _absval = l; \
+ } \
+ (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
+ if (_negative) \
+ (d) = -(d); \
+}
+
+#define jlong_I2L(l, i) ((l).hi = (i) >> 31, (l).lo = (i))
+#define jlong_UI2L(l, ui) ((l).hi = 0, (l).lo = (ui))
+#define jlong_F2L(l, f) { double _d = (double) f; jlong_D2L(l, _d); }
+
+#define jlong_D2L(l, d) { \
+ int _negative; \
+ double _absval, _d_hi; \
+ jlong _lo_d; \
+ \
+ _negative = ((d) < 0); \
+ _absval = _negative ? -(d) : (d); \
+ \
+ (l).hi = (juint)(_absval / 4.294967296e9); \
+ (l).lo = 0; \
+ jlong_L2D(_d_hi, l); \
+ _absval -= _d_hi; \
+ _lo_d.hi = 0; \
+ if (_absval < 0) { \
+ _lo_d.lo = (juint) -_absval; \
+ jlong_SUB(l, l, _lo_d); \
+ } else { \
+ _lo_d.lo = (juint) _absval; \
+ jlong_ADD(l, l, _lo_d); \
+ } \
+ \
+ if (_negative) \
+ jlong_NEG(l, l); \
+}
+
+#endif /* !HAVE_LONG_LONG */
+
+/******************************************************************************/
+/*
+** 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 */
+/******************************************************************************/
diff --git a/plugin/include/jritypes.h b/plugin/include/jritypes.h
new file mode 100644
index 0000000..3b84641
--- /dev/null
+++ b/plugin/include/jritypes.h
@@ -0,0 +1,181 @@
+/* $Xorg: jritypes.h,v 1.3 2000/08/17 19:55:01 cpqbld Exp $ */
+/* -*- 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 JRIValue jvalue;
+
+typedef enum JRIBoolean {
+ JRIFalse = 0,
+ JRITrue = 1
+} JRIBoolean;
+
+typedef enum JRIConstant {
+ JRIUninitialized = -1
+} JRIConstant;
+
+/* convenience types: */
+typedef JRIRef jbooleanArray;
+typedef JRIRef jbyteArray;
+typedef JRIRef jcharArray;
+typedef JRIRef jshortArray;
+typedef JRIRef jintArray;
+typedef JRIRef jlongArray;
+typedef JRIRef jfloatArray;
+typedef JRIRef jdoubleArray;
+typedef JRIRef jobjectArray;
+typedef JRIRef jstringArray;
+typedef JRIRef jarrayArray;
+
+#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 */
+/******************************************************************************/
diff --git a/plugin/include/npapi.h b/plugin/include/npapi.h
new file mode 100644
index 0000000..598faa1
--- /dev/null
+++ b/plugin/include/npapi.h
@@ -0,0 +1,393 @@
+/* $Xorg: npapi.h,v 1.3 2000/08/17 19:55:02 cpqbld Exp $ */
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+ * npapi.h Revision: 1.76
+ * 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);
+jref 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_ */
diff --git a/plugin/include/npupp.h b/plugin/include/npupp.h
new file mode 100644
index 0000000..dfd4974
--- /dev/null
+++ b/plugin/include/npupp.h
@@ -0,0 +1,996 @@
+/* $Xorg: npupp.h,v 1.3 2000/08/17 19:55:02 cpqbld Exp $ */
+/* -*- Mode: C; tab-width: 4; -*- */
+/*
+ * npupp.h Revision: 1.37
+ * function call mecahnics needed by platform specific glue code.
+ */
+
+
+#ifndef _NPUPP_H_
+#define _NPUPP_H_
+
+#ifndef GENERATINGCFM
+#define GENERATINGCFM 0
+#endif
+
+#ifndef _NPAPI_H_
+#include "npapi.h"
+#endif
+
+#include "jri.h"
+
+/******************************************************************************************
+ plug-in function table macros
+ for each function in and out of the plugin API we define
+ typedef NPP_FooUPP
+ #define NewNPP_FooProc
+ #define CallNPP_FooProc
+ for mac, define the UPP magic for PPC/68K calling
+ *******************************************************************************************/
+
+
+/* NPP_Initialize */
+
+#if GENERATINGCFM
+typedef UniversalProcPtr NPP_InitializeUPP;
+
+enum {
+ uppNPP_InitializeProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0))
+ | RESULT_SIZE(SIZE_CODE(0))
+};
+
+#define NewNPP_InitializeProc(FUNC) \
+ (NPP_InitializeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_InitializeProcInfo, GetCurrentArchitecture())
+#define CallNPP_InitializeProc(FUNC) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_InitializeProcInfo)
+
+#else
+
+typedef void (*NPP_InitializeUPP)(void);
+#define NewNPP_InitializeProc(FUNC) \
+ ((NPP_InitializeUPP) (FUNC))
+#define CallNPP_InitializeProc(FUNC) \
+ (*(FUNC))()
+
+#endif
+
+
+/* NPP_Shutdown */
+
+#if GENERATINGCFM
+typedef UniversalProcPtr NPP_ShutdownUPP;
+
+enum {
+ uppNPP_ShutdownProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0))
+ | RESULT_SIZE(SIZE_CODE(0))
+};
+
+#define NewNPP_ShutdownProc(FUNC) \
+ (NPP_ShutdownUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_ShutdownProcInfo, GetCurrentArchitecture())
+#define CallNPP_ShutdownProc(FUNC) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_ShutdownProcInfo)
+
+#else
+
+typedef void (*NPP_ShutdownUPP)(void);
+#define NewNPP_ShutdownProc(FUNC) \
+ ((NPP_ShutdownUPP) (FUNC))
+#define CallNPP_ShutdownProc(FUNC) \
+ (*(FUNC))()
+
+#endif
+
+
+/* NPP_New */
+
+#if GENERATINGCFM
+typedef UniversalProcPtr NPP_NewUPP;
+
+enum {
+ uppNPP_NewProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPMIMEType)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(uint16)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int16)))
+ | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(char **)))
+ | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(char **)))
+ | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(NPSavedData *)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+
+#define NewNPP_NewProc(FUNC) \
+ (NPP_NewUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewProcInfo, GetCurrentArchitecture())
+#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewProcInfo, \
+ (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7))
+#else
+
+typedef NPError (*NPP_NewUPP)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved);
+#define NewNPP_NewProc(FUNC) \
+ ((NPP_NewUPP) (FUNC))
+#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7))
+
+#endif
+
+
+/* NPP_Destroy */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_DestroyUPP;
+enum {
+ uppNPP_DestroyProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPSavedData **)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPP_DestroyProc(FUNC) \
+ (NPP_DestroyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyProcInfo, GetCurrentArchitecture())
+#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyProcInfo, (ARG1), (ARG2))
+#else
+
+typedef NPError (*NPP_DestroyUPP)(NPP instance, NPSavedData** save);
+#define NewNPP_DestroyProc(FUNC) \
+ ((NPP_DestroyUPP) (FUNC))
+#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \
+ (*(FUNC))((ARG1), (ARG2))
+
+#endif
+
+
+/* NPP_SetWindow */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_SetWindowUPP;
+enum {
+ uppNPP_SetWindowProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPWindow *)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPP_SetWindowProc(FUNC) \
+ (NPP_SetWindowUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_SetWindowProcInfo, GetCurrentArchitecture())
+#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_SetWindowProcInfo, (ARG1), (ARG2))
+
+#else
+
+typedef NPError (*NPP_SetWindowUPP)(NPP instance, NPWindow* window);
+#define NewNPP_SetWindowProc(FUNC) \
+ ((NPP_SetWindowUPP) (FUNC))
+#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \
+ (*(FUNC))((ARG1), (ARG2))
+
+#endif
+
+
+/* NPP_NewStream */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_NewStreamUPP;
+enum {
+ uppNPP_NewStreamProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPStream *)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPBool)))
+ | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(uint16 *)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPP_NewStreamProc(FUNC) \
+ (NPP_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewStreamProcInfo, GetCurrentArchitecture())
+#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewStreamProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5))
+#else
+
+typedef NPError (*NPP_NewStreamUPP)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype);
+#define NewNPP_NewStreamProc(FUNC) \
+ ((NPP_NewStreamUPP) (FUNC))
+#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5))
+#endif
+
+
+/* NPP_DestroyStream */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_DestroyStreamUPP;
+enum {
+ uppNPP_DestroyStreamProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPP_DestroyStreamProc(FUNC) \
+ (NPP_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, GetCurrentArchitecture())
+#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, (NPParg), (NPStreamPtr), (NPReasonArg))
+
+#else
+
+typedef NPError (*NPP_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason);
+#define NewNPP_DestroyStreamProc(FUNC) \
+ ((NPP_DestroyStreamUPP) (FUNC))
+#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \
+ (*(FUNC))((NPParg), (NPStreamPtr), (NPReasonArg))
+
+#endif
+
+
+/* NPP_WriteReady */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_WriteReadyUPP;
+enum {
+ uppNPP_WriteReadyProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(int32)))
+};
+#define NewNPP_WriteReadyProc(FUNC) \
+ (NPP_WriteReadyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, GetCurrentArchitecture())
+#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \
+ (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, (NPParg), (NPStreamPtr))
+
+#else
+
+typedef int32 (*NPP_WriteReadyUPP)(NPP instance, NPStream* stream);
+#define NewNPP_WriteReadyProc(FUNC) \
+ ((NPP_WriteReadyUPP) (FUNC))
+#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \
+ (*(FUNC))((NPParg), (NPStreamPtr))
+
+#endif
+
+
+/* NPP_Write */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_WriteUPP;
+enum {
+ uppNPP_WriteProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int32)))
+ | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(void*)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(int32)))
+};
+#define NewNPP_WriteProc(FUNC) \
+ (NPP_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteProcInfo, GetCurrentArchitecture())
+#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \
+ (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteProcInfo, (NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr))
+
+#else
+
+typedef int32 (*NPP_WriteUPP)(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer);
+#define NewNPP_WriteProc(FUNC) \
+ ((NPP_WriteUPP) (FUNC))
+#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \
+ (*(FUNC))((NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr))
+
+#endif
+
+
+/* NPP_StreamAsFile */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_StreamAsFileUPP;
+enum {
+ uppNPP_StreamAsFileProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *)))
+ | RESULT_SIZE(SIZE_CODE(0))
+};
+#define NewNPP_StreamAsFileProc(FUNC) \
+ (NPP_StreamAsFileUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, GetCurrentArchitecture())
+#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, (ARG1), (ARG2), (ARG3))
+
+#else
+
+typedef void (*NPP_StreamAsFileUPP)(NPP instance, NPStream* stream, const char* fname);
+#define NewNPP_StreamAsFileProc(FUNC) \
+ ((NPP_StreamAsFileUPP) (FUNC))
+#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3))
+#endif
+
+
+/* NPP_Print */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_PrintUPP;
+enum {
+ uppNPP_PrintProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPrint *)))
+ | RESULT_SIZE(SIZE_CODE(0))
+};
+#define NewNPP_PrintProc(FUNC) \
+ (NPP_PrintUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_PrintProcInfo, GetCurrentArchitecture())
+#define CallNPP_PrintProc(FUNC, NPParg, voidPtr) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_PrintProcInfo, (NPParg), (voidPtr))
+
+#else
+
+typedef void (*NPP_PrintUPP)(NPP instance, NPPrint* platformPrint);
+#define NewNPP_PrintProc(FUNC) \
+ ((NPP_PrintUPP) (FUNC))
+#define CallNPP_PrintProc(FUNC, NPParg, NPPrintArg) \
+ (*(FUNC))((NPParg), (NPPrintArg))
+
+#endif
+
+
+/* NPP_HandleEvent */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_HandleEventUPP;
+enum {
+ uppNPP_HandleEventProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(int16)))
+};
+#define NewNPP_HandleEventProc(FUNC) \
+ (NPP_HandleEventUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_HandleEventProcInfo, GetCurrentArchitecture())
+#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \
+ (int16)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_HandleEventProcInfo, (NPParg), (voidPtr))
+
+#else
+
+typedef int16 (*NPP_HandleEventUPP)(NPP instance, void* event);
+#define NewNPP_HandleEventProc(FUNC) \
+ ((NPP_HandleEventUPP) (FUNC))
+#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \
+ (*(FUNC))((NPParg), (voidPtr))
+
+#endif
+
+
+/* NPP_URLNotify */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_URLNotifyUPP;
+enum {
+ uppNPP_URLNotifyProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*)))
+ | RESULT_SIZE(SIZE_CODE(SIZE_CODE(0)))
+};
+#define NewNPP_URLNotifyProc(FUNC) \
+ (NPP_URLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, GetCurrentArchitecture())
+#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4))
+
+#else
+
+typedef void (*NPP_URLNotifyUPP)(NPP instance, const char* url, NPReason reason, void* notifyData);
+#define NewNPP_URLNotifyProc(FUNC) \
+ ((NPP_URLNotifyUPP) (FUNC))
+#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4))
+
+#endif
+
+
+
+
+/*
+ * Netscape entry points
+ */
+
+#ifdef XP_UNIX
+
+/* NPN_GetValue */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_GetValueUPP;
+enum {
+ uppNPN_GetValueProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPNVariable)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_GetValueProc(FUNC) \
+ (NPN_GetValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetValueProcInfo, GetCurrentArchitecture())
+#define CallNPN_GetURNotifyLProc(FUNC, ARG1, ARG2, ARG3) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetValueProcInfo, (ARG1), (ARG2), (ARG3))
+#else
+
+typedef NPError (*NPN_GetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue);
+#define NewNPN_GetValueProc(FUNC) \
+ ((NPN_GetValueUPP) (FUNC))
+#define CallNPN_GetValueProc(FUNC, ARG1, ARG2, ARG3) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3))
+#endif
+
+#endif /* XP_UNIX */
+
+
+
+/* NPN_GetUrlNotify */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_GetURLNotifyUPP;
+enum {
+ uppNPN_GetURLNotifyProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_GetURLNotifyProc(FUNC) \
+ (NPN_GetURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, GetCurrentArchitecture())
+#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4))
+#else
+
+typedef NPError (*NPN_GetURLNotifyUPP)(NPP instance, const char* url, const char* window, void* notifyData);
+#define NewNPN_GetURLNotifyProc(FUNC) \
+ ((NPN_GetURLNotifyUPP) (FUNC))
+#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4))
+#endif
+
+
+/* NPN_PostUrlNotify */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_PostURLNotifyUPP;
+enum {
+ uppNPN_PostURLNotifyProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32)))
+ | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool)))
+ | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(void*)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_PostURLNotifyProc(FUNC) \
+ (NPN_PostURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, GetCurrentArchitecture())
+#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7))
+#else
+
+typedef NPError (*NPN_PostURLNotifyUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData);
+#define NewNPN_PostURLNotifyProc(FUNC) \
+ ((NPN_PostURLNotifyUPP) (FUNC))
+#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7))
+#endif
+
+
+/* NPN_GetUrl */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_GetURLUPP;
+enum {
+ uppNPN_GetURLProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_GetURLProc(FUNC) \
+ (NPN_GetURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLProcInfo, GetCurrentArchitecture())
+#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLProcInfo, (ARG1), (ARG2), (ARG3))
+#else
+
+typedef NPError (*NPN_GetURLUPP)(NPP instance, const char* url, const char* window);
+#define NewNPN_GetURLProc(FUNC) \
+ ((NPN_GetURLUPP) (FUNC))
+#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3))
+#endif
+
+
+/* NPN_PostUrl */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_PostURLUPP;
+enum {
+ uppNPN_PostURLProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32)))
+ | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*)))
+ | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_PostURLProc(FUNC) \
+ (NPN_PostURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLProcInfo, GetCurrentArchitecture())
+#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6))
+#else
+
+typedef NPError (*NPN_PostURLUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file);
+#define NewNPN_PostURLProc(FUNC) \
+ ((NPN_PostURLUPP) (FUNC))
+#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \
+ (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6))
+#endif
+
+
+/* NPN_RequestRead */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_RequestReadUPP;
+enum {
+ uppNPN_RequestReadProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPStream *)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPByteRange *)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_RequestReadProc(FUNC) \
+ (NPN_RequestReadUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_RequestReadProcInfo, GetCurrentArchitecture())
+#define CallNPN_RequestReadProc(FUNC, stream, range) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_RequestReadProcInfo, (stream), (range))
+
+#else
+
+typedef NPError (*NPN_RequestReadUPP)(NPStream* stream, NPByteRange* rangeList);
+#define NewNPN_RequestReadProc(FUNC) \
+ ((NPN_RequestReadUPP) (FUNC))
+#define CallNPN_RequestReadProc(FUNC, stream, range) \
+ (*(FUNC))((stream), (range))
+
+#endif
+
+
+/* NPN_NewStream */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_NewStreamUPP;
+enum {
+ uppNPN_NewStreamProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPStream **)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_NewStreamProc(FUNC) \
+ (NPN_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_NewStreamProcInfo, GetCurrentArchitecture())
+#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_NewStreamProcInfo, (npp), (type), (window), (stream))
+
+#else
+
+typedef NPError (*NPN_NewStreamUPP)(NPP instance, NPMIMEType type, const char* window, NPStream** stream);
+#define NewNPN_NewStreamProc(FUNC) \
+ ((NPN_NewStreamUPP) (FUNC))
+#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \
+ (*(FUNC))((npp), (type), (window), (stream))
+
+#endif
+
+
+/* NPN_Write */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_WriteUPP;
+enum {
+ uppNPN_WriteProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32)))
+ | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(int32)))
+};
+#define NewNPN_WriteProc(FUNC) \
+ (NPN_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_WriteProcInfo, GetCurrentArchitecture())
+#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \
+ (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_WriteProcInfo, (npp), (stream), (len), (buffer))
+
+#else
+
+typedef int32 (*NPN_WriteUPP)(NPP instance, NPStream* stream, int32 len, void* buffer);
+#define NewNPN_WriteProc(FUNC) \
+ ((NPN_WriteUPP) (FUNC))
+#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \
+ (*(FUNC))((npp), (stream), (len), (buffer))
+
+#endif
+
+
+/* NPN_DestroyStream */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_DestroyStreamUPP;
+enum {
+ uppNPN_DestroyStreamProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP )))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPN_DestroyStreamProc(FUNC) \
+ (NPN_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, GetCurrentArchitecture())
+#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \
+ (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, (npp), (stream), (reason))
+
+#else
+
+typedef NPError (*NPN_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason);
+#define NewNPN_DestroyStreamProc(FUNC) \
+ ((NPN_DestroyStreamUPP) (FUNC))
+#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \
+ (*(FUNC))((npp), (stream), (reason))
+
+#endif
+
+
+/* NPN_Status */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_StatusUPP;
+enum {
+ uppNPN_StatusProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char *)))
+};
+
+#define NewNPN_StatusProc(FUNC) \
+ (NPN_StatusUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_StatusProcInfo, GetCurrentArchitecture())
+#define CallNPN_StatusProc(FUNC, npp, msg) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_StatusProcInfo, (npp), (msg))
+
+#else
+
+typedef void (*NPN_StatusUPP)(NPP instance, const char* message);
+#define NewNPN_StatusProc(FUNC) \
+ ((NPN_StatusUPP) (FUNC))
+#define CallNPN_StatusProc(FUNC, npp, msg) \
+ (*(FUNC))((npp), (msg))
+
+#endif
+
+
+/* NPN_UserAgent */
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_UserAgentUPP;
+enum {
+ uppNPN_UserAgentProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(const char *)))
+};
+
+#define NewNPN_UserAgentProc(FUNC) \
+ (NPN_UserAgentUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_UserAgentProcInfo, GetCurrentArchitecture())
+#define CallNPN_UserAgentProc(FUNC, ARG1) \
+ (const char*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_UserAgentProcInfo, (ARG1))
+
+#else
+
+typedef const char* (*NPN_UserAgentUPP)(NPP instance);
+#define NewNPN_UserAgentProc(FUNC) \
+ ((NPN_UserAgentUPP) (FUNC))
+#define CallNPN_UserAgentProc(FUNC, ARG1) \
+ (*(FUNC))((ARG1))
+
+#endif
+
+
+/* NPN_MemAlloc */
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_MemAllocUPP;
+enum {
+ uppNPN_MemAllocProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(void *)))
+};
+
+#define NewNPN_MemAllocProc(FUNC) \
+ (NPN_MemAllocUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemAllocProcInfo, GetCurrentArchitecture())
+#define CallNPN_MemAllocProc(FUNC, ARG1) \
+ (void*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemAllocProcInfo, (ARG1))
+
+#else
+
+typedef void* (*NPN_MemAllocUPP)(uint32 size);
+#define NewNPN_MemAllocProc(FUNC) \
+ ((NPN_MemAllocUPP) (FUNC))
+#define CallNPN_MemAllocProc(FUNC, ARG1) \
+ (*(FUNC))((ARG1))
+
+#endif
+
+
+/* NPN__MemFree */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_MemFreeUPP;
+enum {
+ uppNPN_MemFreeProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(void *)))
+};
+
+#define NewNPN_MemFreeProc(FUNC) \
+ (NPN_MemFreeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFreeProcInfo, GetCurrentArchitecture())
+#define CallNPN_MemFreeProc(FUNC, ARG1) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFreeProcInfo, (ARG1))
+
+#else
+
+typedef void (*NPN_MemFreeUPP)(void* ptr);
+#define NewNPN_MemFreeProc(FUNC) \
+ ((NPN_MemFreeUPP) (FUNC))
+#define CallNPN_MemFreeProc(FUNC, ARG1) \
+ (*(FUNC))((ARG1))
+
+#endif
+
+
+/* NPN_MemFlush */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_MemFlushUPP;
+enum {
+ uppNPN_MemFlushProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(uint32)))
+};
+
+#define NewNPN_MemFlushProc(FUNC) \
+ (NPN_MemFlushUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFlushProcInfo, GetCurrentArchitecture())
+#define CallNPN_MemFlushProc(FUNC, ARG1) \
+ (uint32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFlushProcInfo, (ARG1))
+
+#else
+
+typedef uint32 (*NPN_MemFlushUPP)(uint32 size);
+#define NewNPN_MemFlushProc(FUNC) \
+ ((NPN_MemFlushUPP) (FUNC))
+#define CallNPN_MemFlushProc(FUNC, ARG1) \
+ (*(FUNC))((ARG1))
+
+#endif
+
+
+
+/* NPN_ReloadPlugins */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_ReloadPluginsUPP;
+enum {
+ uppNPN_ReloadPluginsProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPBool)))
+ | RESULT_SIZE(SIZE_CODE(0))
+};
+
+#define NewNPN_ReloadPluginsProc(FUNC) \
+ (NPN_ReloadPluginsUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, GetCurrentArchitecture())
+#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \
+ (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, (ARG1))
+
+#else
+
+typedef void (*NPN_ReloadPluginsUPP)(NPBool reloadPages);
+#define NewNPN_ReloadPluginsProc(FUNC) \
+ ((NPN_ReloadPluginsUPP) (FUNC))
+#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \
+ (*(FUNC))((ARG1))
+
+#endif
+
+
+/* NPN_GetJavaEnv */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_GetJavaEnvUPP;
+enum {
+ uppNPN_GetJavaEnvProcInfo = kThinkCStackBased
+ | RESULT_SIZE(SIZE_CODE(sizeof(JRIEnv*)))
+};
+
+#define NewNPN_GetJavaEnvProc(FUNC) \
+ (NPN_GetJavaEnvUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo, GetCurrentArchitecture())
+#define CallNPN_GetJavaEnvProc(FUNC) \
+ (JRIEnv*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo)
+
+#else
+
+typedef JRIEnv* (*NPN_GetJavaEnvUPP)(void);
+#define NewNPN_GetJavaEnvProc(FUNC) \
+ ((NPN_GetJavaEnvUPP) (FUNC))
+#define CallNPN_GetJavaEnvProc(FUNC) \
+ (*(FUNC))()
+
+#endif
+
+
+/* NPN_GetJavaPeer */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPN_GetJavaPeerUPP;
+enum {
+ uppNPN_GetJavaPeerProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(jref)))
+};
+
+#define NewNPN_GetJavaPeerProc(FUNC) \
+ (NPN_GetJavaPeerUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, GetCurrentArchitecture())
+#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \
+ (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, (ARG1))
+
+#else
+
+typedef jref (*NPN_GetJavaPeerUPP)(NPP instance);
+#define NewNPN_GetJavaPeerProc(FUNC) \
+ ((NPN_GetJavaPeerUPP) (FUNC))
+#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \
+ (*(FUNC))((ARG1))
+
+#endif
+
+
+
+
+/******************************************************************************************
+ * The actual plugin function table definitions
+ *******************************************************************************************/
+
+typedef struct _NPPluginFuncs {
+ uint16 size;
+ uint16 version;
+ NPP_NewUPP newp;
+ NPP_DestroyUPP destroy;
+ NPP_SetWindowUPP setwindow;
+ NPP_NewStreamUPP newstream;
+ NPP_DestroyStreamUPP destroystream;
+ NPP_StreamAsFileUPP asfile;
+ NPP_WriteReadyUPP writeready;
+ NPP_WriteUPP write;
+ NPP_PrintUPP print;
+ NPP_HandleEventUPP event;
+ NPP_URLNotifyUPP urlnotify;
+ JRIGlobalRef javaClass;
+} NPPluginFuncs;
+
+typedef struct _NPNetscapeFuncs {
+ uint16 size;
+ uint16 version;
+ NPN_GetURLUPP geturl;
+ NPN_PostURLUPP posturl;
+ NPN_RequestReadUPP requestread;
+ NPN_NewStreamUPP newstream;
+ NPN_WriteUPP write;
+ NPN_DestroyStreamUPP destroystream;
+ NPN_StatusUPP status;
+ NPN_UserAgentUPP uagent;
+ NPN_MemAllocUPP memalloc;
+ NPN_MemFreeUPP memfree;
+ NPN_MemFlushUPP memflush;
+ NPN_ReloadPluginsUPP reloadplugins;
+ NPN_GetJavaEnvUPP getJavaEnv;
+ NPN_GetJavaPeerUPP getJavaPeer;
+ NPN_GetURLNotifyUPP geturlnotify;
+ NPN_PostURLNotifyUPP posturlnotify;
+#ifdef XP_UNIX
+ NPN_GetValueUPP getvalue;
+#endif /* XP_UNIX */
+} NPNetscapeFuncs;
+
+
+
+#ifdef XP_MAC
+/******************************************************************************************
+ * Mac platform-specific plugin glue stuff
+ *******************************************************************************************/
+
+/*
+ * Main entry point of the plugin.
+ * This routine will be called when the plugin is loaded. The function
+ * tables are passed in and the plugin fills in the NPPluginFuncs table
+ * and NPPShutdownUPP for Netscape's use.
+ */
+
+#if GENERATINGCFM
+
+typedef UniversalProcPtr NPP_MainEntryUPP;
+enum {
+ uppNPP_MainEntryProcInfo = kThinkCStackBased
+ | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPNetscapeFuncs*)))
+ | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPluginFuncs*)))
+ | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPP_ShutdownUPP*)))
+ | RESULT_SIZE(SIZE_CODE(sizeof(NPError)))
+};
+#define NewNPP_MainEntryProc(FUNC) \
+ (NPP_MainEntryUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_MainEntryProcInfo, GetCurrentArchitecture())
+#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \
+ CallUniversalProc((UniversalProcPtr)(FUNC), (ProcInfoType)uppNPP_MainEntryProcInfo, (netscapeFunc), (pluginFunc), (shutdownUPP))
+
+#else
+
+typedef NPError (*NPP_MainEntryUPP)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownUPP*);
+#define NewNPP_MainEntryProc(FUNC) \
+ ((NPP_MainEntryUPP) (FUNC))
+#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \
+ (*(FUNC))((netscapeFunc), (pluginFunc), (shutdownUPP))
+
+#endif
+#endif /* MAC */
+
+
+#ifdef _WINDOWS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* plugin meta member functions */
+
+NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs);
+
+NPError WINAPI NP_Initialize(NPNetscapeFuncs* pFuncs);
+
+NPError WINAPI NP_Shutdown();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WINDOWS */
+
+#ifdef XP_UNIX
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* plugin meta member functions */
+
+char* NP_GetMIMEDescription(void);
+NPError NP_Initialize(NPNetscapeFuncs*, NPPluginFuncs*);
+NPError NP_Shutdown(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XP_UNIX */
+
+#endif /* _NPUPP_H_ */
diff --git a/plugin/libxrx.man b/plugin/libxrx.man
new file mode 100644
index 0000000..6ceca60
--- /dev/null
+++ b/plugin/libxrx.man
@@ -0,0 +1,152 @@
+.\" $Xorg: libxrx.man,v 1.4 2001/02/09 02:05:57 xorgcvs Exp $
+.\" Copyright 1996, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.\"
+.TH LIBXRX 1 "Release 6.4" "X Version 11"
+.SH NAME
+libxrx - RX Netscape Navigator Plug-in
+.SH DESCRIPTION
+The \fBRX Plug-in\fP may be used with Netscape Navigator (3.0 or later) to
+interpret documents in the RX MIME type format and start remote
+applications.
+.PP
+The \fBRX Plug-in\fP reads an RX document, from which it gets the list
+of services the application wants to use. Based on this information, the
+\fBRX Plug-in\fP sets the various requested services, including creating
+authorization keys if your X server supports the SECURITY extension. It
+then passes the relevant data, such as the X display name, to the
+application through an HTTP GET request of the associated CGI script. The
+Web server then executes the CGI script to start the application. The
+client runs on the web server host connected to your X server. In
+addition when the RX document is used within the EMBED tag (a Netscape
+extension to HTML), the \fBRX Plug-in\fP uses the XC-APPGROUP extension, if
+it is supported by your X server, to cause the remote application to be
+embedded within the browser page from which it was launched.
+.PP
+.SH INSTALLATION
+To install the \fBRX Plug-in\fP so that Netscape Navigator can use it, find
+the file named libxrx.so.6.3 or libxrx.sl.6.3 (or similar, depending on
+your platform) in <ProjectRoot>/lib (e.g. /usr/X11R6.4/lib) and copy it to
+either /usr/local/lib/netscape/plugins or $HOME/.netscape/plugins. Do
+not install the symlinks libxrx.so or libxrx.sl; they would confuse
+Netscape.
+.PP
+If you have configured Netscape Navigator to use the RX helper program
+(\fBxrx\fP), you must reconfigure it. Generally you simply need to remove
+or comment out the line you may have previously added in your mailcap file
+to use the RX helper program.
+Otherwise the plug-in will not be enabled. (The usual comment character for
+mailcap is ``#''.)
+.PP
+If you are already running Netscape Navigator, you need to exit and restart
+it after copying the plug-in library so the new plug-in will be found.
+Once this is done you can check that Navigator has successfully loaded the
+plug-in by checking the ``About Plug-ins'' page from the Help menu. This
+should show something like:
+
+ RX Plug-in
+
+ File name: /usr/local/lib/netscape/plugins/libxrx.sl.6.3
+
+ X Remote Activation Plug-in
+
+ Mime Type Description Suffixes Enabled
+ application/x-rx X Remote Activation Plug-in xrx Yes
+
+.PP
+Once correctly configured, Netscape Navigator will activate the \fBRX
+Plug-in\fP whenever you retrieve any document of the MIME type
+\fIapplication/x-rx\fP.
+.PP
+.SH RESOURCES
+The \fBRX Plug-in\fP looks for resources associated with the widget
+\fBnetscape.Navigator (\fPclass\fB Netscape.TopLevelShell)\fP and
+understands the following resource names and classes:
+.\".in +1in
+.TP 8
+.B "xrxHasFirewallProxy (\fPclass\fB XrxHasFirewallProxy)"
+Specifies whether an X server firewall proxy (see xfwp) is running and
+should be used. Default is ``False.'' The X firewall proxy uses
+the X Security Extension and this extension will only allow clients
+to connect to the X server if host-based authentication is turned
+on. See \fBxfwp(1)\fP for more information.
+.TP 8
+.B "xrxInternalWebServers (\fPclass\fB XrxInternalWebServers)"
+The web servers for which the X server firewall proxy should not be used
+(only relevant when \fBxrxHasFirewallProxy\fP is ``True''). Its value is a
+comma separated list of mask/value pairs to be used to filter internal
+web servers, based on their address. The mask part specifies which segments
+of the address are to be considered and the value part specifies what the
+result should match. For instance the following list:
+
+ 255.255.255.0/198.112.45.0, 255.255.255.0/198.112.46.0
+
+matches the address sets: 198.112.45.* and 198.112.46.*. More precisely,
+the test is (address & mask) == value.
+.TP 8
+.B "xrxFastWebServers (\fPclass\fB XrxFastWebServers)"
+The web servers for which LBX should not be used. The resource value is a
+list of address mask/value pairs, as previously described.
+.TP 8
+.B "xrxTrustedWebServers (\fPclass\fB XrxTrustedWebServers)"
+The web servers from which remote applications should be run as trusted
+clients. The default is to run remote applications as untrusted
+clients. The resource value is a list of address mask/value pairs, as
+previously described.
+.PP
+.SH ENVIRONMENT
+If the RX document requests X-UI-LBX service and the default X server does
+not advertise the LBX extension, the \fIRX Plug-in\fP will look for the
+environment variable ``XREALDISPLAY'' to get a second address for your X
+server and look for the LBX extension there. When running your browser
+through \fIlbxproxy\fP you will need to set XREALDISPLAY to the actual
+address of your server if you wish remote applications to be able to use
+LBX across the Internet.
+.PP
+If the RX document requests XPRINT service, \fIRX Plug-in\fP looks for the
+variable ``XPRINTER'' to get the printer name and X Print server address to
+use. If the server address is not specified as part of XPRINTER, \fIRX
+Plug-in\fP uses the first one specified through the variable
+``XPSERVERLIST'' when it is set. When it is not \fIRX Plug-in\fP then tries
+to use the video server as the print server. If the printer name is not
+specified via XPRINTER, \fIRX Plug-in\fP looks for it in the variables
+``PDPRINTER'', then ``LPDEST'', and finally ``PRINTER'',
+.PP
+Finally, if you are using a firewall proxy, \fIRX Plug-in\fP will look for
+``PROXY_MANAGER'' to get the address of your proxy manager (see
+proxymngr). When not specified it will use ":6500" as the default.
+.PP
+.SH KNOWN BUG
+When an authorization key is created for a remote application to use the X
+Print service, the \fBRX Plug-in\fP has to create the key with an infinite
+timeout since nobody knows when the application will actually connect to
+the X Print server. It then revokes the key when its instance is destroyed
+(that is when you go to another page). However, if the Plug-in does not get
+destroyed properly, which happens when Netscape Navigator dies
+unexpectedly, the print authorization key will never get revoked.
+.PP
+.SH SEE ALSO
+xrx (1), xfwp (1), lbxproxy (1), proxymngr (1), The RX Document specification
+.SH AUTHORS
+Arnaud Le Hors and Kaleb Keithley, X Consortium
diff --git a/plugin/stubs.c b/plugin/stubs.c
new file mode 100644
index 0000000..4aab758
--- /dev/null
+++ b/plugin/stubs.c
@@ -0,0 +1,15 @@
+/* $Xorg: stubs.c,v 1.3 2000/08/17 19:54:59 cpqbld Exp $ */
+/* -*- 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
diff --git a/rx/BuildReq.c b/rx/BuildReq.c
new file mode 100644
index 0000000..50ba6b5
--- /dev/null
+++ b/rx/BuildReq.c
@@ -0,0 +1,150 @@
+/* $Xorg: BuildReq.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxI.h"
+
+/* build the GET request to perform to launch the remote application */
+char *
+RxBuildRequest(RxReturnParams *params)
+{
+ char *request, *ptr;
+ int len, action_len, embed_len, width_len, height_len,
+ ui_len, print_len, x_ui_lbx_len, x_print_lbx_len;
+ char width_str[10], height_str[10];
+
+ /* the action parameter is mandatory */
+ if (params->action == NULL)
+ return NULL;
+
+ /*
+ * compute string size
+ */
+ action_len = embed_len = width_len = height_len = 0;
+ ui_len = print_len = x_ui_lbx_len = x_print_lbx_len = 0;
+
+ len = (action_len = strlen(params->action)) + 1; /* URL + delimiter */
+
+ /* RX_EMBEDDED + "=" + value + delimiter,
+ sizeof including '\0' no need to add anything for the delimiter */
+ if (params->embedded != RxUndef)
+ len += (embed_len = sizeof(RX_EMBEDDED) +
+ (params->embedded == RxTrue ? sizeof(RX_YES) : sizeof(RX_NO)));
+
+ /* RX_WIDTH + "=" + value + delimiter */
+ if (params->width != RxUndef) {
+ sprintf(width_str, "%d", params->width);
+ len += (width_len = sizeof(RX_WIDTH) + strlen(width_str) + 1);
+ }
+ /* RX_HEIGHT + "=" + value + delimiter */
+ if (params->height != RxUndef) {
+ sprintf(height_str, "%d", params->height);
+ len += (height_len = sizeof(RX_HEIGHT) + strlen(height_str) + 1);
+ }
+ if (params->ui != NULL)
+ /* "UI=" + URL + delimiter */
+ len += (ui_len = sizeof(RX_UI)+ strlen(params->ui) + 1);
+ if (params->print != NULL)
+ /* "PRINT=" + URL + delimiter */
+ len += (print_len = sizeof(RX_PRINT) + strlen(params->print) + 1);
+
+ /* RX_X_UI_LBX + "=" + value + delimiter,
+ sizeof including '\0' no need to add anything for the delimiter */
+ if (params->x_ui_lbx != RxUndef) {
+ x_ui_lbx_len = sizeof(RX_X_UI_LBX);
+ if (params->x_ui_lbx == RxTrue) {
+ x_ui_lbx_len += sizeof(RX_YES);
+ if (params->x_ui_lbx_auth != NULL) /* 6 for ";auth=" */
+ x_ui_lbx_len += strlen(params->x_ui_lbx_auth) + 6;
+ } else
+ x_ui_lbx_len += sizeof(RX_NO);
+ len += x_ui_lbx_len;
+ }
+
+ /* RX_X_PRINT_LBX + "=" + value + delimiter,
+ sizeof including '\0' no need to add anything for the delimiter */
+ if (params->x_print_lbx != RxUndef) {
+ x_print_lbx_len = sizeof(RX_X_PRINT_LBX);
+ if (params->x_print_lbx == RxTrue) {
+ x_print_lbx_len += sizeof(RX_YES);
+ if (params->x_print_lbx_auth != NULL) /* 6 for ";auth=" */
+ x_print_lbx_len += strlen(params->x_print_lbx_auth) + 6;
+ } else
+ x_print_lbx_len += sizeof(RX_NO);
+ len += x_print_lbx_len;
+ }
+
+ /*
+ * malloc string and set it
+ */
+ request = ptr = (char *)Malloc(len);
+ strcpy(ptr, params->action);
+ ptr += action_len;
+ if (embed_len != 0) {
+ sprintf(ptr, "%c%s=%s", RX_QUERY_DELIMITER, RX_EMBEDDED,
+ (params->embedded == RxTrue ? RX_YES : RX_NO));
+ ptr += embed_len; /* be careful delimiter is included here */
+ }
+ if (width_len != 0) {
+ sprintf(ptr, "%c%s=%s", RX_QUERY_DELIMITER, RX_WIDTH, width_str);
+ ptr += width_len;
+ }
+ if (height_len != 0) {
+ sprintf(ptr, "%c%s=%s", RX_QUERY_DELIMITER, RX_HEIGHT, height_str);
+ ptr += height_len;
+ }
+ if (ui_len != 0) {
+ sprintf(ptr, "%c%s=%s", RX_QUERY_DELIMITER, RX_UI, params->ui);
+ ptr += ui_len;
+ }
+ if (print_len != 0) {
+ sprintf(ptr, "%c%s=%s", RX_QUERY_DELIMITER, RX_PRINT, params->print);
+ ptr += print_len;
+ }
+ if (x_ui_lbx_len != 0) {
+ if (params->x_ui_lbx == RxTrue && params->x_ui_lbx_auth != NULL)
+ sprintf(ptr, "%c%s=%s;auth=%s", RX_QUERY_DELIMITER, RX_X_UI_LBX,
+ RX_YES, params->x_ui_lbx_auth);
+ else
+ sprintf(ptr, "%c%s=%s", RX_QUERY_DELIMITER, RX_X_UI_LBX,
+ (params->x_ui_lbx == RxTrue ? RX_YES : RX_NO));
+ ptr += x_ui_lbx_len;
+ }
+ if (x_print_lbx_len != 0) {
+ if (params->x_print_lbx == RxTrue
+ && params->x_print_lbx_auth != NULL)
+ sprintf(ptr, "%c%s=%s;auth=%s", RX_QUERY_DELIMITER,
+ RX_X_PRINT_LBX, RX_YES, params->x_print_lbx_auth);
+ else
+ sprintf(ptr, "%c%s=%s", RX_QUERY_DELIMITER, RX_X_PRINT_LBX,
+ (params->x_print_lbx == RxTrue ? RX_YES : RX_NO));
+ ptr += x_print_lbx_len;
+ }
+
+ return request;
+}
diff --git a/rx/PParse.c b/rx/PParse.c
new file mode 100644
index 0000000..07e360b
--- /dev/null
+++ b/rx/PParse.c
@@ -0,0 +1,460 @@
+/* $Xorg: PParse.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxI.h"
+
+#define RX_DEFAULT_VERSION 1
+#define RX_DEFAULT_REVISION 0
+
+
+typedef struct {
+ char *string;
+ int length;
+ int index;
+} Token;
+
+/* macros to make token tables */
+#define TOKEN(s, i) { s, sizeof(s) - 1, i }
+#define NULLTOKEN { NULL, 0, 0 }
+
+/* tables of tokens,
+ each token is made of a string and its associated enum value.
+ */
+static Token RxServices[] = {
+ TOKEN(RX_UI, UI),
+ TOKEN(RX_PRINT, Print),
+ NULLTOKEN
+};
+
+static Token RxUIs[] = {
+ TOKEN("X", XUI),
+ NULLTOKEN
+};
+
+static Token RxPrints[] = {
+ TOKEN("XPrint", XPrint),
+ NULLTOKEN
+};
+
+
+static Token RxXAuthentications[] = {
+ TOKEN("MIT-MAGIC-COOKIE-1", MitMagicCookie1),
+ NULLTOKEN
+};
+
+#ifdef NEED_STRCASECMP
+/*
+ * in case str[n]casecmp are not provided by the system here are some
+ * which do the trick
+ */
+int
+_RxStrcasecmp(register const char *s1, register const char *s2)
+{
+ register int c1, c2;
+
+ while (*s1 && *s2) {
+ c1 = tolower(*s1);
+ c2 = tolower(*s2);
+ if (c1 != c2)
+ return (c1 - c2);
+ s1++;
+ s2++;
+ }
+ return (int) (*s1 - *s2);
+}
+
+int
+_RxStrncasecmp(register const char *s1, register const char *s2, size_t n)
+{
+ register int c1, c2;
+ const char *l1 = s1 + n;
+ const char *l2 = s2 + n;
+
+ while (*s1 && *s2 && s1 < l1 && s2 < l2) {
+ c1 = tolower(*s1);
+ c2 = tolower(*s2);
+ if (c1 != c2)
+ return (c1 - c2);
+ s1++;
+ s2++;
+ }
+ if (s1 < l1 && s2 < l2)
+ return (int) (*s1 - *s2);
+ else if (s1 < l1)
+ return (int) *s1;
+ else if (s2 < l2)
+ return (int) *s2;
+ return 0;
+}
+#endif
+
+/* string copy functions */
+static char *
+strcopy(char *src)
+{
+ char *cpy = (char *)Malloc(strlen(src) + 1);
+ if (cpy)
+ strcpy(cpy, src);
+ return cpy;
+}
+
+static char *
+strncopy(char *src, int n)
+{
+ char *cpy = (char *)Malloc(n + 1);
+ if (cpy) {
+ strncpy(cpy, src, n);
+ cpy[n] = '\0';
+ }
+ return cpy;
+}
+
+
+/* print out warning message */
+#define WARNING(m, p) if (debug != 0) Warning(m, p)
+static void
+Warning(char *message, char *param)
+{
+ fprintf(stderr, "Warning: %s%s\n", message, param);
+}
+
+#define WARNINGN(m, p, n) if (debug != 0) WarningN(m, p, n)
+static void
+WarningN(char *message, char *param, int param_len)
+{
+ fprintf(stderr, "Warning: %s", message);
+ fwrite((void *)param, sizeof(char), param_len, stderr);
+ putc('\n', stderr);
+}
+
+/* print out error message */
+static void
+Error(char *message, char *param)
+{
+ fprintf(stderr, "Error: %s%s\n", message, param);
+}
+
+/* look for a known token and return its index or 0 */
+static int
+LookForToken(char *string, Token *token)
+{
+ for (; token->string != NULL; token++)
+ if (Strncasecmp(string, token->string, token->length) == 0)
+ return token->index;
+ return 0;
+}
+
+/* parse a comma separated list string: a,b,c
+ for each element look for a known token,
+ when found store the associated index in the given index table,
+ when not found print out a WARNING and skip,
+ terminate the index table with 0,
+ return number of recognized tokens.
+ Note that no array bound verification is done!
+ */
+static int
+ParseList(char *value, Token *tokens, int *indices, int debug)
+{
+ char *next;
+ int token;
+ int n = 0;
+
+ do {
+ token = LookForToken(value, tokens);
+ next = strchr(value, ',');
+
+ /* if unknown token print out WARNING */
+ if (token == 0) {
+ if (next != NULL) {
+ /* not a NULL terminated string, so make one */
+ char buf[BUFSIZ];
+ int len = (next - value < BUFSIZ) ? next - value : BUFSIZ;
+
+ strncpy(buf, value, len);
+ buf[len] = '\0';
+ WARNING("unknown parameter value: ", buf);
+ } else
+ WARNING("unknown parameter value: ", value);
+ } else
+ indices[n++] = token;
+
+ if (next != NULL)
+ value = next + 1;
+ } while (next);
+
+ indices[n] = 0;
+
+ return n;
+}
+
+/* Parse a comma separated list of pairs name[:value] such as: A:a,B,C:c
+ for each element look for a known token,
+ when found store the associated index in the given index table and copy
+ the associated value,
+ when not found print out a WARNING and skip,
+ terminate the index table with 0,
+ return number of recognized tokens.
+ Note that no array bound verification is done!
+ */
+static int
+ParseAuthList(char *value, Token *tokens, int *indices, char **values,
+ int debug)
+{
+ char *next, *ptr;
+ int token;
+ int n = 0;
+
+ do {
+ token = LookForToken(value, tokens);
+ ptr = strchr(value, ':');
+ next = strchr(((ptr != NULL) ? ptr : value), ',');
+
+ /* if unknown token print out WARNING */
+ if (token == 0) {
+ if (next != NULL) {
+ /* not a NULL terminated string, so make one */
+ char buf[BUFSIZ];
+ int len = (next - value < BUFSIZ) ? next - value : BUFSIZ;
+
+ strncpy(buf, value, len);
+ buf[len] = '\0';
+ WARNING("unknown parameter value: ", buf);
+ } else
+ WARNING("unknown parameter value: ", value);
+ } else {
+ indices[n] = token;
+ if (ptr != NULL) { /* there is an associated data */
+ if (next != NULL)
+ values[n++] = strncopy(ptr + 1, next - ptr);
+ else
+ values[n++] = strcopy(ptr + 1);
+ } else
+ values[n++] = NULL;
+ }
+
+ if (next != NULL)
+ value = next + 1;
+ } while (next);
+
+ indices[n] = 0;
+
+ return n;
+}
+
+/* parse a boolean string value returning 0 on success, 1 otherwise */
+static int
+ParseBoolean(char *strvalue, RxBool *value_ret)
+{
+ if (Strcasecmp(strvalue, RX_YES) == 0) {
+ *value_ret = RxTrue;
+ return 0;
+ } else if (Strcasecmp(strvalue, RX_NO) == 0) {
+ *value_ret = RxFalse;
+ return 0;
+ }
+ return 1;
+}
+
+/* parse an X-UI-INPUT-METHOD parameter value */
+static int
+ParseXInputMethod(char *value,
+ RxBool *input_method_ret, char **input_method_url_ret,
+ int debug)
+{
+ char *url;
+
+ url = strchr(value, ';');
+ if (url != NULL) {
+ if (strncmp(value, RX_YES, sizeof(RX_YES) - 1) == 0) {
+ *input_method_ret = RxTrue;
+ *input_method_url_ret = strcopy(url + 1);
+ } else if (strncmp(value, RX_YES, sizeof(RX_YES) - 1) == 0)
+ *input_method_ret = RxFalse;
+ else
+ WARNINGN("not a boolean value: ", value, url - value);
+ } else {
+ if (ParseBoolean(value, input_method_ret) != 0)
+ WARNING("not a boolean value: ", value);
+ }
+ return 0;
+}
+
+
+/* parse an RX parameter */
+static int
+ParseParam(char *name, char *value, RxParams *params, int debug)
+{
+ if (Strcasecmp(name, RX_ACTION) == 0) {
+ Free(params->action);
+ params->action = strcopy(value);
+ } else if (Strcasecmp(name, RX_EMBEDDED) == 0) {
+ if (ParseBoolean(value, &params->embedded) != 0)
+ WARNING("not a boolean value: ", value);
+ } else if (Strcasecmp(name, RX_AUTO_START) == 0) {
+ if (ParseBoolean(value, &params->auto_start) != 0)
+ WARNING("not a boolean value: ", value);
+ } else if (Strcasecmp(name, RX_WIDTH) == 0)
+ params->width = atoi(value);
+ else if (Strcasecmp(name, RX_HEIGHT) == 0)
+ params->height = atoi(value);
+ else if (Strcasecmp(name, RX_APP_GROUP) == 0) {
+ Free(params->app_group);
+ params->app_group = strcopy(value);
+ } else if (Strcasecmp(name, RX_REQUIRED_SERVICES) == 0)
+ ParseList(value, RxServices, (int*)params->required_services, debug);
+ else if (Strcasecmp(name, RX_UI) == 0)
+ ParseList(value, RxUIs, (int*)params->ui, debug);
+ else if (Strcasecmp(name, RX_PRINT) == 0)
+ ParseList(value, RxPrints, (int*)params->print, debug);
+ else if (Strcasecmp(name, RX_X_UI_INPUT_METHOD) == 0)
+ ParseXInputMethod(value, &params->x_ui_input_method,
+ &params->x_ui_input_method_url, debug);
+ else if (Strcasecmp(name, RX_X_AUTH) == 0)
+ ParseAuthList(value, RxXAuthentications,
+ (int*)params->x_auth, params->x_auth_data, debug);
+ else if (Strcasecmp(name, RX_X_UI_AUTH) == 0)
+ ParseAuthList(value, RxXAuthentications,
+ (int*)params->x_ui_auth, params->x_ui_auth_data, debug);
+ else if (Strcasecmp(name, RX_X_PRINT_AUTH) == 0)
+ ParseAuthList(value, RxXAuthentications,
+ (int*)params->x_print_auth, params->x_print_auth_data,
+ debug);
+ else if (Strcasecmp(name, RX_X_UI_LBX_AUTH) == 0)
+ ParseAuthList(value, RxXAuthentications,
+ (int*)params->x_ui_lbx_auth,
+ params->x_ui_lbx_auth_data, debug);
+ else if (Strcasecmp(name, RX_X_PRINT_LBX_AUTH) == 0)
+ ParseAuthList(value, RxXAuthentications,
+ (int*)params->x_print_lbx_auth,
+ params->x_print_lbx_auth_data,
+ debug);
+ else if (Strcasecmp(name, RX_X_UI_LBX) == 0) {
+ if (ParseBoolean(value, &params->x_ui_lbx) != 0)
+ WARNING("not a boolean value: ", value);
+ } else if (Strcasecmp(name, RX_X_PRINT_LBX) == 0) {
+ if (ParseBoolean(value, &params->x_print_lbx) != 0)
+ WARNING("not a boolean value: ", value);
+ } else /* unknown parameter */
+ WARNING("unknown parameter name: ", name);
+ return 0;
+}
+
+/* parse a list of RX arguments storing result in the given RxParams struct,
+ * since this function might be called several times using the same structure,
+ * it is assumed that the structure is correctly initialized.
+ */
+int
+RxParseParams(char *argn[], char *argv[], int argc, RxParams *params,
+ int debug)
+{
+ int i;
+ int version, revision;
+
+ if (argc == 0)
+ return 0;
+
+ /* the first param should be the Version number */
+ if (Strcasecmp(argn[0], RX_VERSION) == 0) {
+ if (sscanf(argv[0], "%d.%d", &version, &revision) == 2) {
+ params->version = version;
+ params->revision = revision;
+ } else {
+ Error("invalid version identifier: ", argv[0]);
+ return 1;
+ }
+ argn++;
+ argv++;
+ i = 1;
+ } else {
+ /* no version identifier assume 1.0 */
+ params->version = RX_DEFAULT_VERSION;
+ params->revision = RX_DEFAULT_REVISION;
+ i = 0;
+ }
+
+ /* parse given params */
+ for (; i < argc; i++, argn++, argv++)
+ if (ParseParam(*argn, *argv, params, debug))
+ return 1;
+
+ return 0;
+}
+
+/* Initialize RxParams structure */
+void
+RxInitializeParams(RxParams *params)
+{
+ memset(params, 0, sizeof(RxParams));
+ params->embedded = RxUndef;
+ params->auto_start = RxUndef;
+ params->width = RxUndef;
+ params->height = RxUndef;
+ /* init X params */
+ params->x_ui_input_method = RxUndef;
+ params->x_ui_input_method_url = NULL;
+ params->x_ui_lbx = RxUndef;
+ params->x_print_lbx = RxUndef;
+}
+
+void
+FreeAuthListData(char **list)
+{
+ while (*list != NULL)
+ Free(*list++);
+}
+
+/* Free data stored in RxParams structure */
+int
+RxFreeParams(RxParams *params)
+{
+ Free(params->action);
+ Free(params->app_group);
+
+ Free(params->x_ui_input_method_url);
+ FreeAuthListData(params->x_auth_data);
+ FreeAuthListData(params->x_ui_auth_data);
+ FreeAuthListData(params->x_print_auth_data);
+ FreeAuthListData(params->x_ui_lbx_auth_data);
+ FreeAuthListData(params->x_print_lbx_auth_data);
+
+ return 0;
+}
+
+/* Free data stored in RxReturnParams structure */
+int
+RxFreeReturnParams(RxReturnParams *params)
+{
+ /* action is only a reference - do not free */
+ Free(params->ui);
+ Free(params->print);
+
+ Free(params->x_ui_lbx_auth);
+ Free(params->x_print_lbx_auth);
+ return 0;
+}
diff --git a/rx/PRead.c b/rx/PRead.c
new file mode 100644
index 0000000..ce09217
--- /dev/null
+++ b/rx/PRead.c
@@ -0,0 +1,274 @@
+/* $Xorg: PRead.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxI.h"
+#include <ctype.h>
+
+
+/* Not null terminated string */
+typedef struct {
+ char *ptr; /* beginning of string */
+ int length; /* length of string */
+} NString;
+
+
+#ifdef NETSCAPE_PLUGIN
+/* utility function for netscape plugin where realloc is not available
+ * it's too bad we need both the old size and the new one...
+ */
+void *
+_RxRealloc(void *p, size_t olds, size_t s)
+{
+ void *np = Malloc(s);
+ if (np) {
+ memcpy(np, p, olds);
+ Free(p);
+ }
+ return np;
+}
+#endif
+
+
+/* get next word and return trailing stream */
+static char *
+NextWord(char *stream, char *limit, NString *word)
+{
+ /* skip leading whitespace */
+ while (isspace((int) *stream) && *stream && stream != limit)
+ stream++;
+ word->ptr = stream;
+ /* go to first whitespace */
+ while (!isspace((int) *stream) && *stream && stream != limit)
+ stream++;
+ word->length = stream - word->ptr;
+ return stream;
+}
+
+
+/* get next chunk of text, with possible quoted sections,
+ and return trailing stream */
+static char *
+NextChunk(char *stream, char *limit, NString *word)
+{
+ /* skip leading whitespace */
+ while (isspace((int) *stream) && *stream && stream != limit)
+ stream++;
+ word->ptr = stream;
+
+ /* go to first whitespace or end of string */
+ while (!isspace((int) *stream) && *stream && stream != limit) {
+ if (*stream == '"' || *stream == '\'') {
+ char quote = *stream;
+ do
+ stream++;
+ while (*stream != quote && *stream && stream != limit);
+ if (*stream && stream != limit)
+ stream++;
+ break;
+ } else
+ stream++;
+ }
+ word->length = stream - word->ptr;
+ return stream;
+}
+
+
+/* get next SGML element "< ... >" and return next trailing stream */
+static char *
+NextElement(char *stream, NString *element)
+{
+
+ /* look for opening bracket */
+ while (*stream != '<' && *stream)
+ stream++;
+
+ element->ptr = stream;
+
+ /* look for closing bracket */
+ while (*stream != '>' && *stream)
+ stream++;
+
+ element->length = stream - element->ptr;
+
+ return *stream ? stream + 1 : stream;
+}
+
+
+/* seek next PARAM element content: "<PARAM ... >" (delimiters excluded)
+ and return next trailing stream */
+static char *
+NextParam(char *stream, NString *param)
+{
+ NString element, word;
+
+ do {
+ stream = NextElement(stream, &element);
+
+ if (element.length)
+ /* get element name */
+ (void) NextWord(element.ptr + 1, element.ptr + element.length - 1,
+ &word);
+ else {
+ /* no more elements stop here */
+ param->ptr = 0;
+ param->length = 0;
+
+ return stream;
+ }
+
+ /* check if it's a PARAM element */
+ } while(word.length != 5 && memcmp("PARAM", word.ptr, 5) != 0 && *stream);
+
+ param->ptr = word.ptr + word.length;
+ param->length = element.length - word.length - 1; /* delimiters excluded */
+
+ return stream;
+}
+
+
+/* return literal value as a Null terminated string,
+ removing possible quotes and extra whitespace */
+static char *
+GetLiteralValue(NString *literal)
+{
+ char *ptr, *limit, *value, *vptr;
+ char quote;
+ int skip;
+
+ value = vptr = (char *)Malloc(literal->length + 1);
+ if (!value)
+ return 0;
+
+ ptr = literal->ptr;
+ limit = ptr + literal->length;
+ quote = (*ptr == '"' || *ptr == '\'') ? *ptr++ : '\0';
+ skip = 0;
+ do
+ if (isspace((int) *ptr)) {
+ if (!skip) {
+ *vptr++ = ' ';
+ skip = 1;
+ }
+ ptr++;
+ } else {
+ skip = 0;
+ *vptr++ = *ptr++;
+ }
+ while (*ptr != quote && ptr != limit);
+ *vptr = '\0';
+
+ return value;
+}
+
+
+/* parse PARAM tag content: " NAME=... VALUE=... " */
+static int
+ParseParam(NString *param, char **name_ret, char **value_ret)
+{
+ NString word, name, value;
+ char *stream = param->ptr;
+ char *limit = param->ptr + param->length;
+
+ /* look for the name part */
+ do
+ stream = NextChunk(stream, limit, &word);
+ while (word.length < 5 && memcmp("NAME=", word.ptr, 5 != 0) && *stream);
+ if (stream == limit)
+ return 1;
+ name.ptr = word.ptr + 5;
+ name.length = word.length - 5;
+ *name_ret = GetLiteralValue(&name);
+
+ /* look for the value part */
+ do
+ stream = NextChunk(stream, limit, &word);
+ while (word.length < 6 && memcmp("VALUE=", word.ptr, 6) != 0 && *stream);
+ value.ptr = word.ptr + 6;
+ value.length = word.length - 6;
+ *value_ret = GetLiteralValue(&value);
+
+ return 0;
+}
+
+/* how much we make a params array bigger every time we reach the limit */
+#define PARAMSINC 10
+
+/* read an RX document stream and augment the given list of arguments */
+int
+RxReadParams(char *stream,
+ char **argn_ret[], char **argv_ret[], int *argc_ret)
+{
+ char **argv, **argn;
+ int argc, n;
+ NString param;
+ char *name, *value;
+ int status;
+
+ status = 0;
+ argc = n = 0;
+ argn = argv = NULL;
+ if (stream != NULL) {
+ do {
+ stream = NextParam(stream, &param);
+ if (param.length != 0 && ParseParam(&param, &name, &value) == 0) {
+ argc++;
+ if (n == 0) { /* alloc first block */
+ n = PARAMSINC;
+ argn = (char **)Malloc(sizeof(char *) * n);
+ if (!argn)
+ return 1;
+ argv = (char **)Malloc(sizeof(char *) * n);
+ if (!argv) {
+ Free(argn);
+ return 1;
+ }
+ }
+ if (argc % PARAMSINC == 0) { /* we need to add a block */
+ n += PARAMSINC;
+ argn = (char **)
+ Realloc(argn, sizeof(char *) * argc, sizeof(char *) * n);
+ argv = (char **)
+ Realloc(argv, sizeof(char *) * argc, sizeof(char *) * n);
+ if (!argn || !argv) {
+ argc--;
+ status = 1;
+ break;
+ }
+ }
+ argn[argc - 1] = name;
+ argv[argc - 1] = value;
+ }
+ } while (*stream);
+ }
+ *argn_ret = argn;
+ *argv_ret = argv;
+ *argc_ret = argc;
+
+ return status;
+}
diff --git a/rx/Prefs.c b/rx/Prefs.c
new file mode 100644
index 0000000..428cf62
--- /dev/null
+++ b/rx/Prefs.c
@@ -0,0 +1,273 @@
+/* $Xorg: Prefs.c,v 1.5 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "Prefs.h"
+#include <ctype.h>
+#include "RxI.h" /* for Malloc & Free */
+#include <X11/StringDefs.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+typedef struct {
+ Boolean has_fwp;
+ String internal_webservers; /* servers for which we won't use a fwp */
+ String trusted_webservers;
+ String fast_webservers; /* servers for which we won't use lbx */
+} Prefs;
+
+#define offset(field) XtOffsetOf(Prefs, field)
+
+static XtResource resources[] = {
+ { "XrxHasFirewallProxy", "xrxHasFirewallProxy",
+ XtRBoolean, sizeof(Boolean),
+ offset(has_fwp), XtRImmediate, (caddr_t) False },
+ { "XrxInternalWebServers", "xrxInternalWebServers",
+ XtRString, sizeof(String),
+ offset(internal_webservers), XtRImmediate, (caddr_t) NULL },
+ { "XrxTrustedWebServers", "xrxTrustedWebServers",
+ XtRString, sizeof(String),
+ offset(trusted_webservers), XtRImmediate, (caddr_t) NULL },
+ { "XrxFastWebServers", "xrxFastWebServers", XtRString, sizeof(String),
+ offset(fast_webservers), XtRImmediate, (caddr_t) NULL }
+};
+
+
+/*
+ * Return the next available element in a list of AddressFilters, making the
+ * list bigger when necessary.
+ */
+/* how much bigger we make the list every time we reach the limit */
+#define SIZEINC 8
+
+static AddressFilter *
+NextAFListElem(AddressFilter **list, int *count)
+{
+ AddressFilter *l;
+ int n;
+
+ l = *list;
+ n = *count;
+
+ /* first make sure the list is big enough */
+ if (n == 0) {
+ l = (AddressFilter *)Malloc(sizeof(AddressFilter) * SIZEINC);
+ if (l == NULL)
+ return NULL;
+ *list = l;
+ } else if (n % SIZEINC == 0) { /* we need to enlarge the list */
+ l = (AddressFilter *)Realloc(l, sizeof(AddressFilter) * n,
+ sizeof(AddressFilter) * (n + SIZEINC));
+ if (l == NULL)
+ return NULL;
+ *list = l;
+ }
+ /* then just return the first available element */
+ *count = n + 1;
+ return (*list) + n;
+}
+
+/*
+ * find the end of next element of a comma separated string,
+ * returning the pointer to the trailing string or NULL if there is none
+ */
+static char *
+NextListElem(char *ptr, char **end_ret)
+{
+ char *end = strchr(ptr, ',');
+ if (end != NULL) {
+ /* skip comma and possible following space */
+ ptr = end + 1;
+ while (*ptr && isspace(*ptr))
+ ptr++;
+ } else {
+ end = ptr + strlen(ptr);
+ ptr = NULL;
+ }
+ *end_ret = end;
+ return ptr;
+}
+
+
+/*
+ * retreive the two parts of mask/value from the given string, specified by
+ * its beginning and end, and copy them into the given buffers
+ */
+static int
+ParseListElem(char *bos, char *eos,
+ char *buf1, int len1, char *buf2, int len2)
+{
+ char *sep = strchr(bos, '/');
+ if (sep != NULL) {
+ int len = sep - bos;
+ if (len < len1) {
+ strncpy(buf1, bos, len);
+ buf1[len] = '\0';
+ /* now deal with the second part */
+ bos = sep + 1;
+ len = eos - bos;
+ if (len < len2) {
+ strncpy(buf2, bos, len);
+ buf2[len] = '\0';
+ return 1;
+ }
+ }
+ }
+ return 0; /* failed */
+}
+
+
+/*
+ * parse a comma separated list of AddressFilters: mask/value
+ */
+static void
+ParseList(String string, AddressFilter **list_return, int *count_return)
+{
+ char *ptr, *boe, *eoe;
+#define BUFLEN 32
+ char mask[BUFLEN], value[BUFLEN];
+ AddressFilter *elem;
+
+ *list_return = NULL;
+ *count_return = 0;
+ if (string == NULL || *string == '\0')
+ return;
+
+ ptr = string;
+ do {
+ boe = ptr;
+ ptr = NextListElem(ptr, &eoe);
+ if (boe && eoe) {
+ elem = NULL;
+ if (ParseListElem(boe, eoe, mask, BUFLEN, value, BUFLEN) != 0) {
+ unsigned long imask = inet_addr(mask);
+ unsigned long ivalue = inet_addr(value);
+ if (((long) imask) != -1 && ((long) ivalue) != -1) {
+ elem = NextAFListElem(list_return, count_return);
+ elem->mask = imask;
+ elem->value = ivalue;
+ }
+ }
+ if (elem == NULL) {
+ /* copy whathever we can in one of our bufs to print it out */
+#define MYMIN(a,b) ((a) > (b) ? (b) : (a))
+ int len = MYMIN(eoe - boe, BUFLEN - 1);
+ strncpy(mask, boe, len);
+ mask[len] = '\0';
+ fprintf(stderr,
+ "Could not convert \"%s\" into a pair mask/value\n",
+ mask);
+ }
+ }
+ } while (ptr && *ptr);
+}
+
+void
+GetPreferences(Widget widget, Preferences *preferences)
+{
+ Prefs prefs;
+ XtGetApplicationResources(widget, &prefs,
+ resources, XtNumber(resources),
+ NULL, 0);
+
+ preferences->has_fwp = prefs.has_fwp;
+ ParseList(prefs.internal_webservers,
+ &preferences->internal_webservers,
+ &preferences->internal_webservers_count);
+ ParseList(prefs.trusted_webservers,
+ &preferences->trusted_webservers,
+ &preferences->trusted_webservers_count);
+ ParseList(prefs.fast_webservers,
+ &preferences->fast_webservers,
+ &preferences->fast_webservers_count);
+}
+
+void
+FreePreferences(Preferences *preferences)
+{
+ if (preferences->internal_webservers)
+ Free(preferences->internal_webservers);
+ if (preferences->trusted_webservers)
+ Free(preferences->trusted_webservers);
+ if (preferences->fast_webservers)
+ Free(preferences->fast_webservers);
+}
+
+static Boolean
+FilterHost(char *hostname, AddressFilter *filters, int count)
+{
+ struct hostent *host;
+ unsigned int addr;
+ int i;
+
+ if (count == 0 || filters == NULL)
+ return False;
+
+ /* first find the host address number */
+ host = gethostbyname(hostname);
+ if (host == NULL || host->h_addrtype != AF_INET)
+ /* host or address type unknown */
+ return False;
+
+ addr = ((struct in_addr*) host->h_addr_list[0])->s_addr;
+
+ for (i = 0; i < count; i++, filters++)
+ if ((addr & filters->mask) == (filters->value & filters->mask))
+ return True;
+
+ return False;
+}
+
+void
+ComputePreferences(Preferences *prefs, char *webserver,
+ Boolean *trusted_ret, Boolean *use_fwp_ret, Boolean *use_lbx_ret)
+{
+ if (webserver != NULL) {
+ if (prefs->has_fwp == True) {
+ *use_fwp_ret =
+ FilterHost(webserver,
+ prefs->internal_webservers,
+ prefs->internal_webservers_count) ? False : True;
+ } else
+ *use_fwp_ret = False;
+
+ *trusted_ret = FilterHost(webserver,
+ prefs->trusted_webservers,
+ prefs->trusted_webservers_count);
+ *use_lbx_ret = FilterHost(webserver,
+ prefs->fast_webservers,
+ prefs->fast_webservers_count) ? False : True;
+ } else {
+ /* can't do much without webserver name */
+ *use_fwp_ret = prefs->has_fwp;
+ *trusted_ret = False;
+ *use_lbx_ret = True;
+ }
+}
diff --git a/rx/Prefs.h b/rx/Prefs.h
new file mode 100644
index 0000000..6c7462d
--- /dev/null
+++ b/rx/Prefs.h
@@ -0,0 +1,56 @@
+/* $Xorg: Prefs.h,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifndef _Prefs_h
+#define _Prefs_h
+
+#include <X11/Intrinsic.h>
+
+typedef struct {
+ unsigned int mask;
+ unsigned int value;
+} AddressFilter;
+
+typedef struct {
+ Boolean has_fwp;
+ AddressFilter *internal_webservers;
+ AddressFilter *trusted_webservers;
+ AddressFilter *fast_webservers;
+ int internal_webservers_count;
+ int trusted_webservers_count;
+ int fast_webservers_count;
+} Preferences;
+
+
+extern void GetPreferences(Widget widget, Preferences *preferences);
+extern void FreePreferences(Preferences *preferences);
+extern void ComputePreferences(Preferences *preferences, char *webserver,
+ Boolean *trusted_ret, Boolean *use_fwp_ret, Boolean *use_lbx_ret);
+
+#endif /* _Prefs_h */
diff --git a/rx/Rx.h b/rx/Rx.h
new file mode 100644
index 0000000..2260d48
--- /dev/null
+++ b/rx/Rx.h
@@ -0,0 +1,129 @@
+/* $Xorg: Rx.h,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifndef _Rx_h
+#define _Rx_h
+
+/* a fancy Boolean type */
+typedef enum { RxUndef=-1, RxFalse=0, RxTrue=1 } RxBool;
+
+
+/* various enums, starting from index 1,
+ with a dummy last value allowing to easily get the size,
+ new values must be inserted before the last one */
+typedef enum { UI=1, Print, LASTService } RxService;
+typedef enum { XUI=1, LASTUIProtocol } RxUIProtocol;
+typedef enum { XPrint=1, LASTPrintProtocol } RxPrintProtocol;
+
+typedef enum { MitMagicCookie1=1, LASTXAuthentication } RxXAuthentication;
+
+/* for each of the above enum define the corresponding max array size,
+ counting 1 for NULL terminating */
+#define MAX_SERVICES LASTService
+#define MAX_UIPROTOS LASTUIProtocol
+#define MAX_PRINTPROTOS LASTPrintProtocol
+
+#define MAX_XAUTHENTICATIONS LASTXAuthentication
+
+/* RxParams structure,
+ designed so it can handle whatever parameter is defined in an RX document */
+typedef struct {
+ short version; /* document version number */
+ short revision; /* document revision number */
+
+ char *action; /* URL */
+ RxBool embedded;
+ RxBool auto_start;
+ int width;
+ int height;
+ char *app_group; /* application group name */
+
+ /* NULL terminated "lists" */
+ RxService required_services[MAX_SERVICES];
+ RxUIProtocol ui[MAX_UIPROTOS];
+ RxPrintProtocol print[MAX_PRINTPROTOS];
+
+ /* private params */
+ RxBool x_ui_input_method;
+ char *x_ui_input_method_url;
+
+ RxBool x_ui_lbx;
+ RxBool x_print_lbx;
+
+ RxXAuthentication x_auth[MAX_XAUTHENTICATIONS];
+ char *x_auth_data[MAX_XAUTHENTICATIONS];
+
+ RxXAuthentication x_ui_auth[MAX_XAUTHENTICATIONS];
+ char *x_ui_auth_data[MAX_XAUTHENTICATIONS];
+
+ RxXAuthentication x_print_auth[MAX_XAUTHENTICATIONS];
+ char *x_print_auth_data[MAX_XAUTHENTICATIONS];
+
+ RxXAuthentication x_ui_lbx_auth[MAX_XAUTHENTICATIONS];
+ char *x_ui_lbx_auth_data[MAX_XAUTHENTICATIONS];
+
+ RxXAuthentication x_print_lbx_auth[MAX_XAUTHENTICATIONS];
+ char *x_print_lbx_auth_data[MAX_XAUTHENTICATIONS];
+
+} RxParams;
+
+
+typedef struct {
+ RxBool embedded;
+ int width;
+ int height;
+ char *action;
+ char *ui; /* URL */
+ char *print; /* URL */
+
+ /* private params */
+ RxBool x_ui_lbx;
+ char *x_ui_lbx_auth;
+ RxBool x_print_lbx;
+ char *x_print_lbx_auth;
+} RxReturnParams;
+
+
+/* functions */
+extern int
+RxReadParams(char *stream,
+ char **argn_ret[], char **argv_ret[], int *argc_ret);
+
+extern void RxInitializeParams(RxParams *params);
+
+extern int
+RxParseParams(char *argn[], char *argv[], int argc, RxParams *params,
+ int debug); /* (1/0) */
+
+extern char *RxBuildRequest(RxReturnParams *params);
+
+extern int RxFreeParams(RxParams *params);
+extern int RxFreeReturnParams(RxReturnParams *params);
+
+#endif /* _Rx_h */
diff --git a/rx/RxI.h b/rx/RxI.h
new file mode 100644
index 0000000..d652c14
--- /dev/null
+++ b/rx/RxI.h
@@ -0,0 +1,95 @@
+/* $Xorg: RxI.h,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifndef _RxI_h
+#define _RxI_h
+
+#include "Rx.h"
+#include <X11/Xos.h> /* for strcmp() etc... */
+#include <stdlib.h>
+#include <stdio.h>
+
+
+/* "wrappers" to std functions */
+#ifdef NETSCAPE_PLUGIN
+#include "npapi.h"
+#define Malloc(s) NPN_MemAlloc(s)
+#define Realloc(p, olds, s) _RxRealloc(p, olds, s)
+#define Free(p) { if (p) NPN_MemFree(p); }
+extern void * _RxRealloc(void *p, size_t olds, size_t s);
+#else
+#define Malloc(s) malloc(s)
+#define Realloc(p, olds, s) realloc(p, s)
+#define Free(p) { if (p) free(p); }
+#endif
+
+#ifdef NEED_STRCASECMP
+#define Strcasecmp(s1,s2) _RxStrcasecmp(s1,s2)
+#define Strncasecmp(s1,s2,n) _RxStrncasecmp(s1,s2,n)
+extern int _RxStrcasecmp(const char *, const char *);
+extern int _RxStrncasecmp(const char *, const char *, size_t);
+#else
+#define Strcasecmp(s1,s2) strcasecmp(s1,s2)
+#define Strncasecmp(s1,s2,n) strncasecmp(s1,s2,n)
+#endif
+
+/* recognized parameter names */
+#define RX_VERSION "VERSION"
+#define RX_ACTION "ACTION"
+#define RX_EMBEDDED "EMBEDDED"
+#define RX_AUTO_START "AUTO-START"
+#define RX_WIDTH "WIDTH"
+#define RX_HEIGHT "HEIGHT"
+#define RX_APP_GROUP "APP-GROUP"
+#define RX_REQUIRED_SERVICES "REQUIRED-SERVICES"
+#define RX_UI "UI"
+#define RX_PRINT "PRINT"
+
+/* X protocol private parameter names */
+#define RX_X_UI_INPUT_METHOD "X-UI-INPUT-METHOD"
+#define RX_X_UI_LBX "X-UI-LBX"
+#define RX_X_PRINT_LBX "X-PRINT-LBX"
+#define RX_X_AUTH "X-AUTH"
+#define RX_X_UI_AUTH "X-UI-AUTH"
+#define RX_X_PRINT_AUTH "X-PRINT-AUTH"
+#define RX_X_UI_LBX_AUTH "X-UI-LBX-AUTH"
+#define RX_X_PRINT_LBX_AUTH "X-PRINT-LBX-AUTH"
+
+
+/* recognized parameter values */
+#define RX_YES "YES"
+#define RX_NO "NO"
+
+
+/* HTTP GET request delimiters */
+#define RX_QUERY_DELIMITER '?'
+#define RX_PARAM_DELIMITER ';'
+
+
+#endif /* _RxI_h */
diff --git a/rx/XAuth.c b/rx/XAuth.c
new file mode 100644
index 0000000..89e904b
--- /dev/null
+++ b/rx/XAuth.c
@@ -0,0 +1,163 @@
+/* $Xorg: XAuth.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxI.h"
+#ifdef XFUNCPROTO_NOT_AVAILABLE
+#include <X11/Xfuncproto.h>
+#endif
+#include <X11/Xlib.h>
+#include <X11/extensions/security.h>
+#ifndef XFUNCPROTO_NOT_AVAILABLE
+#include <X11/Xauth.h>
+#endif
+
+static void
+printhexdigit(char *ptr, unsigned int d)
+{
+ if (d > 9)
+ d += 'A' - 10;
+ else
+ d += '0';
+
+ sprintf(ptr, "%c", d);
+}
+
+static void
+printhex(char *buffer, unsigned char *data, int len)
+{
+ char *ptr;
+ unsigned int c;
+
+ ptr = buffer;
+ while (len--) {
+ c = *data++;
+ printhexdigit(ptr++, c >> 4);
+ printhexdigit(ptr++, c & 0xf);
+ }
+ *ptr = '\0';
+}
+
+static int
+MakeAuthString(char *auth_name, char *data, int len, char **auth_ret)
+{
+ char *auth, *ptr;
+ int name_len;
+
+ name_len = strlen(auth_name);
+ /* we'll have the name + ':' + 2 characters per byte + '\0' */
+ auth = (char *) Malloc(name_len + 1 + 2*len + 1);
+ if (auth == NULL)
+ return 1;
+
+ strcpy(auth, auth_name);
+ ptr = auth + name_len;
+ *ptr++ = ':';
+ printhex(ptr, (unsigned char *)data, len);
+
+ *auth_ret = auth;
+
+ return 0;
+}
+
+int
+GetXAuth(Display *dpy, RxXAuthentication auth_name, char *auth_data,
+ Bool trusted, XID group, unsigned int timeout, Bool want_revoke_event,
+ char **auth_string_ret, XSecurityAuthorization *auth_id_ret,
+ int *event_type_base_ret)
+{
+ unsigned int trust =
+ trusted ? XSecurityClientTrusted : XSecurityClientUntrusted;
+ int dum, major_version, minor_version;
+ int status;
+ Xauth *auth_in, *auth_return;
+ XSecurityAuthorizationAttributes xsa;
+ unsigned long xsamask;
+
+ auth_return = NULL;
+ if (!XQueryExtension(dpy, "SECURITY", &dum, event_type_base_ret, &dum)) {
+ fprintf(stderr, "Warning: Cannot setup authorization as requested, \
+SECURITY extension not supported\n");
+ return 1;
+ }
+
+ if (auth_name == MitMagicCookie1) {
+ auth_in = XSecurityAllocXauth();
+ auth_in->name = "MIT-MAGIC-COOKIE-1";
+ } else {
+ fprintf(stderr,
+ "Error: Unknown authentication protocol name requested\n");
+ return 1;
+ }
+ /* auth_data is not used for now */
+
+ status = XSecurityQueryExtension(dpy, &major_version, &minor_version);
+ if (status == 0) {
+ fprintf(stderr, "Error: Failed to setup authorization\n");
+ goto error;
+ }
+
+ auth_in->name_length = strlen(auth_in->name);
+ if (auth_in->data)
+ auth_in->data_length = strlen(auth_in->data);
+
+ xsa.timeout = timeout;
+ xsa.trust_level = trust;
+ xsa.group = group;
+ xsamask = XSecurityTimeout | XSecurityTrustLevel | XSecurityGroup;
+ if (want_revoke_event == True) {
+ xsa.event_mask = XSecurityAuthorizationRevokedMask;
+ xsamask |= XSecurityEventMask;
+ }
+ auth_return = XSecurityGenerateAuthorization(dpy, auth_in, xsamask,
+ &xsa, auth_id_ret);
+ if (auth_return == 0) {
+ fprintf(stderr,
+ "Error: Failed to setup authorization, cannot create key\n");
+ goto error;
+ }
+ status = MakeAuthString(auth_in->name,
+ auth_return->data, auth_return->data_length,
+ auth_string_ret);
+ if (status != 0) {
+ fprintf(stderr,
+ "Error: Failed to setup authorization, not enough memory\n");
+ goto error;
+ }
+ XSecurityFreeXauth(auth_in);
+ XSecurityFreeXauth(auth_return);
+
+ return 0;
+
+error:
+ XSecurityFreeXauth(auth_in);
+ if (auth_return != NULL)
+ XSecurityFreeXauth(auth_return);
+
+ return 1;
+}
diff --git a/rx/XAuth.h b/rx/XAuth.h
new file mode 100644
index 0000000..f7c6624
--- /dev/null
+++ b/rx/XAuth.h
@@ -0,0 +1,39 @@
+/* $Xorg: XAuth.h,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifndef _XAuth_h
+#define _XAuth_h
+
+extern int
+GetXAuth(Display *dpy, RxXAuthentication auth_name, char *auth_data,
+ Bool trusted, XID group, unsigned int timeout, Bool want_revoke_event,
+ char **auth_string_ret, XSecurityAuthorization *auth_id_ret,
+ int *event_type_base_ret);
+
+#endif /* _XAuth_h */
diff --git a/rx/XDpyName.c b/rx/XDpyName.c
new file mode 100644
index 0000000..0a5c006
--- /dev/null
+++ b/rx/XDpyName.c
@@ -0,0 +1,513 @@
+/* $Xorg: XDpyName.c,v 1.5 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifdef XP_UNIX
+#include "RxPlugin.h" /* for PluginGlobal */
+#endif
+#include "RxI.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <X11/Xfuncs.h>
+#include <X11/Xmd.h>
+#include <X11/ICE/ICElib.h>
+#include <X11/ICE/ICEmsg.h>
+#include <X11/ICE/ICEproto.h>
+#include <X11/PM/PM.h>
+#include <X11/PM/PMproto.h>
+
+#define DEFAULT_PROXY_MANAGER ":6500"
+
+/*
+ * Pad to a 64 bit boundary
+ */
+
+#define PAD64(_bytes) ((8 - ((unsigned int) (_bytes) % 8)) % 8)
+
+#define PADDED_BYTES64(_bytes) (_bytes + PAD64 (_bytes))
+
+
+/*
+ * Number of 8 byte units in _bytes.
+ */
+
+#define WORD64COUNT(_bytes) (((unsigned int) ((_bytes) + 7)) >> 3)
+
+
+/*
+ * Compute the number of bytes for a STRING representation
+ */
+
+#define STRING_BYTES(_str) (2 + (_str ? strlen (_str) : 0) + \
+ PAD64 (2 + (_str ? strlen (_str) : 0)))
+
+
+
+#define SKIP_STRING(_pBuf, _swap) \
+{ \
+ CARD16 _len; \
+ EXTRACT_CARD16 (_pBuf, _swap, _len); \
+ _pBuf += _len; \
+ if (PAD64 (2 + _len)) \
+ _pBuf += PAD64 (2 + _len); \
+}
+
+/*
+ * STORE macros
+ */
+
+#define STORE_CARD16(_pBuf, _val) \
+{ \
+ *((CARD16 *) _pBuf) = _val; \
+ _pBuf += 2; \
+}
+
+#define STORE_STRING(_pBuf, _string) \
+{ \
+ int _len = _string ? strlen (_string) : 0; \
+ STORE_CARD16 (_pBuf, _len); \
+ if (_len) { \
+ memcpy (_pBuf, _string, _len); \
+ _pBuf += _len; \
+ } \
+ if (PAD64 (2 + _len)) \
+ _pBuf += PAD64 (2 + _len); \
+}
+
+
+/*
+ * EXTRACT macros
+ */
+
+#define EXTRACT_CARD16(_pBuf, _swap, _val) \
+{ \
+ _val = *((CARD16 *) _pBuf); \
+ _pBuf += 2; \
+ if (_swap) \
+ _val = lswaps (_val); \
+}
+
+#define EXTRACT_STRING(_pBuf, _swap, _string) \
+{ \
+ CARD16 _len; \
+ EXTRACT_CARD16 (_pBuf, _swap, _len); \
+ _string = (char *) malloc (_len + 1); \
+ memcpy (_string, _pBuf, _len); \
+ _string[_len] = '\0'; \
+ _pBuf += _len; \
+ if (PAD64 (2 + _len)) \
+ _pBuf += PAD64 (2 + _len); \
+}
+
+
+/*
+ * Byte swapping
+ */
+
+/* byte swap a long literal */
+#define lswapl(_val) ((((_val) & 0xff) << 24) |\
+ (((_val) & 0xff00) << 8) |\
+ (((_val) & 0xff0000) >> 8) |\
+ (((_val) >> 24) & 0xff))
+
+/* byte swap a short literal */
+#define lswaps(_val) ((((_val) & 0xff) << 8) | (((_val) >> 8) & 0xff))
+
+
+#define CHECK_AT_LEAST_SIZE(_iceConn, _majorOp, _minorOp, _expected_len, _actual_len, _severity) \
+ if ((((_actual_len) - SIZEOF (iceMsg)) >> 3) > _expected_len) \
+ { \
+ _IceErrorBadLength (_iceConn, _majorOp, _minorOp, _severity); \
+ return; \
+ }
+
+
+#define CHECK_COMPLETE_SIZE(_iceConn, _majorOp, _minorOp, _expected_len, _actual_len, _pStart, _severity) \
+ if (((PADDED_BYTES64((_actual_len)) - SIZEOF (iceMsg)) >> 3) \
+ != _expected_len) \
+ { \
+ _IceErrorBadLength (_iceConn, _majorOp, _minorOp, _severity); \
+ IceDisposeCompleteMessage (iceConn, _pStart); \
+ return; \
+ }
+
+static void PMprocessMessages ();
+
+#ifdef XP_UNIX
+#define PMOPCODE RxGlobal.pm_opcode
+#define ICECONN RxGlobal.ice_conn
+#else
+static int pm_opcode;
+#define PMOPCODE pm_opcode
+#define ICECONN ice_conn
+#endif
+
+static int PMversionCount = 1;
+static IcePoVersionRec PMversions[] =
+ {{PM_MAJOR_VERSION, PM_MINOR_VERSION, PMprocessMessages}};
+
+typedef struct {
+ int status;
+ char *addr;
+ char *error;
+} GetProxyAddrReply;
+
+static int findproxy (proxyname, manager, server, name)
+ char* proxyname;
+ char* manager;
+ char* server;
+ char* name;
+{
+#ifndef XP_UNIX
+ IceConn ice_conn;
+#endif
+ IceProtocolSetupStatus setupstat;
+ char *vendor = NULL;
+ char *release = NULL;
+ pmGetProxyAddrMsg *pMsg;
+ char *pData;
+ int len;
+ IceReplyWaitInfo replyWait;
+ GetProxyAddrReply reply;
+ int majorVersion, minorVersion;
+ Bool gotReply, ioErrorOccured;
+ char errorString[255];
+
+ /*
+ * Register support for PROXY_MANAGEMENT.
+ */
+
+ if (PMOPCODE == 0) {
+ if ((PMOPCODE = IceRegisterForProtocolSetup (
+ PM_PROTOCOL_NAME,
+ "XC", "1.0",
+ PMversionCount, PMversions,
+ 0, /* authcount */
+ NULL, /* authnames */
+ NULL, /* authprocs */
+ NULL /* IceIOErrorProc */ )) < 0) {
+ fprintf (stderr,
+ "Could not register PROXY_MANAGEMENT protocol with ICE\n");
+ return 0;
+ }
+
+ if ((ICECONN = IceOpenConnection (
+ manager, NULL, 0, 0, 256, errorString)) == NULL) {
+ fprintf (stderr,
+ "Could not open ICE connection to proxy manager\n (%s)\n",
+ errorString);
+ return 0;
+ }
+
+ setupstat = IceProtocolSetup (ICECONN, PMOPCODE, NULL,
+ False /* mustAuthenticate */,
+ &majorVersion, &minorVersion,
+ &vendor, &release, 256, errorString);
+
+ if (setupstat != IceProtocolSetupSuccess) {
+ IceCloseConnection (ICECONN);
+ fprintf (stderr,
+ "Could not initialize proxy management protocol\n (%s)\n",
+ errorString);
+ fprintf (stderr, "%d\n", setupstat);
+ return 0;
+ }
+ }
+
+ /*
+ * Now send the GetProxyAddr request.
+ */
+
+ len = STRING_BYTES (name) + STRING_BYTES (server) +
+ STRING_BYTES ("") + STRING_BYTES ("");
+
+ IceGetHeaderExtra (ICECONN, PMOPCODE, PM_GetProxyAddr,
+ SIZEOF (pmGetProxyAddrMsg), WORD64COUNT (len),
+ pmGetProxyAddrMsg, pMsg, pData);
+
+ pMsg->authLen = 0;
+
+ STORE_STRING (pData, name);
+ STORE_STRING (pData, server);
+ STORE_STRING (pData, ""); /* host address, if there was any */
+ STORE_STRING (pData, ""); /* start options, if there were any */
+
+ IceFlush (ICECONN);
+
+ replyWait.sequence_of_request = IceLastSentSequenceNumber (ICECONN);
+ replyWait.major_opcode_of_request = PMOPCODE;
+ replyWait.minor_opcode_of_request = PM_GetProxyAddr;
+ replyWait.reply = (IcePointer) &reply;
+
+ gotReply = False;
+ ioErrorOccured = False;
+
+ while (!gotReply && !ioErrorOccured) {
+ ioErrorOccured = (IceProcessMessages (
+ ICECONN, &replyWait, &gotReply) == IceProcessMessagesIOError);
+
+ if (ioErrorOccured) {
+ fprintf (stderr, "IO error occured\n");
+ IceCloseConnection (ICECONN);
+ return 0;
+ } else if (gotReply) {
+ if (reply.status == PM_Success) {
+ strcpy (proxyname, reply.addr);
+ } else {
+ fprintf (stderr, "Error from proxy manager: %s\n",
+ reply.error);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+
+
+static void
+PMprocessMessages (iceConn, clientData, opcode,
+ length, swap, replyWait, replyReadyRet)
+
+IceConn iceConn;
+IcePointer clientData;
+int opcode;
+unsigned long length;
+Bool swap;
+IceReplyWaitInfo *replyWait;
+Bool *replyReadyRet;
+
+{
+ if (replyWait)
+ *replyReadyRet = False;
+
+ switch (opcode) {
+ case PM_GetProxyAddrReply:
+
+ if (!replyWait ||
+ replyWait->minor_opcode_of_request != PM_GetProxyAddr) {
+ _IceReadSkip (iceConn, length << 3);
+
+ _IceErrorBadState (iceConn, PMOPCODE,
+ PM_GetProxyAddrReply, IceFatalToProtocol);
+ } else {
+ pmGetProxyAddrReplyMsg *pMsg;
+ char *pData, *pStart;
+ GetProxyAddrReply *reply =
+ (GetProxyAddrReply *) (replyWait->reply);
+
+ CHECK_AT_LEAST_SIZE (iceConn, PMOPCODE, opcode,
+ length, SIZEOF (pmGetProxyAddrReplyMsg), IceFatalToProtocol);
+
+ IceReadCompleteMessage (iceConn, SIZEOF (pmGetProxyAddrReplyMsg),
+ pmGetProxyAddrReplyMsg, pMsg, pStart);
+
+ if (!IceValidIO (iceConn)) {
+ IceDisposeCompleteMessage (iceConn, pStart);
+ return;
+ }
+
+ pData = pStart;
+
+ SKIP_STRING (pData, swap); /* proxy-address */
+ SKIP_STRING (pData, swap); /* failure-reason */
+
+ CHECK_COMPLETE_SIZE (iceConn, PMOPCODE, opcode,
+ length, pData - pStart + SIZEOF (pmGetProxyAddrReplyMsg),
+ pStart, IceFatalToProtocol);
+
+ pData = pStart;
+
+ EXTRACT_STRING (pData, swap, reply->addr);
+ EXTRACT_STRING (pData, swap, reply->error);
+
+ reply->status = pMsg->status;
+ *replyReadyRet = True;
+
+ IceDisposeCompleteMessage (iceConn, pStart);
+ }
+ break;
+
+ default:
+ _IceErrorBadMinor (iceConn, PMOPCODE, opcode, IceCanContinue);
+ _IceReadSkip (iceConn, length << 3);
+ break;
+ }
+}
+
+
+
+/* This function returns the X Print Display name and the printer name.
+ * Both are copies which the caller is responsible to free.
+ */
+char *
+GetXPrintDisplayName(char **printer_return)
+{
+ char *display_name, *pdpy_name;
+ char *ptr, *printer_name;
+
+ display_name = getenv("XPRINTER");
+
+ if (display_name != NULL) {
+ /* if name is of the form "xprint:display" change it to "display"
+ * Note: this is quite unlikely to happen for now but it might in the
+ * future... I guess this is what some call forward compatibility ?-)
+ */
+ if (strncmp(display_name, "xprint:", 7) == 0)
+ pdpy_name = display_name + 7;
+ else
+ pdpy_name = display_name;
+
+ ptr = strchr(pdpy_name, '@');
+ if (ptr != NULL) {
+ /* server specified, store printer and remove it from
+ * display name */
+ printer_name = (char *)Malloc(ptr - pdpy_name + 1);
+ if (printer_name != NULL) {
+ strncpy(printer_name, pdpy_name, ptr - pdpy_name);
+ printer_name[ptr - pdpy_name] = '\0';
+ }
+ ptr++;
+ pdpy_name = (char *)Malloc(strlen(ptr) + 1);
+ if (pdpy_name != NULL)
+ strcpy(pdpy_name, ptr);
+ } else {
+ printer_name = (char *)Malloc(strlen(pdpy_name) + 1);
+ if (printer_name != NULL)
+ strcpy(printer_name, pdpy_name);
+ pdpy_name = NULL;
+ }
+ } else {
+ pdpy_name = NULL;
+ /* look for printer name in other variables */
+ printer_name = getenv("PDPRINTER");
+ if (printer_name == NULL) {
+ printer_name = getenv("LPDEST");
+ if (printer_name == NULL)
+ printer_name = getenv("PRINTER");
+ }
+ /* make a copy */
+ if (printer_name != NULL) {
+ ptr = printer_name;
+ printer_name = (char *)Malloc(strlen(ptr) + 1);
+ if (printer_name != NULL)
+ strcpy(printer_name, ptr);
+ }
+ }
+
+ /* if no server was specified in XPRINTER, look at XPSERVERLIST */
+ if (pdpy_name == NULL) {
+ char *servers_list = getenv("XPSERVERLIST");
+ if (servers_list != NULL && servers_list[0] != '\0') {
+ /* use the first one from the server list */
+ ptr = strchr(servers_list, ' ');
+ if (ptr != NULL) {
+ pdpy_name = (char *) Malloc(ptr - servers_list + 1);
+ if (pdpy_name != NULL) {
+ strncpy(pdpy_name, servers_list, ptr - servers_list);
+ pdpy_name[ptr - servers_list] = '\0';
+ }
+ } else {
+ pdpy_name = (char *) Malloc(strlen(servers_list) + 1);
+ if (pdpy_name != NULL)
+ strcpy(pdpy_name, servers_list);
+ }
+ }
+ }
+ *printer_return = printer_name;
+ return pdpy_name;
+}
+
+#define MAXLEN 256
+
+char *
+GetXFwpDisplayName(char *dpy_name)
+{
+#if 0
+ char *fwp_dpy_name, *ptr, *limit;
+ FILE *in;
+ int c, status;
+#else
+ char *fwp_dpy_name;
+#endif
+ char buf[MAXLEN];
+ char *proxy_mngr;
+
+ /* first, let's figure out where the proxy manager should be */
+ proxy_mngr = getenv("PROXY_MANAGER");
+ if (proxy_mngr == NULL)
+ proxy_mngr = DEFAULT_PROXY_MANAGER;
+
+#if 0
+ /* now let's see if we can find a firewall proxy */
+ sprintf(buf,
+ "xfindproxy -manager %s -server %s -name xfwp 2>/dev/null",
+ proxy_mngr, dpy_name);
+ in = popen(buf, "r");
+ if (in != NULL) {
+ ptr = buf;
+ limit = buf + MAXLEN - 1;
+ /* read in first line */
+ while ((c = fgetc(in)) != EOF && c != '\n' && ptr < limit)
+ *ptr++ = c;
+ status = pclose(in);
+
+ (void) fprintf (stderr, "buf: %s\n", buf);
+ (void) fprintf (stderr, "status: %d\n", status);
+ (void) fprintf (stderr, "ptr: %p, buf: %p\n", ptr, buf);
+ if (status == -1 || ptr == buf) {
+ perror ("too bad");
+ /* xfindproxy failed, consider we do not have a firewall */
+ fwp_dpy_name = NULL;
+ } else {
+ /* make sure we have a NULL terminated string */
+ *ptr = '\0';
+ fwp_dpy_name = (char *) Malloc(ptr - buf + 1);
+ if (fwp_dpy_name != NULL)
+ strcpy(fwp_dpy_name, buf);
+ }
+ } else {
+ /* failed to run xfindproxy, consider that we don't have a firewall */
+ fwp_dpy_name = NULL;
+ }
+#else
+ fwp_dpy_name = NULL;
+ if (findproxy (buf, proxy_mngr, dpy_name, "xfwp")) {
+ fwp_dpy_name = (char *) Malloc (strlen (buf) + 1);
+ if (fwp_dpy_name != NULL)
+ strcpy (fwp_dpy_name, buf);
+ }
+#endif
+
+ return fwp_dpy_name;
+}
diff --git a/rx/XDpyName.h b/rx/XDpyName.h
new file mode 100644
index 0000000..93f4b12
--- /dev/null
+++ b/rx/XDpyName.h
@@ -0,0 +1,39 @@
+/* $Xorg: XDpyName.h,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifndef _XDpyName_h
+#define _XDpyName_h
+
+extern char *
+GetXPrintDisplayName(char **printer_return);
+
+extern char *
+GetXFwpDisplayName(char *dpy_name);
+
+#endif
diff --git a/rx/XUrls.c b/rx/XUrls.c
new file mode 100644
index 0000000..28d5540
--- /dev/null
+++ b/rx/XUrls.c
@@ -0,0 +1,360 @@
+/* $Xorg: XUrls.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxI.h"
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <limits.h> /* for MAXHOSTNAMELEN */
+#include <errno.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+
+/* and in case we didn't get it from the headers above */
+#ifndef MAXHOSTNAMELEN
+# define MAXHOSTNAMELEN 256
+#endif
+
+/*
+ * Return a good hostname, even on multi-homed hosts, e.g. machines
+ * connected to the internet via PPP which also have a local network
+ * are multi-homed.
+ *
+ * This might still fail to provide the right name if netscape is
+ * running on a different host than it is being displayed on. E.g,
+ *
+ * netscapehost <--ethernet--> display host <--ppp--//--> webserver
+ *
+ * The display host is multi-homed and has the nodename myhost.mynet
+ * as far as netscape and the netscape host are concerned, but has
+ * the name pppX.myispnet to the outside world. When this happens the
+ * user is going to have to set the XREALDISPLAY environment variable
+ * when they run netscape like this.
+ */
+static char*
+MyBestHostname (
+ char* myname,
+ int myname_len,
+ char* display_name,
+ char* dest_url)
+{
+ struct sockaddr_in local, remote;
+ struct hostent* hp;
+ struct utsname host;
+ int s, rv, namelen;
+ char dest_hostname[MAXHOSTNAMELEN + 1];
+
+ *myname = '\0';
+
+ /* if of the form ":0.0" get the real hostname */
+ if (display_name[0] == ':') {
+
+/* for some reason this doesn't work on Solaris 2.x */
+#if !(defined(sun) && defined(SVR4))
+ ParseHostname (dest_url, dest_hostname, sizeof dest_hostname);
+
+ hp = gethostbyname (dest_hostname);
+
+ if (hp) {
+ memcpy (&remote.sin_addr, hp->h_addr_list[0], sizeof remote.sin_addr);
+ remote.sin_port = htons(60000);
+ remote.sin_family = AF_INET;
+#ifdef BSD44SOCKETS
+ remote.sin_len = sizeof remote;
+#endif
+
+ local.sin_addr.s_addr = htonl(INADDR_ANY);
+ local.sin_port = htons(60000);
+ local.sin_family = AF_INET;
+#ifdef BSD44SOCKETS
+ local.sin_len = sizeof remote;
+#endif
+
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s != -1) {
+ do {
+ rv = bind (s, (struct sockaddr*) &local, sizeof local);
+ local.sin_port = htons (ntohs (local.sin_port) + 1);
+ } while (rv == -1 && errno == EADDRINUSE);
+
+ if (rv != -1) {
+ do {
+ rv = connect (s, (struct sockaddr*) &remote, sizeof remote);
+ remote.sin_port = htons (ntohs (remote.sin_port) + 1);
+ } while (rv == -1 && errno == EADDRINUSE);
+
+ if (rv != -1) {
+ namelen = sizeof local;
+ rv = getsockname (s, (struct sockaddr*) &local, &namelen);
+
+ if (rv != -1) {
+ hp = gethostbyaddr ((char*) &local.sin_addr.s_addr,
+ sizeof local.sin_addr.s_addr,
+ AF_INET);
+ if (hp) {
+ strncpy (myname, hp->h_name, myname_len);
+ myname[MAXHOSTNAMELEN] = '\0';
+ close (s);
+ return display_name;
+ }
+ }
+ }
+ }
+ close (s);
+ }
+ }
+#endif
+ /* none of the above worked, punt */
+
+ uname(&host);
+ strncpy (myname, host.nodename, myname_len);
+ myname[MAXHOSTNAMELEN] = '\0';
+ } else { /* otherwise believe the display_name */
+ char *ptr;
+
+ ptr = strchr(display_name, ':');
+ if (ptr == NULL) {
+ /* if there's no ":0" in the name, just copy it */
+ strncpy(myname, display_name, myname_len);
+ myname[MAXHOSTNAMELEN] = '\0';
+ } else {
+ /* otherwise copy everthing up to the ":0" */
+ strncpy(myname, display_name, ptr - display_name);
+ myname[ptr - display_name] = '\0';
+ return ptr;
+ }
+ }
+ return display_name;
+}
+
+
+/* return the Url of the user's X display
+ * this must be of the form:
+ * x11: [protocol/] [hostname] : [:] displaynumber [.screennumber] \
+ * [ ; auth= auth_data ]
+ */
+char *
+GetXUrl(char *display_name, char *auth, char* dest_url)
+{
+ char *dpy_name, *proto;
+ char *url, *ptr;
+ char *name;
+ struct hostent *host;
+ int len, proto_len, dpy_len, name_len, auth_len;
+ char hostname[MAXHOSTNAMELEN + 1];
+
+ len = 5; /* this is for "x11:" */
+
+ /* if of the form "x11:display" change it to "display" */
+ if (strncmp(display_name, "x11:", 4) == 0)
+ dpy_name = display_name + 4;
+ else
+ dpy_name = display_name;
+
+ /* if protocol is specified store it and remove it from display name */
+ ptr = strchr(dpy_name, '/');
+ if (ptr != NULL) {
+ proto = dpy_name;
+ proto_len = ptr - dpy_name;
+ dpy_name = ptr + 1;
+ /* if local forget it */
+ if (strncmp(proto, "local", proto_len) == 0)
+ proto_len = 0;
+ } else
+ proto_len = 0;
+
+ /* if of the form "unix:0.0" change it to ":0.0" */
+ if (strncmp(dpy_name, "unix", 4) == 0)
+ dpy_name += 4;
+
+ dpy_name = MyBestHostname (hostname, MAXHOSTNAMELEN, dpy_name, dest_url);
+ host = gethostbyname(hostname);
+ name = host->h_name;
+ name_len = strlen(name);
+
+ dpy_len = dpy_name == NULL ? 0 : strlen(dpy_name);
+ auth_len = auth == NULL ? 0 : 6 + strlen(auth); /* 6 for ";auth=" */
+ len += proto_len + 1 + name_len + dpy_len + auth_len;
+
+ url = ptr = (char *)Malloc(len);
+ if (url == NULL)
+ return NULL;
+
+ strcpy(ptr, "x11:");
+ ptr += 4;
+ if (proto_len != 0) {
+ strncpy(ptr, proto, proto_len + 1);
+ ptr += proto_len + 1;
+ }
+ if (name_len != 0) {
+ strcpy(ptr, name);
+ ptr += name_len;
+ }
+ if (dpy_len != 0) {
+ strcpy(ptr, dpy_name);
+ ptr += dpy_len;
+ }
+ if (auth_len != 0)
+ sprintf(ptr, ";auth=%s", auth);
+ else
+ *ptr = '\0';
+
+ return url;
+}
+
+
+/* return the Url of the user's XPrint server
+ * this must be of the form:
+ * xprint: [printername@] [protocol/] [hostname] : [:] displaynumber \
+ * [ ; auth= auth_data ]
+ */
+char *
+GetXPrintUrl(char *display_name, char *printer, char *auth, char* dest_url)
+{
+ char *dpy_name, *proto;
+ char *url, *ptr;
+ char *name;
+ struct hostent *host;
+ int len, proto_len, dpy_len, name_len, auth_len, printer_len;
+ char hostname[MAXHOSTNAMELEN + 1];
+
+ len = 7; /* this is for "xprint:" */
+
+ /* if of the form "xprint:display" change it to "display" */
+ if (strncmp(display_name, "xprint:", 7) == 0)
+ dpy_name = display_name + 7;
+ else
+ dpy_name = display_name;
+
+ /* if protocol is specified store it and remove it from display name */
+ ptr = strchr(dpy_name, '/');
+ if (ptr != NULL) {
+ proto = dpy_name;
+ proto_len = ptr - dpy_name;
+ dpy_name = ptr + 1;
+ /* if local forget it */
+ if (strncmp(proto, "local", proto_len) == 0)
+ proto_len = 0;
+ } else
+ proto_len = 0;
+
+ /* if of the form "unix:0.0" change it to ":0.0" */
+ if (strncmp(dpy_name, "unix", 4) == 0)
+ dpy_name += 4;
+
+ dpy_name = MyBestHostname (hostname, MAXHOSTNAMELEN, dpy_name, dest_url);
+ host = gethostbyname(hostname);
+ name = host->h_name;
+
+ /* if a screen number is specified strip it - not valid for printing */
+ ptr = strchr(dpy_name, '.');
+ if (ptr != NULL)
+ dpy_len = ptr - dpy_name;
+ else
+ dpy_len = strlen(dpy_name);
+
+ name_len = strlen(name);
+ printer_len = printer ? strlen(printer) : 0;
+ auth_len = auth == NULL ? 0 : 6 + strlen(auth); /* 6 for ";auth=" */
+ len += printer_len + 1 + proto_len + 1 + name_len + dpy_len + auth_len;
+
+ url = ptr = (char *)Malloc(len);
+ if (url == NULL)
+ return NULL;
+
+ strcpy(ptr, "xprint:");
+ ptr += 7;
+ if (printer_len != 0) {
+ strcpy(ptr, printer);
+ ptr += printer_len;
+ *ptr++ = '@';
+ }
+ if (proto_len != 0) {
+ strncpy(ptr, proto, proto_len + 1);
+ ptr += proto_len + 1;
+ }
+ if (name_len != 0) {
+ strcpy(ptr, name);
+ ptr += name_len;
+ }
+ if (dpy_len != 0) {
+ strncpy(ptr, dpy_name, dpy_len);
+ ptr += dpy_len;
+ }
+ if (auth_len != 0)
+ sprintf(ptr, ";auth=%s", auth);
+ else
+ *ptr = '\0';
+
+ return url;
+}
+
+/*
+ * Extract the hostname of a given url. The hostname is copied to the given
+ * buffer if it is big enough and its length is returned.
+ * This relies strongly on the following expected syntax:
+ * scheme : [//] hostname [: port] [/path]
+ */
+int
+ParseHostname(char *url, char *buf, int buflen)
+{
+ char *ptr, *begin;
+
+ if (url == NULL)
+ return 0;
+
+ /* skip scheme part */
+ ptr = strchr(url, ':');
+ if (ptr != NULL)
+ ptr++;
+ else
+ ptr = url;
+ /* skip possible "//" */
+ while (*ptr && *ptr == '/')
+ ptr++;
+ begin = ptr;
+ /* look for possible port specification */
+ ptr = strchr(begin, ':');
+ if (ptr == NULL) {
+ /* look for possible path */
+ ptr = strchr(begin, '/');
+ if (ptr == NULL)
+ ptr += strlen(begin);
+ }
+ if (ptr - begin < buflen) {
+ strncpy(buf, begin, ptr - begin);
+ buf[ptr - begin] = '\0';
+ return ptr - begin;
+ } else
+ return 0;
+}
diff --git a/rx/XUrls.h b/rx/XUrls.h
new file mode 100644
index 0000000..9c54e77
--- /dev/null
+++ b/rx/XUrls.h
@@ -0,0 +1,37 @@
+/* $Xorg: XUrls.h,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#ifndef _XUrls_h
+#define _XUrls_h
+
+extern char *GetXUrl(char *display, char *auth, char* dest);
+extern char *GetXPrintUrl(char *display, char *printer, char *auth, char* dest);
+extern int ParseHostname(char *url, char *buf, int buflen);
+
+#endif /* _XUrls_h */
diff --git a/testplugin/testplugin.c b/testplugin/testplugin.c
new file mode 100644
index 0000000..7132be4
--- /dev/null
+++ b/testplugin/testplugin.c
@@ -0,0 +1,671 @@
+/* $Xorg: testplugin.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+/*
+ * This is a (not so) basic program to "test" a netscape plugin.
+ * It exercises the plugin in a way close (I hope) to how netscape does.
+ * It is designed to allow minimal debugging of the plugin, with the
+ * possibility of using purify.
+ *
+ * Arnaud Le Hors
+ */
+
+#include <stdio.h>
+#include <Xm/Form.h>
+#include <Xm/DrawingA.h>
+#include <Xm/ScrolledW.h>
+#include <Xm/PushB.h>
+#ifdef SUPPORT_EDITRES
+#include <X11/Xmu/Editres.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#if defined(SYSV) || defined(SVR4)
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include "npapi.h"
+
+/* default mime type */
+#ifndef MIMETYPE
+#define MIMETYPE "undefined"
+#endif
+
+/* define how many bytes should be read at most */
+#ifndef READNBYTES
+#define READNBYTES 100
+#endif
+
+/* default plugin size */
+#define DEFAULT_WIDTH 50
+#define DEFAULT_HEIGHT 50
+
+
+#ifdef PLUGIN_TRACE
+#define PRINTTRACE(msg) fprintf(stderr, msg)
+#else
+#define PRINTTRACE(msg)
+#endif
+
+/* different possible states */
+typedef enum {
+ SETUP, SETUPWINDOW, PROCESSINPUT, SETUPSTREAM, PROCESSREPLY, DONE
+} State;
+
+/* main structure */
+typedef struct {
+ State state;
+ char **plugin_argn;
+ char **plugin_argv;
+ int plugin_argc;
+ uint32 width;
+ uint32 height;
+ Widget plugin;
+ char *src;
+ NPStream **streams;
+ int nstreams;
+ int streams_len;
+ Bool setup_window;
+} AppData;
+
+/* create plugin instance */
+void
+SetupPlugin(NPP instance)
+{
+ AppData *data = (AppData *)instance->ndata;
+ NPError status;
+
+ /* NPError NPP_Initialize(void) */
+ PRINTTRACE(" NPP_Initialize\n");
+ status = NPP_Initialize();
+
+ /*
+ * NPError NPP_New(NPMIMEType *pluginType, NPP instance, uint16 mode,
+ * int16 argc, char *argn[], char *argv[], NPSavedData *saved)
+ */
+ PRINTTRACE(" NPP_New\n");
+ status = NPP_New(MIMETYPE, instance, 0,
+ data->plugin_argc, data->plugin_argn, data->plugin_argv,
+ NULL);
+}
+
+
+void
+SetupPluginWindow(NPP instance)
+{
+ AppData *data = (AppData *)instance->ndata;
+ NPError status;
+ NPSetWindowCallbackStruct window_data;
+ NPWindow window;
+
+ /* setup window structure */
+ window_data.type = 0; /* what's this supposed to be ? */
+ window_data.display = XtDisplay(data->plugin);
+ window_data.visual = DefaultVisual(window_data.display,
+ DefaultScreen(window_data.display));
+ window_data.colormap = DefaultColormap(window_data.display,
+ DefaultScreen(window_data.display));
+ window_data.depth = DefaultDepth(window_data.display,
+ DefaultScreen(window_data.display));
+
+ window.window = (void *) XtWindow(data->plugin);
+ window.x = 0;
+ window.y = 0;
+ window.width = data->width;
+ window.height = data->height;
+ window.ws_info = (void *) &window_data;
+
+ /* NPError NPP_SetWindow(NPP instance, NPWindow *window) */
+ PRINTTRACE(" NPP_SetWindow\n");
+ status = NPP_SetWindow(instance, &window);
+}
+
+void
+MakeStream(NPP instance, const char *url, const char *window, FILE *fp)
+{
+ AppData *data = (AppData *)instance->ndata;
+ NPStream *stream, **ptr;
+ char *urlcopy;
+
+ /* setup a stream */
+ stream = (NPStream *) malloc(sizeof(NPStream));
+ if (stream == NULL) {
+ fprintf(stderr, "cannot malloc enough memory: %d\n",
+ sizeof(NPStream));
+ exit(1);
+ }
+
+ urlcopy = (char *) malloc(strlen(url) + 1);
+ if (urlcopy == NULL) {
+ fprintf(stderr, "cannot malloc enough memory: %d\n",
+ strlen(url) + 1);
+ exit(1);
+ }
+ strcpy(urlcopy, url);
+
+ stream->ndata = (void *) fp;
+ stream->pdata = NULL;
+ stream->url = urlcopy;
+ /* if target window different from plugin window throw reply away */
+ stream->end = (window == NULL) ? 0 : -1;
+ stream->lastmodified = 0; /* I don't have this info */
+ stream->notifyData = NULL; /* I don't support this for now */
+
+ /* add it to the queue */
+ data->nstreams++;
+ if (data->nstreams > data->streams_len) {
+ ptr = (NPStream **) realloc(data->streams,
+ sizeof(NPStream *) * data->nstreams);
+ if (ptr == NULL) {
+ fprintf(stderr, "cannot malloc enough memory: %d\n",
+ sizeof(NPStream *) * data->nstreams);
+ exit(1);
+ }
+ data->streams = ptr;
+ data->streams_len = data->nstreams;
+ }
+ data->streams[data->nstreams - 1] = stream;
+}
+
+void
+DestroyStream(NPP instance, int i)
+{
+ AppData *data = (AppData *)instance->ndata;
+ /*
+ * NPError NPP_DestroyStream(NPP instance, NPStream *stream,
+ * NPError reason)
+ */
+ PRINTTRACE(" NPP_DestroyStream\n");
+ NPP_DestroyStream(instance, data->streams[i], NPRES_DONE);
+ if (data->streams[i]->url != NULL)
+ free((void *)data->streams[i]->url);
+ free(data->streams[i]);
+}
+
+void
+CloseStream(NPP instance, int i)
+{
+ AppData *data = (AppData *)instance->ndata;
+ FILE *fp = (FILE *) data->streams[i]->ndata;
+
+ DestroyStream(instance, 0);
+ /* remove from queue */
+ data->nstreams--;
+ for (i = 0; i < data->nstreams; i++)
+ data->streams[i] = data->streams[i + 1];
+}
+
+void
+WriteStreamProc(NPP instance, int *fd, XtInputId *id)
+{
+ AppData *data = (AppData *)instance->ndata;
+ FILE *fp = (FILE *) data->streams[0]->ndata;
+ NPError status;
+ char buf[BUFSIZ];
+ int32 readysize, readb, len;
+
+ /* int32 NPP_WriteReady(NPP instance, NPStream *stream) */
+ PRINTTRACE(" NPP_WriteReady\n");
+ readysize = NPP_WriteReady(instance, data->streams[0]);
+
+ /* make sure we won't read more than our buf size */
+ if (readysize > BUFSIZ)
+ readysize = BUFSIZ;
+
+ /* force a smaller read size so NPP_Write is called more than once,
+ this is just for the purpose of testing! */
+ if (readysize > READNBYTES)
+ len = READNBYTES;
+ else /* take half of the given value */
+ len = (readysize >> 1);
+
+ /* read next chunk of data */
+ len = fread(buf, sizeof(char), len, fp);
+
+ if (len != 0) { /* send it to plugin */
+ /*
+ * int32 NPP_Write(NPP instance, NPStream *stream, int32 offset,
+ * int32 len, void *buf);
+ */
+ PRINTTRACE(" NPP_Write\n");
+ readb = NPP_Write(instance, data->streams[0], data->streams[0]->end,
+ len, buf);
+
+ /* plugin should have read all of it since we read less than readysize,
+ * if it read less than what it claimed it was ready to use bark */
+ if (readb < len) {
+ fprintf(stderr,
+ "plugin claimed to be ready to read %d but only read %d\n",
+ readysize, readb);
+ exit(1);
+ }
+ data->streams[0]->end += len;
+ } else { /* no more to read */
+ XtRemoveInput(*id);
+ data->state = DONE;
+ }
+}
+
+/* destroy plugin */
+void
+ShutdownPlugin(NPP instance)
+{
+ AppData *data = (AppData *)instance->ndata;
+ NPSavedData *saved_data = NULL;
+
+ if (data->streams != NULL) {
+ int i;
+ for (i = 0; i < data->nstreams; i++)
+ DestroyStream(instance, i);
+ free(data->streams);
+ }
+ PRINTTRACE(" NPP_Destroy\n");
+ NPP_Destroy(instance, &saved_data);
+ if (saved_data != NULL)
+ free(saved_data); /* so this is not reported as memory leak */
+ PRINTTRACE(" NPP_Shutdown\n");
+ NPP_Shutdown();
+}
+
+/* quit callback: shutdown plugin and exit */
+void
+QuitCB(Widget widget, XtPointer closure, XtPointer call_data)
+{
+ ShutdownPlugin((NPP) closure);
+ exit(0);
+}
+
+/* resize handler: like Netscape change the plugin widget */
+void
+ResizeEH(Widget toplevel, XtPointer client_data, XEvent *event, Boolean *cont)
+{
+ if (event->type == ConfigureNotify) {
+ NPP instance = (NPP) client_data;
+ AppData *data = (AppData *)instance->ndata;
+ Arg args[10];
+ int n;
+ Widget oldplugin, scrolledW;
+ Dimension width, height;
+
+ /* remove the current plugin from its parent's geometry management */
+ oldplugin = data->plugin;
+
+ if (XtIsRealized(oldplugin) == False)
+ return;
+
+ /* we only want to deal with resize */
+ if (event->xconfigure.x != 0 || event->xconfigure.y != 0)
+ return;
+
+ scrolledW = XtParent(XtParent(oldplugin));
+ XtUnmanageChild(oldplugin);
+
+ /* create a copy of the plugin widget */
+ n = 0;
+ XtSetArg(args[n], XmNwidth, &width); n++;
+ XtSetArg(args[n], XmNheight, &height); n++;
+ XtGetValues(oldplugin, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XmNwidth, width); n++;
+ XtSetArg(args[n], XmNheight, height); n++;
+ XtSetArg(args[n], XmNmarginWidth, 0); n++;
+ XtSetArg(args[n], XmNmarginHeight, 0); n++;
+ XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
+ data->plugin = XmCreateDrawingArea(scrolledW, "plugin", args, n);
+
+ n = 0;
+ XtSetArg(args[n], XmNworkWindow, data->plugin); n++;
+ XtSetValues(scrolledW, args, n);
+ XtManageChild(data->plugin);
+
+ /* then destroy the old plugin widget */
+ XtDestroyWidget(oldplugin);
+
+ data->setup_window = True;
+ }
+}
+
+/* build a GUI with a form containing a ScrolledWindow over a DrawingArea for
+ the plugin and a button to quit */
+Widget
+BuildGUI(Widget toplevel, Dimension width, Dimension height, NPP instance)
+{
+ Widget form, scrolledW, plugin, button;
+ Arg args[10];
+ int n;
+
+ XtAddRawEventHandler(toplevel, StructureNotifyMask, False,
+ ResizeEH, instance);
+
+ form = XmCreateForm(toplevel, "form", NULL, 0);
+
+ n = 0;
+ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+ XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
+ XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
+ button = XmCreatePushButton(form, "quit", args, n);
+ XtAddCallback(button, XmNactivateCallback, QuitCB, instance);
+
+ n = 0;
+ XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
+ XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
+ XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
+ XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
+ XtSetArg(args[n], XmNbottomWidget, button); n++;
+ XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++;
+ XtSetArg(args[n], XmNscrollingPolicy, XmAUTOMATIC); n++;
+ scrolledW = XmCreateScrolledWindow(form, "scrolledWindow", args, n);
+
+ n = 0;
+ XtSetArg(args[n], XmNwidth, width); n++;
+ XtSetArg(args[n], XmNheight, height); n++;
+ XtSetArg(args[n], XmNmarginWidth, 0); n++;
+ XtSetArg(args[n], XmNmarginHeight, 0); n++;
+ XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
+ plugin = XmCreateDrawingArea(scrolledW, "plugin", args, n);
+
+ n = 0;
+ XtSetArg(args[n], XmNworkWindow, plugin); n++;
+ XtSetValues(scrolledW, args, n);
+
+ XtManageChild(plugin);
+ XtManageChild(scrolledW);
+ XtManageChild(button);
+ XtManageChild(form);
+ return plugin;
+}
+
+/* parse program arguments and return plugin arguments list */
+void
+ParseProgramArgs(int pg_argc, char **pg_argv,
+ int *argc_ret, char ***argn_ret, char ***argv_ret)
+{
+ int argc, i;
+ char **argn, **argv, *ptr;
+
+ argn = (char **)malloc(sizeof(char *) * pg_argc);
+ argv = (char **)malloc(sizeof(char *) * pg_argc);
+ if (argn == NULL || argv == NULL) {
+ fprintf(stderr, "cannot malloc enough memory: %d\n",
+ sizeof(char *) * pg_argc);
+ exit(1);
+ }
+ argc = 0;
+ for (i = 0; i < pg_argc; i++) {
+ /* look for arguments of the form "name=value", skip malformed ones */
+ ptr = strchr(pg_argv[i], '=');
+ if (ptr != NULL) {
+ /* "split" the string and store both parts */
+ *ptr = '\0';
+ argn[argc] = pg_argv[i];
+ argv[argc] = ptr + 1;
+ argc++;
+ } else
+ fprintf(stderr, "invalid argument: %s\n", pg_argv[i]);
+ }
+ *argn_ret = argn;
+ *argv_ret = argv;
+ *argc_ret = argc;
+}
+
+
+/* retreive src, width, and height arguments value */
+void
+ParsePluginArgs(int argc, char **argn, char **argv,
+ char **src_ret, int *width_ret, int *height_ret)
+{
+ int i;
+
+ *src_ret = NULL;
+ *width_ret = DEFAULT_WIDTH;
+ *height_ret = DEFAULT_HEIGHT;
+ /* dumb look up */
+ for (i = 0; i < argc; i++) {
+ if (strcasecmp(argn[i], "src") == 0)
+ *src_ret = argv[i];
+ else if (strcasecmp(argn[i], "width") == 0)
+ *width_ret = atoi(argv[i]);
+ else if (strcasecmp(argn[i], "height") == 0)
+ *height_ret = atoi(argv[i]);
+ }
+}
+
+/* main routine exercising the plug-in within a state machine */
+Boolean
+MainWorkProc(XtPointer closure)
+{
+ NPP instance = (NPP) closure;
+ AppData *data = (AppData *)instance->ndata;
+ NPError status;
+
+ switch (data->state) {
+ case SETUP:
+ /* create plugin instance */
+ SetupPlugin(instance);
+ data->state = SETUPWINDOW;
+ break;
+
+ case SETUPWINDOW:
+ /* create plugin window */
+ SetupPluginWindow(instance);
+ data->state = PROCESSINPUT;
+ break;
+
+ case PROCESSINPUT:
+ /* set default next state,
+ may be overriden by the call to GetURL */
+ data->state = DONE;
+
+ /* perform GET request on input data */
+ if (data->src != NULL) {
+ status = NPN_GetURL(instance, data->src, NULL);
+ data->state = SETUPSTREAM;
+ }
+ break;
+
+ case SETUPSTREAM:
+ /* if there is a GET request in progress setup to process reply */
+ if (data->streams != NULL && data->nstreams != 0) {
+ if (data->streams[0]->end == -1) /* throw it away */
+ fprintf(stderr,
+ "GetURL request response is thrown away (sorry)\n");
+ else {
+ /*
+ * NPError NPP_NewStream(NPP instance, NPMIMEType type,
+ * NPStream *stream, NPBool seekable, uint16* stype)
+ */
+ PRINTTRACE(" NPP_NewStream\n");
+ status = NPP_NewStream(instance, MIMETYPE, data->streams[0],
+ FALSE, (uint16*)NP_NORMAL);
+ /* and add a handler for it */
+ XtAppAddInput(XtWidgetToApplicationContext(data->plugin),
+ fileno((FILE *)(data->streams[0]->ndata)),
+ (XtPointer) XtInputReadMask,
+ (XtInputCallbackProc) WriteStreamProc,
+ (XtPointer) instance);
+ }
+ }
+ data->state = PROCESSREPLY;
+ break;
+
+ case PROCESSREPLY:
+ /* if no more query responses are pending move to next state */
+ if (data->streams == NULL || data->nstreams == 0 ||
+ data->streams[0]->end == -1)
+ data->state = DONE; /* no more to be read */
+ break;
+
+ case DONE:
+ /* if there is a registered stream close it */
+ if (data->streams != NULL && data->nstreams != 0) {
+ CloseStream(instance, 0);
+ if (data->nstreams > 0) {
+ /* then call for process of next reply */
+ data->state = SETUPSTREAM;
+ return False; /* work proc is to be called again */
+ }
+ }
+ /* then exit from state machine */
+ return True; /* work proc is to be removed */
+ }
+ return False; /* work proc is to be called again */
+}
+
+main(int argc, char **argv)
+{
+ Widget toplevel, plugin;
+ XtAppContext app_context;
+ NPP_t instance;
+ AppData app_data;
+ char **plugin_argn, **plugin_argv;
+ int plugin_argc;
+ char *src;
+ int width, height;
+ XEvent event;
+
+ if (argc < 2 || !strncmp(argv[1], "-h", 2) || !strncmp(argv[1], "-?", 2)) {
+ fprintf(stderr,
+ "Usage: %s src=url [width=w] [height=h] [name=value ...]\n",
+ argv[0]);
+ exit(1);
+ }
+
+ /* build GUI */
+ toplevel = XtAppInitialize(&app_context, "Plugin Test", 0, 0,
+ &argc, argv, 0, 0, 0);
+#ifdef SUPPORT_EDITRES
+ XtAddEventHandler(toplevel, 0, True, _XEditResCheckMessages, NULL);
+#endif
+
+ ParseProgramArgs(argc - 1, argv + 1,
+ &plugin_argc, &plugin_argn, &plugin_argv);
+
+ ParsePluginArgs(plugin_argc, plugin_argn, plugin_argv,
+ &src, &width, &height);
+
+ /* make sure width and height are valid */
+ if (width < 0 || height < 0) {
+ fprintf(stderr, "invalid size specification (< 0) width=%d height=%d",
+ width, height);
+ exit(1);
+ }
+
+ if (src == NULL) {
+ fprintf(stderr, "source argument required!\n");
+ exit(1);
+ }
+
+ plugin =
+ BuildGUI(toplevel, (Dimension)width, (Dimension)height, &instance);
+
+ /* setup instance structure */
+ app_data.state = SETUP;
+ app_data.plugin_argn = plugin_argn;
+ app_data.plugin_argv = plugin_argv;
+ app_data.plugin_argc = plugin_argc;
+ app_data.width = (uint32) width;
+ app_data.height = (uint32) height;
+ app_data.plugin = plugin;
+ app_data.src = src;
+ app_data.streams = NULL;
+ app_data.nstreams = 0;
+ app_data.streams_len = 0;
+ app_data.setup_window = False;
+ instance.ndata = (void *) &app_data;
+
+ /* register main work proc (heart of the beast) */
+ XtAppAddWorkProc(app_context, MainWorkProc, &instance);
+
+ XtRealizeWidget(toplevel);
+
+ /* wait for user to quit */
+ for (;;) {
+ XtAppNextEvent (app_context, &event);
+ XtDispatchEvent (&event);
+ if (app_data.setup_window) {
+ SetupPluginWindow(&instance);
+ app_data.setup_window = False;
+ }
+ }
+}
+
+
+/*
+ * Netscape Methods
+ */
+
+void *
+NPN_MemAlloc(uint32 size)
+{
+ return malloc(size);
+}
+
+uint32
+NPN_MemFlush(uint32 size)
+{
+ /* do nothing */
+ return 0;
+}
+
+void
+NPN_MemFree(void *ptr)
+{
+ free(ptr);
+}
+
+/* This is an asynchronous function, so perform request, setup stream for
+ * reply, and put it in the queue. */
+NPError
+NPN_GetURL(NPP instance, const char *url, const char *window)
+{
+ AppData *data = (AppData *)instance->ndata;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ if (url == NULL)
+ return NPERR_INVALID_URL;
+
+ /* perform request using "www" */
+ sprintf(buf, "www -source \"%s\"", url);
+ fp = popen(buf, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "GetURL request failed on: %s\n", url);
+ return NPERR_INVALID_URL;
+ }
+
+ MakeStream(instance, url, window, fp);
+
+ return NPERR_NO_ERROR;
+}
diff --git a/testplugin/testplugin.man b/testplugin/testplugin.man
new file mode 100644
index 0000000..6c1edc8
--- /dev/null
+++ b/testplugin/testplugin.man
@@ -0,0 +1,66 @@
+.\" $Xorg: testplugin.man,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $
+.\" Copyright 1996, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH TESTPLUGIN 1 "Release 6.4" "X Version 11"
+.SH NAME
+testplugin - a Netscape Plug-in test bed utility
+.SH SYNOPSIS
+.B testplugin
+src=\fIurl\fP
+[width=\fIwidth\fP]
+[height=\fIheight\fP]
+[\fIname\fP=\fIvalue\fP] ...
+.SH DESCRIPTION
+This program is designed to provide a means for testing Netscape Navigator
+UNIX plug-ins. It exercises the plug-in in a way close (I hope) to how
+Navigator does, and because it is a standalone program it allows you to run
+it through debugger and to use various program analysis tools.
+.PP
+The line-mode browser \fBwww\fP, must be in your \fBPATH\fP to be able to
+use testplugin successfully.
+.SH ARGUMENTS
+.PP
+.TP 8
+.B src=\fIurl\fP
+This argument specifies the source document to use. It should be of the MIME
+type your plug-in is expecting since unlike within Netscape, no type checking
+is done and the document is simply streamed to the plug-in.
+.PP
+.TP 8
+.B [width=\fIwidth\fP] [height=\fIheight\fP]
+These options allow to specify the plug-in window size.
+.PP
+.TP 8
+.B [\fIname\fP=\fIvalue\fP]...
+In addition to the arguments described above, any other argument can be
+specified and will be passed uninterpreted to the plug-in (through the
+NPP_New method).
+.SH CURRENT LIMITATIONS
+I've not implemented all of the "Netscape Methods", but only the ones I've
+needed so far. Also the "Plug-in Methods" are not called in every possible
+manner so it does not provide a 100% testing coverage.
+.SH "SEE ALSO"
+www(1), Netscape Navigator Documentation
+.SH AUTHOR
+Arnaud Le Hors, X Consortium
diff --git a/xnest-plugin/NewNDest.c b/xnest-plugin/NewNDest.c
new file mode 100644
index 0000000..52b038c
--- /dev/null
+++ b/xnest-plugin/NewNDest.c
@@ -0,0 +1,65 @@
+/* $Xorg: NewNDest.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxPlugin.h"
+#include <sys/types.h>
+#include <signal.h>
+
+
+NPError
+NPP_Initialize(void)
+{
+ RxpInitXnestDisplayNumbers();
+ return NPERR_NO_ERROR;
+}
+
+void
+NPP_Shutdown(void)
+{
+}
+
+/***********************************************************************
+ * Functions to init and free private members
+ ***********************************************************************/
+
+void
+RxpNew(PluginInstance *This)
+{
+ This->window = None;
+ This->child_pid = 0;
+ This->toplevel_widget = NULL;
+}
+
+void
+RxpDestroy(PluginInstance *This)
+{
+ /* kill child process */
+ kill(This->child_pid, SIGKILL);
+ RxpFreeXnestDisplayNumber(This->display_num);
+}
diff --git a/xnest-plugin/PProcess.c b/xnest-plugin/PProcess.c
new file mode 100644
index 0000000..b90ae6c
--- /dev/null
+++ b/xnest-plugin/PProcess.c
@@ -0,0 +1,71 @@
+/* $Xorg: PProcess.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxPlugin.h"
+#include "XUrls.h"
+
+/***********************************************************************
+ * Process the given RxParams and make the RxReturnParams
+ ***********************************************************************/
+int
+RxpProcessParams(PluginInstance* This, RxParams *in, RxReturnParams *out)
+{
+ /* init return struture */
+ memset(out, 0, sizeof(RxReturnParams));
+ out->x_ui_lbx = RxUndef;
+ out->x_print_lbx = RxUndef;
+
+ out->action = in->action;
+ if (in->embedded != RxUndef)
+ out->embedded = RxTrue; /* we do support embbeding! */
+ else
+ out->embedded = RxUndef;
+
+ out->width = in->width;
+ out->height = in->height;
+
+ if (in->ui[0] == XUI) { /* X display needed */
+ out->ui = GetXUrl(RxpXnestDisplay(This->display_num), NULL, in->action);
+
+ if (in->x_ui_lbx != RxUndef)
+ out->x_ui_lbx = RxFalse; /* we do not support LBX */
+ else
+ out->x_ui_lbx = RxUndef;
+ }
+
+ if (in->print[0] == XPrint) { /* XPrint server needed */
+ out->print = NULL;
+
+ if (in->x_print_lbx != RxUndef)
+ out->x_print_lbx = RxFalse; /* we do not support LBX */
+ else
+ out->x_print_lbx = RxUndef;
+ }
+ return 0;
+}
diff --git a/xnest-plugin/RxPlugin.h b/xnest-plugin/RxPlugin.h
new file mode 100644
index 0000000..ce7c420
--- /dev/null
+++ b/xnest-plugin/RxPlugin.h
@@ -0,0 +1,119 @@
+/* $Xorg: RxPlugin.h,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+/*
+ * RX plug-in header file, based on the UnixTemplate file provided by Netcape.
+ */
+
+/* -*- Mode: C; tab-width: 4; -*- */
+/******************************************************************************
+ * Copyright 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>
+ *
+ */
+
+#ifndef _RxPlugin_h
+#define _RxPLugin_h
+
+#include "npapi.h"
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+#include <stdio.h>
+#include "Rx.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 enum { LOADING, /* STARTING, */ WAITING, RUNNING} PluginState;
+
+typedef struct _PluginInstance
+{
+ NPP instance;
+ int16 argc; /* HTML arguments given by Netscape */
+ char **argn;
+ char **argv;
+ short parse_reply; /* 0 - no
+ 1 - look for status line
+ 2 - done */
+ short status; /* returned application status */
+ RxBool dont_reparent; /* whether client windows need reparent*/
+ char *query;
+ PluginState state;
+ Widget status_widget;
+ Widget plugin_widget;
+ Dimension width, height;
+ /* The following fields need to be taken care by RxpNew & RxpDestroy */
+ Window window;
+ pid_t child_pid;
+ int display_num; /* Xnest display number */
+ Widget toplevel_widget;
+} PluginInstance;
+
+#define PLUGIN_NAME "RX Xnest Plug-in"
+#define PLUGIN_DESCRIPTION "This X Remote Activation Plug-in uses the \
+Xnest program to perform embedding of X applications."
+#define PLUGIN_MIME_DESCRIPTION \
+ "application/x-rx:xrx:X Remote Activation Plug-in"
+
+
+/* functions to init and free private members */
+extern void RxpNew(PluginInstance *This);
+extern void RxpDestroy(PluginInstance *This);
+
+extern int
+RxpProcessParams(PluginInstance* This, RxParams *in, RxReturnParams *out);
+
+extern void
+RxpSetStatusWidget(PluginInstance*, PluginState);
+
+extern void RxpInitXnestDisplayNumbers();
+extern int RxpXnestDisplayNumber();
+extern void RxpFreeXnestDisplayNumber(int i);
+extern char * RxpXnestDisplay(int display_number);
+
+#endif
diff --git a/xnest-plugin/SetWin.c b/xnest-plugin/SetWin.c
new file mode 100644
index 0000000..33e80a6
--- /dev/null
+++ b/xnest-plugin/SetWin.c
@@ -0,0 +1,216 @@
+/* $Xorg: SetWin.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+/*
+ * RX plug-in module based on the UnixTemplate file provided by Netcape.
+ */
+
+/* -*- Mode: C; tab-width: 4; -*- */
+/******************************************************************************
+ * Copyright 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 "RxPlugin.h"
+#include <X11/StringDefs.h>
+
+/***********************************************************************
+ * Sometimes the plugin widget gets stupidly destroyed, that is whenever
+ * Netscape relayouts the page. This callback reparents the Xnest
+ * window to the root window so it does not get destroyed as well.
+ * Eventually the NPP_SetWindow function should be called and we'll
+ * reparent it back under the plugin.
+ ***********************************************************************/
+static void
+DestroyCB (Widget widget, XtPointer client_data, XtPointer call_data)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+ int i;
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "DestroyCB, This: 0x%x\n", This);
+#endif
+ This->plugin_widget = NULL;
+ This->status_widget = NULL;
+ if (This->dont_reparent == RxFalse) {
+ XUnmapWindow(XtDisplay(widget), This->window);
+ XReparentWindow(XtDisplay(widget), This->window,
+ RootWindowOfScreen(XtScreen(widget)), 0, 0);
+ This->dont_reparent = RxTrue;
+ } else
+ This->dont_reparent = RxFalse;
+ /*
+ * not worth removing event handlers on this widget since it's
+ * about to be destroyed anyway.
+ */
+}
+
+
+/***********************************************************************
+ * Sometimes the plugin widget gets stupidly resized, because of poor
+ * geometry when its child (that is the status widget) gets destroyed.
+ * So this callback resizes it back to the right size.
+ * Note that this could lead to an endless battle, but it appears that
+ * it doesn't so far...
+ ***********************************************************************/
+static void
+ResizeCB (Widget widget, XtPointer client_data, XtPointer call_data)
+{
+ PluginInstance* This = (PluginInstance*) client_data;
+ Arg args[5];
+ int n;
+
+#ifdef PLUGIN_TRACE
+ fprintf (stderr, "ResizeCB, This: 0x%x\n", This);
+#endif
+ /* make sure plugin widget gets the same size back */
+ n = 0;
+ XtSetArg(args[n], XtNwidth, This->width); n++;
+ XtSetArg(args[n], XtNheight, This->height); n++;
+ XtSetValues(This->plugin_widget, args, n);
+}
+
+static Widget
+FindToplevel(Widget widget)
+{
+ while (XtParent(widget) != NULL && !XtIsTopLevelShell(widget))
+ widget = XtParent(widget);
+
+ return widget;
+}
+
+/***********************************************************************
+ * This function gets called first when the plugin widget is created and
+ * then whenever the plugin is changed.
+ ***********************************************************************/
+NPError
+NPP_SetWindow(NPP instance, NPWindow* window)
+{
+ PluginInstance* This;
+ Display *display;
+ Widget netscape_widget;
+ pid_t pid;
+
+ 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.
+ */
+ display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
+ netscape_widget = XtWindowToWidget(display, (Window) window->window);
+ if (This->toplevel_widget == NULL)
+ This->toplevel_widget = FindToplevel(netscape_widget);
+
+ if (This->plugin_widget != netscape_widget) {
+
+ /* We have a new widget store it */
+ This->plugin_widget = netscape_widget;
+ This->width = window->width;
+ This->height = window->height;
+
+ XtAddCallback (This->plugin_widget, XtNdestroyCallback,
+ DestroyCB, (XtPointer) This);
+ XtAddCallback (This->plugin_widget, "resizeCallback",
+ ResizeCB, (XtPointer) This);
+
+ if (This->window == None) {
+
+ This->window = XCreateSimpleWindow(display, (Window)window->window,
+ 0, 0,
+ window->width, window->height,
+ 0, 0, 0);
+ XMapWindow(display, This->window);
+
+ This->display_num = RxpXnestDisplayNumber();
+#ifdef PLUGIN_TRACE
+ fprintf(stderr, "Windows: %ld %ld\n",
+ (Window) window->window, XtWindow(This->window));
+#endif
+ pid = fork();
+ if (pid == 0) { /* child process */
+ static char *argv[] = {
+ "Xnest",
+ "-ac", /* no access control (sic!) */
+ ":00", /* display number */
+ "-parent",
+ "01234567890123456789", /* parent window id */
+ NULL
+ };
+ close(ConnectionNumber(display));
+
+ sprintf(argv[2], ":%d", This->display_num);
+ sprintf(argv[4], "%ld", This->window);
+ /* exec Xnest */
+ execvp("Xnest", argv);
+ perror("Xnest");
+ return NPERR_GENERIC_ERROR;
+ } else { /* parent process */
+ /* store child pid so we can kill it later on */
+ This->child_pid = pid;
+ }
+ } else {
+ /* Xnest is either under the RootWindow or the old widget */
+ XReparentWindow(display, This->window, (Window)window->window,
+ 0, 0);
+ if (This->dont_reparent == RxTrue)
+ XMapWindow(display, This->window);
+ if (This->state != RUNNING)
+ RxpSetStatusWidget(This, This->state);
+ }
+ if (This->dont_reparent != RxFalse) /* can be True or Undef */
+ This->dont_reparent = RxFalse;
+ else
+ This->dont_reparent = RxTrue;
+ }
+
+ return NPERR_NO_ERROR;
+}
diff --git a/xnest-plugin/XnestDis.c b/xnest-plugin/XnestDis.c
new file mode 100644
index 0000000..10dddf0
--- /dev/null
+++ b/xnest-plugin/XnestDis.c
@@ -0,0 +1,106 @@
+/* $Xorg: XnestDis.c,v 1.4 2001/02/09 02:05:58 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+The Open Group.
+
+*/
+
+#include "RxPlugin.h"
+
+/***********************************************************************
+ * Utility functions and global variable to manage display numbers
+ ***********************************************************************/
+
+/* maximum numbers of concurrent instances */
+#define MAX_PLUGINS 10
+
+/* start from 5 to avoid possible conflict with multi-display X server */
+#define XNEST_OFFSET 5
+
+/* global allowing to know which display numbers are in use */
+static int16 xnest_display_numbers[MAX_PLUGINS];
+
+void
+RxpInitXnestDisplayNumbers()
+{
+ memset(xnest_display_numbers, 0, sizeof(int16) * MAX_PLUGINS);
+}
+
+/* function returning first display number available */
+int
+RxpXnestDisplayNumber()
+{
+ int i;
+ for (i = 0; i < MAX_PLUGINS; i++)
+ if (xnest_display_numbers[i] == 0) {
+ xnest_display_numbers[i] = 1;
+ return i + XNEST_OFFSET;
+ }
+ /* no more available */
+ return -1;
+}
+
+/* function returning first display number available */
+void
+RxpFreeXnestDisplayNumber(int i)
+{
+ xnest_display_numbers[i - XNEST_OFFSET] = 0;
+}
+
+/* function returning display name with specified display number */
+char *
+RxpXnestDisplay(int display_number)
+{
+ static char name[1024];
+ char *display_name, *dpy_name, *display_num, *screen_num;
+
+ display_name = getenv("DISPLAY");
+ if (display_name == NULL)
+ return NULL;
+
+ /* if of the form x11:display skip scheme part */
+ if (strncmp(display_name, "x11:", 4) == 0)
+ dpy_name = display_name + 4;
+ else
+ dpy_name = display_name;
+
+ /* display number is after next ":" character */
+ display_num = strchr(dpy_name, ':');
+ if (display_num == NULL) /* invalid display specification */
+ return NULL;
+
+ /* copy display name up to the display number */
+ strncpy(name, display_name, display_num - display_name);
+
+ /* override display_number */
+ sprintf(name + (display_num - display_name), ":%d", display_number);
+
+ /* append screen number */
+ screen_num = strchr(display_num, '.');
+ if (screen_num != NULL)
+ strcat(name, screen_num);
+
+ return name;
+}