diff options
Diffstat (limited to 'plugin/PProcess.c')
-rw-r--r-- | plugin/PProcess.c | 1017 |
1 files changed, 1017 insertions, 0 deletions
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; +} |