1 /*****************************************************************************\
2 services.cpp : HP Inkjet Server
3
4 Copyright (c) 2001 - 2004, HP Co.
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3. Neither the name of the Hewlett-Packard nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 NOT LIMITED TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30 \*****************************************************************************/
31
32 #include <sys/stat.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <stdarg.h>
36 #include <syslog.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include "header.h"
41 #include "ijs.h"
42 #include "ijs_server.h"
43 #include "hpijs.h"
44 #include "services.h"
45
46 #if defined(HAVE_LIBHPIP) && defined(HAVE_DBUS)
47 #include <dbus/dbus.h>
48 #define DBUS_INTERFACE "com.hplip.StatusService"
49 #define DBUS_PATH "/"
50 static DBusError dbus_err;
51 static DBusConnection *dbus_conn;
52 void InitDbus (void);
53 void SendDbusMessage (const char *dev, const char *printer, int code,
54 const char *username, const int jobid, const char *title);
55 #else
SendDbusMessage(const char * dev,const char * printer,int code,const char * username,const int jobid,const char * title)56 void SendDbusMessage (const char *dev, const char *printer, int code,
57 const char *username, const int jobid, const char *title)
58 {
59 }
60 #endif
61
InitDuplexBuffer()62 int UXServices::InitDuplexBuffer()
63 {
64 /* Free buffer if new page size in middle of print job. */
65 if (RastersOnPage)
66 delete [] RastersOnPage;
67 if (KRastersOnPage)
68 delete [] KRastersOnPage;
69
70 /* Calculate duplex page buffer */
71 CurrentRaster = ph.height - 1; /* Height = physical page in pixels */
72 RastersOnPage = (BYTE **) new BYTE[(ph.height) * sizeof (BYTE *)];
73 KRastersOnPage = (BYTE **) new BYTE[(ph.height) * sizeof (BYTE *)];
74 for (int i = 0; i < ph.height; i++)
75 {
76 RastersOnPage[i] = NULL;
77 KRastersOnPage[i] = NULL;
78 }
79 return 0;
80 }
81
SendBackPage()82 int UXServices::SendBackPage()
83 {
84 DRIVER_ERROR err;
85 int i = CurrentRaster+1;
86
87 while (i < ph.height)
88 {
89 if (KRGB)
90 {
91 if ((err = pJob->SendRasters(KRastersOnPage[i], RastersOnPage[i])) != NO_ERROR)
92 return err;
93 }
94 else
95 {
96 if ((err = pJob->SendRasters(RastersOnPage[i])) != NO_ERROR)
97 return err;
98 }
99
100 if (RastersOnPage[i])
101 delete [] RastersOnPage[i];
102 if (KRastersOnPage[i])
103 delete [] KRastersOnPage[i];
104 i++;
105 }
106
107 CurrentRaster = ph.height - 1; /* reset raster index */
108
109 return 0;
110 }
111
112 static unsigned char xmask[] =
113 {
114 0x80, /* x=0 */
115 0x40, /* 1 */
116 0x20, /* 2 */
117 0x10, /* 3 */
118 0x08, /* 4 */
119 0x04, /* 5 */
120 0x02, /* 6 */
121 0x01 /* 7 */
122 };
123
ProcessRaster(char * raster,char * k_raster)124 int UXServices::ProcessRaster(char *raster, char *k_raster)
125 {
126 if (!((pPC->QueryDuplexMode() == DUPLEXMODE_BOOK) && pPC->RotateImageForBackPage() && BackPage))
127 {
128 if (KRGB)
129 return pJob->SendRasters((unsigned char *)k_raster, (unsigned char *)raster);
130 else
131 return pJob->SendRasters((unsigned char *)raster);
132 }
133 else
134 {
135 if (CurrentRaster < 0)
136 return -1;
137
138 BYTE *new_raster;
139 int new_raster_size;
140 int i,w;
141
142 if (raster == NULL)
143 {
144 RastersOnPage[CurrentRaster] = NULL;
145 }
146 else
147 {
148 new_raster_size = pPC->InputPixelsPerRow() * 3;
149 new_raster = new BYTE[new_raster_size];
150 if (new_raster == 0)
151 {
152 BUG("unable to create duplex buffer, size=%d: %m\n", new_raster_size);
153 return -1;
154 }
155 memset(new_raster, 0xFF, new_raster_size);
156 RastersOnPage[CurrentRaster] = new_raster;
157 BYTE *p = new_raster + new_raster_size - 3;
158 for (i = 0; i < new_raster_size; i += 3)
159 {
160 memcpy (p, raster+i, 3); /* rotate rgb image */
161 p -= 3;
162 }
163 }
164
165 if (k_raster == NULL)
166 {
167 KRastersOnPage[CurrentRaster] = NULL;
168 }
169 else
170 {
171 new_raster_size = (pPC->InputPixelsPerRow() + 7) >> 3;
172 new_raster = new BYTE[new_raster_size];
173 if (new_raster == 0)
174 {
175 BUG("unable to create black duplex buffer, size=%d: %m\n", new_raster_size);
176 return -1;
177 }
178 memset(new_raster, 0, new_raster_size);
179 KRastersOnPage[CurrentRaster] = new_raster;
180 w = pPC->InputPixelsPerRow();
181 for (i=0; i<w; i++)
182 {
183 if (k_raster[i>>3] & xmask[i&7])
184 new_raster[(w-i)>>3] |= xmask[(w-i)&7]; /* rotate k image */
185 }
186 int k = ((w + 7) / 8) * 8 - w;
187 BYTE c = 0xff << k;
188 if (k != 0)
189 new_raster[0] = c & k_raster[new_raster_size-1];
190 }
191
192 CurrentRaster--;
193
194 return 0;
195 }
196 }
197
198
199 #ifdef HAVE_LIBHPIP
200
201 /*
202 * Check models.xml for bi-di flag and also check the
203 * device id string for integrity. Some devices return
204 * device id without some expected fields.
205 *
206 */
CanDoBiDi()207 BOOL UXServices::CanDoBiDi ()
208 {
209 char *hpDev;
210 struct hpmud_model_attributes ma;
211 char strDevID[512];
212
213 // Check for CUPS environment
214
215 if ((hpDev = getenv ("DEVICE_URI")) == NULL)
216 {
217 return FALSE;
218 }
219
220 // Check for HP Backend
221
222 if (strncmp (hpDev, "hp:", 3))
223 {
224 return FALSE;
225 }
226
227 // Check io-mode in models.xml for this device
228
229 hpmud_query_model(hpDev, &ma);
230
231 if (ma.prt_mode == HPMUD_UNI_MODE)
232 {
233 return FALSE;
234 }
235 if (hpmud_open_device(hpDev, ma.prt_mode, &hpFD) != HPMUD_R_OK)
236 {
237 return FALSE;
238 }
239 memset (strDevID, 0, 512);
240 if ((ReadDeviceID ((BYTE *) strDevID, 512)) != NO_ERROR)
241 {
242 return FALSE;
243 }
244
245 // Check if this is a laser device
246 if (strstr (strDevID, "Laser") || strstr (strDevID, "laser"))
247 {
248 return TRUE;
249 }
250
251 // Check if device id is complete
252 if (!(strstr (strDevID, ";S:")) && !(strstr (strDevID, "VSTATUS")))
253 {
254 return FALSE;
255 }
256 return TRUE;
257 }
258
259 #else
260
CanDoBiDi()261 BOOL UXServices::CanDoBiDi ()
262 {
263 return FALSE;
264 }
265
266 #endif // HAVE_LIBHPIP
267
UXServices()268 UXServices::UXServices():SystemServices()
269 {
270 constructor_error = NO_ERROR;
271 hpFD = -1;
272
273 // instead of InitDeviceComm(), just do...
274 IOMode.bDevID = IOMode.bStatus = FALSE; /* uni-di support is default */
275
276 #if 0 // Old code
277
278 /* Check for CUPS environment and HP backend. */
279 if ((hpDev = getenv("DEVICE_URI")) != NULL)
280 {
281 if (strncmp(hpDev, "hp:", 3) == 0)
282 {
283 hplip_Init();
284 hplip_ModelQuery(hpDev, &ma); /* check io-mode in models.xml for this device */
285 if (ma.prt_mode != UNI_MODE)
286 {
287 if ((hpFD = hplip_OpenHP(hpDev, &ma)) >= 0)
288 {
289 InitDeviceComm(); /* lets try bi-di support */
290 }
291 if(IOMode.bDevID == FALSE)
292 BUG("unable to set bi-di for hp backend\n");
293 }
294 }
295 }
296
297 #endif // Old code
298
299 if (CanDoBiDi ())
300 {
301 InitDeviceComm ();
302 if (IOMode.bDevID == FALSE)
303 {
304 BUG ("Unable to set bi-di for hp backend\n");
305 }
306 }
307
308 Quality = QUALITY_NORMAL;
309 MediaType = MEDIA_PLAIN;
310 ColorMode = COLOR;
311 PenSet = DUMMY_PEN;
312
313 RastersOnPage = 0;
314 KRastersOnPage = 0;
315 pPC = NULL;
316 pJob = NULL;
317 Duplex = 0;
318 Tumble = 0;
319 FullBleed = 0;
320 FirstRaster = 1;
321 MediaPosition = sourceTrayAuto;
322 Model = -1;
323 strcpy(ph.cs, "sRGB");
324 VertAlign = -1;
325 DisplayStatus = NODISPLAYSTATUS;
326 OutputPath = -1;
327 outfp = NULL;
328 m_iLogLevel = 0;
329
330 m_pbyPclBuffer = NULL;
331 m_iPclBufferSize = BUFFER_CHUNK_SIZE;
332 m_iCurPclBufferPos = 0;
333 m_iPageCount = 0;
334 m_bSpeedMechEnabled = FALSE;
335 }
336
~UXServices()337 UXServices::~UXServices()
338 {
339 if (m_bSpeedMechEnabled)
340 {
341 SendLastPage ();
342 }
343
344 if (RastersOnPage)
345 delete [] RastersOnPage;
346 if (KRastersOnPage)
347 delete [] KRastersOnPage;
348 #ifdef HAVE_LIBHPIP
349 if (hpFD >= 0)
350 hpmud_close_device(hpFD);
351 #endif
352 if (outfp)
353 {
354 fclose (outfp);
355 }
356 }
357
ToDevice(const BYTE * pBuffer,DWORD * Count)358 DRIVER_ERROR UXServices::ToDevice(const BYTE * pBuffer, DWORD * Count)
359 {
360 if (OutputPath == -1)
361 {
362 return IO_ERROR;
363 }
364
365 if (m_bSpeedMechEnabled)
366 {
367 if ((CopyData (pBuffer, *Count)) == 0)
368 {
369 *Count = 0;
370 return NO_ERROR;
371 }
372 }
373
374 if (outfp)
375 {
376 fwrite (pBuffer, 1, *Count, outfp);
377 if (!(m_iLogLevel & SEND_TO_PRINTER))
378 {
379 *Count = 0;
380 return NO_ERROR;
381 }
382 }
383
384 /* Write must be not-buffered, don't use streams */
385 if (write(OutputPath, pBuffer, *Count) != (ssize_t)*Count)
386 {
387 static int cnt=0;
388 if (cnt++ < 5)
389 BUG("unable to write to output, fd=%d, count=%d: %m\n", OutputPath, *Count);
390 return IO_ERROR;
391 }
392
393 *Count = 0;
394 return NO_ERROR;
395 }
396
GetStatusInfo(BYTE * bStatReg)397 BOOL UXServices::GetStatusInfo (BYTE * bStatReg)
398 {
399 #ifdef HAVE_LIBHPIP
400 unsigned int s;
401 if (hpmud_get_device_status(hpFD, &s) == HPMUD_R_OK)
402 {
403 *bStatReg = (BYTE)s;
404 return TRUE;
405 }
406 #endif
407 return FALSE;
408 }
409
ReadDeviceID(BYTE * strID,int iSize)410 DRIVER_ERROR UXServices::ReadDeviceID (BYTE * strID, int iSize)
411 {
412 #ifdef HAVE_LIBHPIP
413 int len;
414 hpmud_get_device_id(hpFD, (char *)strID, iSize, &len);
415 if (len < 3)
416 return IO_ERROR;
417 #endif
418 return NO_ERROR;
419 }
420
421 #ifdef HP_PRINTVIEW
422 const char *szPJLHeader = "@PJL SET JOBATTR=\"JobAcct7=HPPrintView.exe\"\012";
GetPJLHeaderBuffer(char ** szPJLBuffer)423 int UXServices::GetPJLHeaderBuffer (char **szPJLBuffer)
424 {
425 *szPJLBuffer = (char *) szPJLHeader;
426 return strlen (szPJLHeader);
427 }
428 #endif // HP_PRINTVIEW
429
GetVerticalAlignmentValue(BYTE * cVertAlignVal)430 BOOL UXServices::GetVerticalAlignmentValue(BYTE* cVertAlignVal)
431 {
432 if (VertAlign == -1)
433 return FALSE;
434
435 *cVertAlignVal = (BYTE)VertAlign;
436 return TRUE;
437 }
438
GetVertAlignFromDevice()439 BOOL UXServices::GetVertAlignFromDevice()
440 {
441 #ifdef HAVE_LIBHPIP
442 if ((VertAlign = ReadHPVertAlign(hpFD)) == -1)
443 return FALSE;
444 #endif
445 return TRUE;
446 }
447
DisplayPrinterStatus(DISPLAY_STATUS ePrinterStatus)448 void UXServices::DisplayPrinterStatus (DISPLAY_STATUS ePrinterStatus)
449 {
450 DisplayStatus = ePrinterStatus;
451 }
452
BusyWait(DWORD msec)453 DRIVER_ERROR UXServices::BusyWait (DWORD msec)
454 {
455 switch (DisplayStatus)
456 {
457 case DISPLAY_ERROR_TRAP:
458 case DISPLAY_COMM_PROBLEM:
459 case DISPLAY_PRINTER_NOT_SUPPORTED:
460 case DISPLAY_OUT_OF_PAPER:
461 case DISPLAY_PHOTOTRAY_MISMATCH:
462 case DISPLAY_TOP_COVER_OPEN:
463 case DISPLAY_NO_COLOR_PEN:
464 case DISPLAY_NO_BLACK_PEN:
465 case DISPLAY_NO_PENS:
466 BUG("WARNING: printer bi-di error=%d\n", DisplayStatus);
467 DisplayStatus = DISPLAY_PRINTING_CANCELED;
468 return JOB_CANCELED; /* bail-out otherwise APDK will wait forever */
469 default:
470 break;
471 }
472 return NO_ERROR;
473 }
474
GetDriverMessage(DRIVER_ERROR err)475 const char * UXServices::GetDriverMessage (DRIVER_ERROR err)
476 {
477 const char *p=NULL;
478
479 /* Map driver error to text message. TODO: text needs to be localized. */
480 switch(err)
481 {
482 case(WARN_MODE_MISMATCH):
483 p = "printmode mismatch with pen, tray, etc.";
484 break;
485 case(WARN_LOW_INK_BOTH_PENS):
486 p = "both pens have low ink";
487 break;
488 case(WARN_LOW_INK_BLACK):
489 p = "black pen has low ink";
490 break;
491 case(WARN_LOW_INK_COLOR):
492 p = "color pen has low ink";
493 break;
494 case(WARN_LOW_INK_PHOTO):
495 p = "photo pen has low ink";
496 break;
497 case(WARN_LOW_INK_GREY):
498 p = "grey pen has low ink";
499 break;
500 case(WARN_LOW_INK_BLACK_PHOTO):
501 p = "black photo has low ink";
502 break;
503 case(WARN_LOW_INK_COLOR_PHOTO):
504 p = "color photo pen has low ink";
505 break;
506 case(WARN_LOW_INK_GREY_PHOTO):
507 p = "grey photo pen has low ink";
508 break;
509 case(WARN_LOW_INK_COLOR_GREY):
510 p = "grey pen has low ink";
511 break;
512 case(WARN_LOW_INK_COLOR_GREY_PHOTO):
513 p = "color grey photo pen has low ink";
514 break;
515 case(WARN_LOW_INK_COLOR_BLACK_PHOTO):
516 p = "color back pen has low ink";
517 break;
518 case(WARN_LOW_INK_CYAN):
519 p = "cyan has low ink";
520 break;
521 case(WARN_LOW_INK_MAGENTA):
522 p = "magenta has low ink";
523 break;
524 case(WARN_LOW_INK_YELLOW):
525 p = "yellow has low ink";
526 break;
527 case(WARN_LOW_INK_MULTIPLE_PENS):
528 p = "more that one ink is low";
529 break;
530 case(WARN_FULL_BLEED_UNSUPPORTED):
531 p = "fullbleed is not supported";
532 break;
533 case(WARN_FULL_BLEED_3SIDES):
534 p = "fullbleed is 3 sides";
535 break;
536 case(WARN_FULL_BLEED_PHOTOPAPER_ONLY):
537 p = "fullbleed photo paper only";
538 break;
539 case(WARN_FULL_BLEED_3SIDES_PHOTOPAPER_ONLY):
540 p = "fullbleed 3 sides photo paper only";
541 break;
542 case(WARN_ILLEGAL_PAPERSIZE):
543 p = "illegal paper size";
544 break;
545 case(WARN_INVALID_MEDIA_SOURCE):
546 p = "invalid media source";
547 break;
548 default:
549 p = "driver error";
550 BUG("driver error=%d\n", err);
551 break;
552 }
553 return p;
554 }
555
MapPaperSize(float width,float height)556 int UXServices::MapPaperSize (float width, float height)
557 {
558 int i, r, size;
559 float dx, dy;
560
561 /* Map gs paper sizes to APDK paper sizes, or do custom. */
562 size = CUSTOM_SIZE;
563 for (i=0; i<MAX_PAPER_SIZE; i++)
564 {
565 r = pPC->SetPaperSize ((PAPER_SIZE)i);
566
567 if (r != NO_ERROR)
568 continue;
569
570 dx = width > pPC->PhysicalPageSizeX () ? width - pPC->PhysicalPageSizeX () : pPC->PhysicalPageSizeX () - width;
571 dy = height > pPC->PhysicalPageSizeY () ? height - pPC->PhysicalPageSizeY () : pPC->PhysicalPageSizeY () - height;
572
573 if ((dx < 0.05) && (dy < 0.05))
574 {
575 size = i; /* found standard paper size */
576 break;
577 }
578 }
579
580 if (size == CUSTOM_SIZE)
581 pPC->SetCustomSize (width, height);
582
583 if ((r = pPC->SetPaperSize ((PAPER_SIZE)size, FullBleed)) != NO_ERROR)
584 {
585 if (r > 0)
586 {
587 BUG("unable to set paper size=%d, err=%d, width=%0.5g, height=%0.5g\n", size, r, width, height);
588 }
589 else
590 {
591 BUG("warning setting paper size=%d, err=%d, width=%0.5g, height=%0.5g\n", size, r, width, height);
592 }
593 /*
594 * Call failed, reset our PaperWidth and PaperHeight values.
595 * This ensures that we return correct values when gs queries for printable area.
596 */
597
598 PaperWidth = pPC->PhysicalPageSizeX ();
599 PaperHeight = pPC->PhysicalPageSizeY ();
600 return -1;
601 }
602
603 PaperWidth = pPC->PhysicalPageSizeX ();
604 PaperHeight = pPC->PhysicalPageSizeY ();
605
606 return 0;
607 }
608
ResetIOMode(BOOL bDevID,BOOL bStatus)609 void UXServices::ResetIOMode (BOOL bDevID, BOOL bStatus)
610 {
611 if (pPC)
612 {
613 IOMode.bDevID = bDevID;
614 IOMode.bStatus = bStatus;
615 pPC->ResetIOMode (bDevID, bStatus);
616 }
617 }
618
InitSpeedMechBuffer()619 void UXServices::InitSpeedMechBuffer ()
620 {
621 if (m_pbyPclBuffer)
622 {
623 return;
624 }
625 m_pbyPclBuffer = new BYTE[m_iPclBufferSize + 2];
626 if (m_pbyPclBuffer)
627 {
628 iSendBufferSize = 0;
629 }
630 }
631
SendPreviousPage()632 int UXServices::SendPreviousPage ()
633 {
634 DRIVER_ERROR err;
635 if (m_bSpeedMechEnabled == FALSE)
636 {
637 return 0;
638 }
639 m_iPageCount++;
640 if (m_iPageCount == 1)
641 {
642 return 0;
643 }
644 m_bSpeedMechEnabled = FALSE;
645 err = ToDevice (m_pbyPclBuffer, (DWORD *) &m_iCurPclBufferPos);
646 if (err != NO_ERROR)
647 {
648 return 1;
649 }
650 m_bSpeedMechEnabled = TRUE;
651 m_iCurPclBufferPos = 0;
652
653 // Request the printer to inject speed mech command. Also, let it know this is not the last page
654
655 pPC->SetPrinterHint (SPEED_MECH_HINT, 0);
656 return 0;
657 }
658
CopyData(const BYTE * pBuffer,DWORD iCount)659 int UXServices::CopyData (const BYTE *pBuffer, DWORD iCount)
660 {
661 if (m_iCurPclBufferPos + (int) iCount < m_iPclBufferSize)
662 {
663 memcpy (m_pbyPclBuffer + m_iCurPclBufferPos, pBuffer, iCount);
664 m_iCurPclBufferPos += iCount;
665 return 0;
666 }
667 BYTE *p = new BYTE[m_iPclBufferSize + BUFFER_CHUNK_SIZE + 2];
668 if (p == NULL)
669 {
670 m_bSpeedMechEnabled = FALSE;
671 return 1;
672 }
673 memcpy (p, m_pbyPclBuffer, m_iCurPclBufferPos);
674 delete [] m_pbyPclBuffer;
675 m_pbyPclBuffer = p;
676 memcpy (m_pbyPclBuffer + m_iCurPclBufferPos, pBuffer, iCount);
677 m_iCurPclBufferPos += iCount;
678 m_iPclBufferSize += BUFFER_CHUNK_SIZE;
679 return 0;
680 }
681
682 // Note that this is good only for VIP printers
683 const char *pbySpeedMechCmd = "\x1B*o5W\x0D\x02\x00";
684
SendLastPage()685 void UXServices::SendLastPage ()
686 {
687 if (m_pbyPclBuffer == NULL)
688 {
689 return;
690 }
691 // Look for speed mech command in the buffer, set the page count and last page flag
692 int i = 0;
693 BYTE *p = m_pbyPclBuffer;
694 while (i < m_iPclBufferSize)
695 {
696 if (*p == '\x1B')
697 {
698 if (!(memcmp (p, pbySpeedMechCmd, 8)))
699 {
700 p += 8;
701 *p++ = (BYTE) ((m_iPageCount & 0xFF00) >> 8);
702 *p++ = (BYTE) ((m_iPageCount & 0x00FF));
703 *(p + 9) = 1;
704 break;
705 }
706 }
707 i++;
708 p++;
709 }
710 m_bSpeedMechEnabled = FALSE;
711 ToDevice (m_pbyPclBuffer, (DWORD *) &m_iCurPclBufferPos);
712 delete [] m_pbyPclBuffer;
713 }
714
715 #if defined(HAVE_LIBHPIP) && defined(HAVE_DBUS)
SendDbusMessage(const char * dev,const char * printer,int code,const char * username,const int jobid,const char * title)716 void SendDbusMessage (const char *dev, const char *printer, int code,
717 const char *username, const int jobid, const char *title)
718 {
719 DBusMessage * msg = NULL;
720
721 InitDbus ();
722 if (dbus_conn == NULL)
723 return;
724 msg = dbus_message_new_signal(DBUS_PATH, DBUS_INTERFACE, "Event");
725
726 if (NULL == msg)
727 {
728 BUG("dbus message is NULL!\n");
729 return;
730 }
731
732 dbus_message_append_args(msg,
733 DBUS_TYPE_STRING, &dev,
734 DBUS_TYPE_STRING, &printer,
735 DBUS_TYPE_UINT32, &code,
736 DBUS_TYPE_STRING, &username,
737 DBUS_TYPE_UINT32, &jobid,
738 DBUS_TYPE_STRING, &title,
739 DBUS_TYPE_INVALID);
740
741 if (!dbus_connection_send(dbus_conn, msg, NULL))
742 {
743 BUG("dbus message send failed!\n");
744 return;
745 }
746
747 dbus_connection_flush(dbus_conn);
748 dbus_message_unref(msg);
749
750 return;
751 }
752
InitDbus(void)753 void InitDbus (void)
754 {
755 dbus_error_init (&dbus_err);
756 dbus_conn = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_err);
757
758 if (dbus_error_is_set (&dbus_err))
759 {
760 BUG ("dBus Connection Error (%s)!\n", dbus_err.message);
761 dbus_error_free (&dbus_err);
762 }
763
764 return;
765 }
766 #endif /* HAVE_DBUS */
767
768
769