Subversion Repositories Scribus

Rev

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