Stampare un file con le funzioni del API di cups

Da Gambas-it.org - Wikipedia.

Per stampare un file con le funzioni esterne del API di CUPS (Common Unix Printing System), e dunque senza l'uso della Classe Printer, bisognerà richiamare l'attuale libreria esterna: libcups.so.2 .


Mostriamo di seguito due esempi pratici; un semplice e breve codice per stampare un solo file:

Public Struct Cups_option_s     ' Opzioni di stampa
  name As Pointer               ' Nome dell'opzione
  value As Pointer	        ' Valore dell'opzione
End Struct

Library "libcups:2"

' int cupsGetDests(cups_dest_t **dests)
Private Extern cupsGetDests(dests As Pointer) As Integer

' int cupsPrintFile(const char *printer, const char *filename, const char *title, int num_options, cups_option_t *options)
Private Extern cupsPrintFile(stampante As String, nomefile As String, titolo As String, num_opzioni As Integer, opzioni As Cups_option_s) As Integer


Public Sub Main()

 Dim stamp_Def, predef As String
 Dim num_dests, err As Integer
 Dim p, pstmp As Pointer
 Dim st As Stream
 Dim b, j As Byte


  num_dests = cupsGetDests(VarPtr(p))

  Print "Sono state riscontrate installate nel sistema num. "; num_dests; " stampanti:\n"

' Dereferenziando la variabile di tipo "Puntatore" si ottengono i nomi delle stampanti installate.
' In particolare ciascun nome è uguale a quello del file .ppd afferente alla stampante installata,
' presente nella cartella "/etc/cups/ppd" e privo della sua estensione.
' Il nome della stampante andrà passato, come primo argomento, alla funzione "cupsPrintFile()".
  st = Memory p For Read
 
  For b = 0 To num_dests - 1
    Seek #st, b * 32
    Read #st, pstmp
    Seek #st, Seek(st) + 8
    Read #st, j
    If j = 1 Then
      stamp_Def = String@(pstmp)
      predef = " - Default\n"
    Endif
' Mostriamo in console il nome delle stampanti trovate installate nel sistema:
    Print b + 1, String@(pstmp) & predef
  Next

' In questo esempio passiamo alla funzione "cupsPrintFile()" il nome della stampante 'predefinita' trovata:
  Print "Stampa sulla stampante: "; stamp_Def

  st.Close()
 
  err = cupsPrintFile(stamp_Def, "/percorso/del/file/da/stampare/", "Breve titolo qualsiasi", 0, Null)
  If err = 0 then Error.Raise("Stampa del file fallita !")

End


ed un altro un po' più complesso che utilizza altre funzioni esterne di CUPS rispetto al precedente esempio:

Public Struct Cups_option_s     ' Opzioni di stampa
  name As Pointer               ' Nome dell'opzione
  value As Pointer	        ' Valore dell'opzione
End Struct

Public Struct cups_dest_s
  name As Pointer
  instance As Pointer
  is_default As Integer
  num_options As Integer
  options As Cups_option_s
End Struct


Library "libcups:2"

Private Const CUPS_HTTP_DEFAULT As Integer = 0
Private Const HTTP_CONTINUE As Integer = 100
Private Const CUPS_FORMAT_AUTO As String = "application/octet-stream"


' cups_file_t *cupsFileOpen(const char *filename, const char *mode)
' Open a CUPS file.
Private Extern cupsFileOpen(filename As String, mode As String) As Pointer

' int cupsCreateJob(http_t *http, const char *name, const char *title, int num_options, cups_option_t *options)
' Create an empty job for streaming.
Private Extern cupsCreateJob(http As Pointer, name As String, title As String, num_options As Integer, options As Cups_option_s) As Integer

' http_status_t cupsStartDocument(http_t *http, const char *name, int job_id, const char *docname, const char *format, int last_document)
' Add a document to a job created with cupsCreateJob().
Private Extern cupsStartDocument(http As Pointer, name As String, jobI As Integer, docname As String, format$ As String, last_document As Integer) As Integer

' ssize_t cupsFileRead(cups_file_t *fp, char *buf, size_t bytes)
' Read from a file.
Private Extern cupsFileRead(fp As Pointer, buf As Byte[], size_t As Integer) As Integer

' http_status_t cupsWriteRequestData(http_t *http, const char *buffer, size_t length)
' Write additional data after an IPP request.
Private Extern cupsWriteRequestData(http As Pointer, buf As Byte[], length As Integer) As Integer

' ipp_status_t cupsFinishDocument(http_t *http, const char *name)
' Finish sending a document.
Private Extern cupsFinishDocument(http As Pointer, name As String) As Integer

' cups_dest_t *cupsGetNamedDest(http_t *http, const char *name, const char *instance)
' Get options for the named destination.
Private Extern cupsGetNamedDest(http As Pointer, name As String, instance As String) As Cups_dest_s


Public Sub Main()

 Dim cups_file As Pointer
 Dim fl, stampante As String
 Dim id, http_stato, byte As Integer
 Dim buffer As Byte[]                        ' Buffer di lettura/scrittura
 Dim dest As New Cups_dest_s
 
 
  fl = "/percorso/del/file/da/stampare"
  stampante = "nome_della_stampante"
 
  cups_file = cupsFileOpen(fl, "r")
  If IsNull(cups_file) Then Error.Raise("Impossibile aprire il file !")
   
  id = cupsCreateJob(CUPS_HTTP_DEFAULT, stampante, "testo qualsiasi", 0, Null)
  If id <= 0 Then Error.Raise("Impossibile stampare con 'Canon-BJ-200' !")
  Print "Processo di stampa num. "; id

  http_stato = cupsStartDocument(CUPS_HTTP_DEFAULT, stampante, id, "nome documento", CUPS_FORMAT_AUTO, 1)
  If http_stato <> HTTP_CONTINUE Then Error.Raise("Impossibile avviare la stampa del documento !")
   
  buffer = New Byte[Stat(fl).Size]
   
  byte = cupsFileRead(cups_file, buffer, buffer.Count)
  While byte > 0

    If cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, byte) <> HTTP_CONTINUE Then Error.Raise("Impossibile scrivere byte !")

    Wait 0.5
     
    byte = cupsFileRead(cups_file, buffer, buffer.Count)
     
  Wend
   
   
  cupsFinishDocument(CUPS_HTTP_DEFAULT, stampante)
   
  dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, Null, Null)
  Print "Stampa del documento su: "; String@(dest.name)
  
End



Riferimenti