/*******************************************************************************
 * Copyright (c) 2000, 2016 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.*;
import org.eclipse.swt.internal.cairo.*;
import org.eclipse.swt.internal.gtk.*;

/**
 * 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;
	static long /*int*/ findPrinter;
	static PrinterData findData;

	PrinterData data;
	long /*int*/ printer;
	long /*int*/ printJob;
	long /*int*/ settings;
	long /*int*/ pageSetup;
	long /*int*/ surface;
	long /*int*/ cairo;

	/**
	 * whether or not a GC was created for this printer
	 */
	boolean isGCCreated = false;

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

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

	static boolean disablePrinting = System.getProperty("org.eclipse.swt.internal.gtk.disablePrinting") != null; //$NON-NLS-1$

static void gtk_init() {
	if (OS.GLIB_VERSION < OS.VERSION(2, 32, 0)) {
		if (!OS.g_thread_supported()) {
			OS.g_thread_init(0);
		}
	}
	if (!OS.gtk_init_check (new long /*int*/ [] {0}, null)) {
		SWT.error (SWT.ERROR_NO_HANDLES, null, " [gtk_init_check() failed]");
	}
}

/**
 * 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 (disablePrinting) {
		return printerList;
	}
	gtk_init();
	Callback printerCallback = new Callback(Printer.class, "GtkPrinterFunc_List", 2); //$NON-NLS-1$
	long /*int*/ GtkPrinterFunc_List = printerCallback.getAddress();
	if (GtkPrinterFunc_List == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
	OS.gtk_enumerate_printers(GtkPrinterFunc_List, 0, 0, true);
	/*
	* This call to gdk_threads_leave() is a temporary work around
	* to avoid deadlocks when gdk_threads_init() is called by native
	* code outside of SWT (i.e AWT, etc). It ensures that the current
	* thread leaves the GTK lock acquired by the function above.
	*/
	OS.gdk_threads_leave();
	printerCallback.dispose ();
	return printerList;
}

static long /*int*/ GtkPrinterFunc_List (long /*int*/ printer, long /*int*/ 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() {
	findData = null;
	if (disablePrinting) {
		return null;
	}
	gtk_init();
	Callback printerCallback = new Callback(Printer.class, "GtkPrinterFunc_Default", 2); //$NON-NLS-1$
	long /*int*/ GtkPrinterFunc_Default = printerCallback.getAddress();
	if (GtkPrinterFunc_Default == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
	OS.gtk_enumerate_printers(GtkPrinterFunc_Default, 0, 0, true);
	/*
	* This call to gdk_threads_leave() is a temporary work around
	* to avoid deadlocks when gdk_threads_init() is called by native
	* code outside of SWT (i.e AWT, etc). It ensures that the current
	* thread leaves the GTK lock acquired by the function above.
	*/
	OS.gdk_threads_leave();
	printerCallback.dispose ();
	return findData;
}

static long /*int*/ GtkPrinterFunc_Default (long /*int*/ printer, long /*int*/ user_data) {
	if (OS.gtk_printer_is_default(printer)) {
		findData = printerDataFromGtkPrinter(printer);
		return 1;
	}
	return 0;
}

static long /*int*/ gtkPrinterFromPrinterData(PrinterData data) {
	gtk_init();
	Callback printerCallback = new Callback(Printer.class, "GtkPrinterFunc_FindNamedPrinter", 2); //$NON-NLS-1$
	long /*int*/ GtkPrinterFunc_FindNamedPrinter = printerCallback.getAddress();
	if (GtkPrinterFunc_FindNamedPrinter == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
	findPrinter = 0;
	findData = data;
	OS.gtk_enumerate_printers(GtkPrinterFunc_FindNamedPrinter, 0, 0, true);
	/*
	* This call to gdk_threads_leave() is a temporary work around
	* to avoid deadlocks when gdk_threads_init() is called by native
	* code outside of SWT (i.e AWT, etc). It ensures that the current
	* thread leaves the GTK lock acquired by the function above.
	*/
	OS.gdk_threads_leave();
	printerCallback.dispose ();
	return findPrinter;
}

static long /*int*/ GtkPrinterFunc_FindNamedPrinter (long /*int*/ printer, long /*int*/ user_data) {
	PrinterData pd = printerDataFromGtkPrinter(printer);
	if ((pd.driver.equals(findData.driver) && pd.name.equals(findData.name))
			|| (pd.driver.equals(GTK_FILE_BACKEND)) && findData.printToFile && findData.driver == null && findData.name == null) {
			// TODO: GTK_FILE_BACKEND is not GTK API (see gtk bug 345590)
		findPrinter = printer;
		OS.g_object_ref(printer);
		return 1;
	}
	return 0;
}

static PrinterData printerDataFromGtkPrinter(long /*int*/ printer) {
	long /*int*/ backend = OS.gtk_printer_get_backend(printer);
	long /*int*/ 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 (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 (buffer));

	return new PrinterData (backendType, name);
}

/*
* Restore printer settings and page_setup data from data.
*/
static void restore(byte [] data, long /*int*/ settings, long /*int*/ 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 (keyBuffer))+": "+new String (Converter.mbcsToWcs (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$
	long /*int*/ 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 byte [] uriFromFilename(String filename) {
	if (filename == null) return null;
	int length = filename.length();
	if (length == 0) return null;
	char[] chars = new char[length];
	filename.getChars(0, length, chars, 0);
	long /*int*/[] error = new long /*int*/[1];
	long /*int*/ utf8Ptr = OS.g_utf16_to_utf8(chars, chars.length, null, null, error);
	if (error[0] != 0 || utf8Ptr == 0) return null;
	long /*int*/ localePtr = OS.g_filename_from_utf8(utf8Ptr, -1, null, null, error);
	OS.g_free(utf8Ptr);
	if (error[0] != 0 || localePtr == 0) return null;
	long /*int*/ uriPtr = OS.g_filename_to_uri(localePtr, 0, error);
	OS.g_free(localePtr);
	if (error[0] != 0 || uriPtr == 0) return null;
	length = OS.strlen(uriPtr);
	byte[] uri = new byte[length + 1];
	OS.memmove (uri, uriPtr, length);
	OS.g_free(uriPtr);
	return uri;
}

static DeviceData checkNull (PrinterData data) {
	if (data == null) data = new PrinterData();
	if (data.driver == null || data.name == null) {
		PrinterData defaultData = null;
		if (data.printToFile) {
			long /*int*/ filePrinter = gtkPrinterFromPrinterData(data);
			if (filePrinter != 0) {
				defaultData = printerDataFromGtkPrinter(filePrinter);
				OS.g_object_unref(filePrinter);
			}
		}
		if (defaultData == null) {
			defaultData = getDefaultPrinterData();
			if (defaultData == null) SWT.error(SWT.ERROR_NO_HANDLES);
		}
		data.driver = defaultData.driver;
		data.name = defaultData.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 is no valid default printer
 * </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 (keyBuffer))+": "+new String (Converter.mbcsToWcs (valueBuffer)));

	return valueBuffer;
}

/**
 * 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
 *
 * @noreference This method is not intended to be referenced by clients.
 */
@Override
public long /*int*/ internal_new_GC(GCData data) {
	long /*int*/ gc, drawable = 0;
	if (OS.USE_CAIRO) {
		gc = cairo;
	} else {
		GdkVisual visual = new GdkVisual ();
		OS.memmove (visual, OS.gdk_visual_get_system());
		drawable = OS.gdk_pixmap_new(OS.gdk_get_default_root_window(), 1, 1, visual.depth);
		gc = OS.gdk_gc_new (drawable);
	}
	if (gc == 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 ();
		Point dpi = getDPI(), screenDPI = getIndependentDPI();
		data.width = (int)(OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS) * dpi.x / screenDPI.x);
		data.height = (int)(OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS) * dpi.y / screenDPI.y);
		if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		Cairo.cairo_identity_matrix(cairo);
		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);
		Cairo.cairo_translate(cairo, printX, printY);
		Cairo.cairo_scale(cairo, screenDPI.x / (float)dpi.x, screenDPI.y / (float)dpi.y);
		double[] matrix = new double[6];
		Cairo.cairo_get_matrix(cairo, matrix);
		data.identity = matrix;
		data.cairo = cairo;
		isGCCreated = true;
	}
	return gc;
}

/**
 * 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
 *
 * @noreference This method is not intended to be referenced by clients.
 */
@Override
public void internal_dispose_GC(long /*int*/ hDC, GCData data) {
	long /*int*/ gc = hDC;
	if (data != null) isGCCreated = false;
	if (OS.USE_CAIRO) return;
	OS.g_object_unref (gc);
	if (data != null) {
		if (data.drawable != 0) OS.g_object_unref (data.drawable);
		data.drawable = data.cairo = 0;
	}
}

/**
 * @noreference This method is not intended to be referenced by clients.
 */
@Override
public boolean isAutoScalable() {
	return false;
}

/**
 * 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 (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.
 */
@Override
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);
	OS.g_object_unref(printJob);
	printJob = 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)
	Cairo.cairo_surface_finish(surface);
	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>
 */
@Override
public Point getDPI() {
	checkDevice();
	int resolution = OS.gtk_print_settings_get_resolution(settings);
	if (DEBUG) System.out.println("print_settings.resolution=" + resolution);
	//TODO: use new api for get x resolution and get y resolution
	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
 */
@Override
public Rectangle getBounds() {
	checkDevice();
	Point dpi = getDPI(), screenDPI = getIndependentDPI();
	double width = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS) * dpi.x / screenDPI.x;
	double height = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS) * dpi.y / screenDPI.y;
	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
 */
@Override
public Rectangle getClientArea() {
	checkDevice();
	Point dpi = getDPI(), screenDPI = getIndependentDPI();
	double width = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS) * dpi.x / screenDPI.x;
	double height = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS) * dpi.y / screenDPI.y;
	return new Rectangle(0, 0, (int) width, (int) height);
}

Point getIndependentDPI () {
	return new Point(72, 72);
}

/**
 * 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();
	Point dpi = getDPI(), screenDPI = getIndependentDPI();
	double printWidth = OS.gtk_page_setup_get_page_width(pageSetup, OS.GTK_UNIT_POINTS) * dpi.x / screenDPI.x;
	double printHeight = OS.gtk_page_setup_get_page_height(pageSetup, OS.GTK_UNIT_POINTS) * dpi.y / screenDPI.y;
	double paperWidth = OS.gtk_page_setup_get_paper_width (pageSetup, OS.GTK_UNIT_POINTS) * dpi.x / screenDPI.x;
	double paperHeight = OS.gtk_page_setup_get_paper_height (pageSetup, OS.GTK_UNIT_POINTS) * dpi.y / screenDPI.y;
	double printX = -OS.gtk_page_setup_get_left_margin(pageSetup, OS.GTK_UNIT_POINTS) * dpi.x / screenDPI.x;
	double printY = -OS.gtk_page_setup_get_top_margin(pageSetup, OS.GTK_UNIT_POINTS) * dpi.y / screenDPI.y;
	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
 */
@Override
protected void create(DeviceData deviceData) {
	this.data = (PrinterData)deviceData;
	if (disablePrinting) SWT.error(SWT.ERROR_NO_HANDLES);
	printer = gtkPrinterFromPrinterData(data);
	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
 */
@Override
protected void 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. */
	if (data.printToFile && data.fileName != null) {
		byte [] uri = uriFromFilename(data.fileName);
		if (uri != null) {
			OS.gtk_print_settings_set(settings, OS.GTK_PRINT_SETTINGS_OUTPUT_URI, uri);
		}
	}
	OS.gtk_print_settings_set_n_copies(settings, data.copyCount);
	OS.gtk_print_settings_set_collate(settings, data.collate);
	if (data.duplex != SWT.DEFAULT) {
		int duplex = data.duplex == PrinterData.DUPLEX_LONG_EDGE ? OS.GTK_PRINT_DUPLEX_HORIZONTAL
			: data.duplex == PrinterData.DUPLEX_SHORT_EDGE ? OS.GTK_PRINT_DUPLEX_VERTICAL
			: OS.GTK_PRINT_DUPLEX_SIMPLEX;
		OS.gtk_print_settings_set_duplex (settings, duplex);
		/*
		 * Bug in GTK.  The cups backend only looks at the value
		 * of the non-API field cups-Duplex in the print_settings.
		 * The fix is to manually set cups-Duplex to Tumble or NoTumble.
		 */
		String cupsDuplexType = null;
		if (duplex == OS.GTK_PRINT_DUPLEX_HORIZONTAL) cupsDuplexType = "DuplexNoTumble";
		else if (duplex == OS.GTK_PRINT_DUPLEX_VERTICAL) cupsDuplexType = "DuplexTumble";
		if (cupsDuplexType != null) {
			byte [] keyBuffer = Converter.wcsToMbcs ("cups-Duplex", true);
			byte [] valueBuffer = Converter.wcsToMbcs (cupsDuplexType, true);
			OS.gtk_print_settings_set(settings, keyBuffer, valueBuffer);
		}
	}
	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);
	super.init ();
}

/**
 * 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;
}

}
