vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / print / drivers / gutenprint / GPBinding.cpp
bloba6157ba0c1f7015bf5c355aed53c3203783aab50
1 /*
2 * Copyright 2010, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Michael Pfeiffer
7 */
8 #include "GPBinding.h"
10 #include <list>
11 #include <set>
12 #include <string>
14 #include <gutenprint/gutenprint.h>
17 #include "GPCapabilityExtractor.h"
19 using namespace std;
22 // printer manufacturer
23 static const char* kManufacturerId = "id";
24 static const char* kManufacturerDisplayName = "name";
26 // printer model
27 static const char* kModelDisplayName = "model";
28 static const char* kModelDriver = "driver";
31 GPBinding::GPBinding()
33 fInitialized(false),
34 fOutputStream(NULL)
40 GPBinding::~GPBinding()
42 DeleteBands();
46 status_t
47 GPBinding::GetPrinterManufacturers(BMessage& manufacturers)
49 InitGutenprint();
51 list<string> ids;
52 set<string> manufacturerSet;
54 for (int i = 0; i < stp_printer_model_count(); i ++) {
55 const stp_printer_t* printer = stp_get_printer_by_index(i);
56 string manufacturer = stp_printer_get_manufacturer(printer);
58 // ignore unnamed manufacturers
59 if (manufacturer == "")
60 continue;
62 // add manufacturer only once
63 if (manufacturerSet.find(manufacturer) != manufacturerSet.end())
64 continue;
66 manufacturerSet.insert(manufacturer);
68 ids.push_back(manufacturer);
71 ids.sort();
73 list<string>::iterator it = ids.begin();
74 for (; it != ids.end(); it ++) {
75 string manufacturer = *it;
76 const char* id = manufacturer.c_str();
77 const char* name = manufacturer.c_str();
78 AddManufacturer(manufacturers, id, name);
80 return B_OK;
84 bool
85 GPBinding::ExtractManufacturer(const BMessage& manufacturers, int32 index,
86 BString& id, BString& displayName)
88 if (manufacturers.FindString(kManufacturerId, index, &id) != B_OK)
89 return false;
90 if (manufacturers.FindString(kManufacturerDisplayName, index, &displayName)
91 != B_OK)
92 return false;
93 return true;
97 void
98 GPBinding::AddManufacturer(BMessage& manufacturers, const char* id,
99 const char* displayName)
101 manufacturers.AddString(kManufacturerId, id);
102 manufacturers.AddString(kManufacturerDisplayName, displayName);
106 status_t
107 GPBinding::GetPrinterModels(const char* manufacturer, BMessage& models)
109 for (int i = 0; i < stp_printer_model_count(); i ++) {
110 const stp_printer_t* printer = stp_get_printer_by_index(i);
111 if (strcmp(manufacturer, stp_printer_get_manufacturer(printer)) != 0)
112 continue;
114 const char* displayName = stp_printer_get_long_name(printer);
115 const char* driver = stp_printer_get_driver(printer);
116 AddModel(models, displayName, driver);
118 return B_OK;
122 bool
123 GPBinding::ExtractModel(const BMessage& models, int32 index, BString& displayName,
124 BString& driver)
126 if (models.FindString(kModelDisplayName, index, &displayName) != B_OK)
127 return false;
128 if (models.FindString(kModelDriver, index, &driver) != B_OK)
129 return false;
130 return true;
134 void
135 GPBinding::AddModel(BMessage& models, const char* displayName, const char* driver)
137 models.AddString(kModelDisplayName, displayName);
138 models.AddString(kModelDriver, driver);
142 status_t
143 GPBinding::GetCapabilities(const char* driver, GPCapabilities* capabilities)
145 InitGutenprint();
146 const stp_printer_t* printer = stp_get_printer_by_driver(driver);
147 if (printer == NULL)
148 return B_ERROR;
150 GPCapabilityExtractor extractor(capabilities);
151 extractor.Visit(printer);
152 return B_OK;
156 status_t
157 GPBinding::BeginJob(GPJobConfiguration* configuration,
158 OutputStream* outputStream)
159 throw(TransportException)
161 fOutputStream = outputStream;
162 fJob.SetApplicationName("Gutenprint");
163 fJob.SetConfiguration(configuration);
164 fJob.SetOutputStream(outputStream);
166 return fJob.Begin();
170 void
171 GPBinding::EndJob() throw(TransportException)
173 fJob.End();
174 fOutputStream = NULL;
178 void
179 GPBinding::BeginPage() throw(TransportException)
184 void
185 GPBinding::EndPage() throw(TransportException)
187 status_t status = fJob.PrintPage(fBands);
188 DeleteBands();
189 if (status == B_IO_ERROR)
190 throw TransportException("I/O Error");
191 if (status == B_ERROR) {
192 BString message;
193 fJob.GetErrorMessage(message);
194 throw TransportException(message.String());
199 status_t
200 GPBinding::AddBitmapToPage(BBitmap* bitmap, BRect validRect, BPoint where)
202 GPBand* band = new(nothrow) GPBand(bitmap, validRect, where);
203 if (band == NULL) {
204 return B_NO_MEMORY;
207 fBands.push_back(band);
208 return B_OK;
212 void
213 GPBinding::InitGutenprint()
215 if (fInitialized)
216 return;
217 fInitialized = true;
218 // there is no "destroy" counter part so this creates memory leaks
219 // this is no problem because the print server loads printer add-ons
220 // in a new application instance that is terminated when not used anymore
221 stp_init();
222 stp_set_output_codeset("UTF-8");
226 void
227 GPBinding::DeleteBands()
229 list<GPBand*>::iterator it = fBands.begin();
230 for (; it != fBands.end(); it ++) {
231 GPBand* band = *it;
232 delete band;
234 fBands.clear();