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)
' Get the list of destinations from the default server.
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)
' Print a file to a printer or class on the default server.
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, stampa 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()".
  For b = 1 To num_dests
    stampa = String@(Pointer@(p))
    p = p + 16
    If Byte@(p) = 1 Then
      stamp_Def = stampa
      predef = " - Default\n"
    Endif
' Mostriamo in console il nome delle stampanti trovate installate nel sistema:
    Print b, stampa & predef
    predef = Null
    p = p + 16
  Next
  

' Se, invece, volessimo usare i "Memory Stream":
  ' 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
    ' Print b + 1, String@(pstmp) & predef
    ' predef = Null
  ' Next
  '
  ' st.Close()


' In questo esempio passiamo alla funzione "cupsPrintFile()" il nome della stampante 'predefinita' trovata:
  Print "\nStampa sulla stampante: "; stamp_Def
 
  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. E' necessario inserire nella variabile "stampante" il nome della

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"

' int cupsGetDests(cups_dest_t **dests)
' Get the list of destinations from the default server.
Private Extern cupsGetDests(dests As Pointer) As Integer

' 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 p, cups_file As Pointer
 Dim num_dests As Integer
 Dim b As Byte
 Dim fl, stampa, predef, 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"

  num_dests = cupsGetDests(VarPtr(p))
  Print "Sono state riscontrate installate nel sistema num. "; num_dests; " stampanti:\n"

  For b = 1 To num_dests
    stampa = String@(Pointer@(p))
    p = p + 16
    If Byte@(p) = 1 Then
      stampante = stampa
      predef = " - Default\n"
    Endif
' Mostriamo in console il nome delle stampanti trovate installate nel sistema:
    Print b, stampa & predef
    predef = Null
    p = p + 16
  Next
  
  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 '" & stampante & "' !")
  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