Subversion Repositories Scribus

Rev

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