Subversion Repositories Scribus

Rev

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

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