headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / print / Printer.cpp
blobf638c2dd1ccc039cddae1ecd00f582b1001471dd
1 /*
2 * Copyright 2008 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Julun, <host.haiku@gmx.de
7 */
9 #include <Printer.h>
11 #include <FindDirectory.h>
12 #include <NodeInfo.h>
13 #include <NodeMonitor.h>
16 #include <new>
19 namespace BPrivate {
20 namespace Print {
23 // TODO: remove, after pr_server.h cleanup
25 // mime file types
26 #define PSRV_PRINTER_MIMETYPE "application/x-vnd.Be.printer"
29 // printer attributes
30 #define PSRV_PRINTER_ATTR_STATE "state"
31 #define PSRV_PRINTER_ATTR_COMMENTS "Comments"
32 #define PSRV_PRINTER_ATTR_TRANSPORT "transport"
33 #define PSRV_PRINTER_ATTR_DRIVER_NAME "Driver Name"
34 #define PSRV_PRINTER_ATTR_PRINTER_NAME "Printer Name"
35 #define PSRV_PRINTER_ATTR_DEFAULT_PRINTER "Default Printer"
36 #define PSRV_PRINTER_ATTR_TRANSPORT_ADDRESS "transport_address"
39 // message fields
40 #define PSRV_FIELD_CURRENT_PRINTER "current_printer"
43 BPrinter::BPrinter()
44 : fListener(NULL)
46 memset(&fPrinterEntryRef, 0, sizeof(entry_ref));
50 BPrinter::BPrinter(const BEntry& entry)
51 : fListener(NULL)
53 SetTo(entry);
57 BPrinter::BPrinter(const BPrinter& printer)
59 *this = printer;
63 BPrinter::BPrinter(const node_ref& nodeRef)
64 : fListener(NULL)
66 SetTo(nodeRef);
70 BPrinter::BPrinter(const entry_ref& entryRef)
71 : fListener(NULL)
72 , fPrinterEntryRef(entryRef)
77 BPrinter::BPrinter(const BDirectory& directory)
78 : fListener(NULL)
80 SetTo(directory);
84 BPrinter::~BPrinter()
86 StopWatching();
90 status_t
91 BPrinter::SetTo(const BEntry& entry)
93 StopWatching();
94 entry.GetRef(&fPrinterEntryRef);
96 return InitCheck();
100 status_t
101 BPrinter::SetTo(const node_ref& nodeRef)
103 SetTo(BDirectory(&nodeRef));
104 return InitCheck();
108 status_t
109 BPrinter::SetTo(const entry_ref& entryRef)
111 StopWatching();
112 fPrinterEntryRef = entryRef;
114 return InitCheck();
118 status_t
119 BPrinter::SetTo(const BDirectory& directory)
121 StopWatching();
123 BEntry entry;
124 directory.GetEntry(&entry);
125 entry.GetRef(&fPrinterEntryRef);
127 return InitCheck();
131 void
132 BPrinter::Unset()
134 StopWatching();
135 memset(&fPrinterEntryRef, 0, sizeof(entry_ref));
139 bool
140 BPrinter::IsValid() const
142 BDirectory spoolDir(&fPrinterEntryRef);
143 if (spoolDir.InitCheck() != B_OK)
144 return false;
146 BNode node(spoolDir);
147 char type[B_MIME_TYPE_LENGTH];
148 BNodeInfo(&node).GetType(type);
150 if (strcmp(type, PSRV_PRINTER_MIMETYPE) != 0)
151 return false;
153 return true;
157 status_t
158 BPrinter::InitCheck() const
160 BDirectory spoolDir(&fPrinterEntryRef);
161 return spoolDir.InitCheck();
165 bool
166 BPrinter::IsFree() const
168 return (State() == "free");
172 bool
173 BPrinter::IsDefault() const
175 bool isDefault = false;
177 BDirectory spoolDir(&fPrinterEntryRef);
178 if (spoolDir.InitCheck() == B_OK)
179 spoolDir.ReadAttr(PSRV_PRINTER_ATTR_DEFAULT_PRINTER, B_BOOL_TYPE, 0,
180 &isDefault, sizeof(bool));
182 return isDefault;
186 bool
187 BPrinter::IsShareable() const
189 if (Name() == "Preview")
190 return true;
192 return false;
196 BString
197 BPrinter::Name() const
199 return _ReadAttribute(PSRV_PRINTER_ATTR_PRINTER_NAME);
203 BString
204 BPrinter::State() const
206 return _ReadAttribute(PSRV_PRINTER_ATTR_STATE);
210 BString
211 BPrinter::Driver() const
213 return _ReadAttribute(PSRV_PRINTER_ATTR_DRIVER_NAME);
217 BString
218 BPrinter::Comments() const
220 return _ReadAttribute(PSRV_PRINTER_ATTR_COMMENTS);
224 BString
225 BPrinter::Transport() const
227 return _ReadAttribute(PSRV_PRINTER_ATTR_TRANSPORT);
231 BString
232 BPrinter::TransportAddress() const
234 return _ReadAttribute(PSRV_PRINTER_ATTR_TRANSPORT_ADDRESS);
238 status_t
239 BPrinter::DefaultSettings(BMessage& settings)
241 status_t status = B_ERROR;
242 image_id id = _LoadDriver();
243 if (id < 0)
244 return status;
246 typedef BMessage* (*default_settings_func_t)(BNode*);
247 default_settings_func_t default_settings;
248 if (get_image_symbol(id, "default_settings", B_SYMBOL_TYPE_TEXT
249 , (void**)&default_settings) == B_OK) {
250 BNode printerNode(&fPrinterEntryRef);
251 BMessage *newSettings = default_settings(&printerNode);
252 if (newSettings) {
253 status = B_OK;
254 settings = *newSettings;
255 _AddPrinterName(settings);
257 delete newSettings;
259 unload_add_on(id);
260 return status;
264 status_t
265 BPrinter::StartWatching(const BMessenger& listener)
267 StopWatching();
269 if (!listener.IsValid())
270 return B_BAD_VALUE;
272 fListener = new(std::nothrow) BMessenger(listener);
273 if (!fListener)
274 return B_NO_MEMORY;
276 node_ref nodeRef;
277 nodeRef.device = fPrinterEntryRef.device;
278 nodeRef.node = fPrinterEntryRef.directory;
280 return watch_node(&nodeRef, B_WATCH_DIRECTORY, *fListener);
284 void
285 BPrinter::StopWatching()
287 if (fListener) {
288 stop_watching(*fListener);
289 delete fListener;
290 fListener = NULL;
295 BPrinter&
296 BPrinter::operator=(const BPrinter& printer)
298 if (this != &printer) {
299 Unset();
300 fPrinterEntryRef = printer.fPrinterEntryRef;
301 if (printer.fListener)
302 StartWatching(*printer.fListener);
304 return *this;
308 bool
309 BPrinter::operator==(const BPrinter& printer) const
311 return (fPrinterEntryRef == printer.fPrinterEntryRef);
315 bool
316 BPrinter::operator!=(const BPrinter& printer) const
318 return (fPrinterEntryRef != printer.fPrinterEntryRef);
322 status_t
323 BPrinter::_Configure() const
325 status_t status = B_ERROR;
326 image_id id = _LoadDriver();
327 if (id < 0)
328 return status;
330 BString printerName(_ReadAttribute(PSRV_PRINTER_ATTR_PRINTER_NAME));
331 if (printerName.Length() > 0) {
332 typedef char* (*add_printer_func_t)(const char*);
333 add_printer_func_t add_printer;
334 if (get_image_symbol(id, "add_printer", B_SYMBOL_TYPE_TEXT
335 , (void**)&add_printer) == B_OK) {
336 if (add_printer(printerName.String()) != NULL)
337 status = B_OK;
339 } else {
340 status = B_ERROR;
342 unload_add_on(id);
343 return status;
347 status_t
348 BPrinter::_ConfigureJob(BMessage& settings)
350 status_t status = B_ERROR;
351 image_id id = _LoadDriver();
352 if (id < 0)
353 return status;
355 typedef BMessage* (*config_job_func_t)(BNode*, const BMessage*);
356 config_job_func_t configure_job;
357 if (get_image_symbol(id, "config_job", B_SYMBOL_TYPE_TEXT
358 , (void**)&configure_job) == B_OK) {
359 BNode printerNode(&fPrinterEntryRef);
360 BMessage *newSettings = configure_job(&printerNode, &settings);
361 if (newSettings && (newSettings->what == 'okok')) {
362 status = B_OK;
363 settings = *newSettings;
364 _AddPrinterName(settings);
366 delete newSettings;
368 unload_add_on(id);
369 return status;
373 status_t
374 BPrinter::_ConfigurePage(BMessage& settings)
376 status_t status = B_ERROR;
377 image_id id = _LoadDriver();
378 if (id < 0)
379 return status;
381 typedef BMessage* (*config_page_func_t)(BNode*, const BMessage*);
382 config_page_func_t configure_page;
383 if (get_image_symbol(id, "config_page", B_SYMBOL_TYPE_TEXT
384 , (void**)&configure_page) == B_OK) {
385 BNode printerNode(&fPrinterEntryRef);
386 BMessage *newSettings = configure_page(&printerNode, &settings);
387 if (newSettings && (newSettings->what == 'okok')) {
388 status = B_OK;
389 settings = *newSettings;
390 _AddPrinterName(settings);
392 delete newSettings;
394 unload_add_on(id);
395 return status;
399 BPath
400 BPrinter::_DriverPath() const
402 BString driverName(_ReadAttribute(PSRV_PRINTER_ATTR_DRIVER_NAME));
403 if (driverName.Length() <= 0)
404 return BPath();
406 directory_which directories[] = {
407 B_USER_NONPACKAGED_ADDONS_DIRECTORY,
408 B_USER_ADDONS_DIRECTORY,
409 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
410 B_SYSTEM_ADDONS_DIRECTORY
413 BPath path;
414 driverName.Prepend("Print/");
415 for (int32 i = 0; i < sizeof(directories) / sizeof(directories[0]); ++i) {
416 if (find_directory(directories[i], &path) == B_OK) {
417 path.Append(driverName.String());
419 BEntry driver(path.Path());
420 if (driver.InitCheck() == B_OK && driver.Exists() && driver.IsFile())
421 return path;
424 return BPath();
428 image_id
429 BPrinter::_LoadDriver() const
431 BPath driverPath(_DriverPath());
432 if (driverPath.InitCheck() != B_OK)
433 return -1;
435 return load_add_on(driverPath.Path());
439 void
440 BPrinter::_AddPrinterName(BMessage& settings)
442 settings.RemoveName(PSRV_FIELD_CURRENT_PRINTER);
443 settings.AddString(PSRV_FIELD_CURRENT_PRINTER, Name());
447 BString
448 BPrinter::_ReadAttribute(const char* attribute) const
450 BString value;
452 BDirectory spoolDir(&fPrinterEntryRef);
453 if (spoolDir.InitCheck() == B_OK)
454 spoolDir.ReadAttrString(attribute, &value);
456 return value;
460 } // namespace Print
461 } // namespace BPrivate