summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--XLogo.ad6
-rw-r--r--print.c233
-rw-r--r--print.h41
-rw-r--r--xlogo.c128
-rw-r--r--xlogo.h51
5 files changed, 416 insertions, 43 deletions
diff --git a/XLogo.ad b/XLogo.ad
index 202a098..90db2a7 100644
--- a/XLogo.ad
+++ b/XLogo.ad
@@ -1 +1,5 @@
-XLogo.input: false
+XLogo*iconPixmap: xlogo32
+XLogo*iconMask: xlogo32
+XLogo*baseTranslations: #override \
+<Key>q,<Key>Escape: quit()\n\
+<Key>p: print()
diff --git a/print.c b/print.c
new file mode 100644
index 0000000..e9da7f4
--- /dev/null
+++ b/print.c
@@ -0,0 +1,233 @@
+/*
+ * $Xorg: print.c,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#include "xlogo.h"
+#include "Logo.h"
+#include "print.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static Widget
+CreatePrintShell(Widget videoshell,
+ Screen *pscreen,
+ String printshell_name,
+ ArgList args,
+ Cardinal numargs)
+{
+ String videoname,
+ videoclass;
+ Widget pappshell,
+ printshell;
+ Display *pdpy = XDisplayOfScreen(pscreen);
+ int dummyc = 0;
+ String dummys = "";
+ XtGetApplicationNameAndClass(XtDisplay(videoshell),
+ &videoname, &videoclass);
+
+ /* XXX: Why is the |dummyc|&&|dummys| stuff needed here ? */
+ XtDisplayInitialize(XtWidgetToApplicationContext(videoshell), pdpy,
+ videoname, videoclass,
+ NULL, 0,
+ &dummyc, &dummys);
+
+ pappshell = XtVaAppCreateShell(videoname, videoclass,
+ applicationShellWidgetClass,
+ pdpy,
+ XtNscreen, pscreen,
+ NULL);
+ printshell = XtCreatePopupShell(printshell_name,
+ xawPrintShellWidgetClass,
+ pappshell, args, numargs);
+
+
+ /* we're mapping/unmapping at start/end page time */
+ XtSetMappedWhenManaged(printshell, False);
+
+ XtRealizeWidget(printshell);
+
+ return printshell;
+}
+
+typedef struct
+{
+ Widget toplevel;
+ Bool isPrinting;
+ Widget printshell;
+ Display *pdpy;
+ Screen *pscreen;
+ XPContext pcontext;
+ void *printtofile_handle;
+} AppPrintData;
+
+static AppPrintData apdx;
+static AppPrintData *apd = &apdx;
+
+static void
+PageSetupCB(Widget widget, XtPointer client_data, XtPointer call_data)
+{
+ Widget pshell = widget;
+ XawPrintShellCallbackStruct *psp = (XawPrintShellCallbackStruct *)call_data;
+ AppPrintData *p = (AppPrintData *)client_data;
+
+ Log(("--> PageSetupCB\n"));
+
+ if (!psp->last_page_in_job) {
+ Widget plogo;
+ Log(("Creating print logo\n"));
+ plogo = XtCreateManagedWidget("xlogo", logoWidgetClass, pshell, NULL, ZERO);
+
+ /* Make sure that the Xt machinery is really using the right screen (assertion) */
+ if (XpGetScreenOfContext(XtDisplay(plogo), p->pcontext) != XtScreen(plogo))
+ Error(("Widget's screen != print screen. BAD.\n"));
+
+ /* XLogo always only prints one page */
+ psp->last_page_in_job = True;
+ }
+}
+
+void FinishPrinting(AppPrintData *p)
+{
+ if (p->printtofile_handle) {
+ if (XpuWaitForPrintFileChild(p->printtofile_handle) != XPGetDocFinished) {
+ fprintf(stderr, "%s: Error while printing to file.\n", ProgramName);
+ }
+ p->printtofile_handle = NULL;
+ }
+
+ if (p->printshell) {
+ XtDestroyWidget(p->printshell);
+ p->printshell = NULL;
+ }
+
+ if (p->pdpy) {
+ /* We have to use XpDestroyContext() and XtCloseDisplay() instead
+ * of XpuClosePrinterDisplay() to make libXt happy... */
+ if (p->pcontext != None)
+ XpDestroyContext(p->pdpy, p->pcontext);
+ XtCloseDisplay(p->pdpy);
+ }
+
+ /* "Print once and exit"-mode ? */
+ if (userOptions.printAndExit) {
+ XtAppSetExitFlag(XtWidgetToApplicationContext(p->toplevel));
+ }
+
+ p->toplevel = NULL;
+ p->isPrinting = False;
+ p->pdpy = NULL;
+ p->pscreen = NULL;
+ p->pcontext = None;
+}
+
+static
+void PrintEndJobCB(Widget pshell, XtPointer client_data, XtPointer call_data)
+{
+ AppPrintData *p = (AppPrintData *)client_data;
+
+ Log(("--> PrintEndJobCB\n"));
+
+ /* Finish printing and destroy print shell (it's legal to destroy Xt
+ * widgets from within it's own callbacks) */
+ FinishPrinting(p);
+}
+
+void DoPrint(Widget toplevel, const char *printername, const char *toFile)
+{
+ XPPrinterList plist; /* list of printers */
+ int plist_count; /* number of entries in |plist|-array */
+ Display *pdpy = NULL;
+ XPContext pcontext = None;
+ long dpi = 0;
+
+ if (apd->isPrinting) {
+ fprintf(stderr, "%s: Already busy with printing.\n", ProgramName);
+ return;
+ }
+
+ plist = XpuGetPrinterList(printername, &plist_count);
+ if (!plist) {
+ fprintf(stderr, "%s: no printers found for printer spec \"%s\".\n",
+ ProgramName, NULLSTR(printername));
+ return;
+ }
+
+ printername = strdup(plist[0].name);
+ XpuFreePrinterList(plist);
+
+ Log(("Using printer '%s'\n", printername));
+
+ /* Get printer, either by "name" (foobar) or "name@display" (foobar@gaja:5) */
+ if( XpuGetPrinter(printername, &pdpy, &pcontext) != 1 ) {
+ fprintf(stderr, "%s: Cannot open printer '%s'.\n", ProgramName, printername);
+ return;
+ }
+
+ /* Configure the print context (paper size, title etc.)
+ * We must do this before creating any Xt widgets - otherwise they will
+ * make wrong assuptions about fonts, resultions etc. ...
+ */
+ XpuSetJobTitle(pdpy, pcontext, "Xprint XLogo");
+
+ /* Configuration done, set the context */
+ XpSetContext(pdpy, pcontext);
+
+ /* Get default printer resolution */
+ if (XpuGetResolution(pdpy, pcontext, &dpi) != 1) {
+ fprintf(stderr, "%s: No default resolution for printer '%s'\n", ProgramName, printername);
+ XpuClosePrinterDisplay(pdpy, pcontext);
+ return;
+ }
+
+ apd->toplevel = toplevel;
+ apd->pdpy = pdpy;
+ apd->pcontext = pcontext;
+ apd->pscreen = XpGetScreenOfContext(pdpy, pcontext);
+
+ apd->printshell = CreatePrintShell(toplevel, apd->pscreen, "Print", NULL, 0);
+
+ XtAddCallback(apd->printshell, XawNpageSetupCallback, PageSetupCB, (XtPointer)apd);
+ XtAddCallback(apd->printshell, XawNendJobCallback, PrintEndJobCB, (XtPointer)apd);
+
+ apd->isPrinting = True;
+
+ if (toFile) {
+ printf("%s: Printing to file '%s'...\n", ProgramName, toFile);
+ apd->printtofile_handle = XpuStartJobToFile(pdpy, pcontext, toFile);
+ if (!apd->printtofile_handle) {
+ perror("XpuStartJobToFile failure");
+ apd->isPrinting = False;
+ return;
+ }
+ }
+ else
+ {
+ printf("%s: Printing to printer '%s'...\n", ProgramName, printername);
+ XpuStartJobToSpooler(pdpy);
+ }
+}
+
+
diff --git a/print.h b/print.h
new file mode 100644
index 0000000..609074c
--- /dev/null
+++ b/print.h
@@ -0,0 +1,41 @@
+/*
+ * $Xorg: print.h,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#ifndef XLOGO_PRINT_H
+#define XLOGO_PRINT_H 1
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Print.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/XprintUtil/xprintutil.h>
+
+/* Prototypes */
+void DoPrint(Widget toplevel, const char *printername, const char *toFile);
+
+#endif /* !XLOGO_PRINT_H */
diff --git a/xlogo.c b/xlogo.c
index 49cf369..e48afef 100644
--- a/xlogo.c
+++ b/xlogo.c
@@ -1,5 +1,5 @@
/*
- * $Xorg: xlogo.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $
+ * $Xorg: xlogo.c,v 1.5 2004/05/09 02:05:54 gisburn Exp $
*
Copyright 1989, 1998 The Open Group
@@ -27,18 +27,22 @@ in this Software without prior written authorization from The Open Group.
/* $XFree86: xc/programs/xlogo/xlogo.c,v 3.7 2001/07/25 15:05:26 dawes Exp $ */
-#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
+#include "xlogo.h"
#include "Logo.h"
-#include <X11/Xaw/Cardinals.h>
+#include "print.h"
#ifdef XKB
#include <X11/extensions/XKBbells.h>
#endif
+#include <stdio.h>
#include <stdlib.h>
-static void quit(Widget w, XEvent *event, String *params,
- Cardinal *num_params);
+/* Global vars*/
+const char *ProgramName; /* program name (from argv[0]) */
+
+static void quit(Widget w, XEvent *event, String *params, Cardinal *num_params);
+static void print(Widget w, XEvent *event, String *params, Cardinal *num_params);
static XrmOptionDescRec options[] = {
{ "-shape", "*shapeWindow", XrmoptionNoArg, (XPointer) "on" },
@@ -46,25 +50,45 @@ static XrmOptionDescRec options[] = {
{"-render", "*render",XrmoptionNoArg, "TRUE"},
{"-sharp", "*sharp", XrmoptionNoArg, "TRUE"},
#endif
+{"-v", "Verbose", XrmoptionNoArg, "TRUE"},
+{"-print", "Print", XrmoptionNoArg, "TRUE"},
+{"-printer", "printer", XrmoptionSepArg, NULL},
+{"-printfile", "printFile", XrmoptionSepArg, NULL},
};
static XtActionsRec actions[] = {
- {"quit", quit}
+ {"quit", quit },
+ {"print", print}
};
static Atom wm_delete_window;
+/* See xlogo.h */
+XLogoResourceData userOptions;
+
+#define Offset(field) XtOffsetOf(XLogoResourceData, field)
+
+XtResource resources[] = {
+ {"verbose", "Verbose", XtRBoolean, sizeof(Boolean), Offset(verbose), XtRImmediate, (XtPointer)False},
+ {"print", "Print", XtRBoolean, sizeof(Boolean), Offset(printAndExit), XtRImmediate, (XtPointer)False},
+ {"printer", "Printer", XtRString, sizeof(String), Offset(printername), XtRImmediate, (XtPointer)NULL},
+ {"printFile", "PrintFile", XtRString, sizeof(String), Offset(printfile), XtRImmediate, (XtPointer)NULL}
+};
+
+
String fallback_resources[] = {
"*iconPixmap: xlogo32",
"*iconMask: xlogo32",
+ "*baseTranslations: #override \\"
+ "\t<Key>q: quit()\\n\\"
+ "\t<Key>p: print()",
NULL,
};
static void
die(Widget w, XtPointer client_data, XtPointer call_data)
{
- XCloseDisplay(XtDisplay(w));
- exit(0);
+ XtAppSetExitFlag(XtWidgetToApplicationContext(w));
}
static void
@@ -78,34 +102,33 @@ save(Widget w, XtPointer client_data, XtPointer call_data)
*/
static void
-Syntax(Widget toplevel, char *call)
+Syntax(Widget toplevel)
{
Arg arg;
SmcConn connection;
- String reasons[7];
- int i, num_reasons = 7;
-
- reasons[0] = "Usage: ";
- reasons[1] = call;
- reasons[2] = " [-fg <color>] [-bg <color>] [-rv] [-bw <pixels>] [-bd <color>]\n";
- reasons[3] = " [-d [<host>]:[<vs>]]\n";
- reasons[4] = " [-g [<width>][x<height>][<+-><xoff>[<+-><yoff>]]]\n";
+ String reasons[10];
+ int i, n = 0;
+
+ reasons[n++] = "Usage: ";
+ reasons[n++] = (String)ProgramName;
+ reasons[n++] = " [-fg <color>] [-bg <color>] [-rv] [-bw <pixels>] [-bd <color>]\n";
+ reasons[n++] = " [-d [<host>]:[<vs>]]\n";
+ reasons[n++] = " [-g [<width>][x<height>][<+-><xoff>[<+-><yoff>]]]\n";
+ reasons[n++] = " [-print] [-printname <name>] [-printfile <file>]\n";
#ifdef XRENDER
- reasons[5] = " [-render] [-sharp]\n";
-#else
- reasons[5] = "";
-#endif
- reasons[6] = " [-shape]\n\n";
+ reasons[n++] = " [-render] [-sharp]\n";
+#endif /* XRENDER */
+ reasons[n++] = " [-shape]\n\n";
XtSetArg(arg, XtNconnection, &connection);
XtGetValues(toplevel, &arg, (Cardinal)1);
if (connection)
- SmcCloseConnection(connection, num_reasons, reasons);
+ SmcCloseConnection(connection, n, reasons);
else {
- for (i=0; i < num_reasons; i++)
+ for (i=0; i < n; i++)
printf(reasons[i]);
}
- exit(1);
+ exit(EXIT_FAILURE);
}
int
@@ -114,27 +137,40 @@ main(int argc, char *argv[])
Widget toplevel;
XtAppContext app_con;
+ ProgramName = argv[0];
+
toplevel = XtOpenApplication(&app_con, "XLogo",
options, XtNumber(options),
&argc, argv, fallback_resources,
sessionShellWidgetClass, NULL, ZERO);
if (argc != 1)
- Syntax(toplevel, argv[0]);
-
- XtAddCallback(toplevel, XtNsaveCallback, save, NULL);
- XtAddCallback(toplevel, XtNdieCallback, die, NULL);
- XtAppAddActions
- (XtWidgetToApplicationContext(toplevel), actions, XtNumber(actions));
- XtOverrideTranslations
- (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
- XtCreateManagedWidget("xlogo", logoWidgetClass, toplevel, NULL, ZERO);
- XtRealizeWidget(toplevel);
- wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
- False);
- (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
- &wm_delete_window, 1);
+ Syntax(toplevel);
+
+ XtGetApplicationResources(toplevel, (XtPointer)&userOptions, resources,
+ XtNumber(resources), NULL, 0);
+
+ XtAppAddActions(app_con, actions, XtNumber(actions));
+
+ if (userOptions.printAndExit) {
+ XtCallActionProc(toplevel, "print", NULL, NULL, 0);
+ }
+ else
+ {
+ XtAddCallback(toplevel, XtNsaveCallback, save, NULL);
+ XtAddCallback(toplevel, XtNdieCallback, die, NULL);
+ XtOverrideTranslations
+ (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
+ XtCreateManagedWidget("xlogo", logoWidgetClass, toplevel, NULL, ZERO);
+ XtRealizeWidget(toplevel);
+ wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
+ False);
+ (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
+ &wm_delete_window, 1);
+ }
+
XtAppMainLoop(app_con);
- exit(0);
+
+ return EXIT_SUCCESS;
}
/*ARGSUSED*/
@@ -142,9 +178,9 @@ static void
quit(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
Arg arg;
-
+
if (event->type == ClientMessage &&
- event->xclient.data.l[0] != wm_delete_window) {
+ (Atom)event->xclient.data.l[0] != wm_delete_window) {
#ifdef XKB
XkbStdBell(XtDisplay(w), XtWindow(w), 0, XkbBI_BadValue);
#else
@@ -158,3 +194,11 @@ quit(Widget w, XEvent *event, String *params, Cardinal *num_params)
}
}
+/*ARGSUSED*/
+static void
+print(Widget w, XEvent *event, String *params, Cardinal *num_params)
+{
+ DoPrint(w, userOptions.printername, userOptions.printfile);
+}
+
+
diff --git a/xlogo.h b/xlogo.h
new file mode 100644
index 0000000..50d96c3
--- /dev/null
+++ b/xlogo.h
@@ -0,0 +1,51 @@
+/*
+ * $Xorg: xlogo.h,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#ifndef XLOGO_XLOGO_H
+#define XLOGO_XLOGO_H 1
+
+#include <X11/Intrinsic.h>
+
+/* Turn a NULL pointer string into an empty string */
+#define NULLSTR(x) (((x)!=NULL)?(x):(""))
+
+#define Error(x) { printf x ; exit(EXIT_FAILURE); }
+#define Log(x) { if(userOptions.verbose) printf x; }
+
+typedef struct {
+ Boolean verbose;
+ Boolean printAndExit;
+ String printername;
+ String printfile;
+} XLogoResourceData, *XLogoResourceDataPtr;
+
+/* Global vars */
+extern const char *ProgramName; /* program name (from argv[0]) */
+extern XLogoResourceData userOptions;
+
+#endif /* !XLOGO_XLOGO_H */
+