[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    Re: wine based win32 printer drivers
From:       Marcel Partap <mpartap () gmx ! net>
Date:       2008-03-31 3:52:32
Message-ID: 47F06000.7050401 () gmx ! net
[Download RAW message or body]

> A Postscript Driver has no raster renderer...
> A Postscript Driver has a Postscript Engine.
... ^ ^

>> DRIVER_EVENT_INITIALIZE, 3,
> "3" is wrong here. See: myAddPrinterDriverEx(DWORD level, ...
It seemed suspicious to me anyway.. How do those integer shifts creep into my retyped header files 
again and again? mmmmhhh ... *g

> Since there are much more Events, we need the DriverUI in more Places
> later. I suggest a simple struct, which can be extended later
> (The struct must include the Results from GetProcAddress)
a struct.. that contains what? the function pointers and results? i had thought about adding a 
macro.. for hooking driver exports..

> The changes for winspool.drv must go in a seperate Patch.
yeah it jsut was a quick and dirty preview patch ;)

> WINSPOOL_CallDrvDocumentProperties is the wrong name, when you 
> call DrvDocumentPropertySheets.
statement totally makes sense.

> You should collect all API in winspool.drv, that need the driverui
> (some are not implemented) and design a simple struct
> with helper functions (Use monitor_t as example).
I dont really grok it... like the DDI_FUNCS array in the patch i sent you or rather somethign
stuct {
     LPWSTR name;
     LPWSTR driverdll;
     HMODULE hdriver;
     LPWSTR interfacedll;
     HMODULE hinterface,
     DWORD refcount;
} printertriver_t;
?

> Not all Drivers Export DrvDocumentPropertySheets.
> You must prepare to use a Fallback to get the default devmode
> (DrvConvertDevMode)
ok just need to transplant my old code

> See winspool.drv/monitor_load as Example:
l8r :)

> The current Code is a crosscall from DocumentPropertiesW to
> DocumentPropertiesA.
> The DDI-API is unicode and should be the prefered way.
so shall i put the ddi call before that deprecated stuff? and does it need to be called from docpropsA?
oh and I reodne the EnumForms patch (now less monsterous ;). Now here's only the part that provides 
the builtin forms, but very easy to expand, once its ready to be &/ comimtted i'll do the addforms 
delforms stuff..
and oh sh1t gotta write my soc application today last day heh.. this time i'm opting for drupal/php 
code though C/win32api is just too hellish *g
n8

-- 
<div id="signature">
   "Obstacles are those frightful things you see when you take your eyes off your goal."
                                                               -- Henry Ford (1863-1947)
   Change the world! Vote revolution: http://hfopi.org/vote-future
</div>

["0002-winspool-implement-EnumFormsA-W-with-built-in-forms.patch" (text/x-patch)]

From 8018b72f94b3a63598db70c95851ebf0a49da89f Mon Sep 17 00:00:00 2001
From: Marcel Partap <mpartap@gmx.net>
Date: Mon, 31 Mar 2008 05:29:09 +0200
Subject: [PATCH] winspool: implement EnumFormsA/W with built-in forms

---
 dlls/winspool.drv/info.c |  145 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 135 insertions(+), 10 deletions(-)

diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 351aaba..0071ef4 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -123,6 +123,17 @@ typedef struct {
     WCHAR *document_title;
 } job_t;
 
+typedef struct {
+    SIZEL size;
+    RECTL area;
+    DWORD formorder;
+    DWORD flags;
+} form_regentry_t;
+
+typedef struct {
+    WCHAR           formname[CCHFORMNAME];
+    form_regentry_t formdata;
+} builtin_form_t;
 
 typedef struct {
     LPCWSTR  envname;
@@ -248,6 +259,12 @@ static const WCHAR LPR_Port[] = {'L','P','R',':',0};
 static const WCHAR default_doc_title[] = {'L','o','c','a','l',' \
                ','D','o','w','n','l','e','v','e','l',' ',
                                           'D','o','c','u','m','e','n','t',0};
 
+static const builtin_form_t builtin_forms[] = {
+    {{'L','e','t','t','e','r',0}, {{216000,279000}, {0,0,216000,279000}, 0, \
FORM_BUILTIN}}, +    {{'A','3',0}, {{297000,420000}, {0,0,297000,420000}, 0, \
FORM_BUILTIN}}, +    {{'A','4',0}, {{210000,297000}, {0,0,210000,297000}, 0, \
FORM_BUILTIN}}, +    {{'A','5',0}, {{148000,210000}, {0,0,148000,210000}, 0, \
FORM_BUILTIN}} }; +
 static const DWORD di_sizeof[] = {0, sizeof(DRIVER_INFO_1W), sizeof(DRIVER_INFO_2W),
                                      sizeof(DRIVER_INFO_3W), sizeof(DRIVER_INFO_4W),
                                      sizeof(DRIVER_INFO_5W), sizeof(DRIVER_INFO_6W),
@@ -7181,23 +7198,131 @@ BOOL WINAPI DeletePrintProvidorW(LPWSTR pName, LPWSTR \
pEnvironment, LPWSTR pPrin  \
                /******************************************************************************
                
  *      EnumFormsA (WINSPOOL.@)
  */
-BOOL WINAPI EnumFormsA( HANDLE hPrinter, DWORD Level, LPBYTE pForm,
-    DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned )
+BOOL WINAPI EnumFormsA(HANDLE hPrinter, DWORD Level, LPBYTE pForm,
+                       DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
-    FIXME("%p %x %p %x %p %p\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, \
                pcReturned);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    PFORM_INFO_1A fiA;
+    PFORM_INFO_1W fiW;
+    LPBYTE bufferW;
+    BOOL   res;
+    DWORD  i;
+    DWORD  needed = 0;
+    DWORD  num = 0;
+
+    TRACE("(%p %d %p %d %p %p)\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, \
pcReturned); +
+    if (!pcbNeeded || !pcReturned) {
+        SetLastError(RPC_X_NULL_REF_POINTER);
+        return FALSE;
+    }
+    EnumFormsW(hPrinter, Level, NULL, 0, &needed, &num);
+    if (!needed)
+        return FALSE;
+    *pcbNeeded = (needed - num*sizeof(FORM_INFO_1W))/sizeof(WCHAR) + \
num*sizeof(FORM_INFO_1W); +    if (cbBuf < *pcbNeeded) {
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return FALSE;
+    }
+    if (!pForm) {
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+        return FALSE;
+    }
+    bufferW = HeapAlloc(GetProcessHeap(), 0, needed);
+    res = EnumFormsW(hPrinter, Level, bufferW, needed, &needed, pcReturned);
+    if (res) {
+        fiA = (PFORM_INFO_1A)pForm;
+        fiW = (PFORM_INFO_1W)bufferW;
+        for (i = 0; i < *pcReturned; i++) {
+            memcpy(fiA, fiW, sizeof(FORM_INFO_1W));
+            cbBuf -= sizeof(FORM_INFO_1A);
+            cbBuf -= WideCharToMultiByte(CP_ACP, 0, fiW->pName, -1, fiA->pName, \
cbBuf, NULL, NULL); +            fiA++;
+            fiW++;
+        }
+    }
+    HeapFree(GetProcessHeap(), 0, bufferW);
+    TRACE("returning %d with %d (%d Bytes for %d entries)\n", res, GetLastError(), \
*pcbNeeded, *pcReturned); +    return res;
 }
 
 /******************************************************************************
  *      EnumFormsW (WINSPOOL.@)
+ * enumerates available paper forms (not printer specific)
+ * 
+ * PARAMS
+ *  hPrinter   (I) handle to printer (must be valid)
+ *  Level      (I) type of returned form information data structure
+ *  pForm      (O) pointer to user supplied buffer
+ *  cbBuf      (I) size of output buffer
+ *  pcbNeeded  (O) required/ used buffer space
+ *  pcReturned (O) number of returned forms
+ *
+ * RETURNS
+ *  Success: TRUE (non-zero value)
+ *  Failure: FALSE (0)
+ *
+ * FIXME
+ *  level 2 not yet implemented
  */
-BOOL WINAPI EnumFormsW( HANDLE hPrinter, DWORD Level, LPBYTE pForm,
-    DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned )
+BOOL WINAPI EnumFormsW(HANDLE hPrinter, DWORD Level, LPBYTE pForm,
+                       DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 {
-    FIXME("%p %x %p %x %p %p\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, \
                pcReturned);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    opened_printer_t *printer = NULL;
+    PFORM_INFO_1W fiW;
+    LPWSTR strptr;
+    BOOL   res = FALSE;
+    DWORD  i;
+    DWORD  num;
+    DWORD  needed = 0;
+
+    TRACE("(%p %d %p %d %p %p)\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, \
pcReturned); +
+    if (!(printer = get_opened_printer(hPrinter))) {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+    if (Level != 1) {
+        if (Level == 2)
+            FIXME("level 2 not yet supported\n");
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
+
+    num = sizeof(builtin_forms)/sizeof(builtin_form_t);
+    for (i = 0; i < num; i++) {
+        needed += sizeof(FORM_INFO_1W) + \
(strlenW(builtin_forms[i].formname)+1)*sizeof(WCHAR); +    }
+
+    if (cbBuf < needed) {
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        goto efw_cleanup;
+    }
+    if (!pForm) {
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+        goto efw_cleanup;
+    }
+    if (!pcbNeeded || !pcReturned) {
+        SetLastError(RPC_X_NULL_REF_POINTER);
+        goto efw_cleanup;
+    }
+    strptr = (LPWSTR)(pForm + num*sizeof(FORM_INFO_1W));
+    fiW = (PFORM_INFO_1W)pForm;
+    for (i = 0; i < num; i++) {
+        fiW->pName = lstrcpyW(strptr, builtin_forms[i].formname);
+        fiW->Size = builtin_forms[i].formdata.size;
+        fiW->ImageableArea = builtin_forms[i].formdata.area;
+        fiW->Flags = builtin_forms[i].formdata.flags;
+        fiW++;
+        strptr += lstrlenW(builtin_forms[i].formname)+1;
+    }
+    res = TRUE;
+
+efw_cleanup:
+    if (pcbNeeded) *pcbNeeded = needed;
+    if (pcReturned && res) *pcReturned = num;
+
+    TRACE("returning %d with %d (%d Bytes for %d entries)\n", res, GetLastError(), \
needed, num); +    return res;
 }
 
 /*****************************************************************************
-- 
1.5.4.4





[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic