Blame lib/Xm/PrintS.c

Packit b099d7
/* $TOG: PrintS.c /main/38 1997/06/18 17:48:54 samborn $ */
Packit b099d7
/*
Packit b099d7
 * (c) Copyright 1996 Digital Equipment Corporation.
Packit b099d7
 * (c) Copyright 1996 Hewlett-Packard Company.
Packit b099d7
 * (c) Copyright 1996 International Business Machines Corp.
Packit b099d7
 * (c) Copyright 1996 Sun Microsystems, Inc.
Packit b099d7
 * (c) Copyright 1996 Novell, Inc. 
Packit b099d7
 * (c) Copyright 1996 FUJITSU LIMITED.
Packit b099d7
 * (c) Copyright 1996 Hitachi.
Packit b099d7
 */
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#include "XmI.h"
Packit b099d7
#include <Xm/PrintSP.h>
Packit b099d7
#include "ImageCachI.h"
Packit b099d7
#include "SyntheticI.h"
Packit b099d7
#include <stdlib.h>
Packit b099d7
#include <unistd.h>
Packit b099d7
Packit b099d7
/********    Static Function Declarations    ********/
Packit b099d7
Packit b099d7
static void ClassPartInitialize( 
Packit b099d7
                        WidgetClass wc) ;
Packit b099d7
static void ClassInitialize( void ) ;
Packit b099d7
static void Initialize( 
Packit b099d7
                        Widget requested_widget,
Packit b099d7
                        Widget new_widget,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static Boolean SetValues( 
Packit b099d7
                        Widget current,
Packit b099d7
                        Widget request,
Packit b099d7
                        Widget new_w,
Packit b099d7
                        ArgList args,
Packit b099d7
                        Cardinal *num_args) ;
Packit b099d7
static void Destroy( 
Packit b099d7
                        Widget w) ;
Packit b099d7
static void PrintNotifyHandler(
Packit b099d7
		    Widget w,
Packit b099d7
		    XtPointer client_data,
Packit b099d7
		    XEvent *event,
Packit b099d7
		    Boolean *continue_to_dispatch);
Packit b099d7
Packit b099d7
static void ResourcesUpdate(
Packit b099d7
			    Widget w,
Packit b099d7
			    XPContext pcontext,
Packit b099d7
			    Dimension * pwidth, Dimension * pheight);
Packit b099d7
Packit b099d7
static void AttributesNotifyHandler(
Packit b099d7
		    Widget w,
Packit b099d7
		    XtPointer client_data,
Packit b099d7
		    XEvent *event,
Packit b099d7
		    Boolean *continue_to_dispatch);
Packit b099d7
Packit b099d7
Packit b099d7
static void SelectXpEvents (
Packit b099d7
		      Widget widget,
Packit b099d7
		      int *event_types,
Packit b099d7
		      XtPointer *select_data,
Packit b099d7
		      int count,
Packit b099d7
		      XtPointer client_data);
Packit b099d7
Packit b099d7
static void PrintToFileProc(Display  * dpy,
Packit b099d7
			    XPContext context,
Packit b099d7
			    unsigned char *data, 
Packit b099d7
			    unsigned int data_len,
Packit b099d7
			    XPointer client_data);
Packit b099d7
Packit b099d7
static void FinishProc(Display *display,
Packit b099d7
		       XPContext context,
Packit b099d7
		       XPGetDocStatus status,
Packit b099d7
		       XPointer client_data);
Packit b099d7
Packit b099d7
static void PDMPhase2Handler(Widget w,
Packit b099d7
			     XtPointer data,
Packit b099d7
			     XEvent *event,
Packit b099d7
			     Boolean *cont);
Packit b099d7
Packit b099d7
static void PDMSelectionProc (Widget w, 
Packit b099d7
			 XtPointer client_data,
Packit b099d7
			 Atom *selection,
Packit b099d7
			 Atom *type,
Packit b099d7
			 XtPointer value,
Packit b099d7
			 unsigned long *length,
Packit b099d7
			 int *format);
Packit b099d7
Packit b099d7
static Boolean PrintDispatchEvent (XEvent *event);
Packit b099d7
Packit b099d7
static void GetFromTable (Display* pdpy, XPContext context, Widget * widget);
Packit b099d7
static void DeleteFromTable (XPContext context, Widget widget);
Packit b099d7
static void AddToTable (XPContext context, Widget widget);
Packit b099d7
Packit b099d7
Packit b099d7
#define Offset(x) (XtOffsetOf(XmPrintShellRec, print.x))
Packit b099d7
Packit b099d7
static XtResource resources[] = {
Packit b099d7
   {
Packit b099d7
      XmNallowShellResize, XmCAllowShellResize, XmRBoolean, 
Packit b099d7
      sizeof(Boolean), XtOffsetOf(XmPrintShellRec, shell.allow_shell_resize), 
Packit b099d7
      XtRImmediate, (XtPointer)False,
Packit b099d7
   },
Packit b099d7
   {
Packit b099d7
       XmNminX, XmCMinX, XmRHorizontalDimension, sizeof (Dimension), 
Packit b099d7
       Offset(min_x), XmRImmediate, (XtPointer) 0,
Packit b099d7
   },
Packit b099d7
   {
Packit b099d7
       XmNminY, XmCMinY, XmRVerticalDimension, sizeof (Dimension), 
Packit b099d7
       Offset(min_y), XmRImmediate, (XtPointer) 0,
Packit b099d7
   },
Packit b099d7
   {
Packit b099d7
       XmNmaxX, XmCMaxX, XmRHorizontalDimension, sizeof (Dimension), 
Packit b099d7
       Offset(max_x), XmRImmediate, (XtPointer) 0,
Packit b099d7
   },
Packit b099d7
   {
Packit b099d7
       XmNmaxY, XmCMaxY, XmRVerticalDimension, sizeof (Dimension), 
Packit b099d7
       Offset(max_y), XmRImmediate, (XtPointer) 0,
Packit b099d7
   },    
Packit b099d7
   {
Packit b099d7
	XmNdefaultPixmapResolution, XmCDefaultPixmapResolution, XmRShort,
Packit b099d7
	sizeof(unsigned short), Offset(default_pixmap_resolution), 
Packit b099d7
	XmRImmediate, (XtPointer)100,
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNstartJobCallback, XmCCallback,
Packit b099d7
 	XmRCallback, sizeof(XtCallbackList),
Packit b099d7
 	Offset(start_job_callback),
Packit b099d7
        XmRImmediate, (XtPointer)NULL,
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNendJobCallback, XmCCallback,
Packit b099d7
 	XmRCallback, sizeof(XtCallbackList),
Packit b099d7
 	Offset(end_job_callback),
Packit b099d7
        XmRImmediate, (XtPointer)NULL,
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNpageSetupCallback, XmCCallback,
Packit b099d7
 	XmRCallback, sizeof(XtCallbackList),
Packit b099d7
 	Offset(page_setup_callback),
Packit b099d7
        XmRImmediate, (XtPointer)NULL,
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNpdmNotificationCallback, XmCCallback,
Packit b099d7
 	XmRCallback, sizeof(XtCallbackList),
Packit b099d7
 	Offset(pdm_notification_callback),
Packit b099d7
        XmRImmediate, (XtPointer)NULL,
Packit b099d7
    },
Packit b099d7
Packit b099d7
};
Packit b099d7
Packit b099d7
/** only getvalues is supported on these, not setvalues hook therefore */
Packit b099d7
static XmSyntheticResource syn_resources[] =
Packit b099d7
{
Packit b099d7
    {
Packit b099d7
        XmNminX, sizeof(Dimension), Offset(min_x),
Packit b099d7
        XmeFromHorizontalPixels,NULL,
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNminY, sizeof(Dimension), Offset(min_y),
Packit b099d7
        XmeFromVerticalPixels,NULL,
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNmaxX, sizeof(Dimension), Offset(max_x),
Packit b099d7
        XmeFromHorizontalPixels,NULL,
Packit b099d7
    },
Packit b099d7
    {
Packit b099d7
        XmNmaxY, sizeof(Dimension), Offset(max_y),
Packit b099d7
        XmeFromVerticalPixels,NULL,
Packit b099d7
    },
Packit b099d7
};
Packit b099d7
Packit b099d7
#undef Offset
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
externaldef(xmprintshellclassrec)
Packit b099d7
XmPrintShellClassRec xmPrintShellClassRec = {
Packit b099d7
    {	
Packit b099d7
	(WidgetClass) &applicationShellClassRec,  /* superclass		*/   
Packit b099d7
	"XmPrintShell",			/* class_name 		*/   
Packit b099d7
	sizeof(XmPrintShellRec),	/* size 		*/   
Packit b099d7
	ClassInitialize,		/* Class Initializer 	*/   
Packit b099d7
	ClassPartInitialize,	        /* class_part_init 	*/ 
Packit b099d7
	FALSE, 				/* Class init'ed ? 	*/   
Packit b099d7
	Initialize,		        /* initialize         	*/   
Packit b099d7
 	NULL,		                /* initialize_notify    */ 
Packit b099d7
	XtInheritRealize,		/* realize            	*/   
Packit b099d7
	NULL,	 			/* actions            	*/   
Packit b099d7
	0,				/* num_actions        	*/   
Packit b099d7
	resources,			/* resources          	*/   
Packit b099d7
	XtNumber(resources),		/* resource_count     	*/   
Packit b099d7
	NULLQUARK, 			/* xrm_class          	*/   
Packit b099d7
	FALSE, 				/* compress_motion    	*/   
Packit b099d7
	XtExposeCompressSeries, 	/* compress_exposure  	*/   
Packit b099d7
	FALSE, 				/* compress_enterleave	*/   
Packit b099d7
	FALSE, 				/* visible_interest   	*/   
Packit b099d7
	Destroy,			/* destroy            	*/   
Packit b099d7
	XtInheritResize, 		/* resize             	*/   
Packit b099d7
	(XtExposeProc)NULL, 		/* expose             	*/   
Packit b099d7
	SetValues, 		        /* set_values         	*/   
Packit b099d7
	(XtArgsFunc)NULL, 		/* set_values_hook      */ 
Packit b099d7
	XtInheritSetValuesAlmost,	/* set_values_almost    */ 
Packit b099d7
	_XmPrintShellGetValuesHook,	/* get_values_hook      */ 
Packit b099d7
	(XtAcceptFocusProc)NULL, 	/* accept_focus       	*/   
Packit b099d7
	XtVersion, 			/* intrinsics version 	*/   
Packit b099d7
	NULL, 				/* callback offsets   	*/   
Packit b099d7
	XtInheritTranslations,		/* tm_table           	*/   
Packit b099d7
	XtInheritQueryGeometry, 	/* query_geometry       */ 
Packit b099d7
	(XtStringProc)NULL, 		/* display_accelerator  */ 
Packit b099d7
	(XtPointer)NULL, 	        /* extension            */ 
Packit b099d7
    },	
Packit b099d7
    { 					/* composite class record */
Packit b099d7
	XtInheritGeometryManager,	/* geometry_manager 	*/
Packit b099d7
	XtInheritChangeManaged,		/* change_managed	*/
Packit b099d7
	XtInheritInsertChild,		/* insert_child		*/
Packit b099d7
	XtInheritDeleteChild, 		/* from the shell 	*/
Packit b099d7
	NULL, 				/* extension record     */
Packit b099d7
    },
Packit b099d7
    { 					/* shell class record 	*/
Packit b099d7
	NULL, 				/* extension record     */
Packit b099d7
    },
Packit b099d7
    { 					/* wm shell class record */
Packit b099d7
	NULL, 				/* extension record     */
Packit b099d7
    },
Packit b099d7
    { 					/* vendor shell class record */
Packit b099d7
	NULL,				/* extension record     */
Packit b099d7
    },
Packit b099d7
    { 					/* toplevelclass record */
Packit b099d7
	NULL, 				/* extension record     */
Packit b099d7
    },
Packit b099d7
    { 					/* appShell record 	*/
Packit b099d7
	NULL, 				/* extension record     */
Packit b099d7
    },
Packit b099d7
    {					/* PrintShell class	*/
Packit b099d7
	syn_resources,         		/* syn_resources */
Packit b099d7
	XtNumber(syn_resources),	/* num_syn_resources */
Packit b099d7
	NULL,				/* extension		*/
Packit b099d7
    },
Packit b099d7
};
Packit b099d7
Packit b099d7
externaldef(xmprintshellclass) WidgetClass 
Packit b099d7
      xmPrintShellWidgetClass = (WidgetClass) (&xmPrintShellClassRec);
Packit b099d7
Packit b099d7
Packit b099d7
static XContext PrintContextToWidget = 0;
Packit b099d7
Packit b099d7
/* global because used in ResInd.c to find out about resolution */
Packit b099d7
XContext _XmPrintScreenToShellContext = 0;
Packit b099d7
Cardinal _XmPrintShellCounter = 0 ;
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ClassInitialize
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
ClassInitialize( void )
Packit b099d7
{
Packit b099d7
    if (PrintContextToWidget == 0)
Packit b099d7
	PrintContextToWidget = XUniqueContext();
Packit b099d7
    if (_XmPrintScreenToShellContext == 0)
Packit b099d7
	_XmPrintScreenToShellContext = XUniqueContext();
Packit b099d7
}    
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  ClassPartInitialize
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
ClassPartInitialize(
Packit b099d7
	WidgetClass wc )
Packit b099d7
{
Packit b099d7
	_XmFastSubclassInit(wc, XmPRINT_SHELL_BIT);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void 
Packit b099d7
PrintNotifyHandler(
Packit b099d7
		    Widget w,
Packit b099d7
		    XtPointer client_data,
Packit b099d7
		    XEvent *event,
Packit b099d7
		    Boolean *continue_to_dispatch)
Packit b099d7
{
Packit b099d7
    XPPrintEvent * xpev = (XPPrintEvent *) event ;
Packit b099d7
    XmPrintShellWidget print_shell = (XmPrintShellWidget) w ;
Packit b099d7
    XmPrintShellCallbackStruct pr_cbs ;
Packit b099d7
    
Packit b099d7
    /* don't interfere with the app if it hasn't set any callback.
Packit b099d7
       (since we set the handler all the time)
Packit b099d7
       It is probably using it's own handler doing start page, etc */
Packit b099d7
    if (!print_shell->print.start_job_callback &&
Packit b099d7
	!print_shell->print.page_setup_callback &&
Packit b099d7
	!print_shell->print.end_job_callback) return ;
Packit b099d7
Packit b099d7
    pr_cbs.event = event;
Packit b099d7
    pr_cbs.context = xpev->context ;
Packit b099d7
Packit b099d7
    switch (xpev->detail) {
Packit b099d7
    case XPStartJobNotify :
Packit b099d7
	print_shell->print.last_page = False ;
Packit b099d7
	pr_cbs.reason = XmCR_START_JOB ;
Packit b099d7
	pr_cbs.last_page = False ;
Packit b099d7
	XtCallCallbackList (w, print_shell->print.start_job_callback, 
Packit b099d7
			    &pr_cbs);
Packit b099d7
	/* fall thru : call both callbacks if present */
Packit b099d7
    case XPEndPageNotify :
Packit b099d7
	/* if last end page, no need to call pagesetup again */
Packit b099d7
	if (!print_shell->print.last_page) {
Packit b099d7
	    pr_cbs.reason = XmCR_PAGE_SETUP;
Packit b099d7
	    pr_cbs.last_page = False ;
Packit b099d7
	    XtCallCallbackList (w, print_shell->print.page_setup_callback, 
Packit b099d7
				&pr_cbs);
Packit b099d7
	    /* on return from pageSetup, save whether or not that was the
Packit b099d7
	       last page set up by the app */
Packit b099d7
	    print_shell->print.last_page = pr_cbs.last_page;
Packit b099d7
Packit b099d7
	    /* only start a page if a callback is there */
Packit b099d7
	    if (print_shell->print.page_setup_callback) {
Packit b099d7
		XpStartPage(XtDisplay(w), XtWindow(w));	
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	break ;
Packit b099d7
    case XPStartPageNotify :
Packit b099d7
	if (print_shell->print.page_setup_callback) {
Packit b099d7
	    XpEndPage(XtDisplay(w));
Packit b099d7
	    if (print_shell->print.last_page) XpEndJob(XtDisplay(w));
Packit b099d7
	}
Packit b099d7
	break ;
Packit b099d7
    case XPEndJobNotify :
Packit b099d7
	pr_cbs.reason = XmCR_PAGE_SETUP;
Packit b099d7
	pr_cbs.last_page = True ;
Packit b099d7
	XtCallCallbackList (w, print_shell->print.page_setup_callback, 
Packit b099d7
			    &pr_cbs);
Packit b099d7
	pr_cbs.reason = XmCR_END_JOB ;
Packit b099d7
	XtCallCallbackList (w, print_shell->print.end_job_callback, 
Packit b099d7
			    &pr_cbs);
Packit b099d7
	break ;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
ResourcesUpdate(Widget w, XPContext pcontext,
Packit b099d7
		Dimension * pwidth, Dimension * pheight)
Packit b099d7
{
Packit b099d7
    XmPrintShellWidget print_shell = (XmPrintShellWidget) w ;
Packit b099d7
    String string_resolution ;
Packit b099d7
    XRectangle imageable_area ;
Packit b099d7
Packit b099d7
    /*** Get the resolution so that unit Type conversion works */
Packit b099d7
    string_resolution =  
Packit b099d7
	XpGetOneAttribute(XtDisplay(w), pcontext,
Packit b099d7
			  XPDocAttr, "default-printer-resolution") ;
Packit b099d7
    print_shell->print.print_resolution = atoi(string_resolution);
Packit b099d7
    XFree(string_resolution);
Packit b099d7
Packit b099d7
    if (!print_shell->print.print_resolution)
Packit b099d7
	/* compute from the X screen resolution */
Packit b099d7
	print_shell->print.print_resolution = 
Packit b099d7
	    (254 * WidthOfScreen(XtScreen(w)) +
Packit b099d7
	     5 * WidthMMOfScreen(XtScreen(w))) /
Packit b099d7
	    (10 * WidthMMOfScreen(XtScreen(w))) ;
Packit b099d7
Packit b099d7
    /* get our size from the print server now */
Packit b099d7
    XpGetPageDimensions(XtDisplay(w), pcontext,
Packit b099d7
			pwidth, pheight, 
Packit b099d7
			&imageable_area);
Packit b099d7
    print_shell->print.min_x = imageable_area.x ;    
Packit b099d7
    print_shell->print.min_y = imageable_area.y ;    
Packit b099d7
    print_shell->print.max_x = imageable_area.x + imageable_area.width ;    
Packit b099d7
    print_shell->print.max_y = imageable_area.y + imageable_area.height ;
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
AttributesNotifyHandler(
Packit b099d7
		    Widget w,
Packit b099d7
		    XtPointer client_data,
Packit b099d7
		    XEvent *event,
Packit b099d7
		    Boolean *continue_to_dispatch)
Packit b099d7
{
Packit b099d7
    XPAttributeEvent * xatrev = (XPAttributeEvent *) event ;
Packit b099d7
    XmPrintShellWidget print_shell = (XmPrintShellWidget) w ;
Packit b099d7
    Dimension width = w->core.width, height = w->core.height;
Packit b099d7
Packit b099d7
    /* For now, blindly update resolution and sizes */
Packit b099d7
    ResourcesUpdate(w, xatrev->context, &width, &height);
Packit b099d7
Packit b099d7
    XtResizeWidget(w, width, height, w->core.border_width);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void 
Packit b099d7
SelectXpEvents (
Packit b099d7
		Widget widget,
Packit b099d7
		int *event_types,
Packit b099d7
		XtPointer *select_data,
Packit b099d7
		int count,
Packit b099d7
		XtPointer client_data)
Packit b099d7
{
Packit b099d7
    XpSelectInput(XtDisplay(widget),
Packit b099d7
		  XpGetContext(XtDisplay(widget)),
Packit b099d7
		  XPPrintMask|XPAttributeMask);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*****************************
Packit b099d7
  Maintain a XPContext to widget binding for use in event dispatch to 
Packit b099d7
  print shell logic. 
Packit b099d7
  Limitation is only one shell per XPContext in this implementation.
Packit b099d7
  Could improve to dispatch to all widget in this context later, but
Packit b099d7
  not sure if supported by Xp itself.
Packit b099d7
******************************/
Packit b099d7
Packit b099d7
static void GetFromTable (Display* pdpy, XPContext context, Widget * widget) 
Packit b099d7
{
Packit b099d7
    XFindContext(pdpy, (XID)context, PrintContextToWidget, 
Packit b099d7
		 (XPointer *) widget);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void DeleteFromTable (XPContext context, Widget widget) 
Packit b099d7
{
Packit b099d7
    XDeleteContext(XtDisplay(widget), (XID)context, PrintContextToWidget);
Packit b099d7
}
Packit b099d7
Packit b099d7
static void AddToTable (XPContext context, Widget widget) 
Packit b099d7
{
Packit b099d7
    XSaveContext(XtDisplay(widget), (XID)context, PrintContextToWidget, 
Packit b099d7
	 	 (XPointer) widget);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*****************************/
Packit b099d7
static Boolean 
Packit b099d7
PrintDispatchEvent (XEvent *event)
Packit b099d7
{
Packit b099d7
    XPPrintEvent * xpev = (XPPrintEvent *) event ;
Packit b099d7
    Widget widget = NULL ;
Packit b099d7
Packit b099d7
    /* I only have a context, not a window, so I can't use
Packit b099d7
       XtWindowToWidget..  I have to maintain my own table
Packit b099d7
       widget/context.  Limitation: one context to one widget for now */
Packit b099d7
Packit b099d7
    GetFromTable(xpev->display, xpev->context, &widget);
Packit b099d7
    /* If ever supported, need to loop thru a list, if several
Packit b099d7
       print_shell have been created under the same XPContext, and
Packit b099d7
       dispatch the event to all of them */
Packit b099d7
Packit b099d7
    if (!widget) return False ;
Packit b099d7
Packit b099d7
    /* spec says to call filter first, even though in my case,
Packit b099d7
       I shouldn't have any IM around... */
Packit b099d7
    if (XFilterEvent(event, XtWindow(widget)))
Packit b099d7
	return True ;
Packit b099d7
Packit b099d7
    return XtDispatchEventToWidget(widget, event);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Initialize
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
static void 
Packit b099d7
Initialize(
Packit b099d7
        Widget req_widget,
Packit b099d7
        Widget new_widget,
Packit b099d7
        ArgList args,
Packit b099d7
        Cardinal *num_args )
Packit b099d7
{
Packit b099d7
    int event_base_return, error_base_return ;
Packit b099d7
    XmPrintShellWidget print_shell = (XmPrintShellWidget) new_widget ;
Packit b099d7
    XPContext pcontext ;
Packit b099d7
    Screen * pscreen ;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    /* mark the screen of this print shell in this context */
Packit b099d7
    XSaveContext(XtDisplay(new_widget), (XID)XtScreen(new_widget), 
Packit b099d7
		 _XmPrintScreenToShellContext, (XPointer) new_widget);
Packit b099d7
    /* also maintain a counter of all shell */
Packit b099d7
     _XmPrintShellCounter ++ ;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    print_shell->print.xp_connected = False ;
Packit b099d7
    print_shell->print.print_resolution = 100 ;
Packit b099d7
Packit b099d7
    /*** first check if the Print extension is present at all */
Packit b099d7
    if (!XpQueryExtension (XtDisplay(new_widget),
Packit b099d7
			   &event_base_return, &error_base_return)) {
Packit b099d7
	return ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* need to check that the print context is set for
Packit b099d7
       the screen of this print shell (i.e. it's a print screen,
Packit b099d7
       not just a screen on a display that support printing
Packit b099d7
       and for which a context was establish on a different screen -
Packit b099d7
       which can be common in preview case */
Packit b099d7
    pcontext = XpGetContext(XtDisplay(new_widget));
Packit b099d7
    if (!pcontext || 
Packit b099d7
	XpGetScreenOfContext(XtDisplay(new_widget),pcontext) 
Packit b099d7
	!= XtScreen(new_widget)) {
Packit b099d7
	return ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    print_shell->print.xp_connected = True ;
Packit b099d7
Packit b099d7
    /*** add an element to a widget/XPContext table, used in 
Packit b099d7
         the event dispatch mechanism */
Packit b099d7
    AddToTable(pcontext, new_widget);
Packit b099d7
Packit b099d7
    /*** add extension event Handler for Start/End Job/Page Notify */
Packit b099d7
    XtInsertEventTypeHandler(new_widget, 
Packit b099d7
			     event_base_return + XPPrintNotify,
Packit b099d7
			     (XtPointer)XPPrintMask, 
Packit b099d7
			     PrintNotifyHandler, NULL, 
Packit b099d7
			     XtListTail);
Packit b099d7
Packit b099d7
    /*** also add extension event Handler for tracking attributes change */
Packit b099d7
    XtInsertEventTypeHandler(new_widget, 
Packit b099d7
			     event_base_return + XPAttributeNotify,
Packit b099d7
			     (XtPointer)XPAttributeMask, 
Packit b099d7
			     AttributesNotifyHandler, NULL, 
Packit b099d7
			     XtListTail);
Packit b099d7
Packit b099d7
    /* always register the extension selector, and the event dispatcher,
Packit b099d7
       it will override itself accordingly and works ok for different
Packit b099d7
       display connection */
Packit b099d7
    XtRegisterExtensionSelector(XtDisplay(new_widget), 
Packit b099d7
				event_base_return + XPPrintNotify, 
Packit b099d7
				event_base_return + XPAttributeNotify, 
Packit b099d7
				SelectXpEvents,
Packit b099d7
				NULL);
Packit b099d7
    (void) XtSetEventDispatcher(XtDisplay(new_widget), 
Packit b099d7
				event_base_return + XPPrintNotify, 
Packit b099d7
				PrintDispatchEvent);
Packit b099d7
    (void) XtSetEventDispatcher(XtDisplay(new_widget), 
Packit b099d7
				event_base_return + XPAttributeNotify, 
Packit b099d7
				PrintDispatchEvent);
Packit b099d7
			
Packit b099d7
    /* go and get resolution and initial sizes */
Packit b099d7
    ResourcesUpdate(new_widget, pcontext, 
Packit b099d7
		    &(new_widget->core.width), 
Packit b099d7
		    &(new_widget->core.height));
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  SetValues
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean 
Packit b099d7
SetValues(
Packit b099d7
        Widget current,
Packit b099d7
        Widget request,		/* unused */
Packit b099d7
        Widget new_w,
Packit b099d7
        ArgList args,		/* unused */
Packit b099d7
        Cardinal *num_args )	/* unused */
Packit b099d7
{
Packit b099d7
    XmPrintShellWidget cur_print_shell = (XmPrintShellWidget) current ;
Packit b099d7
    XmPrintShellWidget new_print_shell = (XmPrintShellWidget) new_w ;
Packit b099d7
Packit b099d7
    if (!new_print_shell->print.xp_connected)
Packit b099d7
	return False ;
Packit b099d7
Packit b099d7
    /* need to check for changes in getvalues only resources .
Packit b099d7
       need to put out a warning */
Packit b099d7
    if (cur_print_shell->print.min_x != new_print_shell->print.min_x)
Packit b099d7
	new_print_shell->print.min_x = cur_print_shell->print.min_x ;
Packit b099d7
    if (cur_print_shell->print.min_y != new_print_shell->print.min_y)
Packit b099d7
	new_print_shell->print.min_y = cur_print_shell->print.min_y ;
Packit b099d7
    if (cur_print_shell->print.max_x != new_print_shell->print.max_x)
Packit b099d7
	new_print_shell->print.max_x = cur_print_shell->print.max_x ;
Packit b099d7
    if (cur_print_shell->print.max_y != new_print_shell->print.max_y)
Packit b099d7
	new_print_shell->print.max_y = cur_print_shell->print.max_y ;
Packit b099d7
Packit b099d7
    return False ;
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Destroy
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
Destroy(
Packit b099d7
        Widget w )
Packit b099d7
{
Packit b099d7
    XmPrintShellWidget print_shell = (XmPrintShellWidget) w ;
Packit b099d7
Packit b099d7
    /* need to remove the pixmap from this shell: no sharing
Packit b099d7
       between diff shell and the same shell pointer id can
Packit b099d7
       come up next time */
Packit b099d7
    _XmCleanPixmapCache (XtScreen(w), w);
Packit b099d7
Packit b099d7
    if (!print_shell->print.xp_connected)
Packit b099d7
	return ;
Packit b099d7
Packit b099d7
    /*** remove entry in the widget/XPContext table, used in 
Packit b099d7
         the event dispatch mechanism */
Packit b099d7
    DeleteFromTable(XpGetContext(XtDisplay(w)), w);
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    /* unmark the screen of this print shell in this context */
Packit b099d7
    XDeleteContext(XtDisplay(w), (XID)XtScreen(w), 
Packit b099d7
		   _XmPrintScreenToShellContext);
Packit b099d7
    /* also maintain a counter of all shells alive */
Packit b099d7
    _XmPrintShellCounter -- ;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  Public API
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  XmPrintSetup
Packit b099d7
 *
Packit b099d7
 *    add print display in app context and create the print shell 
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
 
Packit b099d7
Packit b099d7
Widget
Packit b099d7
XmPrintSetup(
Packit b099d7
             Widget           video_widget,
Packit b099d7
             Screen           *print_screen,
Packit b099d7
             String            print_shell_name,
Packit b099d7
             ArgList           args,
Packit b099d7
             Cardinal          num_args)
Packit b099d7
{
Packit b099d7
    String video_name, video_class ;
Packit b099d7
    Widget pappshell ;
Packit b099d7
    Widget print_shell;
Packit b099d7
    Display  *print_display = DisplayOfScreen(print_screen);
Packit b099d7
Packit b099d7
    /* get to the video app root shell */
Packit b099d7
    while(!XtIsApplicationShell(video_widget))
Packit b099d7
	video_widget = XtParent(video_widget);
Packit b099d7
Packit b099d7
    if (!video_widget) return NULL;
Packit b099d7
Packit b099d7
    XtGetApplicationNameAndClass(XtDisplay(video_widget),
Packit b099d7
                                 &video_name, &video_class);
Packit b099d7
Packit b099d7
    /* we want to be able to specify things like:
Packit b099d7
       dtpad.print*textFontList: somefont
Packit b099d7
       dtpad.print*background:white
Packit b099d7
       so we create a first shell unrealized and them a popup
Packit b099d7
       named "print".
Packit b099d7
       */
Packit b099d7
    pappshell = XtVaAppCreateShell(video_name, video_class,
Packit b099d7
                                   applicationShellWidgetClass, 
Packit b099d7
                                   print_display, 
Packit b099d7
                                   XmNscreen, print_screen, 
Packit b099d7
                                   NULL);
Packit b099d7
Packit b099d7
    /* then create the XmPrintShell */
Packit b099d7
    print_shell = XtCreatePopupShell(print_shell_name, 
Packit b099d7
				     xmPrintShellWidgetClass, 
Packit b099d7
				     pappshell, args, num_args);
Packit b099d7
Packit b099d7
    /* Add callback to destroy application Shell parent. */
Packit b099d7
    XtAddCallback(print_shell, XmNdestroyCallback, 
Packit b099d7
                  _XmDestroyParentCallback, (XtPointer) NULL) ;
Packit b099d7
Packit b099d7
    /* we're mapping/unmapping at start/end page time */
Packit b099d7
    XtSetMappedWhenManaged(print_shell, False);
Packit b099d7
Packit b099d7
    /* realize the shell now, so that XmPrintPopupPDM works dy default */
Packit b099d7
    XtRealizeWidget(print_shell);
Packit b099d7
Packit b099d7
    return print_shell ;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  XmPrintToFile
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
/* need to be able to remove the filename or write/close the file */
Packit b099d7
typedef struct {
Packit b099d7
    String file_name;
Packit b099d7
    FILE * file;
Packit b099d7
    int pipe;
Packit b099d7
} FileDescRec ;
Packit b099d7
Packit b099d7
Packit b099d7
typedef struct { 
Packit b099d7
  Display *display;
Packit b099d7
  XPFinishProc finish_proc;
Packit b099d7
  XPointer client_data;
Packit b099d7
  int pipe;
Packit b099d7
  XtInputId input_id;
Packit b099d7
} FileCallbackRec;
Packit b099d7
Packit b099d7
Packit b099d7
static void PrintToFileProc(Display  * dpy,
Packit b099d7
			    XPContext context,
Packit b099d7
			    unsigned char *data, 
Packit b099d7
			    unsigned int data_len,
Packit b099d7
			    XPointer client_data)
Packit b099d7
{
Packit b099d7
    FileDescRec * file_desc = (FileDescRec *) client_data ;
Packit b099d7
    
Packit b099d7
    /* write to the file */
Packit b099d7
    fwrite(data, data_len, 1, file_desc->file);
Packit b099d7
}   
Packit b099d7
Packit b099d7
Packit b099d7
static void FinishProc(Display *display,
Packit b099d7
		       XPContext context,
Packit b099d7
		       XPGetDocStatus status,
Packit b099d7
		       XPointer client_data)
Packit b099d7
{
Packit b099d7
    FileDescRec * file_desc = (FileDescRec *) client_data ;
Packit b099d7
Packit b099d7
    /* remove the file if not successfull */
Packit b099d7
    if (status != XPGetDocFinished)
Packit b099d7
	 remove(file_desc->file_name);
Packit b099d7
    else fclose(file_desc->file);
Packit b099d7
Packit b099d7
    /* write the status to the parent */
Packit b099d7
    (void) write(file_desc->pipe, &status, sizeof(XPGetDocStatus));
Packit b099d7
Packit b099d7
    /* we don't do any free's or close's, as we are just
Packit b099d7
       going to exit, in fact, get out without calling any C++
Packit b099d7
       destructors, etc., as we don't want anything funny to happen
Packit b099d7
       to the parent */
Packit b099d7
    _exit(0);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void FilePipeCB(XtPointer client_data, int *source, XtInputId *id)
Packit b099d7
{
Packit b099d7
  FileCallbackRec *cb = (FileCallbackRec *) client_data;
Packit b099d7
  XPGetDocStatus status;
Packit b099d7
Packit b099d7
  /* read the status from the child */ 
Packit b099d7
  (void) read(cb->pipe, &status, sizeof(XPGetDocStatus));
Packit b099d7
Packit b099d7
  XtRemoveInput(cb->input_id);
Packit b099d7
Packit b099d7
  close(cb->pipe);
Packit b099d7
Packit b099d7
  if (cb->finish_proc) {
Packit b099d7
    (*cb->finish_proc)(cb->display, XpGetContext(cb->display),
Packit b099d7
		       status, cb->client_data);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  XtFree((char*)cb);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void ChildPrintToFile(String display_name, 
Packit b099d7
		      XPContext pcontext,
Packit b099d7
		      FILE *file,
Packit b099d7
		      char *file_name,
Packit b099d7
		      int pipe,
Packit b099d7
		      String application_name, 
Packit b099d7
		      String application_class)
Packit b099d7
{
Packit b099d7
  FileDescRec *file_desc;
Packit b099d7
  XtAppContext app_context;
Packit b099d7
  int argc = 0;
Packit b099d7
  String argv[] = { NULL };
Packit b099d7
  Display *display;
Packit b099d7
Packit b099d7
  file_desc = (FileDescRec *) XtMalloc(sizeof(FileDescRec));
Packit b099d7
  file_desc->file_name = XtNewString(file_name);
Packit b099d7
  file_desc->file = file;
Packit b099d7
  file_desc->pipe = pipe;
Packit b099d7
Packit b099d7
  app_context = XtCreateApplicationContext();
Packit b099d7
  if ((display = XtOpenDisplay(app_context, display_name, 
Packit b099d7
			       application_name, application_class,
Packit b099d7
			       NULL, 0, &argc, argv)) == NULL) {
Packit b099d7
    _exit(1);
Packit b099d7
  }
Packit b099d7
Packit b099d7
  XpGetDocumentData(display, pcontext,
Packit b099d7
		    PrintToFileProc, FinishProc, 
Packit b099d7
		    (XPointer) file_desc);
Packit b099d7
Packit b099d7
  XtAppMainLoop(app_context);
Packit b099d7
Packit b099d7
  _exit(0);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
XtEnum XmPrintToFile(Display *pdpy, 
Packit b099d7
		     char *file_name,
Packit b099d7
		     XPFinishProc finish_proc, 
Packit b099d7
		     XPointer client_data)
Packit b099d7
{
Packit b099d7
    FileCallbackRec *callback;
Packit b099d7
    int pid;
Packit b099d7
    XPContext pcontext ;
Packit b099d7
    String application_name, application_class, display_name;
Packit b099d7
    FILE *file;
Packit b099d7
    int filedes[2];
Packit b099d7
    
Packit b099d7
    /* make sure we can open the file for writing */
Packit b099d7
    if ((file = fopen(file_name, "w")) == NULL) {
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if ((pipe(filedes)) == -1) {
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* its important to flush before we fork, to make sure that the
Packit b099d7
       XpStartJob gets through first in the parent */
Packit b099d7
    XFlush(pdpy);
Packit b099d7
Packit b099d7
    XtGetApplicationNameAndClass(pdpy,
Packit b099d7
				 &application_name, &application_class);
Packit b099d7
Packit b099d7
    display_name = XDisplayString(pdpy) ;
Packit b099d7
    pcontext = XpGetContext(pdpy) ;
Packit b099d7
    pid = fork();
Packit b099d7
Packit b099d7
    if (pid == 0) {
Packit b099d7
      ChildPrintToFile(display_name, pcontext, file, file_name, filedes[1],
Packit b099d7
		       application_name, application_class);
Packit b099d7
    }
Packit b099d7
    else if (pid < 0) {
Packit b099d7
      return False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* we are in the parent */
Packit b099d7
Packit b099d7
    fclose(file);
Packit b099d7
    close(filedes[1]);
Packit b099d7
Packit b099d7
    /* allocate the space for a callback */
Packit b099d7
    callback = (FileCallbackRec *) XtMalloc(sizeof(FileCallbackRec));
Packit b099d7
    callback->display = pdpy;
Packit b099d7
    callback->pipe = filedes[0];
Packit b099d7
    callback->finish_proc = finish_proc;
Packit b099d7
    callback->client_data = client_data;
Packit b099d7
Packit b099d7
    /* notification that the child has completed */
Packit b099d7
    callback->input_id = 
Packit b099d7
        XtAppAddInput(XtDisplayToApplicationContext(pdpy), 
Packit b099d7
		      callback->pipe, (XtPointer)XtInputReadMask,
Packit b099d7
		      FilePipeCB, callback);
Packit b099d7
Packit b099d7
    return True;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*************************************************************
Packit b099d7
 **  XmPrintPopupPDM   code
Packit b099d7
 *************************************************************/
Packit b099d7
Packit b099d7
static void
Packit b099d7
PDMPhase2Handler(Widget w,
Packit b099d7
		 XtPointer data,
Packit b099d7
		 XEvent *event,
Packit b099d7
		 Boolean *cont)
Packit b099d7
{
Packit b099d7
    enum { XmAPDM_REPLY, XmAPDM_EXIT_OK, XmAPDM_EXIT_ERROR,
Packit b099d7
	   XmAPDM_EXIT_CANCEL, NUM_ATOMS };
Packit b099d7
    static char *atom_names[] =
Packit b099d7
      { XmIPDM_REPLY, XmIPDM_EXIT_OK, XmIPDM_EXIT_ERROR, XmIPDM_EXIT_CANCEL };
Packit b099d7
Packit b099d7
    XmPrintShellWidget print_shell = (XmPrintShellWidget) w ;
Packit b099d7
    XmPrintShellCallbackStruct pr_cbs ;
Packit b099d7
    XClientMessageEvent * xevent = (XClientMessageEvent *) event;
Packit b099d7
    Atom atoms[XtNumber(atom_names)];
Packit b099d7
Packit b099d7
    assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
    XInternAtoms(XtDisplay(print_shell), atom_names, XtNumber(atom_names), 
Packit b099d7
		 False, atoms);
Packit b099d7
Packit b099d7
    if (xevent->type == ClientMessage &&
Packit b099d7
	xevent->message_type == atoms[XmAPDM_REPLY]) {
Packit b099d7
Packit b099d7
	/* check for the exit status of the PDM */
Packit b099d7
	if (xevent->data.l[0] == atoms[XmAPDM_EXIT_OK])
Packit b099d7
	    pr_cbs.reason = XmCR_PDM_OK ;
Packit b099d7
	else 
Packit b099d7
	if (xevent->data.l[0] == atoms[XmAPDM_EXIT_CANCEL])
Packit b099d7
	    pr_cbs.reason = XmCR_PDM_CANCEL ;
Packit b099d7
	else 
Packit b099d7
	if (xevent->data.l[0] == atoms[XmAPDM_EXIT_ERROR])
Packit b099d7
	    pr_cbs.reason = XmCR_PDM_EXIT_ERROR ;
Packit b099d7
	    /* some error message might have been logged */
Packit b099d7
Packit b099d7
	XtCallCallbackList (w, print_shell->print.pdm_notification_callback, 
Packit b099d7
			    &pr_cbs);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* remove me */
Packit b099d7
    XtAddEventHandler(w, (EventMask) 0, True, PDMPhase2Handler, NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
typedef struct {
Packit b099d7
    Atom pdm_selection ;
Packit b099d7
    XmPrintShellWidget print_shell ;
Packit b099d7
    Widget transient_for_video_shell ;
Packit b099d7
    Window transient_for_input_only_window;
Packit b099d7
} PDMSelectData ;
Packit b099d7
Packit b099d7
static void PDMSelectionProc (Widget w, 
Packit b099d7
			 XtPointer client_data,
Packit b099d7
			 Atom *selection,
Packit b099d7
			 Atom *type,
Packit b099d7
			 XtPointer value,
Packit b099d7
			 unsigned long *length,
Packit b099d7
			 int *format)
Packit b099d7
{
Packit b099d7
    enum { XmAPDM_START_OK, XmAPDM_START_ERROR, XmAPDM_START_VXAUTH,
Packit b099d7
	   XmAPDM_START_PXAUTH, NUM_ATOMS };
Packit b099d7
    static char *atom_names[] = {
Packit b099d7
      XmIPDM_START_OK, XmIPDM_START_ERROR, XmIPDM_START_VXAUTH,
Packit b099d7
      XmIPDM_START_PXAUTH };
Packit b099d7
Packit b099d7
    XmPrintShellCallbackStruct pr_cbs ;
Packit b099d7
    PDMSelectData * pdm_select_data = (PDMSelectData *) client_data ;
Packit b099d7
    Atom atoms[XtNumber(atom_names)];
Packit b099d7
Packit b099d7
    assert(XtNumber(atom_names) == NUM_ATOMS);
Packit b099d7
    XInternAtoms(XtDisplay(pdm_select_data->print_shell), atom_names,
Packit b099d7
		 XtNumber(atom_names), False, atoms);
Packit b099d7
Packit b099d7
    /* set back the video shell widget usable */
Packit b099d7
    XDestroyWindow(XtDisplay(pdm_select_data->transient_for_video_shell), 
Packit b099d7
		  pdm_select_data->transient_for_input_only_window);
Packit b099d7
Packit b099d7
    /* look at value and decide if success or failure */
Packit b099d7
Packit b099d7
    if (!value) {
Packit b099d7
	pr_cbs.reason = XmCR_PDM_NONE ;
Packit b099d7
	pr_cbs.detail = (XtPointer) pdm_select_data->pdm_selection ;
Packit b099d7
    } else {
Packit b099d7
	/* look if value is PDM_START_OK, or PDM_START_VXAUTH, etc */
Packit b099d7
	if (*(Atom *)value == atoms[XmAPDM_START_OK])
Packit b099d7
	    pr_cbs.reason = XmCR_PDM_UP ;
Packit b099d7
	else
Packit b099d7
        if (*(Atom *)value == atoms[XmAPDM_START_ERROR])
Packit b099d7
	    pr_cbs.reason = XmCR_PDM_START_ERROR ;
Packit b099d7
	else
Packit b099d7
        if (*(Atom *)value == atoms[XmAPDM_START_VXAUTH])
Packit b099d7
	    pr_cbs.reason = XmCR_PDM_START_VXAUTH ;
Packit b099d7
	else
Packit b099d7
        if (*(Atom *)value == atoms[XmAPDM_START_PXAUTH])
Packit b099d7
	    pr_cbs.reason = XmCR_PDM_START_PXAUTH ;
Packit b099d7
Packit b099d7
	/* if PDM is up, install a handler for phase 2 */
Packit b099d7
	if (pr_cbs.reason == XmCR_PDM_UP) {
Packit b099d7
	    XtAddEventHandler((Widget)pdm_select_data->print_shell, 
Packit b099d7
			      (EventMask) 0, 
Packit b099d7
			      True, /* ClientMessage are non maskable */
Packit b099d7
			      PDMPhase2Handler, NULL);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
	
Packit b099d7
    XtCallCallbackList ((Widget)pdm_select_data->print_shell, 
Packit b099d7
			pdm_select_data->print_shell
Packit b099d7
			   ->print.pdm_notification_callback, 
Packit b099d7
			&pr_cbs);
Packit b099d7
	
Packit b099d7
    XtFree((char*)pdm_select_data);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
XtEnum
Packit b099d7
XmPrintPopupPDM(Widget print_shell,
Packit b099d7
		Widget transient_for_video_shell)
Packit b099d7
{
Packit b099d7
Packit b099d7
    Atom pdm_selection;
Packit b099d7
    Atom type;
Packit b099d7
    unsigned char * value;
Packit b099d7
    int length;
Packit b099d7
    int format;
Packit b099d7
    Atom PDM_START ;
Packit b099d7
    Display * display_used ;
Packit b099d7
    PDMSelectData * pdm_select_data ;
Packit b099d7
    Widget widget_for_selection ;
Packit b099d7
    XtAppContext app;
Packit b099d7
    unsigned long old_timeout;
Packit b099d7
Packit b099d7
    /* get parameter for PDM_START from libXp 
Packit b099d7
       ask conversion using XtSetSelectionParameters, 
Packit b099d7
       and then call XtGetSelectionValue, which registers a
Packit b099d7
       XtSelectionCallbackProc that will wait for failure (no pdm
Packit b099d7
       owner, or timeout) or success.
Packit b099d7
Packit b099d7
       Phase 2 of the pdm (clientmessage) will be handled by a
Packit b099d7
       event handler set up from the selection callback on success */
Packit b099d7
Packit b099d7
    if (!XpGetPdmStartParams (XtDisplay(print_shell), 
Packit b099d7
			 XtWindow(print_shell), 
Packit b099d7
			 XpGetContext(XtDisplay(print_shell)), 
Packit b099d7
			 XtDisplay(transient_for_video_shell),
Packit b099d7
			 XtWindow(transient_for_video_shell), &display_used,
Packit b099d7
			 &pdm_selection, &type, &format, &value, &length))
Packit b099d7
	return XmPDM_NOTIFY_FAIL;
Packit b099d7
Packit b099d7
    /* only support XPDMDISPLAY = "print" or "video" */
Packit b099d7
    if (display_used == XtDisplay(print_shell))
Packit b099d7
	widget_for_selection = print_shell ;
Packit b099d7
    else 
Packit b099d7
    if (display_used == XtDisplay(transient_for_video_shell))
Packit b099d7
	widget_for_selection = transient_for_video_shell ;
Packit b099d7
    else 
Packit b099d7
	return XmPDM_NOTIFY_FAIL ;
Packit b099d7
Packit b099d7
    XtSetSelectionParameters(widget_for_selection, pdm_selection,
Packit b099d7
			     type, (XtPointer)value, length, format);
Packit b099d7
Packit b099d7
    XFree(value);
Packit b099d7
Packit b099d7
    pdm_select_data = (PDMSelectData *) XtMalloc(sizeof(PDMSelectData));
Packit b099d7
    pdm_select_data->pdm_selection = pdm_selection ;
Packit b099d7
    pdm_select_data->transient_for_video_shell = transient_for_video_shell ;
Packit b099d7
    pdm_select_data->print_shell = (XmPrintShellWidget) print_shell ; 
Packit b099d7
                                  /* need this one in all cases */
Packit b099d7
Packit b099d7
    PDM_START = XInternAtom(XtDisplay(widget_for_selection), 
Packit b099d7
			    XmIPDM_START, False);
Packit b099d7
Packit b099d7
    app = XtWidgetToApplicationContext(widget_for_selection);
Packit b099d7
Packit b099d7
/* twenty minutes */
Packit b099d7
#define REALLY_LONG_TIMEOUT (2 * 60 * 1000) 
Packit b099d7
Packit b099d7
    _XmAppLock(app);
Packit b099d7
Packit b099d7
    old_timeout = XtAppGetSelectionTimeout(app);
Packit b099d7
Packit b099d7
    XtAppSetSelectionTimeout(app, REALLY_LONG_TIMEOUT);
Packit b099d7
Packit b099d7
    XtGetSelectionValue(widget_for_selection, 
Packit b099d7
			pdm_selection,
Packit b099d7
			PDM_START, 
Packit b099d7
			PDMSelectionProc, 
Packit b099d7
			(XtPointer)pdm_select_data, 
Packit b099d7
			XtLastTimestampProcessed(
Packit b099d7
				       XtDisplay(widget_for_selection)));
Packit b099d7
Packit b099d7
    XtAppSetSelectionTimeout(app, old_timeout);
Packit b099d7
Packit b099d7
    _XmAppUnlock(app);
Packit b099d7
Packit b099d7
    /* put up a InputOnly window on top of the dialog,
Packit b099d7
       so that the end-user cannot  muck around with the print setup 
Packit b099d7
       dialog hile the PDM is  trying to come up. 
Packit b099d7
       This is removed in PDMSelectionProc */
Packit b099d7
Packit b099d7
    pdm_select_data->transient_for_input_only_window =
Packit b099d7
	XCreateWindow(XtDisplay(transient_for_video_shell),
Packit b099d7
		      XtWindow(transient_for_video_shell),
Packit b099d7
		      0, 0, 
Packit b099d7
		      XtWidth(transient_for_video_shell), 
Packit b099d7
		      XtHeight(transient_for_video_shell), 
Packit b099d7
		      0, CopyFromParent, InputOnly, CopyFromParent, 
Packit b099d7
		      0, NULL);
Packit b099d7
    XMapRaised(XtDisplay(transient_for_video_shell),
Packit b099d7
	       pdm_select_data->transient_for_input_only_window);
Packit b099d7
Packit b099d7
    return XmPDM_NOTIFY_SUCCESS ;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************************
Packit b099d7
 *
Packit b099d7
 *  XmRedisplayWidget
Packit b099d7
 *
Packit b099d7
 *    Call the expose method of the passed widget with a fake
Packit b099d7
 *    event corresponding to its entire area.
Packit b099d7
 *
Packit b099d7
 ************************************************************************/
Packit b099d7
Packit b099d7
void 
Packit b099d7
XmRedisplayWidget(Widget widget) 
Packit b099d7
{
Packit b099d7
    XExposeEvent xev ;
Packit b099d7
    Region region ;
Packit b099d7
Packit b099d7
    xev.type = Expose ;
Packit b099d7
                 /* is this better than 0 ? shouldn't make much difference
Packit b099d7
		  unless the expose method is very tricky... */
Packit b099d7
    xev.serial = LastKnownRequestProcessed(XtDisplay(widget)) ;  
Packit b099d7
    xev.send_event = False ;
Packit b099d7
    xev.display = XtDisplay(widget);
Packit b099d7
    xev.window = XtWindowOfObject(widget);  /* work with gadget too */
Packit b099d7
    xev.x = 0 ;
Packit b099d7
    xev.y = 0 ;
Packit b099d7
    xev.width = widget->core.width ;
Packit b099d7
    xev.height = widget->core.height ;
Packit b099d7
    xev.count = 0 ;
Packit b099d7
Packit b099d7
    region = XCreateRegion();
Packit b099d7
    XtAddExposureToRegion((XEvent*)&xev, region);    
Packit b099d7
Packit b099d7
    if (widget->core.widget_class->core_class.expose)
Packit b099d7
	(*(widget->core.widget_class->core_class.expose))
Packit b099d7
	    (widget, (XEvent*)&xev, region);
Packit b099d7
Packit b099d7
    XDestroyRegion(region);
Packit b099d7
}