NetSurf
print.c
Go to the documentation of this file.
1/*
2 * Copyright 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "amiga/os3support.h"
20
21#include <string.h>
22#include <proto/utility.h>
23#include <proto/iffparse.h>
24#include <proto/dos.h>
25#include <proto/intuition.h>
26#include <proto/Picasso96API.h>
27#include <devices/printer.h>
28#include <devices/prtbase.h>
29
30#include <prefs/prefhdr.h>
31#include <prefs/printertxt.h>
32#include <libraries/gadtools.h>
33
34#include <proto/window.h>
35#include <proto/layout.h>
36#include <proto/integer.h>
37#include <proto/label.h>
38#include <proto/chooser.h>
39#include <proto/fuelgauge.h>
40#include <classes/window.h>
41#include <gadgets/fuelgauge.h>
42#include <gadgets/layout.h>
43#include <gadgets/integer.h>
44#include <gadgets/chooser.h>
45#include <images/label.h>
46
47#include <reaction/reaction_macros.h>
48
49#include "utils/nsoption.h"
50#include "utils/messages.h"
51#include "utils/utils.h"
52#include "utils/nsurl.h"
53#include "netsurf/plotters.h"
54#include "netsurf/layout.h"
55#include "netsurf/mouse.h"
56#include "netsurf/window.h"
57#include "netsurf/content.h"
58#include "desktop/printer.h"
59#include "desktop/print.h"
60
61#include "amiga/plotters.h"
62#include "amiga/font.h"
63#include "amiga/gui.h"
64#include "amiga/libs.h"
65#include "amiga/misc.h"
66#include "amiga/print.h"
67#include "amiga/utf8.h"
68
69bool ami_print_begin(struct print_settings *ps);
70bool ami_print_next_page(void);
71void ami_print_end(void);
72bool ami_print_dump(void);
73void ami_print_progress(void);
74void ami_print_close_device(void);
75
76enum
77{
88};
89
90const struct printer amiprinter = {
91 &amiplot,
95};
96
98{
99 struct gui_globals *gg;
100 struct IODRPTagsReq *PReq;
101 struct PrinterData *PD;
102 struct PrinterExtendedData *PED;
103 struct MsgPort *msgport;
106 int page;
107 int pages;
110 struct Window *win;
111};
112
115 struct Window *win;
119};
120
121#define IFFPrefChunkCnt 2
122static LONG IFFPrefChunks[] =
123{
124 ID_PREF, ID_PRHD,
125 ID_PREF, ID_PDEV,
126};
127
129
130static CONST_STRPTR gadlab[PGID_LAST];
131static STRPTR printers[11];
132
133static BOOL ami_print_event(void *w);
134
137 NULL, /* we don't explicitly close the print window on quit (or at all???) */
138};
139
140static void ami_print_ui_setup(void)
141{
142 gadlab[PGID_PRINTER] = (char *)ami_utf8_easy((char *)messages_get("Printer"));
143 gadlab[PGID_SCALE] = (char *)ami_utf8_easy((char *)messages_get("Scale"));
144 gadlab[PGID_COPIES] = (char *)ami_utf8_easy((char *)messages_get("Copies"));
145 gadlab[PGID_PRINT] = (char *)ami_utf8_easy((char *)messages_get("ObjPrint"));
146 gadlab[PGID_CANCEL] = (char *)ami_utf8_easy((char *)messages_get("Cancel"));
147}
148
149static void ami_print_ui_free(void)
150{
151 int i;
152
153 for(i = 0; i < PGID_LAST; i++) {
154 if(gadlab[i]) free((APTR)gadlab[i]);
155 }
156
157 for(i = 0; i < 10; i++) {
158 if(printers[i]) free(printers[i]);
159 }
160}
161
162static BOOL ami_print_readunit(CONST_STRPTR filename, char name[],
163 uint32 namesize, int unitnum)
164{
165 /* This is a modified version of a function from the OS4 SDK.
166 * The README says "You can use it in your application",
167 * no licence is specified. (c) 1999 Amiga Inc */
168
169 BPTR fp;
170 BOOL ok;
171 struct IFFHandle *iff;
172 struct ContextNode *cn;
173 struct PrefHeader phead;
174 struct PrinterDeviceUnitPrefs pdev;
175
176 SNPrintf(name,namesize,"Unit %ld",unitnum);
177 fp = Open(filename, MODE_OLDFILE);
178 if (fp)
179 {
180 iff = AllocIFF();
181 if (iff)
182 {
183 iff->iff_Stream = fp;
184 InitIFFasDOS(iff);
185
186 if (!OpenIFF(iff, IFFF_READ))
187 {
188 if (!ParseIFF(iff, IFFPARSE_STEP))
189 {
190 cn = CurrentChunk(iff);
191 if (cn->cn_ID == ID_FORM && cn->cn_Type == ID_PREF)
192 {
193 if (!StopChunks(iff, IFFPrefChunks, IFFPrefChunkCnt))
194 {
195 ok = TRUE;
196 while (ok)
197 {
198 if (ParseIFF(iff, IFFPARSE_SCAN))
199 break;
200 cn = CurrentChunk(iff);
201 if (cn->cn_Type == ID_PREF)
202 {
203 switch (cn->cn_ID)
204 {
205 case ID_PRHD:
206 if (ReadChunkBytes(iff, &phead, sizeof(struct PrefHeader)) != sizeof(struct PrefHeader))
207 {
208 ok = FALSE;
209 break;
210 }
211 if (phead.ph_Version != 0)
212 {
213 ok = FALSE;
214 break;
215 }
216 break;
217 case ID_PDEV:
218 if (ReadChunkBytes(iff, &pdev, sizeof(pdev)) == sizeof(pdev))
219 {
220 if (pdev.pd_UnitName[0])
221 strcpy(name,pdev.pd_UnitName);
222 }
223 break;
224 default:
225 break;
226 }
227 }
228 }
229 }
230 }
231 }
232 CloseIFF(iff);
233 }
234 FreeIFF(iff);
235 }
236 Close(fp);
237 }
238 else return FALSE;
239
240 return TRUE;
241}
242
244{
245 char filename[30];
246 int i;
247
248 struct ami_print_window *pw = calloc(1, sizeof(struct ami_print_window));
249
250 pw->c = c;
251
252 printers[0] = calloc(1, 50);
253 ami_print_readunit("ENV:Sys/printer.prefs", printers[0], 50, 0);
254
255 strcpy(filename,"ENV:Sys/printerN.prefs");
256 for (i = 1; i < 10; i++)
257 {
258 filename[15] = '0' + i;
259 printers[i] = malloc(50);
260 if(!ami_print_readunit(filename, printers[i], 50, i))
261 {
262 free(printers[i]);
263 printers[i] = NULL;
264 break;
265 }
266
267 }
268
270
272 WA_ScreenTitle, ami_gui_get_screen_title(),
273 WA_Title, gadlab[PGID_PRINT],
274 WA_Activate, TRUE,
275 WA_DepthGadget, TRUE,
276 WA_DragBar, TRUE,
277 WA_CloseGadget, TRUE,
278 WA_SizeGadget, FALSE,
279 WA_PubScreen, ami_gui_get_screen(),
280 WINDOW_SharedPort, ami_gui_get_shared_msgport(),
281 WINDOW_UserData, pw,
282 WINDOW_IconifyGadget, FALSE,
283 WINDOW_Position, WPOS_CENTERSCREEN,
284 WINDOW_ParentGroup, pw->gadgets[PGID_MAIN] = LayoutVObj,
285 LAYOUT_AddChild, ChooserObject,
286 GA_ID, PGID_PRINTER,
287 GA_RelVerify, TRUE,
288 GA_TabCycle, TRUE,
289 CHOOSER_LabelArray, printers,
290 CHOOSER_Selected, nsoption_int(printer_unit),
291 ChooserEnd,
292 CHILD_Label, LabelObject,
293 LABEL_Text, gadlab[PGID_PRINTER],
294 LabelEnd,
295 LAYOUT_AddChild, IntegerObject,
296 GA_ID, PGID_COPIES,
297 GA_RelVerify, TRUE,
298 GA_TabCycle, TRUE,
299 INTEGER_Number, 1,
300 INTEGER_Minimum, 1,
301 INTEGER_Maximum, 100,
302 INTEGER_Arrows, TRUE,
303 IntegerEnd,
304 CHILD_Label, LabelObject,
305 LABEL_Text, gadlab[PGID_COPIES],
306 LabelEnd,
307 LAYOUT_AddChild, HGroupObject,
308 LAYOUT_LabelColumn, PLACETEXT_RIGHT,
309 LAYOUT_AddChild, pw->gadgets[PGID_SCALE] = IntegerObj,
310 GA_ID, PGID_SCALE,
311 GA_RelVerify, TRUE,
312 GA_TabCycle, TRUE,
313 INTEGER_Number, nsoption_int(print_scale),
314 INTEGER_Minimum, 0,
315 INTEGER_Maximum, 100,
316 INTEGER_Arrows, TRUE,
317 IntegerEnd,
318 CHILD_WeightedWidth, 0,
319 CHILD_Label, LabelObject,
320 LABEL_Text, "%",
321 LabelEnd,
322 LayoutEnd,
323 CHILD_Label, LabelObject,
324 LABEL_Text, gadlab[PGID_SCALE],
325 LabelEnd,
326 LAYOUT_AddChild, HGroupObject,
327 LAYOUT_AddChild, pw->gadgets[PGID_PRINT] = ButtonObj,
328 GA_ID, PGID_PRINT,
329 GA_RelVerify,TRUE,
330 GA_Text, gadlab[PGID_PRINT],
331 GA_TabCycle,TRUE,
332 ButtonEnd,
333 CHILD_WeightedHeight,0,
334 LAYOUT_AddChild, pw->gadgets[PGID_CANCEL] = ButtonObj,
335 GA_ID, PGID_CANCEL,
336 GA_RelVerify, TRUE,
337 GA_Text, gadlab[PGID_CANCEL],
338 GA_TabCycle,TRUE,
339 ButtonEnd,
340 LayoutEnd,
341 CHILD_WeightedHeight,0,
342 EndGroup,
343 EndWindow;
344
345 pw->win = (struct Window *)RA_OpenWindow(pw->objects[POID_MAIN]);
347}
348
349static void ami_print_close(struct ami_print_window *pw)
350{
351 DisposeObject(pw->objects[POID_MAIN]);
353
355}
356
357static BOOL ami_print_event(void *w)
358{
359 /* return TRUE if window destroyed */
360 struct ami_print_window *pw = (struct ami_print_window *)w;
361 ULONG result;
362 uint16 code;
363 struct hlcache_handle *c;
364 int copies;
365 int print_scale;
366 int printer_unit;
367
368 while((result = RA_HandleInput(pw->objects[POID_MAIN],&code)) != WMHI_LASTMSG)
369 {
370 switch(result & WMHI_CLASSMASK) // class
371 {
372 case WMHI_GADGETUP:
373 switch(result & WMHI_GADGETMASK)
374 {
375 case PGID_PRINT:
376 GetAttr(INTEGER_Number, pw->gadgets[PGID_SCALE],
377 (ULONG *)&print_scale);
378 GetAttr(INTEGER_Number, pw->gadgets[PGID_COPIES],
379 (ULONG *)&copies);
380 GetAttr(CHOOSER_Selected, pw->gadgets[PGID_PRINTER],
381 (ULONG *)&printer_unit);
382
384 nsoption_set_int(printer_unit, printer_unit);
385
386 c = pw->c;
388 ami_print(c, copies);
389 return TRUE;
390 break;
391
392 case PGID_CANCEL:
394 return TRUE;
395 break;
396 }
397 break;
398
399 case WMHI_CLOSEWINDOW:
401 return TRUE;
402 break;
403 }
404 }
405 return FALSE;
406}
407
408void ami_print(struct hlcache_handle *c, int copies)
409{
410 double height;
411 float scale = nsoption_int(print_scale) / 100.0;
412
413 if(ami_print_info.msgport == NULL)
415#ifdef __amigaos4__
416 if(!(ami_print_info.PReq =
417 (struct IODRPTagsReq *)AllocSysObjectTags(ASOT_IOREQUEST,
418 ASOIOR_Size, sizeof(struct IODRPTagsReq),
419 ASOIOR_ReplyPort, ami_print_info.msgport,
420 ASO_NoTrack, FALSE,
421 TAG_DONE))) return;
422#else
423 if(!(ami_print_info.PReq =
424 (struct IODRPTagsReq *)CreateIORequest(ami_print_info.msgport,
425 sizeof(struct IODRPTagsReq)))) return;
426#endif
427
428 if(OpenDevice("printer.device", nsoption_int(printer_unit),
429 (struct IORequest *)ami_print_info.PReq, 0))
430 {
431 amiga_warn_user("CompError","printer.device");
432 return;
433 }
434
435 ami_print_info.PD = (struct PrinterData *)ami_print_info.PReq->io_Device;
436 ami_print_info.PED = &ami_print_info.PD->pd_SegmentData->ps_PED;
437
441 ami_print_info.ps->scale = scale;
443
445 {
446 amiga_warn_user("PrintError","print_set_up() returned false");
448 return;
449 }
450
453 ami_print_info.c = c;
454
456
457 while(ami_print_cont()); /* remove while() for async printing */
458}
459
461{
462 bool ret = false;
463
465 {
468 ret = true;
469 }
470 else
471 {
473 ret = false;
474 }
475
476 return ret;
477}
478
479struct MsgPort *ami_print_init(void)
480{
482 ASO_NoTrack,FALSE,
483 TAG_DONE);
484
485 return ami_print_info.msgport;
486}
487
489{
491 ami_print_info.msgport = NULL;
492}
493
494struct MsgPort *ami_print_get_msgport(void)
495{
496 return ami_print_info.msgport;
497}
498
500{
502 ami_print_info.PED->ped_MaxYDots,
503 true, false);
504 if(!ami_print_info.gg) return false;
505
507
508 return true;
509}
510
512{
514
516 ami_print_info.win, NULL,
517 FUELGAUGE_Level, ami_print_info.page,
518 TAG_DONE);
519 return true;
520}
521
523{
525 DisposeObject(ami_print_info.objects[POID_MAIN]);
526
529}
530
532{
533 CloseDevice((struct IORequest *)ami_print_info.PReq);
535}
536
538{
539 ami_print_info.PReq->io_Command = PRD_DUMPRPORT;
540 ami_print_info.PReq->io_Flags = 0;
541 ami_print_info.PReq->io_Error = 0;
543 ami_print_info.PReq->io_ColorMap = NULL;
544 ami_print_info.PReq->io_Modes = 0;
545 ami_print_info.PReq->io_SrcX = 0;
546 ami_print_info.PReq->io_SrcY = 0;
547 ami_print_info.PReq->io_SrcWidth = ami_print_info.PED->ped_MaxXDots;
548 ami_print_info.PReq->io_SrcHeight = ami_print_info.PED->ped_MaxYDots;
549 ami_print_info.PReq->io_DestCols = ami_print_info.PED->ped_MaxXDots;
550 ami_print_info.PReq->io_DestRows = ami_print_info.PED->ped_MaxYDots;
551 ami_print_info.PReq->io_Special = 0;
552
553 DoIO((struct IORequest *)ami_print_info.PReq); /* SendIO for async printing */
554
555 return true;
556}
557
559{
561 WA_ScreenTitle, ami_gui_get_screen_title(),
562 WA_Title, messages_get("Printing"),
563 WA_Activate, TRUE,
564 WA_DepthGadget, TRUE,
565 WA_DragBar, TRUE,
566 WA_CloseGadget, FALSE,
567 WA_SizeGadget, TRUE,
568 WA_PubScreen, ami_gui_get_screen(),
569 //WINDOW_SharedPort,sport,
570 WINDOW_UserData, &ami_print_info,
571 WINDOW_IconifyGadget, FALSE,
572 WINDOW_LockHeight,TRUE,
573 WINDOW_Position, WPOS_CENTERSCREEN,
574 WINDOW_ParentGroup, ami_print_info.gadgets[PGID_MAIN] = LayoutVObj,
576 GA_ID,PGID_STATUS,
577 FUELGAUGE_Min,0,
578 FUELGAUGE_Max,ami_print_info.pages,
579 FUELGAUGE_Level,0,
580 FUELGAUGE_Ticks,11,
581 FUELGAUGE_ShortTicks,TRUE,
582 FUELGAUGE_Percent,TRUE,
583 FUELGAUGE_Justification,FGJ_CENTER,
584 FuelGaugeEnd,
585 CHILD_NominalSize,TRUE,
586 CHILD_WeightedHeight,0,
587/*
588 LAYOUT_AddChild, ami_print_info.gadgets[PGID_CANCEL] = ButtonObj,
589 GA_ID,PGID_CANCEL,
590 GA_Disabled,TRUE,
591 GA_RelVerify,TRUE,
592 GA_Text,messages_get("Abort"),
593 GA_TabCycle,TRUE,
594 ButtonEnd,
595*/
596 EndGroup,
597 EndWindow;
598
599 ami_print_info.win = (struct Window *)RA_OpenWindow(ami_print_info.objects[POID_MAIN]);
600}
601
struct Screen * ami_gui_get_screen(void)
Get a pointer to the screen NetSurf is running on.
Definition: gui.c:403
nserror ami_gui_win_list_add(void *win, int type, const struct ami_win_event_table *table)
Add a window to the NetSurf window list (to enable event processing)
Definition: gui.c:4668
STRPTR ami_gui_get_screen_title(void)
Get the string for NetSurf's screen titlebar.
Definition: gui.c:974
void ami_gui_win_list_remove(void *win)
Remove a window from the NetSurf window list.
Definition: gui.c:4682
struct MsgPort * ami_gui_get_shared_msgport(void)
Get shared message port.
nserror amiga_warn_user(const char *warning, const char *detail)
Warn the user of an event.
Definition: misc.c:79
const struct plotter_table amiplot
Definition: plotters.c:1180
void ami_plot_ra_free(struct gui_globals *gg)
Free a plotter render area.
Definition: plotters.c:258
struct RastPort * ami_plot_ra_get_rastport(struct gui_globals *gg)
Get RastPort associated with a render area.
Definition: plotters.c:290
struct gui_globals * ami_plot_ra_alloc(ULONG width, ULONG height, bool force32bit, bool alloc_pen_list)
Alloc a plotter render area.
Definition: plotters.c:113
STATIC char result[100]
Definition: arexx.c:77
struct print_settings * print_make_settings(print_configuration configuration, const char *filename, const struct gui_layout_table *font_func)
Generates one of the predefined print settings sets.
Definition: print.c:254
bool print_draw_next_page(const struct printer *printer, struct print_settings *settings)
This function draws one page, beginning with the height offset of done_height.
Definition: print.c:176
bool print_cleanup(hlcache_handle *content, const struct printer *printer, struct print_settings *settings)
Memory allocated during printing is being freed here.
Definition: print.c:228
bool print_set_up(hlcache_handle *content, const struct printer *printer, struct print_settings *settings, double *height)
This function prepares the content to be printed.
Definition: print.c:148
Conception: Generalized output-in-pages.
@ PRINT_DEFAULT
Definition: print.h:45
struct gui_layout_table * ami_layout_table
Definition: font.c:162
@ AMINS_PRINTWINDOW
Definition: object.h:35
bool ami_print_begin(struct print_settings *ps)
Definition: print.c:499
static const struct ami_win_event_table ami_print_table
Definition: print.c:135
#define IFFPrefChunkCnt
Definition: print.c:121
void ami_print_progress(void)
Definition: print.c:558
bool ami_print_cont(void)
Definition: print.c:460
void ami_print_end(void)
Definition: print.c:522
void ami_print_close_device(void)
Definition: print.c:531
void ami_print(struct hlcache_handle *c, int copies)
Definition: print.c:408
static struct ami_printer_info ami_print_info
Definition: print.c:128
bool ami_print_dump(void)
Definition: print.c:537
bool ami_print_next_page(void)
Definition: print.c:511
const struct printer amiprinter
Definition: print.c:90
static void ami_print_close(struct ami_print_window *pw)
Definition: print.c:349
static void ami_print_ui_free(void)
Definition: print.c:149
struct MsgPort * ami_print_init(void)
Definition: print.c:479
static BOOL ami_print_readunit(CONST_STRPTR filename, char name[], uint32 namesize, int unitnum)
Definition: print.c:162
static CONST_STRPTR gadlab[PGID_LAST]
Definition: print.c:130
static void ami_print_ui_setup(void)
Definition: print.c:140
static BOOL ami_print_event(void *w)
Definition: print.c:357
void ami_print_ui(struct hlcache_handle *c)
Definition: print.c:243
void ami_print_free(void)
Definition: print.c:488
@ POID_LAST
Definition: print.c:79
@ PGID_PRINTER
Definition: print.c:81
@ PGID_LAST
Definition: print.c:87
@ PGID_CANCEL
Definition: print.c:85
@ PGID_PRINT
Definition: print.c:84
@ PGID_SCALE
Definition: print.c:82
@ POID_MAIN
Definition: print.c:78
@ PGID_MAIN
Definition: print.c:80
@ PGID_COPIES
Definition: print.c:83
@ PGID_STATUS
Definition: print.c:86
struct MsgPort * ami_print_get_msgport(void)
Definition: print.c:494
static LONG IFFPrefChunks[]
Definition: print.c:122
static STRPTR printers[11]
Definition: print.c:131
char * ami_utf8_easy(const char *string)
Definition: utf8.c:109
static float print_scale
Definition: print.c:87
Public content interface.
struct nsurl * hlcache_handle_get_url(const struct hlcache_handle *handle)
Retrieve the URL associated with a high level cache handle.
Interface to platform-specific layout operation table.
Core mouse and pointer states.
Target independent plotting interface.
Interface to platform-specific graphical user interface window operations.
#define FuelGaugeObj
Definition: libs.h:58
#define IntegerObj
Definition: libs.h:62
#define WindowObj
Definition: libs.h:77
#define LayoutVObj
Definition: libs.h:65
#define ButtonObj
Definition: libs.h:54
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
NetSurf URL handling (interface).
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
void FreeSysObject(ULONG type, APTR obj)
Definition: os3support.c:350
ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1,...)
Definition: os3support.c:429
Minimal compatibility header for AmigaOS 3.
#define AllocSysObjectTags(A, B, C, D)
Definition: os3support.h:157
#define SNPrintf
Definition: os3support.h:176
#define ASO_NoTrack
Definition: os3support.h:64
@ ASOT_PORT
Definition: os3support.h:226
@ ASOT_IOREQUEST
Definition: os3support.h:227
uint16_t uint16
Definition: os3support.h:182
uint32_t uint32
Definition: os3support.h:184
Printer interface.
int height
Definition: gui.c:160
Interface to utility string handling.
Object * objects[POID_LAST]
Definition: print.c:116
struct hlcache_handle * c
Definition: print.c:118
Object * gadgets[PGID_LAST]
Definition: print.c:117
struct ami_generic_window w
Definition: print.c:114
struct Window * win
Definition: print.c:115
struct hlcache_handle * c
Definition: print.c:104
Object * gadgets[PGID_LAST]
Definition: print.c:108
struct print_settings * ps
Definition: print.c:105
struct gui_globals * gg
Definition: print.c:99
struct PrinterData * PD
Definition: print.c:101
struct Window * win
Definition: print.c:110
struct PrinterExtendedData * PED
Definition: print.c:102
Object * objects[POID_LAST]
Definition: print.c:109
struct IODRPTagsReq * PReq
Definition: print.c:100
struct MsgPort * msgport
Definition: print.c:103
High-level cache handle.
Definition: hlcache.c:66
void * pw
Client data.
Definition: hlcache.c:70
Settings for a print - filled in by print_make_settings or 'manually' by the caller.
Definition: print.h:50
float scale
Definition: print.h:55
float page_width
Definition: print.h:52
float page_height
Definition: print.h:52
void * priv
Definition: print.h:66
Printer interface.
Definition: printer.h:34
Option reading and saving interface.
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:279
#define nsoption_set_int(OPTION, VALUE)
set an integer option in the default table
Definition: nsoption.h:314
Interface to a number of general purpose functionality.