/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.printing;


import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.Callback;
import org.eclipse.swt.internal.Converter;
import org.eclipse.swt.internal.gtk.GdkVisual;
import org.eclipse.swt.internal.gtk.OS;
import org.eclipse.swt.internal.cairo.Cairo;
import org.eclipse.swt.printing.PrinterData;

/**
 * Instances of this class are used to print to a printer.
 * Applications create a GC on a printer using <code>new GC(printer)</code>
 * and then draw on the printer GC using the usual graphics calls.
 * <p>
 * A <code>Printer</code> object may be constructed by providing
 * a <code>PrinterData</code> object which identifies the printer.
 * A <code>PrintDialog</code> presents a print dialog to the user
 * and returns an initialized instance of <code>PrinterData</code>.
 * Alternatively, calling <code>new Printer()</code> will construct a
 * printer object for the user's default printer.
 * </p><p>
 * Application code must explicitly invoke the <code>Printer.dispose()</code> 
 * method to release the operating system resources managed by each instance
 * when those instances are no longer required.
 * </p>
 *
 * @see PrinterData
 * @see PrintDialog
 * @see <a href="http://www.eclipse.org/swt/snippets/#printing">Printing snippets</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 */
public final class Printer extends Device {
	static PrinterData [] printerList;
	
	PrinterData data;
	int /*long*/ printer;
	int /*long*/ printJob;
	int /*long*/ settings;
	int /*long*/ pageSetup;
	int /*long*/ surface;
	int /*long*/ cairo;
	
	/**
	 * whether or not a GC was created for this printer
	 */
	boolean isGCCreated = false;
	Font systemFont;

	static byte [] settingsData;
	static int start, end;

	static final String GTK_LPR_BACKEND = "GtkPrintBackendLpr"; //$NON-NLS-1$

	static boolean disablePrinting = System.getProperty("org.eclipse.swt.internal.gtk.disablePrinting") != null; //$NON-NLS-1$
	
/**
 * Returns an array of <code>PrinterData</code> objects
 * representing all available printers.  If there are no
 * printers, the array will be empty.
 *
 * @return an array of PrinterData objects representing the available printers
 */
public static PrinterData[] getPrinterList() {
	printerList = new PrinterData [0];
	if (OS.GTK_VERSION < OS.VERSION (2, 10, 0) || disablePrinting) {
		return printerList;
	}
	if (!OS.g_thread_supported ()) {
		OS.g_thread_init (0);
	}
	OS.gtk_set_locale();
	if (!OS.gtk_init_check (new int /*long*/ [] {0}, null)) {
		SWT.error (SWT.ERROR_NO_HANDLES, null, " [gtk_init_check() failed]");
	}
	Callback printerCallback = new Callback(Printer.class, "GtkPrinterFunc_List", 2); //$NON-NLS-1$
	int /*long*/ GtkPrinterFunc_List = printerCallback.getAddress();
	if (GtkPrinterFunc_List == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
	OS.gtk_enumerate_printers(GtkPrinterFunc_List, 0, 0, true);
	printerCallback.dispose ();
	return printerList;
}

static int /*long*/ GtkPrinterFunc_List (int /*long*/ printer, int /*long*/ user_data) {
	int length = printerList.length;
	PrinterData [] newList = new PrinterData [length + 1];
	System.arraycopy (printerList, 0, newList, 0, length);
	printerList = newList;
	printerList [length] = printerDataFromGtkPrinter(printer);
	/*
	* Bug in GTK. While performing a gtk_enumerate_printers(), GTK finds all of the 
	* available printers from each backend and can hang. If a backend requires more 
	* time to gather printer info, GTK will start an event loop waiting for a done 
    * signal before continuing. For the Lpr backend, GTK does not send a done signal
    * which means the event loop never ends. The fix is to check to see if the driver
    * is of type Lpr, and stop the enumeration, which exits the event loop.
	*/
	if (printerList[length].driver.equals (GTK_LPR_BACKEND)) return 1;
	return 0;
}

/**
 * Returns a <code>PrinterData</code> object representing
 * the default printer or <code>null</code> if there is no 
 * default printer.
 *
 * @return the default printer data or null
 * 
 * @since 2.1
 */
public static PrinterData getDefaultPrinterData() {
	printerList = new PrinterData [1];
	if (OS.GTK_VERSION < OS.VERSION (2, 10, 0) || disablePrinting) {
		return null;
	}
	if (!OS.g_thread_supported ()) {
		OS.g_thread_init (0);
	}
	OS.gtk_set_locale();
	if (!OS.gtk_init_check (new int /*long*/ [] {0}, null)) {
		SWT.error (SWT.ERROR_NO_HANDLES, null, " [gtk_init_check() failed]");
	}
	Callback printerCallback = new Callback(Printer.class, "GtkPrinterFunc_Default", 2); //$NON-NLS-1$
	int /*long*/ GtkPrinterFunc_Default = printerCallback.getAddress();
	if (GtkPrinterFunc_Default == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
	OS.gtk_enumerate_printers(GtkPrinterFunc_Default, 0, 0, true);
	printerCallback.dispose ();
	return printerList[0];
}

static int /*long*/ GtkPrinterFunc_Default (int /*long*/ printer, int /*long*/ user_data) {
	if (OS.gtk_printer_is_default(printer)) {
		printerList[0] = printerDataFromGtkPrinter(printer);
		return 1;
	} else if (OS.GTK_VERSION < OS.VERSION(2, 10, 12) && printerDataFromGtkPrinter(printer).driver.equals (GTK_LPR_BACKEND)) { 
		return 1;
	}
	return 0;
}

int /*long*/ gtkPrinterFromPrinterData() {
	Callback printerCallback = new Callback(this, "GtkPrinterFunc_FindNamedPrinter", 2); //$NON-NLS-1$
	int /*long*/ GtkPrinterFunc_FindNamedPrinter = printerCallback.getAddress();
	if (GtkPrinterFunc_FindNamedPrinter == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
	printer = 0;
	OS.gtk_enumerate_printers(GtkPrinterFunc_FindNamedPrinter, 0, 0, true);
	printerCallback.dispose ();
	return printer;
}

int /*long*/ GtkPrinterFunc_FindNamedPrinter (int /*long*/ printer, int /*long*/ user_data) {
	PrinterData pd = printerDataFromGtkPrinter(printer);
	if (pd.driver.equals(data.driver) && pd.name.equals(data.name)) {
		this.printer = printer;
		OS.g_object_ref(printer);
		return 1;
	} else if (OS.GTK_VERSION < OS.VERSION (2, 10, 12) && pd.driver.equals(GTK_LPR_BACKEND)) {
		return 1;
	}
	return 0;
}

static PrinterData printerDataFromGtkPrinter(int /*long*/ printer) {
	int /*long*/ backend = OS.gtk_printer_get_backend(printer);
	int /*long*/ address = OS.G_OBJECT_TYPE_NAME(backend);
	int length = OS.strlen (address);
	byte [] buffer = new byte [length];
	OS.memmove (buffer, address, length);
	String backendType = new String (Converter.mbcsToWcs (null, buffer));
	
	address = OS.gtk_printer_get_name (printer);
	length = OS.strlen (address);
	buffer = new byte [length];
	OS.memmove (buffer, address, length);
	String name = new String (Converter.mbcsToWcs (null, buffer));

	return new PrinterData (backendType, name);
}

/* 
* Restore printer settings and page_setup data from data.
*/
static void restore(byte [] data, int /*long*/ settings, int /*long*/ page_setup) {
	settingsData = data;
	start = end = 0;
	while (end < settingsData.length && settingsData[end] != 0) {
		start = end;
		while (end < settingsData.length && settingsData[end] != 0) end++;
		end++;
		byte [] keyBuffer = new byte [end - start];
		System.arraycopy (settingsData, start, keyBuffer, 0, keyBuffer.length);
		start = end;
		while (end < settingsData.length && settingsData[end] != 0) end++;
		end++;
		byte [] valueBuffer = new byte [end - start];
		System.arraycopy (settingsData, start, valueBuffer, 0, valueBuffer.length);
		OS.gtk_print_settings_set(settings, keyBuffer, valueBuffer);
		if (DEBUG) System.out.println(new String (Converter.mbcsToWcs (null, keyBuffer))+": "+new String (Converter.mbcsToWcs (null, valueBuffer)));
	}
	end++; // skip extra null terminator
	
	/* Retrieve stored page_setup data.
	 * Note that page_setup properties must be stored (in PrintDialog) and restored (here) in the same order.
	 */
	OS.gtk_page_setup_set_orientation(page_setup, restoreInt("orientation")); //$NON-NLS-1$
	OS.gtk_page_setup_set_top_margin(page_setup, restoreDouble("top_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$
	OS.gtk_page_setup_set_bottom_margin(page_setup, restoreDouble("bottom_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$
	OS.gtk_page_setup_set_left_margin(page_setup, restoreDouble("left_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$
	OS.gtk_page_setup_set_right_margin(page_setup, restoreDouble("right_margin"), OS.GTK_UNIT_MM); //$NON-NLS-1$
	byte [] name = restoreBytes("paper_size_name", true); //$NON-NLS-1$
	byte [] display_name = restoreBytes("paper_size_display_name", true); //$NON-NLS-1$
	byte [] ppd_name = restoreBytes("paper_size_ppd_name", true); //$NON-NLS-1$
	double width = restoreDouble("paper_size_width"); //$NON-NLS-1$
	double height = restoreDouble("paper_size_height"); //$NON-NLS-1$
	boolean custom = restoreBoolean("paper_size_is_custom"); //$NON-NLS-1$
	int /*long*/ paper_size = 0;
	if (custom) {
		if (ppd_name.length > 0) {
			paper_size = OS.gtk_paper_size_new_from_ppd(ppd_name, display_name, width, height);
		} else {
			paper_size = OS.gtk_paper_size_new_custom(name, display_name, width, height, OS.GTK_UNIT_MM);
		}
	} else {
		paper_size = OS.gtk_paper_size_new(name);
	}
	OS.gtk_page_setup_set_paper_size(page_setup, paper_size);
	OS.gtk_paper_size_free(paper_size);
}

static DeviceData checkNull (PrinterData data) {
	if (data == null) data = new PrinterData();
	if (data.driver == null || data.name == null) {
		PrinterData defaultPrinter = getDefaultPrinterData();
		if (defaultPrinter == null) SWT.error(SWT.ERROR_NO_HANDLES);
		data.driver = defaultPrinter.driver;
		data.name = defaultPrinter.name;		
	}
	return data;
}

/**
 * Constructs a new printer representing the default printer.
 * <p>
 * Note: You must dispose the printer when it is no longer required. 
 * </p>
 *
 * @exception SWTError <ul>
 *    <li>ERROR_NO_HANDLES - if there are no valid printers
 * </ul>
 *
 * @see Device#dispose
 */
public Printer() {
	this(null);
}

/**
 * Constructs a new printer given a <code>PrinterData</code>
 * object representing the desired printer. If the argument
 * is null, then the default printer will be used.
 * <p>
 * Note: You must dispose the printer when it is no longer required. 
 * </p>
 *
 * @param data the printer data for the specified printer, or null to use the default printer
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the specified printer data does not represent a valid printer
 * </ul>
 * @exception SWTError <ul>
 *    <li>ERROR_NO_HANDLES - if there are no valid printers
 * </ul>
 *
 * @see Device#dispose
 */
public Printer(PrinterData data) {
	super(checkNull(data));
}

static int restoreInt(String key) {
	byte [] value = restoreBytes(key, false);
	return Integer.parseInt(new String(value));
}

static double restoreDouble(String key) {
	byte [] value = restoreBytes(key, false);
	return Double.parseDouble(new String(value));
}

static boolean restoreBoolean(String key) {
	byte [] value = restoreBytes(key, false);
	return Boolean.valueOf(new String(value)).booleanValue();
}

static byte [] restoreBytes(String key, boolean nullTerminate) {
	//get key
	start = end;
	while (end < settingsData.length && settingsData[end] != 0) end++;
	end++;
	byte [] keyBuffer = new byte [end - start];
	System.arraycopy (settingsData, start, keyBuffer, 0, keyBuffer.length);
	
	//get value
	start = end;
	while (end < settingsData.length && settingsData[end] != 0) end++;
	int length = end - start;
	end++;
	if (nullTerminate) length++;
	byte [] valueBuffer = new byte [length];
	System.arraycopy (settingsData, start, valueBuffer, 0, length);
	
	if (DEBUG) System.out.println(new String (Converter.mbcsToWcs (null, keyBuffer))+": "+new String (Converter.mbcsToWcs (null, valueBuffer)));

	return valueBuffer;
}

/**
 * Returns a reasonable font for applications to use.
 * On some platforms, this will match the "default font"
 * or "system font" if such can be found.  This font
 * should not be free'd because it was allocated by the
 * system, not the application.
 * <p>
 * Typically, applications which want the default look
 * should simply not set the font on the widgets they
 * create. Widgets are always created with the correct
 * default font for the class of user-interface component
 * they represent.
 * </p>
 *
 * @return a font
 *
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Font getSystemFont () {
	checkDevice ();
	if (systemFont != null) return systemFont;
	int /*long*/ style = OS.gtk_widget_get_default_style();	
	int /*long*/ defaultFont = OS.pango_font_description_copy (OS.gtk_style_get_font_desc (style));
	return systemFont = Font.gtk_new (this, defaultFont);
}

/**	 
 * Invokes platform specific functionality to allocate a new GC handle.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>Printer</code>. It is marked public only so that it
 * can be shared within the packages provided by SWT. It is not
 * available on all platforms, and should never be called from
 * application code.
 * </p>
 *
 * @param data the platform specific GC data 
 * @return the platform specific GC handle
 */
public int /*long*/ internal_new_GC(GCData data) {
	GdkVisual visual = new GdkVisual ();
	OS.memmove (visual, OS.gdk_visual_get_system());
	int /*long*/ drawable = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), 1, 1, visual.depth);
	int /*long*/ gdkGC = OS.gdk_gc_new (drawable);
	if (gdkGC == 0) SWT.error (SWT.ERROR_NO_HANDLES);
	if (data != null) {
		if (isGCCreated) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
		if ((data.style & mask) == 0) {
			data.style |= SWT.LEFT_TO_RIGHT;
		}
		data.device = this;
		data.drawable = drawable;
		data.background = getSystemColor (SWT.COLOR_WHITE).handle;
		data.foreground = getSystemColor (SWT.COLOR_BLACK).handle;
		data.font = getSystemFont ();
		//TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245)
		data.width = (int)OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS);
		data.height = (int)OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS);
		if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		data.cairo = cairo;
		isGCCreated = true;
	}
	return gdkGC;
}

/**	 
 * Invokes platform specific functionality to dispose a GC handle.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>Printer</code>. It is marked public only so that it
 * can be shared within the packages provided by SWT. It is not
 * available on all platforms, and should never be called from
 * application code.
 * </p>
 *
 * @param hDC the platform specific GC handle
 * @param data the platform specific GC data 
 */
public void internal_dispose_GC(int /*long*/ gdkGC, GCData data) {
	if (data != null) isGCCreated = false;
	OS.g_object_unref (gdkGC);
	if (data != null) {
		if (data.drawable != 0) OS.g_object_unref (data.drawable);
		data.drawable = data.cairo = 0;
	}
}

/**	 
 * Releases any internal state prior to destroying this printer.
 * This method is called internally by the dispose
 * mechanism of the <code>Device</code> class.
 */
protected void release () {
	super.release();
	
	/* Dispose the default font */
	if (systemFont != null) systemFont.dispose ();
	systemFont = null;
}

/**
 * Starts a print job and returns true if the job started successfully
 * and false otherwise.
 * <p>
 * This must be the first method called to initiate a print job,
 * followed by any number of startPage/endPage calls, followed by
 * endJob. Calling startPage, endPage, or endJob before startJob
 * will result in undefined behavior.
 * </p>
 * 
 * @param jobName the name of the print job to start
 * @return true if the job started successfully and false otherwise.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #startPage
 * @see #endPage
 * @see #endJob
 */
public boolean startJob(String jobName) {
	checkDevice();
	byte [] buffer = Converter.wcsToMbcs (null, jobName, true);
	printJob = OS.gtk_print_job_new (buffer, printer, settings, pageSetup);
	if (printJob == 0) return false;
	surface = OS.gtk_print_job_get_surface(printJob, null);
	if (surface == 0) {
		OS.g_object_unref(printJob);
		printJob = 0;
		return false;
	}
	cairo = Cairo.cairo_create(surface);
	if (cairo == 0)  {
		OS.g_object_unref(printJob);
		printJob = 0;
		return false;
	}
	return true;
}

/**	 
 * Destroys the printer handle.
 * This method is called internally by the dispose
 * mechanism of the <code>Device</code> class.
 */
protected void destroy () {
	if (printer != 0) OS.g_object_unref (printer);
	if (settings != 0) OS.g_object_unref (settings);
	if (pageSetup != 0) OS.g_object_unref (pageSetup);
	if (cairo != 0) Cairo.cairo_destroy (cairo);
	if (printJob != 0) OS.g_object_unref (printJob);
	printer = settings = pageSetup = cairo = printJob = 0;
}

/**
 * Ends the current print job.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #startJob
 * @see #startPage
 * @see #endPage
 */
public void endJob() {
	checkDevice();
	if (printJob == 0) return;
	Cairo.cairo_surface_finish(surface);
	OS.gtk_print_job_send(printJob, 0, 0, 0);
}

/**
 * Cancels a print job in progress. 
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void cancelJob() {
	checkDevice();
	if (printJob == 0) return;
	//TODO: Need to implement (waiting on gtk bug 339323) 
	//OS.g_object_unref(printJob);
	//printJob = 0;
}

/**
 * Starts a page and returns true if the page started successfully
 * and false otherwise.
 * <p>
 * After calling startJob, this method may be called any number of times
 * along with a matching endPage.
 * </p>
 * 
 * @return true if the page started successfully and false otherwise.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #endPage
 * @see #startJob
 * @see #endJob
 */
public boolean startPage() {
	checkDevice();
	if (printJob == 0) return false;
	double width = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS);
	double height = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS);
	int type = Cairo.cairo_surface_get_type (surface);
	switch (type) {
		case Cairo.CAIRO_SURFACE_TYPE_PS:
			Cairo.cairo_ps_surface_set_size (surface, width, height);
			break;
		case Cairo.CAIRO_SURFACE_TYPE_PDF:
			Cairo.cairo_pdf_surface_set_size (surface, width, height);
			break;
	}
	return true;
}

/**
 * Ends the current page.
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #startPage
 * @see #startJob
 * @see #endJob
 */
public void endPage() {
	checkDevice();
	if (cairo != 0) Cairo.cairo_show_page(cairo);
}

/**
 * Returns a point whose x coordinate is the horizontal
 * dots per inch of the printer, and whose y coordinate
 * is the vertical dots per inch of the printer.
 *
 * @return the horizontal and vertical DPI
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Point getDPI() {
	checkDevice();
	int resolution = OS.gtk_print_settings_get_resolution(settings);
	if (DEBUG) System.out.println("print_settings.resolution=" + resolution);
	//TODO: Return 72 (1/72 inch = 1 point) until gtk bug 346245 is fixed
	//TODO: Fix this: gtk_print_settings_get_resolution returns 0? (see gtk bug 346252)
	/*if (resolution == 0)*/ return new Point(72, 72);
//	return new Point(resolution, resolution);
}

/**
 * Returns a rectangle describing the receiver's size and location.
 * <p>
 * For a printer, this is the size of the physical page, in pixels.
 * </p>
 *
 * @return the bounding rectangle
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #getClientArea
 * @see #computeTrim
 */
public Rectangle getBounds() {
	checkDevice();
	//TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245)
	double width = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS);
	double height = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS);
	return new Rectangle(0, 0, (int) width, (int) height);
}

/**
 * Returns a rectangle which describes the area of the
 * receiver which is capable of displaying data.
 * <p>
 * For a printer, this is the size of the printable area
 * of the page, in pixels.
 * </p>
 * 
 * @return the client area
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #getBounds
 * @see #computeTrim
 */
public Rectangle getClientArea() {
	checkDevice();
	//TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245)
	double width = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS);
	double height = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS);
	return new Rectangle(0, 0, (int) width, (int) height);
}

/**
 * Given a <em>client area</em> (as described by the arguments),
 * returns a rectangle, relative to the client area's coordinates,
 * that is the client area expanded by the printer's trim (or minimum margins).
 * <p>
 * Most printers have a minimum margin on each edge of the paper where the
 * printer device is unable to print.  This margin is known as the "trim."
 * This method can be used to calculate the printer's minimum margins
 * by passing in a client area of 0, 0, 0, 0 and then using the resulting
 * x and y coordinates (which will be <= 0) to determine the minimum margins
 * for the top and left edges of the paper, and the resulting width and height
 * (offset by the resulting x and y) to determine the minimum margins for the
 * bottom and right edges of the paper, as follows:
 * <ul>
 * 		<li>The left trim width is -x pixels</li>
 * 		<li>The top trim height is -y pixels</li>
 * 		<li>The right trim width is (x + width) pixels</li>
 * 		<li>The bottom trim height is (y + height) pixels</li>
 * </ul>
 * </p>
 * 
 * @param x the x coordinate of the client area
 * @param y the y coordinate of the client area
 * @param width the width of the client area
 * @param height the height of the client area
 * @return a rectangle, relative to the client area's coordinates, that is
 * 		the client area expanded by the printer's trim (or minimum margins)
 *
 * @exception SWTException <ul>
 *    <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #getBounds
 * @see #getClientArea
 */
public Rectangle computeTrim(int x, int y, int width, int height) {
	checkDevice();
	//TODO: We are supposed to return this in pixels, but GTK_UNIT_PIXELS is currently not implemented (gtk bug 346245)
	double printWidth = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS);
	double printHeight = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS);
	double paperWidth = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS);
	double paperHeight = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS);
	double printX = -OS.gtk_page_setup_get_left_margin(pageSetup, OS.GTK_UNIT_POINTS);
	double printY = -OS.gtk_page_setup_get_top_margin(pageSetup, OS.GTK_UNIT_POINTS);
	double hTrim = paperWidth - printWidth;
	double vTrim = paperHeight - printHeight;
	return new Rectangle(x + (int)printX, y + (int)printY, width + (int)hTrim, height + (int)vTrim);
}

/**	 
 * Creates the printer handle.
 * This method is called internally by the instance creation
 * mechanism of the <code>Device</code> class.
 * @param deviceData the device data
 */
protected void create(DeviceData deviceData) {
	this.data = (PrinterData)deviceData;
	if (OS.GTK_VERSION < OS.VERSION (2, 10, 0) || disablePrinting) SWT.error(SWT.ERROR_NO_HANDLES);
	printer = gtkPrinterFromPrinterData();
	if (printer == 0) SWT.error(SWT.ERROR_NO_HANDLES);
}

/**
 * Initializes any internal resources needed by the
 * device.
 * <p>
 * This method is called after <code>create</code>.
 * </p><p>
 * If subclasses reimplement this method, they must
 * call the <code>super</code> implementation.
 * </p>
 * 
 * @see #create
 */
protected void init() {
	super.init ();
	settings = OS.gtk_print_settings_new();
	pageSetup = OS.gtk_page_setup_new();
	if (data.otherData != null) {
		restore(data.otherData, settings, pageSetup);
	}
	
	/* Set values of print_settings and page_setup from PrinterData. */
	//TODO: Should we look at printToFile, or driver/name for "Print to File", or both? (see gtk bug 345590)
	if (data.printToFile && data.fileName != null) {
		byte [] buffer = Converter.wcsToMbcs (null, data.fileName, true);
		OS.gtk_print_settings_set(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI, buffer);
	}
	if (data.driver.equals("GtkPrintBackendFile") && data.name.equals("Print to File") && data.fileName != null) { //$NON-NLS-1$ //$NON-NLS-2$
		byte [] buffer = Converter.wcsToMbcs (null, data.fileName, true);
		OS.gtk_print_settings_set(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI, buffer);
	}
	OS.gtk_print_settings_set_n_copies(settings, data.copyCount);
	OS.gtk_print_settings_set_collate(settings, data.collate);
	int orientation = data.orientation == PrinterData.LANDSCAPE ? OS.GTK_PAGE_ORIENTATION_LANDSCAPE : OS.GTK_PAGE_ORIENTATION_PORTRAIT;
	OS.gtk_page_setup_set_orientation(pageSetup, orientation);
	OS.gtk_print_settings_set_orientation(settings, orientation);
}

/**
 * Returns a <code>PrinterData</code> object representing the
 * target printer for this print job.
 * 
 * @return a PrinterData object describing the receiver
 */
public PrinterData getPrinterData() {
	checkDevice();
	return data;
}

}
