1 /**
2  *
3  * $Header: /cvsroot/lesstif/lesstif/lib/Xm-2.1/PrintShell.c,v 1.24 2002/04/13 11:08:48 amai Exp $
4  *
5  * Copyright � 2000,2001,2002 LessTif Development Team
6  *
7  * This file is part of the GNU LessTif Library.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the Free
21  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  **/
24 
25 static const char rcsid[] = "$Header: /cvsroot/lesstif/lesstif/lib/Xm-2.1/PrintShell.c,v 1.24 2002/04/13 11:08:48 amai Exp $";
26 
27 #include <LTconfig.h>
28 
29 /*
30  * Lots of stuff in this file is only compiled if we have the Xp library.
31  *
32 	#ifdef	HAVE_LIB_XP
33  */
34 
35 #include <stdio.h>
36 
37 #include <XmI/XmI.h>
38 
39 #include <Xm/XmP.h>
40 
41 #include <Xm/PrintSP.h>  /* required in any case */
42 #ifdef HAVE_LIB_XP
43 #include <Xm/Print.h>
44 #endif
45 
46 #include <XmI/DebugUtil.h>
47 
48 
49 /* Forward Declarations */
50 static void class_initialize(void);
51 static void class_part_initialize(WidgetClass w_class);
52 static void initialize(Widget request, Widget new_w,
53 		       ArgList args, Cardinal *num_args);
54 static void destroy(Widget w);
55 static void realize(Widget w, XtValueMask *value_mask,
56 		    XSetWindowAttributes *attributes);
57 static void resize(Widget w);
58 static Boolean set_values(Widget current, Widget request, Widget new_w,
59 			  ArgList args, Cardinal *num_args);
60 static void _XmPrintNotify(Widget w, XtPointer client, XEvent *evp, Boolean *cont);
61 
62 #define Offset(field) XtOffsetOf(XmPrintShellRec, print.field)
63 
64 
65 /* Resources for the PrintShell class */
66 static XtResource resources[] =
67 {
68     {
69 	XmNstartJobCallback, XmCCallback, XmRCallback,
70 	sizeof(XtCallbackList), Offset(start_job_callback),
71 	XmRImmediate, (XtPointer)NULL
72     },
73     {
74 	XmNendJobCallback, XmCCallback, XmRCallback,
75 	sizeof(XtCallbackList), Offset(end_job_callback),
76 	XmRImmediate, (XtPointer)NULL
77     },
78     {
79 	XmNpageSetupCallback, XmCCallback, XmRCallback,
80 	sizeof(XtCallbackList), Offset(page_setup_callback),
81 	XmRImmediate, (XtPointer)NULL
82     },
83     {
84 	XmNpdmNotificationCallback, XmCCallback, XmRCallback,
85 	sizeof(XtCallbackList), Offset(pdm_notification_callback),
86 	XmRImmediate, (XtPointer)NULL
87     },
88     {
89 	XmNminX, XmCMinX, XmRDimension,
90 	sizeof(Dimension), Offset(min_x),
91 	XmRImmediate, (XtPointer)NULL		/* dynamic */
92     },
93     {
94 	XmNminY, XmCMinY, XmRDimension,
95 	sizeof(Dimension), Offset(min_y),
96 	XmRImmediate, (XtPointer)NULL		/* dynamic */
97     },
98     {
99 	XmNmaxX, XmCMaxX, XmRDimension,
100 	sizeof(Dimension), Offset(max_x),
101 	XmRImmediate, (XtPointer)NULL		/* dynamic */
102     },
103     {
104 	XmNmaxY, XmCMaxY, XmRDimension,
105 	sizeof(Dimension), Offset(max_y),
106 	XmRImmediate, (XtPointer)NULL		/* dynamic */
107     },
108     {
109 	XmNdefaultPixmapResolution, XmCDefaultPixmapResolution, XmRShort,
110 	sizeof(unsigned short), Offset(default_pixmap_resolution),
111 	XmRImmediate, (XtPointer)100
112     },
113 };
114 
115 static XtActionsRec actions[] =
116 {
117 #if 0
118     {"MenuShellPopdownOne", MenuShellPopdownOne},
119 #endif
120     {NULL, NULL}
121 };
122 
123 
124 static XmBaseClassExtRec _XmPrintShellCoreClassExtRec = {
125     /* next_extension            */ NULL,
126     /* record_type               */ NULLQUARK,
127     /* version                   */ XmBaseClassExtVersion,
128     /* size                      */ sizeof(XmBaseClassExtRec),
129     /* initialize_prehook        */ NULL,
130     /* set_values_prehook        */ NULL,
131     /* initialize_posthook       */ NULL,
132     /* set_values_posthook       */ NULL,
133     /* secondary_object_class    */ NULL,
134     /* secondary_object_create   */ NULL,
135     /* get_secondary_resources   */ NULL,
136     /* fast_subclass             */ { 0 },
137     /* get_values_prehook        */ NULL,
138     /* get_values_posthook       */ NULL,
139     /* class_part_init_prehook   */ NULL,
140     /* class_part_init_posthook  */ NULL,
141     /* ext_resources             */ NULL,
142     /* compiled_ext_resources    */ NULL,
143     /* num_ext_resources         */ 0,
144     /* use_sub_resources         */ False,
145     /* widget_navigable          */ NULL,
146     /* focus_change              */ NULL,
147     /* wrapper_data              */ NULL
148 };
149 
150 XmPrintShellClassRec xmPrintShellClassRec = {
151     /* Core class part */
152     {
153 	/* superclass            */ (WidgetClass) &applicationShellClassRec,
154         /* class_name            */ "XmPrintShell",
155 	/* widget_size           */ sizeof(XmPrintShellRec),
156 	/* class_initialize      */ class_initialize,
157 	/* class_part_initialize */ class_part_initialize,
158 	/* class_inited          */ False,
159 	/* initialize            */ initialize,
160 	/* initialize_hook       */ NULL,
161 	/* realize               */ realize,
162 	/* actions               */ actions,
163 	/* num_actions           */ XtNumber(actions),
164 	/* resources             */ resources,
165 	/* num_resources         */ XtNumber(resources),
166 	/* xrm_class             */ NULLQUARK,
167 	/* compress_motion       */ True,
168 	/* compress_exposure     */ XtExposeCompressMaximal,
169 	/* compress_enterleave   */ True,
170 	/* visible_interest      */ False,
171 	/* destroy               */ destroy,
172 	/* resize                */ resize,
173 	/* expose                */ XtInheritExpose,
174 	/* set_values            */ set_values,
175 	/* set_values_hook       */ NULL,
176 	/* set_values_almost     */ XtInheritSetValuesAlmost,
177 	/* get_values_hook       */ NULL,
178 	/* accept_focus          */ NULL,
179 	/* version               */ XtVersion,
180 	/* callback offsets      */ NULL,
181 	/* tm_table              */ NULL,
182 	/* query_geometry        */ NULL,
183 	/* display_accelerator   */ NULL,
184 	/* extension             */ (XtPointer)&_XmPrintShellCoreClassExtRec
185     },
186     /* Composite class part */
187     {
188 	/* geometry manager */	XtInheritGeometryManager,
189         /* change_managed   */	XtInheritChangeManaged,
190         /* insert_child     */	XtInheritInsertChild,
191         /* delete_child     */	XtInheritDeleteChild,
192         /* extension        */	NULL,
193     },
194     /* Shell class part */
195     {
196 	/* extension        */ NULL,
197     },
198     /* WM Shell class part */
199     {
200 	/* extension	*/		NULL,
201     },
202     /* VendorShell class part */
203     {
204 	/* extension	*/		NULL,
205     },
206     /* TopLevelShell class part */
207     {
208 	/* extension	*/		NULL,
209     },
210     /* ApplicationShell class part */
211     {
212 	/* extension	*/		NULL,
213     },
214     {
215     	/* ?? */		NULL,
216     },
217 };
218 
219 WidgetClass xmPrintShellWidgetClass = (WidgetClass)&xmPrintShellClassRec;
220 
221 
222 static void
class_initialize(void)223 class_initialize(void)
224 {
225     _XmInitializeExtensions();
226 
227     _XmPrintShellCoreClassExtRec.record_type = XmQmotif;
228 }
229 
230 
231 static void
class_part_initialize(WidgetClass widget_class)232 class_part_initialize(WidgetClass widget_class)
233 {
234 #if 0
235     _XmFastSubclassInit(widget_class, XmMENU_SHELL_BIT);
236 #endif
237 }
238 
239 #ifdef HAVE_LIB_XP
240 /*
241  * This is a static table to keep the link between widgets and XPContexts.
242  * Yeah - this is probably not a very bright idea. Maybe it should also
243  * contain the Display.
244  */
245 static int nfields = 0;
246 typedef struct {
247 	Widget	w;
248 	XPContext	c;
249 } WidgetContext;
250 static WidgetContext *wctxt = NULL;
251 
252 
253 static void
_XmStoreWidgetContext(Widget w,XPContext c)254 _XmStoreWidgetContext(Widget w, XPContext c)
255 {
256 	nfields++;
257 	wctxt = (WidgetContext *)XtRealloc((XtPointer)wctxt, sizeof(WidgetContext) * nfields);
258 	wctxt[nfields-1].w = w;
259 	wctxt[nfields-1].c = c;
260 }
261 
262 static Widget
_XmPrintContextToWidget(XPContext c)263 _XmPrintContextToWidget(XPContext c)
264 {
265 	int	i;
266 
267 	for (i=0; i<nfields; i++)
268 		if (wctxt[i].c == c) {
269 			return wctxt[i].w;
270 		}
271 	return NULL;
272 }
273 
274 static XPContext
_XmPrintWidgetToContext(Widget w)275 _XmPrintWidgetToContext(Widget w)
276 {
277 	int	i;
278 
279 	for (i=0; i<nfields; i++)
280 		if (wctxt[i].w == w) {
281 			return wctxt[i].c;
282 		}
283 	return (XPContext)0;
284 }
285 
286 static void
SelectNotify(Widget w,int * e,XtPointer * s,int n,XtPointer client)287 SelectNotify(Widget w, int *e, XtPointer *s, int n, XtPointer client)
288 {
289 	XPContext	c = XpGetContext(XtDisplay(w));
290 
291 	if (! c) {
292 		_XmWarning(w, "XmPrintShell SelectNotify: no print context\n");
293 		return;
294 	}
295 
296 	XpSelectInput(XtDisplay(w), c, XPPrintMask | XPAttributeMask);
297 
298 	_XmStoreWidgetContext(w, c);	/* Here ? */
299 }
300 
301 
302 static Boolean
DispatchEvent(XEvent * evp)303 DispatchEvent(XEvent *evp)
304 {
305 	XPPrintEvent	*e = (XPPrintEvent*)evp;
306 
307 	Widget		w = _XmPrintContextToWidget(e->context);
308 
309 #if 1	/* Only for debugging */
310 {
311 	int		error_base, event_base;
312 
313 	if (!XpQueryExtension(XtDisplay(w), &event_base, &error_base)) {
314 		return False;
315 	}
316 
317 	if (e->type == event_base + XPPrintNotify) {
318 		switch (e->detail) {
319 		case XPStartJobNotify:
320 			DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell-DispatchEvent XPStartJobNotify\n"));
321 			break;
322 		case XPEndJobNotify:
323 			DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell-DispatchEvent XPEndJobNotify\n"));
324 			break;
325 		case XPStartDocNotify:
326 			DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell-DispatchEvent XPStartDocNotify\n"));
327 			break;
328 		case XPStartPageNotify:
329 			DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell-DispatchEvent XPStartPageNotify\n"));
330 			break;
331 		case XPEndPageNotify:
332 			DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell-DispatchEvent XPEndPageNotify\n"));
333 			break;
334 		case XPEndDocNotify:
335 			DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell-DispatchEvent XPEndDocNotify\n"));
336 			break;
337 		default:
338 			DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell DispatchEvent\n"));
339 		}
340 	}
341 }
342 #endif
343 
344 	return XtDispatchEventToWidget(w, evp);
345 }
346 #endif	/* HAVE_LIB_XP */
347 
348 
349 static void
initialize(Widget request,Widget new_w,ArgList args,Cardinal * num_args)350 initialize(Widget request, Widget new_w, ArgList args, Cardinal *num_args)
351 {
352 #ifdef HAVE_LIB_XP
353 	int	error_base, event_base;
354 
355 	DEBUGOUT(_LtDebug(__FILE__, new_w, "XmPrintShell Initialize\n"));
356 
357 	if (new_w->core.width == 0 || new_w->core.height == 0) {
358 		new_w->core.width = 1000;
359 		new_w->core.height = 1000;	/* FIX ME */
360 	}
361 
362 	if (!XpQueryExtension(XtDisplay(new_w), &event_base, &error_base)) {
363 		DEBUGOUT(_LtDebug(__FILE__, new_w, "XmPrintShell initialize: fail !!\n"));
364 		return;
365 	}
366 
367 	DEBUGOUT(_LtDebug(__FILE__, new_w, "XmPrintShell Initialize event_base %d error_base %d\n",
368 		event_base, error_base));
369 
370 	XtInsertEventTypeHandler(new_w,
371 		event_base + XPPrintNotify,
372 		(XtPointer)XPPrintMask,
373 		_XmPrintNotify, NULL,
374 		XtListTail);
375 
376 	XtRegisterExtensionSelector(XtDisplay(new_w),
377 		event_base + XPPrintNotify,
378                 event_base + XPAttributeNotify,
379                 SelectNotify,
380                 NULL);
381 
382 	(void) XtSetEventDispatcher(XtDisplay(new_w),
383 		event_base + XPPrintNotify,
384 		DispatchEvent);
385 
386 	PS_LastPage(new_w) = False;
387 #endif
388 }
389 
390 
391 static void
destroy(Widget w)392 destroy(Widget w)
393 {
394 	DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell Destroy\n"));
395 }
396 
397 
398 static void
resize(Widget w)399 resize(Widget w)
400 {
401 	DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell Resize\n"));
402 }
403 
404 
405 static void
realize(Widget w,XtValueMask * value_mask,XSetWindowAttributes * attributes)406 realize(Widget w, XtValueMask *value_mask, XSetWindowAttributes *attributes)
407 {
408 	DEBUGOUT(_LtDebug(__FILE__, w, "XmPrintShell Realize\n"));
409 #if 1
410 
411 #define superclass (&applicationShellClassRec)
412     (*superclass->core_class.realize) (w, value_mask, attributes);
413 #undef superclass
414 
415 #endif
416 }
417 
418 
419 static Boolean
set_values(Widget current,Widget request,Widget new_w,ArgList args,Cardinal * num_args)420 set_values(Widget current, Widget request, Widget new_w,
421 	   ArgList args, Cardinal *num_args)
422 {
423 	DEBUGOUT(_LtDebug(__FILE__, new_w, "XmPrintShell SetValues\n"));
424 	return True;
425 }
426 
427 #if 0
428 /*
429  * This isn't a Motif API.
430  */
431 extern Widget
432 XmCreatePrintShell(Widget parent, char *name, ArgList arglist, Cardinal argcount)
433 {
434     while (parent && !XtIsComposite(parent))
435 	parent = XtParent(parent);
436 
437     return XtCreatePopupShell(name, xmPrintShellWidgetClass, parent,
438 			      arglist, argcount);
439 }
440 #endif
441 
442 #ifdef HAVE_LIB_XP
443 static void
_XmPrintNotify(Widget w,XtPointer client,XEvent * evp,Boolean * cont)444 _XmPrintNotify(Widget w, XtPointer client, XEvent *evp, Boolean *cont)
445 {
446 	XPPrintEvent	*e = (XPPrintEvent *)evp;
447 	XmPrintShellCallbackStruct	cbs;
448 
449 	switch (e->detail) {
450 	case XPStartPageNotify:
451 		DEBUGOUT(_LtDebug(__FILE__, w, "XPStartPageNotify\n"));
452 
453 		DEBUGOUT(_LtDebug(__FILE__, w, "XpEndPage\n"));
454 		XpEndPage(XtDisplay(w));
455 
456 		if (PS_LastPage(w)) {
457 			DEBUGOUT(_LtDebug(__FILE__, w, "XpEndJob\n"));
458 			XpEndJob(XtDisplay(w));
459 		}
460 		break;
461 	case XPEndPageNotify:
462 		DEBUGOUT(_LtDebug(__FILE__, w, "XPEndPageNotify\n"));
463 
464 		if (! PS_LastPage(w)) {
465 			DEBUGOUT(_LtDebug(__FILE__, w, "XpStartPage\n"));
466 			XpStartPage(XtDisplay(w), XtWindow(w));
467 
468 			cbs.reason = XmCR_PAGE_SETUP;
469 			cbs.event = evp;
470 			cbs.detail = NULL;
471 			cbs.context = 0;
472 			cbs.last_page = False;
473 			if (PS_PageSetupCallback(w))
474 				XtCallCallbackList(w, PS_PageSetupCallback(w), &cbs);
475 			PS_LastPage(w) = cbs.last_page;
476 		}
477 		break;
478 	case XPStartDocNotify:
479 		DEBUGOUT(_LtDebug(__FILE__, w, "XPStartDocNotify\n"));
480 		break;
481 	case XPEndDocNotify:
482 		DEBUGOUT(_LtDebug(__FILE__, w, "XPEndDocNotify\n"));
483 		break;
484 	case XPStartJobNotify:
485 		DEBUGOUT(_LtDebug(__FILE__, w, "XPStartJobNotify\n"));
486 		PS_LastPage(w) = False;
487 
488 		cbs.reason = XmCR_START_JOB;
489 		cbs.event = evp;
490 		cbs.detail = NULL;
491 		cbs.context = _XmPrintWidgetToContext(w);
492 		cbs.last_page = False;
493 
494 		if (PS_StartJobCallback(w))
495 			XtCallCallbackList(w, PS_StartJobCallback(w), &cbs);
496 
497 #if 0
498 		DEBUGOUT(_LtDebug(__FILE__, w, "XpStartDoc\n"));
499 		XpStartDoc(XtDisplay(w), XPDocNormal);
500 #endif
501 
502 		/* Copied from EndPage section */
503 		if (! cbs.last_page) {
504 			DEBUGOUT(_LtDebug(__FILE__, w, "XpStartPage\n"));
505 			XpStartPage(XtDisplay(w), XtWindow(w));
506 
507 			cbs.reason = XmCR_PAGE_SETUP;
508 			cbs.event = evp;
509 			cbs.detail = NULL;
510 			cbs.context = _XmPrintWidgetToContext(w);
511 			cbs.last_page = False;
512 			if (PS_PageSetupCallback(w))
513 				XtCallCallbackList(w, PS_PageSetupCallback(w), &cbs);
514 
515 			PS_LastPage(w) = cbs.last_page;
516 #if 0
517 			if (cbs.last_page) {
518 				DEBUGOUT(_LtDebug(__FILE__, w, "XpEndPage\n"));
519 				XpEndPage(XtDisplay(w));
520 			}
521 #endif
522 		}
523 		break;
524 	case XPEndJobNotify:
525 		DEBUGOUT(_LtDebug(__FILE__, w, "XPEndJobNotify\n"));
526 		cbs.reason = XmCR_END_JOB;
527 		cbs.event = evp;
528 		cbs.detail = NULL;
529 		cbs.context = 0;
530 		cbs.last_page = False;
531 
532 		if (PS_EndJobCallback(w))
533 			XtCallCallbackList(w, PS_EndJobCallback(w), &cbs);
534 		break;
535 	default:
536 		DEBUGOUT(_LtDebug(__FILE__, w, "_XmPrintNotify(default)\n"));
537 		break;
538 	}
539 }
540 #endif	/* HAVE_LIB_XP */
541