Subversion Repositories Scribus

Rev

Rev 2834 | Rev 2921 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
792 subik 1
#include "objprinter.h"
2
#include "cmdutil.h"
2834 cbradney 3
#include "prefsmanager.h"
792 subik 4
 
413 Franz 5
#include <structmember.h>
420 Franz 6
#include <qfileinfo.h>
413 Franz 7
#include <vector>
910 fschmid 8
#include "libpostscript/pslib.h"
413 Franz 9
 
10
#ifdef HAVE_CUPS
11
#include <cups/cups.h>
12
#endif
13
#ifdef HAVE_CMS
14
extern bool CMSuse;
15
#endif
16
// these functions are located at utils.cpp
418 Franz 17
bool loadText(QString nam, QString *Buffer);
18
void ReOrderText(ScribusDoc *doc, ScribusView *view);
413 Franz 19
// end of utils.cpp
20
 
1745 subik 21
 
733 subik 22
typedef struct
413 Franz 23
{
1745 subik 24
        PyObject_HEAD
25
        PyObject *allPrinters; // list of strings - names of installed printers
26
        PyObject *printer;  // string - selected printer
27
        PyObject *file;  // string - name of file to print into (eg. output.ps)
28
        PyObject *cmd; // string - if "" use standard command else use this as command (eg. "kprinter", "xpp" ...)
29
        PyObject *pages; // list of integers - pages to be printed
30
        int copies; // numer of printed copies
31
        PyObject *separation; // string - No; All; Cyan; Magenta; Yellow; Black
32
        int color; // bool - do we print in color=1 or greyscale=0
33
        int useICC; // bool - do we use ICC Profiles 0 = No 1 = Yes
34
        int pslevel; // integer - 1, 2 or 3 level of used postscript
35
        int mph; // bool - mirror pages horizontally
36
        int mpv; // bool - mirror pages vertically
37
        int ucr; // bool - Under Color Removal
413 Franz 38
} Printer;
39
 
40
 
41
static void Printer_dealloc(Printer* self)
42
{
1745 subik 43
        Py_XDECREF(self->allPrinters);
44
        Py_XDECREF(self->printer);
45
        Py_XDECREF(self->file);
46
        Py_XDECREF(self->cmd);
47
        Py_XDECREF(self->pages);
48
        Py_XDECREF(self->separation);
49
        self->ob_type->tp_free((PyObject *)self);
413 Franz 50
}
51
 
1745 subik 52
static PyObject * Printer_new(PyTypeObject *type, PyObject */*args*/, PyObject */*kwds*/)
413 Franz 53
{
54
// do not create new object if there is no opened document
1745 subik 55
        if (!Carrier->HaveDoc) {
56
                PyErr_SetString(PyExc_SystemError, "Need to open document first");
57
                return NULL;
58
        }
413 Franz 59
 
1745 subik 60
        Printer *self;
61
        self = (Printer *)type->tp_alloc(type, 0);
62
        if (self != NULL) {
413 Franz 63
// set allPrinters attribute
1745 subik 64
                self->allPrinters = PyList_New(0);
65
                if (self->allPrinters == NULL){
66
                        Py_DECREF(self);
67
                        return NULL;
68
                }
413 Franz 69
// set printer attribute
1745 subik 70
                self->printer = PyString_FromString("");
71
                if (self->printer == NULL){
72
                        Py_DECREF(self);
73
                        return NULL;
74
                }
413 Franz 75
// set file attribute
1745 subik 76
                self->file = PyString_FromString("");
77
                if (self->file == NULL){
78
                        Py_DECREF(self);
79
                        return NULL;
80
                }
413 Franz 81
// set cmd attribute
1745 subik 82
                self->cmd = PyString_FromString("");
83
                if (self->cmd == NULL){
84
                        Py_DECREF(self);
85
                        return NULL;
86
                }
413 Franz 87
// set pages attribute
1745 subik 88
                self->pages = PyList_New(0);
89
                if (self->pages == NULL){
90
                        Py_DECREF(self);
91
                        return NULL;
92
                }
413 Franz 93
// set separation attribute
1745 subik 94
                self->separation = PyString_FromString("No");
95
                if (self->separation == NULL){
96
                        Py_DECREF(self);
97
                        return NULL;
98
                }
413 Franz 99
// set color attribute
1745 subik 100
                self->color = 1;
413 Franz 101
// set useICC attribute
1745 subik 102
                self->useICC = 0;
413 Franz 103
// set pslevel attribute
1745 subik 104
                self->pslevel = 3;
413 Franz 105
// set mph attribute
1745 subik 106
                self->mph = 0;
413 Franz 107
// set mpv attribute
1745 subik 108
                self->mpv = 0;
413 Franz 109
// set ucr attribute
1745 subik 110
                self->ucr = 1;
413 Franz 111
// set copies attribute
1745 subik 112
                self->copies = 1;
113
        }
114
        return (PyObject *) self;
413 Franz 115
}
116
 
1745 subik 117
static int Printer_init(Printer *self, PyObject */*args*/, PyObject */*kwds*/)
413 Franz 118
{
119
// pool system for installed printers
120
// most code is stolen and little adopted from druck.cpp
1745 subik 121
        PyObject *allPrinters = PyList_New(0);
122
        if (allPrinters){
123
                Py_DECREF(self->allPrinters);
124
                self->allPrinters = allPrinters;
125
        }
413 Franz 126
#ifdef HAVE_CUPS
1745 subik 127
        cups_dest_t *dests;
128
        int num_dests = cupsGetDests(&dests);
129
        for (int i = 0; i < num_dests; ++i) {
130
                if (dests[i].name != NULL) {
131
                        PyObject *tmp = PyString_FromString(dests[i].name);
132
                        if (tmp) {
133
                                PyList_Append(self->allPrinters, tmp);
134
                                Py_DECREF(tmp);
135
                        }
136
                }
137
        }
138
        cupsFreeDests(num_dests, dests);
413 Franz 139
#else
1745 subik 140
        QString Pcap;
141
        // loadText is defined in utils.cpp
142
        if (loadText("/etc/printcap", &Pcap))
143
        {
144
                QTextStream ts(&Pcap, IO_ReadOnly);
145
                while(!ts.atEnd())
146
                {
147
                        QStringList wt;
148
                        QString tmp = ts.readLine();
149
                        if (tmp.isEmpty())
150
                                continue;
151
                        if ((tmp[0] != '#') && (tmp[0] != ' ') && (tmp[0] != '\n') && (tmp[0] != '\t'))
152
                        {
153
                                tmp = tmp.stripWhiteSpace();
154
                                tmp = tmp.left(tmp.length() - (tmp.right(2) == ":\\" ? 2 : 1));
155
                                wt = QStringList::split("|", tmp);
156
                                PyObject *tmppr = PyString_FromString(wt[0]);
157
                                if (tmppr){
158
                                        PyList_Append(self->allPrinters, tmppr);
159
                                        Py_DECREF(tmppr);
160
                                }
161
                        }
162
                }
163
        }
413 Franz 164
#endif
1745 subik 165
        PyObject *tmp2 = PyString_FromString("File");
166
        PyList_Append(self->allPrinters, tmp2);
167
        Py_DECREF(tmp2);
413 Franz 168
// as defaut set to print into file
1745 subik 169
        PyObject *printer = NULL;
170
        printer = PyString_FromString("File");
171
        if (printer){
172
                Py_DECREF(self->printer);
173
                self->printer = printer;
174
        }
413 Franz 175
// set defaul name of file to print into
1745 subik 176
        QString tf = Carrier->doc->PDF_Options.Datei;
2877 cbradney 177
        if (tf.isEmpty()) {
1745 subik 178
                QFileInfo fi = QFileInfo(Carrier->doc->DocName);
179
                tf = fi.dirPath()+"/"+fi.baseName()+".pdf";
180
        }
181
        PyObject *file = NULL;
182
        file = PyString_FromString(tf.ascii());
183
        if (file){
184
                Py_DECREF(self->file);
185
                self->file = file;
186
        } else {
187
                PyErr_SetString(PyExc_SystemError, "Can not initialize 'file' attribute");
188
                return -1;
189
        }
413 Franz 190
// alternative printer commands default to ""
1745 subik 191
        PyObject *cmd = NULL;
192
        cmd = PyString_FromString("");
193
        if (cmd){
194
                Py_DECREF(self->cmd);
195
                self->cmd = cmd;
196
        }
413 Franz 197
// if document exist when created Printer instance
198
// set to print all pages
1745 subik 199
        PyObject *pages = NULL;
200
        int num = 0;
201
        if (Carrier->HaveDoc)
202
                // which one should I use ???
203
                // new = Carrier->view->Pages.count()
2142 cbradney 204
                num = Carrier->doc->pageCount;
1745 subik 205
        pages = PyList_New(num);
206
        if (pages){
207
                Py_DECREF(self->pages);
208
                self->pages = pages;
209
        }
210
        for (int i = 0; i<num; i++) {
211
                PyObject *tmp=NULL;
212
                tmp = PyInt_FromLong((long)i+1L); // instead of 1 put here first page number
213
                if (tmp)
214
                        PyList_SetItem(self->pages, i, tmp);
215
        }
413 Franz 216
// do not print separation
1745 subik 217
        PyObject *separation = NULL;
218
        separation = PyString_FromString("No");
219
        if (separation){
220
                Py_DECREF(self->separation);
221
                self->separation = separation;
222
        }
413 Franz 223
// print in color
1745 subik 224
        self->color = 1;
413 Franz 225
// do not use ICC Profile
1745 subik 226
        self->useICC = 0;
413 Franz 227
// use PostScrip level 3
1745 subik 228
        self->pslevel = 3;
413 Franz 229
// do not mirror pages
1745 subik 230
        self->mph = 0;
413 Franz 231
// do not mirror pages
1745 subik 232
        self->mpv = 0;
413 Franz 233
// apply Under Color Removal as default
1745 subik 234
        self->ucr = 1;
413 Franz 235
// number of copies
1745 subik 236
        self->copies = 1;
237
        return 0;
413 Franz 238
}
239
 
240
static PyMemberDef Printer_members[] = {
1745 subik 241
        {const_cast<char*>("copies"), T_INT, offsetof(Printer, copies), 0, const_cast<char*>("Number of copies")},
242
        {const_cast<char*>("color"), T_INT, offsetof(Printer, color), 0, const_cast<char*>("Print in color.\n\t True - color  --  Default\n\t False - greyscale")},
243
        {const_cast<char*>("useICC"), T_INT, offsetof(Printer, useICC), 0, const_cast<char*>("Use ICC Profile\n\tTrue\n\tFalse  --  Default")},
244
        {const_cast<char*>("pslevel"), T_INT, offsetof(Printer, pslevel), 0, const_cast<char*>("PostScript Level\nCan be 1 or 2 or 3    -- Default is 3.")},
245
        {const_cast<char*>("mph"), T_INT, offsetof(Printer, mph), 0, const_cast<char*>("Mirror Pages Horizontal\n\tTrue\n\tFalse  --  Default")},
246
        {const_cast<char*>("mpv"), T_INT, offsetof(Printer, mpv), 0, const_cast<char*>("Mirror Pages Vertical\n\t True\n\tFalse  --  Default")},
247
        {const_cast<char*>("ucr"), T_INT, offsetof(Printer, ucr), 0, const_cast<char*>("Apply Under Color Removal\n\tTrue  --  Default\n\tFalse")},
248
        {NULL, 0, 0, 0, NULL} // sentinel
413 Franz 249
};
250
 
251
/* Here begins Getter & Setter functions */
252
 
1745 subik 253
static PyObject *Printer_getallPrinters(Printer *self, void */*closure*/)
413 Franz 254
{
1745 subik 255
        Py_INCREF(self->allPrinters);
256
        return self->allPrinters;
413 Franz 257
}
258
 
1745 subik 259
static int Printer_setallPrinters(Printer */*self*/, PyObject */*value*/, void */*closure*/)
413 Franz 260
{
1745 subik 261
        PyErr_SetString(PyExc_ValueError, "'allPrinters' attribute is READ-ONLY");
262
        return -1;
413 Franz 263
}
264
 
1745 subik 265
static PyObject *Printer_getprinter(Printer *self, void */*closure*/)
413 Franz 266
{
1745 subik 267
        Py_INCREF(self->printer);
268
        return self->printer;
413 Franz 269
}
270
 
1745 subik 271
static int Printer_setprinter(Printer *self, PyObject *value, void */*closure*/)
413 Franz 272
{
1745 subik 273
        if (value == NULL) {
274
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'printer' attribute.");
275
                return -1;
276
        }
277
        if (!PyString_Check(value)) {
278
                PyErr_SetString(PyExc_TypeError, "The 'printer' attribute value must be string.");
279
                return -1;
280
        }
281
        int n = PyList_Size(self->allPrinters);
282
        bool same = 0;
283
        for (int i = 0; i<n; i++)
284
                if (PyObject_RichCompareBool(value, PyList_GetItem(self->allPrinters, i), Py_EQ) == 1)
285
                        same = true;
286
        if (!same) {
287
                PyErr_SetString(PyExc_ValueError, "'printer' value can be only one of string in 'allPrinters' attribute ");
288
                return -1;
289
        }
290
        Py_DECREF(self->printer);
291
        Py_INCREF(value);
292
        self->printer = value;
293
        return 0;
413 Franz 294
}
295
 
1745 subik 296
static PyObject *Printer_getfile(Printer *self, void */*closure*/)
413 Franz 297
{
1745 subik 298
        Py_INCREF(self->file);
299
        return self->file;
413 Franz 300
}
301
 
1745 subik 302
static int Printer_setfile(Printer *self, PyObject *value, void */*closure*/)
413 Franz 303
{
1745 subik 304
        if (value == NULL) {
305
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'file' attribute.");
306
                return -1;
307
        }
308
        if (!PyString_Check(value)) {
309
                PyErr_SetString(PyExc_TypeError, "The 'file' attribute value must be string.");
310
                return -1;
311
        }
312
        Py_DECREF(self->file);
313
        Py_INCREF(value);
314
        self->file = value;
315
        return 0;
413 Franz 316
}
317
 
1745 subik 318
static PyObject *Printer_getcmd(Printer *self, void */*closure*/)
413 Franz 319
{
1745 subik 320
        Py_INCREF(self->cmd);
321
        return self->cmd;
413 Franz 322
}
323
 
1745 subik 324
static int Printer_setcmd(Printer *self, PyObject *value, void */*closure*/)
413 Franz 325
{
1745 subik 326
        if (value == NULL) {
327
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'cmd' attribute.");
328
                return -1;
329
        }
330
        if (!PyString_Check(value)) {
331
                PyErr_SetString(PyExc_TypeError, "The 'cmd' attribute value must be string.");
332
                return -1;
333
        }
334
        Py_DECREF(self->cmd);
335
        Py_INCREF(value);
336
        self->cmd = value;
337
        return 0;
413 Franz 338
}
339
 
1745 subik 340
static PyObject *Printer_getpages(Printer *self, void */*closure*/)
413 Franz 341
{
1745 subik 342
        Py_INCREF(self->pages);
343
        return self->pages;
413 Franz 344
}
345
 
1745 subik 346
static int Printer_setpages(Printer *self, PyObject *value, void */*closure*/)
413 Franz 347
{
1745 subik 348
        if (value == NULL) {
349
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'pages' attribute.");
350
                return -1;
351
        }
352
        if (!PyList_Check(value)) {
353
                PyErr_SetString(PyExc_TypeError, "'pages' attribute value must be list of integers.");
354
                return -1;
355
        }
356
        int len = PyList_Size(value);
357
        for (int i = 0; i<len; i++){
358
                PyObject *tmp = PyList_GetItem(value, i);
359
                if (!PyInt_Check(tmp)){
360
                        PyErr_SetString(PyExc_TypeError, "'pages' attribute must be list containing only integers.");
361
                        return -1;
362
                }
2142 cbradney 363
                if (PyInt_AsLong(tmp) > Carrier->doc->pageCount || PyInt_AsLong(tmp) < 1) {
1745 subik 364
                        PyErr_SetString(PyExc_ValueError, "'pages' value out of range.");
365
                        return -1;
366
                }
367
        }
368
        Py_DECREF(self->pages);
369
        Py_INCREF(value);
370
        self->pages = value;
371
        return 0;
413 Franz 372
}
373
 
1745 subik 374
static PyObject *Printer_getseparation(Printer *self, void */*closure*/)
413 Franz 375
{
1745 subik 376
        Py_INCREF(self->separation);
377
        return self->separation;
413 Franz 378
}
379
 
1745 subik 380
static int Printer_setseparation(Printer *self, PyObject *value, void */*closure*/)
413 Franz 381
{
1745 subik 382
        if (value == NULL) {
383
                PyErr_SetString(PyExc_TypeError, "Cannot delete 'separation' attribute.");
384
                return -1;
385
        }
386
        if (!PyString_Check(value)) {
387
                PyErr_SetString(PyExc_TypeError, "The 'separation' attribute value must be string.");
388
                return -1;
389
        }
390
        Py_DECREF(self->separation);
391
        Py_INCREF(value);
392
        self->separation = value;
393
        return 0;
413 Franz 394
}
395
 
396
 
397
static PyGetSetDef Printer_getseters [] = {
1745 subik 398
        {const_cast<char*>("allPrinters"), (getter)Printer_getallPrinters, (setter)Printer_setallPrinters, const_cast<char*>("List of installed printers  --  read only"), NULL},
399
        {const_cast<char*>("printer"), (getter)Printer_getprinter, (setter)Printer_setprinter, const_cast<char*>("Name of printer to use.\nDefault is 'File' for printing into file"), NULL},
400
        {const_cast<char*>("file"), (getter)Printer_getfile, (setter)Printer_setfile, const_cast<char*>("Name of file to print into"), NULL},
401
        {const_cast<char*>("cmd"), (getter)Printer_getcmd, (setter)Printer_setcmd, const_cast<char*>("Alternative Printer Command"), NULL},
402
        {const_cast<char*>("pages"), (getter)Printer_getpages, (setter)Printer_setpages, const_cast<char*>("List of pages to be printed"), NULL},
403
        {const_cast<char*>("separation"), (getter)Printer_getseparation, (setter)Printer_setseparation, const_cast<char*>("Print separationl\n\t 'No'  -- Default\n\t 'All'\n\t 'Cyan'\n\t 'Magenta'\n\t 'Yellow'\n\t 'Black'\nBeware of misspelling because check is not performed"), NULL},
404
        {NULL, NULL, NULL, NULL, NULL}  // sentinel
413 Franz 405
};
406
 
733 subik 407
// Here we actually print
413 Franz 408
static PyObject *Printer_print(Printer *self)
409
{
1745 subik 410
        if (!Carrier->HaveDoc) {
411
                PyErr_SetString(PyExc_SystemError, "Need to open documetnt first");
412
                return NULL;
413
        }
413 Franz 414
// copied from void ScribusApp::slotFilePrint() in file scribus.cpp
1745 subik 415
        QString fna, prn, cmd, scmd, cc, data, SepName;
416
        QString printcomm;
417
        int Nr, PSLevel;
418
        bool fil, sep, color, PSfile, mirrorH, mirrorV, useICC, DoGCR;
419
        PSfile = false;
413 Franz 420
 
421
//    ReOrderText(Carrier->doc, Carrier->view);
1745 subik 422
        prn = QString(PyString_AsString(self->printer));
423
        fna = QString(PyString_AsString(self->file));
424
        fil = (QString(PyString_AsString(self->printer)) == QString("File")) ? true : false;
425
        std::vector<int> pageNs;
426
        for (int i = 0; i < PyList_Size(self->pages); ++i) {
427
                pageNs.push_back((int)PyInt_AsLong(PyList_GetItem(self->pages, i)));
428
        }
429
        Nr = (self->copies < 1) ? 1 : self->copies;
430
        SepName = QString(PyString_AsString(self->separation));
431
        sep =(SepName == QString("No")) ?  false : true;
432
//       if (SepName == QString("All"))
433
//               SepName = tr(SepName);
434
        color = self->color;
435
        mirrorH = self->mph;
436
        mirrorV = self->mpv;
437
        useICC = self->useICC;
438
        DoGCR = self->ucr;
439
        int psl = self->pslevel;
440
        if (psl < 1)
441
                psl = 1;
442
        else if (psl > 3)
443
                psl = 3;
444
        PSLevel = psl;
445
        printcomm = QString(PyString_AsString(self->cmd));
446
        QMap<QString,QFont> ReallyUsed;
447
        ReallyUsed.clear();
448
        Carrier->GetUsedFonts(&ReallyUsed);
2834 cbradney 449
        PSLib *dd = Carrier->getPSDriver(true, ReallyUsed, Carrier->doc->PageColors, false);
1745 subik 450
        if (dd != NULL)
451
        {
452
                if (!fil)
453
                        fna = Carrier->PrefsPfad+"/tmp.ps";
454
                PSfile = dd->PS_set_file(fna);
455
                if (PSfile)
456
                {
1861 fschmid 457
                        dd->CreatePS(Carrier->doc, Carrier->view, pageNs, sep, SepName, color, mirrorH, mirrorV, useICC, DoGCR, false);
1745 subik 458
                        if (PSLevel != 3)
459
                        {
460
                                QString tmp;
461
                                QString opts = "-dDEVICEWIDTHPOINTS=";
2142 cbradney 462
                                opts += tmp.setNum(Carrier->doc->pageWidth);
1745 subik 463
                                opts += " -dDEVICEHEIGHTPOINTS=";
2142 cbradney 464
                                opts += tmp.setNum(Carrier->doc->pageHeight);
1745 subik 465
                                if (PSLevel == 1)
466
                                        system("ps2ps -dLanguageLevel=1 "+opts+" \""+fna+"\" \""+fna+".tmp\"");
467
                                else
468
                                        system("ps2ps "+opts+" \""+fna+"\" \""+fna+".tmp\"");
469
                                system("mv \""+fna+".tmp\" \""+fna+"\"");
470
                        }
418 Franz 471
 
1745 subik 472
                        if (!fil)
473
                        {
2877 cbradney 474
                                if (!printcomm.isEmpty())
1745 subik 475
                                        cmd = printcomm + " "+fna;
476
                                else
477
                                {
478
                                        cmd = "lpr -P" + prn;
479
                                        if (Nr > 1)
480
                                                cmd += " -#" + cc.setNum(Nr);
413 Franz 481
#ifdef HAVE_CUPS
418 Franz 482
// This need yet to be implemented by object Printer
1745 subik 483
//                                      cmd += printer->PrinterOpts;
413 Franz 484
#endif
1745 subik 485
                                        cmd += " "+fna;
486
                                }
487
                                system(cmd);
488
                                unlink(fna);
489
                        }
490
                }
491
                else {
492
                        delete dd;
493
                        Carrier->closePSDriver();
494
                        PyErr_SetString(PyExc_SystemError, "Printing failed");
495
                        return NULL;
496
                }
497
                delete dd;
498
                Carrier->closePSDriver();
499
        }
500
        Py_INCREF(Py_None);
501
        return Py_None;
413 Franz 502
}
503
 
504
static PyMethodDef Printer_methods[] = {
1745 subik 505
        {const_cast<char*>("print"), (PyCFunction)Printer_print, METH_NOARGS, const_cast<char*>("Prints selected pages.")},
506
        {NULL, (PyCFunction)(0), 0, NULL} // sentinel
413 Franz 507
};
508
 
509
PyTypeObject Printer_Type = {
1745 subik 510
        PyObject_HEAD_INIT(NULL)   // PyObject_VAR_HEAD
511
        0,                       //
512
        const_cast<char*>("Printer"), // char *tp_name; /* For printing, in format "<module>.<name>" */
513
        sizeof(Printer),   // int tp_basicsize, /* For allocation */
514
        0,                     // int tp_itemsize; /* For allocation */
413 Franz 515
 
516
        /* Methods to implement standard operations */
517
 
1745 subik 518
        (destructor) Printer_dealloc, //     destructor tp_dealloc;
519
        0, //     printfunc tp_print;
520
        0, //     getattrfunc tp_getattr;
521
        0, //     setattrfunc tp_setattr;
522
        0, //     cmpfunc tp_compare;
523
        0, //     reprfunc tp_repr;
413 Franz 524
 
525
        /* Method suites for standard classes */
526
 
1745 subik 527
        0, //     PyNumberMethods *tp_as_number;
528
        0, //     PySequenceMethods *tp_as_sequence;
529
        0, //     PyMappingMethods *tp_as_mapping;
413 Franz 530
 
531
        /* More standard operations (here for binary compatibility) */
532
 
1745 subik 533
        0, //     hashfunc tp_hash;
534
        0, //     ternaryfunc tp_call;
535
        0, //     reprfunc tp_str;
536
        0, //     getattrofunc tp_getattro;
537
        0, //     setattrofunc tp_setattro;
413 Franz 538
 
539
        /* Functions to access object as input/output buffer */
1745 subik 540
        0, //     PyBufferProcs *tp_as_buffer;
413 Franz 541
 
542
        /* Flags to define presence of optional/expanded features */
1745 subik 543
        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,    // long tp_flags;
413 Franz 544
 
1745 subik 545
        printer__doc__,      // char *tp_doc; /* Documentation string */
733 subik 546
 
413 Franz 547
        /* Assigned meaning in release 2.0 */
548
        /* call function for all accessible objects */
1745 subik 549
        0, //     traverseproc tp_traverse;
413 Franz 550
 
551
        /* delete references to contained objects */
1745 subik 552
        0, //     inquiry tp_clear;
413 Franz 553
 
554
        /* Assigned meaning in release 2.1 */
555
        /* rich comparisons */
1745 subik 556
        0, //     richcmpfunc tp_richcompare;
413 Franz 557
 
558
        /* weak reference enabler */
1745 subik 559
        0, //     long tp_weaklistoffset;
413 Franz 560
 
561
        /* Added in release 2.2 */
562
        /* Iterators */
1745 subik 563
        0, //     getiterfunc tp_iter;
564
        0, //     iternextfunc tp_iternext;
413 Franz 565
 
566
        /* Attribute descriptor and subclassing stuff */
1745 subik 567
        Printer_methods, //     struct PyMethodDef *tp_methods;
568
        Printer_members, //     struct PyMemberDef *tp_members;
569
        Printer_getseters, //     struct PyGetSetDef *tp_getset;
570
        0, //     struct _typeobject *tp_base;
571
        0, //     PyObject *tp_dict;
572
        0, //     descrgetfunc tp_descr_get;
573
        0, //     descrsetfunc tp_descr_set;
574
        0, //     long tp_dictoffset;
575
        (initproc)Printer_init, //     initproc tp_init;
576
        0, //     allocfunc tp_alloc;
577
        Printer_new, //     newfunc tp_new;
578
        0, //     freefunc tp_free; /* Low-level free-memory routine */
579
        0, //     inquiry tp_is_gc; /* For PyObject_IS_GC */
580
        0, //     PyObject *tp_bases;
581
        0, //     PyObject *tp_mro; /* method resolution order */
582
        0, //     PyObject *tp_cache;
583
        0, //     PyObject *tp_subclasses;
584
        0, //     PyObject *tp_weaklist;
585
        0, //     destructor tp_del;
413 Franz 586
 
587
#ifdef COUNT_ALLOCS
588
        /* these must be last and never explicitly initialized */
1745 subik 589
        //    int tp_allocs;
590
        //    int tp_frees;
591
        //    int tp_maxalloc;
592
        //    struct _typeobject *tp_next;
413 Franz 593
#endif
594
};