Bug 339699 - implement gtk_print_operation_set_show_dialog for Windows

2008-08-02  Tor Lillqvist  <tml@novell.com>

	Bug 339699 - implement gtk_print_operation_set_show_dialog for
	Windows
	
	* gtk/gtkprint-win32.c
	* gtk/gtkprint-win32.h
	* gtk/gtkprintoperation-win32.c: Patch by ecyrbe@gmail.com.


svn path=/trunk/; revision=20942
This commit is contained in:
Tor Lillqvist 2008-08-02 09:27:47 +00:00 committed by Tor Lillqvist
parent 5fde2609d7
commit 8ce17cf990
4 changed files with 232 additions and 10 deletions

View File

@ -1,3 +1,12 @@
2008-08-02 Tor Lillqvist <tml@novell.com>
Bug 339699 - implement gtk_print_operation_set_show_dialog for
Windows
* gtk/gtkprint-win32.c
* gtk/gtkprint-win32.h
* gtk/gtkprintoperation-win32.c: Patch by ecyrbe@gmail.com.
2008-08-02 Matthias Clasen <mclasen@redhat.com>
Bug 544302 GtkStatusIcon should support GIcon

View File

@ -100,10 +100,53 @@ gtk_print_win32_devnames_to_win32 (const GtkPrintWin32Devnames *devnames)
}
HGLOBAL
gtk_print_win32_devnames_from_printer_name (const char *printer)
gtk_print_win32_devnames_to_win32_from_printer_name (const char *printer_name)
{
const GtkPrintWin32Devnames devnames = { "", (char *)printer, "", 0 };
return gtk_print_win32_devnames_to_win32 (&devnames);
HGLOBAL global;
GtkPrintWin32Devnames *devnames;
devnames = gtk_print_win32_devnames_from_printer_name(printer_name);
if(devnames)
{
global = gtk_print_win32_devnames_to_win32 (devnames);
gtk_print_win32_devnames_free(devnames);
}
else
global = NULL;
return global;
}
/**
used to get printer device information from a printer name
since this can fail, because the user have no right to read printer properties, this function can return NULL
*/
GtkPrintWin32Devnames *
gtk_print_win32_devnames_from_printer_name (const char *printer_name)
{
HANDLE hprinter;
gunichar2* win32_printer_name;
GtkPrintWin32Devnames *devnames;
win32_printer_name = g_utf8_to_utf16 (printer_name, -1, NULL, NULL, NULL);
if(OpenPrinterW(win32_printer_name, &hprinter, NULL))
{
DWORD needed;
PRINTER_INFO_2W* printer_info;
GetPrinterW(hprinter, 2, NULL, 0,&needed);
printer_info = (PRINTER_INFO_2W*)g_malloc((gsize)needed);
GetPrinterW(hprinter, 2, (LPBYTE)printer_info,needed,&needed);
devnames = g_new (GtkPrintWin32Devnames, 1);
devnames->driver = g_utf16_to_utf8(printer_info->pDriverName,-1,NULL,NULL,NULL);
devnames->device = g_strdup(printer_name);
devnames->output = g_utf16_to_utf8(printer_info->pPortName,-1,NULL,NULL,NULL);
devnames->flags = 0;
ClosePrinter(hprinter);
g_free(printer_info);
}else
{
// could not open printer
devnames = NULL;
}
g_free(win32_printer_name);
return devnames;
}

View File

@ -52,8 +52,9 @@ typedef struct {
void gtk_print_win32_devnames_free (GtkPrintWin32Devnames *devnames);
GtkPrintWin32Devnames *gtk_print_win32_devnames_from_win32 (HGLOBAL global);
GtkPrintWin32Devnames *gtk_print_win32_devnames_from_printer_name (const char *printer);
HGLOBAL gtk_print_win32_devnames_to_win32 (const GtkPrintWin32Devnames *devnames);
HGLOBAL gtk_print_win32_devnames_from_printer_name (const char *printer);
HGLOBAL gtk_print_win32_devnames_to_win32_from_printer_name (const char *printer);
G_END_DECLS

View File

@ -416,6 +416,21 @@ paper_size_to_win32 (GtkPaperSize *paper_size)
return 0;
}
gchar* win32_get_default_printer(){
gunichar2* win32_printer_name = NULL;
gchar* printer_name = NULL;
DWORD needed;
GetDefaultPrinterW(NULL,&needed);
win32_printer_name = g_malloc((gsize)needed*sizeof(gunichar2));
if(!GetDefaultPrinterW(win32_printer_name,&needed)){
g_free(win32_printer_name);
return NULL;
}
printer_name = g_utf16_to_utf8(win32_printer_name,-1,NULL,NULL,NULL);
g_free(win32_printer_name);
return printer_name;
}
void
win32_start_page (GtkPrintOperation *op,
GtkPrintContext *print_context,
@ -766,7 +781,7 @@ devmode_to_settings (GtkPrintSettings *settings,
}
if (devmode->dmFields & DM_COLOR)
gtk_print_settings_set_use_color (settings, devmode->dmFields == DMCOLOR_COLOR);
gtk_print_settings_set_use_color (settings, devmode->dmColor == DMCOLOR_COLOR);
if (devmode->dmFields & DM_DUPLEX)
{
@ -1179,7 +1194,7 @@ dialog_from_print_settings (GtkPrintOperation *op,
printer = gtk_print_settings_get_printer (settings);
if (printer)
printdlgex->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
printdlgex->hDevNames = gtk_print_win32_devnames_to_win32_from_printer_name (printer);
printdlgex->hDevMode = devmode_from_settings (settings,
op->priv->default_page_setup);
@ -1452,9 +1467,148 @@ create_page_setup (GtkPrintOperation *op)
return page_setup;
}
GtkPrintOperationResult
_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
gboolean show_dialog,
GtkPrintOperationResult gtk_print_operation_run_without_dialog(GtkPrintOperation *op,
gboolean *do_print)
{
GtkPrintOperationResult result;
GtkPrintOperationWin32 *op_win32;
GtkPrintOperationPrivate *priv;
GtkPrintSettings *settings;
GtkPageSetup *page_setup;
DOCINFOW docinfo;
HGLOBAL hDevMode = NULL;
HGLOBAL hDevNames = NULL;
HDC hDC = NULL;
const char* printer = NULL;
double dpi_x, dpi_y;
int job_id;
cairo_t *cr;
*do_print = FALSE;
priv = op->priv;
settings = priv->print_settings;
op_win32 = g_new0 (GtkPrintOperationWin32, 1);
priv->platform_data = op_win32;
priv->free_platform_data = (GDestroyNotify) op_win32_free;
printer = gtk_print_settings_get_printer (settings);
if (!printer){
/**
no printer selected,
get the system default printer and store it to settings
*/
gchar* tmp_printer = win32_get_default_printer();
if(!tmp_printer){
result = GTK_PRINT_OPERATION_RESULT_ERROR;
g_set_error_literal (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_INTERNAL_ERROR,
_("No printer found"));
goto out;
}
gtk_print_settings_set_printer(settings,tmp_printer);
printer = gtk_print_settings_get_printer (settings);
g_free(tmp_printer);
}
hDevNames = gtk_print_win32_devnames_to_win32_from_printer_name (printer);
hDevMode = devmode_from_settings (settings,
op->priv->default_page_setup);
/**
create a printer DC for the print settings and pagesetup provided
*/
DEVNAMES *pdn = GlobalLock(hDevNames);
DEVMODEW *pdm = GlobalLock(hDevMode);
hDC = CreateDCW((gunichar2*)pdn + pdn->wDriverOffset,
(gunichar2*)pdn + pdn->wDeviceOffset,
(gunichar2*)pdn + pdn->wOutputOffset,
pdm );
GlobalUnlock(hDevNames);
GlobalUnlock(hDevMode);
if(!hDC){
result = GTK_PRINT_OPERATION_RESULT_ERROR;
g_set_error_literal (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_INTERNAL_ERROR,
_("Invalid argument to CreateDC"));
goto out;
}
priv->print_context = _gtk_print_context_new (op);
page_setup = create_page_setup (op);
_gtk_print_context_set_page_setup (priv->print_context, page_setup);
g_object_unref (page_setup);
*do_print = TRUE;
op_win32->surface = cairo_win32_printing_surface_create (hDC);
dpi_x = (double)GetDeviceCaps (hDC, LOGPIXELSX);
dpi_y = (double)GetDeviceCaps (hDC, LOGPIXELSY);
cr = cairo_create (op_win32->surface);
gtk_print_context_set_cairo_context (priv->print_context, cr, dpi_x, dpi_y);
cairo_destroy (cr);
memset( &docinfo, 0, sizeof (DOCINFOW));
docinfo.cbSize = sizeof (DOCINFOW);
docinfo.lpszDocName = g_utf8_to_utf16 (op->priv->job_name,
-1, NULL, NULL, NULL);
docinfo.lpszOutput = (LPCWSTR) NULL;
docinfo.lpszDatatype = (LPCWSTR) NULL;
docinfo.fwType = 0;
job_id = StartDocW(hDC, &docinfo);
g_free ((void *)docinfo.lpszDocName);
if (job_id <= 0)
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
g_set_error_literal (&priv->error,
GTK_PRINT_ERROR,
GTK_PRINT_ERROR_GENERAL,
_("Error from StartDoc"));
*do_print = FALSE;
cairo_surface_destroy (op_win32->surface);
op_win32->surface = NULL;
goto out;
}
result = GTK_PRINT_OPERATION_RESULT_APPLY;
op_win32->hdc = hDC;
op_win32->devmode = hDevMode;
op_win32->devnames = hDevNames;
op_win32->job_id = job_id;
op->priv->print_pages = gtk_print_settings_get_print_pages (op->priv->print_settings);
op->priv->num_page_ranges = 0;
if (op->priv->print_pages == GTK_PRINT_PAGES_RANGES)
op->priv->page_ranges = gtk_print_settings_get_page_ranges (op->priv->print_settings,
&op->priv->num_page_ranges);
op->priv->manual_num_copies = 1;
op->priv->manual_collation = FALSE;
op->priv->manual_reverse = FALSE;
op->priv->manual_orientation = FALSE;
op->priv->manual_scale = 1.0;
op->priv->manual_page_set = GTK_PAGE_SET_ALL;
op->priv->start_page = win32_start_page;
op->priv->end_page = win32_end_page;
op->priv->end_run = win32_end_run;
out:
if (!*do_print && hDC != NULL)
DeleteDC(hDC);
if (!*do_print && hDevMode != NULL)
GlobalFree(hDevMode);
if (!*do_print && hDevNames != NULL)
GlobalFree(hDevNames);
return result;
}
GtkPrintOperationResult gtk_print_operation_run_with_dialog(GtkPrintOperation *op,
GtkWindow *parent,
gboolean *do_print)
{
@ -1665,6 +1819,9 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
op->priv->end_run = win32_end_run;
out:
if (!*do_print && printdlgex && printdlgex->hDC != NULL)
DeleteDC(printdlgex->hDC);
if (!*do_print && printdlgex && printdlgex->hDevMode != NULL)
GlobalFree(printdlgex->hDevMode);
@ -1683,6 +1840,18 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
return result;
}
GtkPrintOperationResult
_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
gboolean show_dialog,
GtkWindow *parent,
gboolean *do_print)
{
if(show_dialog)
return gtk_print_operation_run_with_dialog(op,parent,do_print);
else
return gtk_print_operation_run_without_dialog(op,do_print);
}
void
_gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
cairo_surface_t *surface,
@ -1820,7 +1989,7 @@ gtk_print_run_page_setup_dialog (GtkWindow *parent,
pagesetupdlg->hDevNames = NULL;
printer = gtk_print_settings_get_printer (settings);
if (printer)
pagesetupdlg->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
pagesetupdlg->hDevNames = gtk_print_win32_devnames_to_win32_from_printer_name (printer);
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER,
(LPWSTR)&measure_system, sizeof (DWORD));