Setting default printer API

Linux specific forum
fromVB
User
User
Posts: 81
Joined: Sun Jul 29, 2012 2:27 am

Setting default printer API

Post by fromVB »

Anyone familiar with the CUPS API can help me with using this function to set the default printer:

cupsSetDefaultDest

http://www.mit.edu/~mkgray/project/silk ... efaultDest

Thank you in advance!
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Setting default printer API

Post by Oma »

Hi,
i'm really not familiar with cups, but
- installing the devel files in a terminal with

Code: Select all

sudo apt-get install --assume-yes libcups2 libcups2-dev
- and running this code

Code: Select all

EnableExplicit

Import "-lcups"
	cupsGetDefault()
EndImport

Global.i gStdPrt

If OpenWindow(0, 300, 200, 200, 200, "Cups Get StdPrinter", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	
	gStdPrt= cupsGetDefault()
	If gStdPrt
		Debug PeekS(gStdPrt, -1, #PB_UTF8)
	Else
		Debug "none"
	EndIf
	
	Repeat
	Until WaitWindowEvent()= #PB_Event_CloseWindow
EndIf
gave me 'hp-LaserJet-1150' in the Debug-window.
Maybe this helps a little with your first contact :wink: .

Best Regards, Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Setting default printer API

Post by Oma »

Hi!
Though it will not be of interest any longer, i'll post this sources before they get moldy. :wink:

2 solutions as demos to query cups printers / options and set a default printer (used as default by the PrintRequester too)

- The first one uses terminal-commands (no dev-files needed, has a much simpler handling but some string-parsing is required)
- The sec. one uses Cups-API (Dev-Files must be installed for access)

There are 2 Default-Printers:
- The 1. i call "user-default" which is the default printer in Requesters and is 'heart'-ed in e.g. Xubuntu/Mint printer-dialog.
- The 2. i call "server-default" which is 'checked' in all printer-dialogs
However, i've figured out nothing about the detailed difference. :|

May be, that the routines work also on the Mac after slight corrections. :?:
(A extensive printer query for Gtk-API is currently in progress. If you're interested please send an PM.)

Demo with terminal-commands

Code: Select all

;Omi, 03.04.2016
; Linux only ? 
; Query Cups printers & options, get User-default printer with terminal-commands
; Set user-default and server-default printer
; (Querying the server-printer-name needs Cups-API)
; No installations required
;
; A similar code for Cups-API and a extensive printer query for Gtk-API is currently in progress.
;  if you're interested please send an PM.
;
; You need a 2. printer for a test? Install Cups-Pdf: "sudo apt-get install cups-pdf"

EnableExplicit

Enumeration
	#CupsNPrinter
	#CupsListPrinters
	#CupsListOptions
	#CupsSetUserDef
	#CupsSetServerDef
EndEnumeration

Global.i gEvent, gQuit
Global.i gNPrinters
Global.s gDefaultPrinterName

Procedure.s RunProgram_GetOutput(Command.s, Parameter.s, Path.s, OpenRead.i)
	Protected.i ProgramId
	Protected.s PrgOut= ""
	
	ProgramId= RunProgram(Command, Parameter, Path, OpenRead)
	If ProgramId
		While ProgramRunning(ProgramId)
			If AvailableProgramOutput(ProgramId)
				PrgOut + ReadProgramString(ProgramId) + #LF$
			EndIf
		Wend
	EndIf
	ProcedureReturn PrgOut
EndProcedure

Procedure Cups_GetOptionsForPrinter(PrinterName.s, LIG_Options)
	Protected.i I, O, PosTemp
	Protected.s PrgOutAll= "", PrgOutLine, Options
	
	;Options for PrinterName
	PrgOutAll= RunProgram_GetOutput("lpoptions", "-p " + PrinterName + " -l", "", #PB_Program_Open | #PB_Program_Read)
	
	ClearGadgetItems(LIG_Options)
	If PrgOutAll <> ""
		For I= 1 To CountString(PrgOutAll, #LF$)+ 1;                            entries with name & options line by line
			PrgOutLine= StringField(PrgOutAll, I, #LF$);                          whole line
			PosTemp   = FindString(PrgOutLine, ": ")
			If PosTemp
				AddGadgetItem(LIG_Options, -1, Left(PrgOutLine, PosTemp+ 1));       option name
				PrgOutLine= Mid(PrgOutLine, PosTemp+ 2)
				Options   = ""
				For O= 1 To CountString(PrgOutLine, " ")+ 1
					Options+ StringField(PrgOutLine, O, " ")+ #LF$;                   split option values
				Next O
				Options= RTrim(Options, #LF$)
				SetGadgetItemText(LIG_Options, CountGadgetItems(LIG_Options)- 1, Options, 1)
			EndIf
		Next I
	EndIf
EndProcedure

Procedure Cups_ListPrinters(LIG_Printers)
	Protected.i I, PosTemp
	Protected.s PrgOutAll= "", PrgOutLine, PrinterName
	
	;list printer names
	PrgOutAll= RunProgram_GetOutput("lpstat", "-p", "", #PB_Program_Open | #PB_Program_Read)
	
	If PrgOutAll <> ""
		gNPrinters= CountString(PrgOutAll, #LF$)
		For I= 1 To gNPrinters
			PrgOutLine= StringField(PrgOutAll, I, #LF$);                                  printers line by line
			PosTemp   = FindString(PrgOutLine, "printer ")
			If PosTemp
				PrinterName= Mid(PrgOutLine, PosTemp+ 8, FindString(PrgOutLine, " is")- 9); extract printer name
				AddGadgetItem(LIG_Printers, -1, PrinterName)
			EndIf
		Next I
	EndIf
EndProcedure

Procedure Cups_MarkDefaultPrinter(LIG_Printers)
	Protected.i I
	Protected.s PrgOutAll= ""
	
	;Query user default printer names
	PrgOutAll= RunProgram_GetOutput("lpstat", "-d", "", #PB_Program_Open | #PB_Program_Read)
	
	If FindString(PrgOutAll, "system default destination: ")
		PrgOutAll= RTrim(Mid(PrgOutAll, 29), #LF$)
		For I= 0 To CountGadgetItems(LIG_Printers)- 1
			If GetGadgetItemText(LIG_Printers, I, 0) = PrgOutAll
				SetGadgetItemText(LIG_Printers, I, "1", 1)
				gDefaultPrinterName= PrgOutAll
			Else
				SetGadgetItemText(LIG_Printers, I, "0", 1)
			EndIf
		Next I
	EndIf
EndProcedure

Procedure Cups_SetDefaultUserPrinter(LIG_Printers)
	Protected.i I
	
	;Set user default printer from name
	If RunProgram("lpoptions", "-d " + GetGadgetItemText(LIG_Printers, GetGadgetState(LIG_Printers), 0), "");            set user default printer from name, e.g. 'hp-LaserJet-1150'
		For I= 0 To CountGadgetItems(LIG_Printers)- 1
			If I = GetGadgetState(LIG_Printers)
				SetGadgetItemText(LIG_Printers, I, "1", 1)
				gDefaultPrinterName= GetGadgetItemText(LIG_Printers, I, 1)
			Else
				SetGadgetItemText(LIG_Printers, I, "0", 1)
			EndIf
		Next I
	EndIf
EndProcedure

Procedure Cups_SetDefaultServerPrinter(LIG_Printers)
	;Set server default printer from name
	RunProgram("lpadmin", "-d " + GetGadgetItemText(LIG_Printers, GetGadgetState(LIG_Printers), 0), "");                 set server default printer from name, e.g. 'pdf'
EndProcedure


If OpenWindow(0, 300, 200, 800, 320, "Cups printers: List & set default", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	TextGadget(#PB_Any,                   5,  10, 400,  22, "Cups printers with console commands: ")
	TextGadget(#CupsNPrinter,             5,  35, 170,  22, "")
	ListIconGadget(#CupsListPrinters,     5,  60, 350, 170, "Printer name", 250, #PB_ListIcon_GridLines)
	AddGadgetColumn(#CupsListPrinters,    2, "User-Default", 70)
	gtk_tree_selection_set_mode_(gtk_tree_view_get_selection_(GadgetID(#CupsListPrinters)), #GTK_SELECTION_BROWSE)
	
	ListIconGadget(#CupsListOptions,    360,  60, 430, 244, "Option name:", 250, #PB_ListIcon_GridLines)
	AddGadgetColumn(#CupsListOptions,     1, "Value:",  130)
	gtk_tree_selection_set_mode_(gtk_tree_view_get_selection_(GadgetID(#CupsListOptions)), #GTK_SELECTION_NONE)
	
	ButtonGadget(#CupsSetUserDef,         5, 240, 350,  28, "Selected printer as user default")
	ButtonGadget(#CupsSetServerDef,       5, 275, 350,  28, "Selected printer as server default")
	
	Cups_ListPrinters(#CupsListPrinters)
	Cups_MarkDefaultPrinter(#CupsListPrinters)
	SetGadgetText(#CupsNPrinter, "Listed Cups printers: "+ Str(gNPrinters))
	
	GadgetToolTip(#CupsSetUserDef,   "The presetted printer in requesters." + #LF$ + "E.g. 'hearted' in Xubuntu/Mint printer-dial.")
	GadgetToolTip(#CupsSetServerDef, "The server main printer." + #LF$ + "E.g. the 'checked' one in printer dial.")
	
	Repeat
		gEvent= WaitWindowEvent()
		
		Select gEvent
				
			Case #PB_Event_CloseWindow
				gQuit= #True
				
			Case #PB_Event_Gadget
				
				Select EventGadget()
					Case #CupsListPrinters
						If EventType() = #PB_EventType_Change
							If GetGadgetState(#CupsListPrinters) > -1
								Cups_GetOptionsForPrinter(GetGadgetItemText(#CupsListPrinters, GetGadgetState(#CupsListPrinters), 0), #CupsListOptions)
							EndIf
						EndIf
					
					Case #CupsSetUserDef
						If GetGadgetState(#CupsListPrinters) > -1
							Cups_SetDefaultUserPrinter(#CupsListPrinters)
						EndIf
					
					Case #CupsSetServerDef
						If GetGadgetState(#CupsListPrinters) > -1
							Cups_SetDefaultServerPrinter(#CupsListPrinters)
						EndIf
						
				EndSelect
				
		EndSelect
		
	Until gQuit
EndIf
Demo with Cups-API

Code: Select all

; Dev-File are needed: libcups2dev
; install e.g.     : "sudo apt-get install --assume-yes libcups2 libcups2-dev"
; you like cups pdf: "sudo apt-get install cups-pdf" (+ sudo /etc/init.d/cups restart)

EnableExplicit

ImportC "-lcups"
	cupsFreeDests(num_dests.l, *dests)
	cupsGetDefault()
	cupsGetDefault2(*http);                                                            if name = constant
	cupsGetDefault2S(http.p-utf8) As "cupsGetDefault2";                                if name <> #NULL
	cupsGetDests(*dests)
	cupsGetPPD(name.p-utf8)
	cupsServer()
	cupsSetDefaultDest(name.p-utf8, *instance, num_dests.l, *dests);                   if instance = #NULL
	cupsSetDests(num_dests.l, *dests)
	cupsUser()
	cupsUserAgent()
; 	cupsGetDest(*name, *instance, num_dests.l, *dests);                              if name = #NULL
; 	cupsGetDestSName(name.p-utf8, *instance, num_dests.l, *dests) As "cupsGetDest";  if name <> #NULL
; 	cupsSetDefaultDest(name.p-utf8, *instance.p-utf8, num_dests.l, *dests);          if instance <> #NULL
EndImport

Structure cups_option_s
	*name
	*value
EndStructure

Structure cups_dest_s
	*name
	*instance
	is_default.l
	num_options.l
	*options.cups_option_s
EndStructure

; #CUPS_HTTP_DEFAULT= 0

; Object constants
#MainWin  = 0

Enumeration
	#CupsUser
	#CupsUserAgent
	#CupsServer
	#CupsServerPrinterDef
	#CupsNPrinter
	#CupsListPrinters
	#CupsListOptions
	#CupsSetUserDef
	#CupsSetServerDef
EndEnumeration

Global.i           gEvent, gQuit
Global.l           gNumDests
Global.cups_dest_s *gDefPrtDest, *gDefPrtDests


Procedure.s Cups_GetUser()
	Protected   *CupsUser= cupsUser()
	Protected.s S= ""
	
	If *CupsUser
		S= PeekS(*CupsUser, -1, #PB_UTF8)
	EndIf
	ProcedureReturn S
EndProcedure

Procedure.s Cups_GetUserAgent()
	Protected   *CupsUserAgent= cupsUserAgent()
	Protected.s S= ""
	
	If *CupsUserAgent
		S= PeekS(*CupsUserAgent, -1, #PB_UTF8)
	EndIf
	ProcedureReturn S
EndProcedure

Procedure.s Cups_GetServer()
	Protected   *CupsServer= cupsServer()
	Protected.s S= ""
	
	If *CupsServer
		S= PeekS(*CupsServer, -1, #PB_UTF8)
	EndIf
	ProcedureReturn S
EndProcedure

Procedure.s Cups_GetDefaultServerPrinter();                          Only w. Cups API ?
	Protected   *gDefSrvPrt= cupsGetDefault()
	Protected.s S= ""
	
	If *gDefSrvPrt
		S= PeekS(*gDefSrvPrt, -1, #PB_UTF8)
	EndIf
	ProcedureReturn S
EndProcedure

Procedure.l Cups_GetDestinations()
	gNumDests= cupsGetDests(@*gDefPrtDests)
EndProcedure

Procedure Cups_GetPrinterOptions(PrinterId.i)
	Protected   *PrtDest.cups_dest_s= *gDefPrtDests+ (PrinterId * SizeOf(cups_dest_s))
	Protected   *PrinterOption.cups_option_s
	Protected.i I
	
	If *PrtDest\options
		ClearGadgetItems(#CupsListOptions)
		*PrinterOption= *PrtDest\options
		For I= 1 To *PrtDest\num_options
			AddGadgetItem(#CupsListOptions, I - 1, RSet(Str(I), 3) + "." + #LF$ + 
			                                       PeekS(*PrinterOption\name, -1, #PB_UTF8) + #LF$ + 
			                                       PeekS(*PrinterOption\value, -1, #PB_UTF8))
			*PrinterOption+ SizeOf(cups_option_s);                         step through struct array
		Next I
	EndIf
EndProcedure

Procedure Cups_SetUserDefPrinter(PrinterId.i)
	Protected   *PrtDest.cups_dest_s
	Protected.i I
	
	For I= 0 To gNumDests- 1
		*PrtDest= *gDefPrtDests+ (I * SizeOf(cups_dest_s));              step through struct array
		If I = PrinterId
			*PrtDest\is_default= #True;                                    sets user default printer
		Else
			*PrtDest\is_default= #False
		EndIf
		SetGadgetItemText(#CupsListPrinters, I, Str(*PrtDest\is_default), 2)
	Next I
	cupsSetDests(gNumDests, *gDefPrtDests)
EndProcedure

Procedure Cups_SetServerDefPrinter(PrinterId.i)
	Protected   *PrtDest.cups_dest_s= *gDefPrtDests+ (PrinterId * SizeOf(cups_dest_s))
	Protected.s sName
	
	If *PrtDest
		If *PrtDest\name
			sName= PeekS(*PrtDest\name, -1, #PB_UTF8)
			If sName <> ""
				RunProgram("lpadmin", "-d " + sName, "");                    set server default printer
; 				cupsSetDefaultDest(sName, #Null, gNumDests, *gDefPrtDests);  doesn't do the job ???
			EndIf
		EndIf
	EndIf
	Delay(200)
EndProcedure

Procedure CreateWindow_Main()
	Protected.i I
	
	If OpenWindow(#MainWin, 300, 200, 800, 395, "Cups-API: list/get/set default printer", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		TextGadget(#PB_Any,                   5,  10, 170,  22, "Cups user: ", #PB_Text_Right)
		TextGadget(#PB_Any,                   5,  40, 170,  22, "Cups user agent: ", #PB_Text_Right)
		TextGadget(#PB_Any,                   5,  70, 170,  22, "Cups server: ", #PB_Text_Right)
		TextGadget(#PB_Any,                   5, 100, 170,  22, "Default server printer: ", #PB_Text_Right)
		TextGadget(#CupsNPrinter,             5, 130, 170,  22, "Listed Cups printers: ")
		TextGadget(#PB_Any,                 360, 130, 170,  22, "Options for selected printer: ")
		
		StringGadget(#CupsUser,             180,   5, 400,  26, Cups_GetUser(), #PB_String_ReadOnly)
		StringGadget(#CupsUserAgent,        180,  35, 400,  26, Cups_GetUserAgent(), #PB_String_ReadOnly)
		StringGadget(#CupsServer   ,        180,  65, 400,  26, Cups_GetServer(), #PB_String_ReadOnly)
		StringGadget(#CupsServerPrinterDef, 180,  95, 400,  26, Cups_GetDefaultServerPrinter(), #PB_String_ReadOnly)
		Cups_GetDestinations()
		SetGadgetText(#CupsNPrinter, "Listed Cups printers: "+ Str(gNumDests))
		
		ListIconGadget(#CupsListPrinters,     5, 150, 350, 170, "Printer name", 150, #PB_ListIcon_GridLines)
		AddGadgetColumn(#CupsListPrinters,    1, "Instance name", 100)
		AddGadgetColumn(#CupsListPrinters,    2, "User-Default",   70)
		gtk_tree_selection_set_mode_(gtk_tree_view_get_selection_(GadgetID(#CupsListPrinters)), #GTK_SELECTION_BROWSE)
		
		ListIconGadget(#CupsListOptions,    360, 150, 435, 238, "#", 35, #PB_ListIcon_GridLines)
		AddGadgetColumn(#CupsListOptions,     1, "Option", 160)
		AddGadgetColumn(#CupsListOptions,     2, "Value",  250)
		gtk_tree_selection_set_mode_(gtk_tree_view_get_selection_(GadgetID(#CupsListOptions)), #GTK_SELECTION_NONE)
		
		ButtonGadget(#CupsSetUserDef,         5, 327, 350,  28, "Selected printer as user default")
		ButtonGadget(#CupsSetServerDef,       5, 360, 350,  28, "Selected printer as server default")
		
		If gNumDests
			*gDefPrtDest= *gDefPrtDests
			For I= 0 To gNumDests- 1
				AddGadgetItem(#CupsListPrinters, I, "")
				
				If *gDefPrtDest\name
					SetGadgetItemText(#CupsListPrinters, I, PeekS(*gDefPrtDest\name, -1, #PB_UTF8), 0)
				EndIf
				
				If *gDefPrtDest\instance
					SetGadgetItemText(#CupsListPrinters, I, PeekS(*gDefPrtDest\instance, -1, #PB_UTF8), 1)
				EndIf
				
				SetGadgetItemText(#CupsListPrinters, I, Str(*gDefPrtDest\is_default), 2)
				
				*gDefPrtDest+ SizeOf(cups_dest_s);                             step through struct array
			Next I
		EndIf
	EndIf
EndProcedure

CreateWindow_Main()
	
	
Repeat
	gEvent= WaitWindowEvent()
	
	Select gEvent
			
		Case #PB_Event_CloseWindow
			gQuit= #True
			
		Case #PB_Event_Gadget
			
			Select EventGadget()
				Case #CupsListPrinters
					If EventType() = #PB_EventType_Change
						If GetGadgetState(#CupsListPrinters) > -1
							Cups_GetPrinterOptions(GetGadgetState(#CupsListPrinters))
						EndIf
					EndIf
				
				Case #CupsSetUserDef
					If GetGadgetState(#CupsListPrinters) > -1
						Cups_SetUserDefPrinter(GetGadgetState(#CupsListPrinters))
					EndIf
				
				Case #CupsSetServerDef
					If GetGadgetState(#CupsListPrinters) > -1
						Cups_SetServerDefPrinter(GetGadgetState(#CupsListPrinters))
						SetGadgetText(#CupsServerPrinterDef, Cups_GetDefaultServerPrinter())
					EndIf
					
			EndSelect
			
	EndSelect
	
Until gQuit

If gNumDests
	cupsFreeDests(gNumDests, *gDefPrtDests)
EndIf
Best Regards, Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
Ulix
User
User
Posts: 48
Joined: Wed Jan 23, 2008 12:45 pm
Location: France, Montpellier

Re: Setting default printer API

Post by Ulix »

Hello everyone

Thank you OMA, I needed a CUPS command and I had only reused!
So thank you very much! (I hope you read these lines.) :lol:
I know this post is from April 2016, but a thank you is always a pleasure !!

A few comments :
1) Rewrite the code to make it a module "Cups ::" would be nice
2) Include some dialog box to manage the options, (Copies, media, margins, portrait / landscape, resolution) .... to see the most useful
3) Save the options in the file: User + "/. Cups / lpoptions"

In any case, thank you very much. :lol:
Post Reply