Subversion Repositories Scribus

Rev

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