[gs-commits] ghostpdl branch, master, updated. jbig2dec-0.14-1585-g9dae3b2

[email protected] (Chris Liddell)
Newsgroups gmane.comp.printing.ghostscript.cvs
Message-ID <[email protected]>
The ghostpdl branch, master has been updated
       via  9dae3b271e781c076e49d94dc8590ed95e3f38c9 (commit)
      from  6c18c7092e8945dcd932226bfea790c842ae21a0 (commit)

----------------------------------------------------------------------
commit 9dae3b271e781c076e49d94dc8590ed95e3f38c9
Author: Chris Liddell <[email protected]>
Date:   Mon Aug 19 10:03:57 2019 +0100

    Handle drag'n'drop file name/paths
    
    Because we now run by default with the file access permission active,
    we need to do additional work for Windows drag and drop files, so they don't
    throw an invalidaccess error (since we implement drag and drop by sending
    characters to the gs console to do '(file) run').
    
    The problem is, we cannot add the file to read list, send the characters to the
    console, and remove the file from the read list because, although SendMessage()
    blocks until the message is handles, WriteConsoleInput() does not block until
    the console buffers are consumed (i.e. it is asynchronous). So, there is no
    certainty when the final SendMessage() in WM_DROPFILES case is finished that
    Ghostcript will actually have run the file.
    
    So, we create a list of dropped file names, add them to the permit read list,
    when the next WM_DROPFILES event happens, or a WM_DESTROY event, we drop
    file names from the permit read list before, if necessary, adding the current
    ones.

diff --git a/psi/dwimg.c b/psi/dwimg.c
index c38a2c3..62f7f5f 100644
--- a/psi/dwimg.c
+++ b/psi/dwimg.c
@@ -51,6 +51,10 @@
 static const char szImgName2[] = "Ghostscript Image";
 static const char szTrcName2[] = "Ghostscript Graphical Trace";
 
+/* These two are defined in dwmain.c/dwmainc.c because they need access to the gsdll and instance */
+int dwmain_add_file_control_path(const TCHAR *pathfile);
+void dwmain_remove_file_control_path(const TCHAR *pathfile);
+
 /* Forward references */
 LRESULT CALLBACK WndImg2Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 
@@ -1157,6 +1161,8 @@ WndImg2Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     RECT rect;
     int nVscrollInc, nHscrollInc;
     IMAGE *img;
+    static int cFiles = 0;
+    static char** szFiles = NULL;
 
     if (message == WM_CREATE) {
         /* Object is stored in window extra data.
@@ -1455,32 +1461,50 @@ WndImg2Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             if (img->hwndtext)
                 SendMessage(img->hwndtext, message, wParam, lParam);
             else {
-                char *szFile;
-                int i, cFiles;
+                int i, lcFiles, code;
                 unsigned int Len, error;
                 const char *p;
                 const char *szDragPre = "\r(";
                 const char *szDragPost = ") run\r";
                 HDROP hdrop = (HDROP)wParam;
-                cFiles = DragQueryFile(hdrop, (UINT)(-1), (LPSTR)NULL, 0);
-                for (i=0; i<cFiles; i++) {
+                for (i = 0; szFiles != NULL && i < cFiles; i++) {
+                    if (szFiles[i] != NULL) {
+                        dwmain_remove_file_control_path(szFiles[i]);
+                            free(szFiles[i]);
+                            szFiles[i] = NULL;
+                    }
+                }
+                lcFiles = DragQueryFile(hdrop, (UINT)(-1), (LPSTR)NULL, 0);
+                if (cFiles < lcFiles) {
+                    free(szFiles);
+                    szFiles = malloc(lcFiles * sizeof(char*));
+                    if (!szFiles) {
+                        cFiles = 0;
+                        return 0;
+                    }
+                    memset(szFiles, 0x00, lcFiles * sizeof(char*));
+                    cFiles = lcFiles;
+                }
+                for (i=0; i<lcFiles; i++) {
                     Len = DragQueryFile(hdrop, i, NULL, 0);
-                    szFile = malloc(Len+1);
-                    if (szFile != 0) {
-                        error = DragQueryFile(hdrop, i, szFile, Len+1);
+                    szFiles[i] = malloc(Len+1);
+                    if (szFiles[i] != 0) {
+                        error = DragQueryFile(hdrop, i, szFiles[i], Len+1);
                         if (error != 0) {
-                            for (p=szDragPre; *p; p++)
-                                SendMessage(hwnd,WM_CHAR,*p,1L);
-                            for (p=szFile; *p; p++) {
-                                if (*p == '\\')
-                                    SendMessage(hwnd,WM_CHAR,'/',1L);
-                                else
+                            code = dwmain_add_file_control_path(szFiles[i]);
+                            if (code >= 0){
+                                for (p=szDragPre; *p; p++)
+                                    SendMessage(hwnd,WM_CHAR,*p,1L);
+                                for (p=szFiles[i]; *p; p++) {
+                                    if (*p == '\\')
+                                        SendMessage(hwnd,WM_CHAR,'/',1L);
+                                    else
+                                        SendMessage(hwnd,WM_CHAR,*p,1L);
+                                }
+                                for (p=szDragPost; *p; p++)
                                     SendMessage(hwnd,WM_CHAR,*p,1L);
                             }
-                            for (p=szDragPost; *p; p++)
-                                SendMessage(hwnd,WM_CHAR,*p,1L);
                         }
-                        free(szFile);
                     }
                 }
                 DragFinish(hdrop);
@@ -1493,12 +1517,25 @@ WndImg2Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                     img->cx, img->cy);
                 win_set_reg_value((img->device != NULL ? "Image" : "Tracer"), winposbuf);
             }
+            { /* Get rid of left over drag'n'drop file names*/
+                int i;
+                for (i = 0; szFiles != NULL && i < cFiles; i++) {
+                    if (szFiles[i] != NULL) {
+                        dwmain_remove_file_control_path(szFiles[i]);
+                        free(szFiles[i]);
+                        szFiles[i] = NULL;
+                    }
+                }
+                free(szFiles);
+                szFiles = NULL;
+                cFiles = 0;
+            }
             DragAcceptFiles(hwnd, FALSE);
             break;
 
     }
 
-        return DefWindowProc(hwnd, message, wParam, lParam);
+    return DefWindowProc(hwnd, message, wParam, lParam);
 }
 
 /* Repaint a section of the window. */
diff --git a/psi/dwmain.c b/psi/dwmain.c
index 224dd29..ebddbb5 100644
--- a/psi/dwmain.c
+++ b/psi/dwmain.c
@@ -97,6 +97,45 @@ static int GSDLLCALL gsdll_poll(void *handle)
 {
     return poll();
 }
+
+/* make a file readable, for drag'n'drop */
+int dwmain_add_file_control_path(const TCHAR *pathfile)
+{
+    LPSTR p;
+    int code, i;
+    p = malloc(wchar_to_utf8(NULL, (wchar_t *)pathfile));
+    if (p) {
+        wchar_to_utf8(p, (wchar_t *)pathfile);
+        for (i = 0; i < strlen(p); i++) {
+            if (p[i] == '\\') {
+                p[i] = '/';
+            }
+        }
+        code = gsdll.add_control_path(instance, GS_PERMIT_FILE_READING, p);
+        free(p);
+    }
+    else {
+        code = -1;
+    }
+    return code;
+}
+void dwmain_remove_file_control_path(const TCHAR *pathfile)
+{
+    LPSTR p;
+    int i;
+    p = malloc(wchar_to_utf8(NULL, (wchar_t *)pathfile));
+    if (p) {
+        wchar_to_utf8(p, (wchar_t *)pathfile);
+        for (i = 0; i < strlen(p); i++) {
+            if (p[i] == '\\') {
+                p[i] = '/';
+            }
+        }
+        gsdll.remove_control_path(instance, GS_PERMIT_FILE_READING, p);
+        free(p);
+    }
+}
+
 /*********************************************************************/
 
 /* new dll display device */
diff --git a/psi/dwmainc.c b/psi/dwmainc.c
index 9e7558f..cc0db1f 100644
--- a/psi/dwmainc.c
+++ b/psi/dwmainc.c
@@ -109,6 +109,44 @@ gsdll_stderr(void *instance, const char *str, int len)
     return len;
 }
 
+/* make a file readable, for drag'n'drop */
+/* In this version (for the console app) TCHAR is just char */
+int dwmain_add_file_control_path(const TCHAR *pathfile)
+{
+    int i, code;
+    char *p = (char *)pathfile;
+
+    for (i = 0; i < strlen(p); i++) {
+        if (p[i] == '\\') {
+            p[i] = '/';
+        }
+    }
+    code = gsdll.add_control_path(instance, GS_PERMIT_FILE_READING, (const char *)p);
+    for (i = 0; i < strlen(p); i++) {
+        if (p[i] == '/') {
+            p[i] = '\\';
+        }
+    }
+    return code;
+}
+void dwmain_remove_file_control_path(const TCHAR *pathfile)
+{
+    int i;
+    char *p = (char *)pathfile;
+
+    for (i = 0; i < strlen(p); i++) {
+        if (p[i] == '\\') {
+            p[i] = '/';
+        }
+    }
+    gsdll.remove_control_path(instance, GS_PERMIT_FILE_READING, (const char *)p);
+    for (i = 0; i < strlen(p); i++) {
+        if (p[i] == '/') {
+            p[i] = '\\';
+        }
+    }
+}
+
 /* stdio functions - versions that translate to/from utf-8 */
 static int GSDLLCALL
 gsdll_stdin_utf8(void *instance, char *buf, int len)
diff --git a/psi/dwtext.c b/psi/dwtext.c
index 750c216..984ea45 100644
--- a/psi/dwtext.c
+++ b/psi/dwtext.c
@@ -50,6 +50,10 @@
 #define M_COPY_CLIP 1
 #define M_PASTE_CLIP 2
 
+/* These two are defined in dwmain.c/dwmainc.c because they need access to the gsdll and instance */
+int dwmain_add_file_control_path(const TCHAR *pathfile);
+void dwmain_remove_file_control_path(const TCHAR *pathfile);
+
 LRESULT CALLBACK WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 static void text_error(char *message);
 static void text_new_line(TW *tw);
@@ -736,33 +740,52 @@ int ch;
 void
 text_drag_drop(TW *tw, HDROP hdrop)
 {
-    TCHAR *szFile;
-    int i, cFiles;
+    int i, cFiles, code;
     unsigned int Len, error;
     const char *p;
     const TCHAR *t;
     if ( (tw->DragPre==NULL) || (tw->DragPost==NULL) )
             return;
 
+    for (i = 0; tw->szFiles && i < tw->cFiles; i++) {
+        if (tw->szFiles[i] != NULL) {
+            dwmain_remove_file_control_path(tw->szFiles[i]);
+            free(tw->szFiles[i]);
+            tw->szFiles[i] = NULL;
+        }
+    }
+
     cFiles = DragQueryFile(hdrop, (UINT)(-1), (LPTSTR)NULL, 0);
+    if (tw->cFiles < cFiles) {
+        free(tw->szFiles);
+        tw->szFiles = malloc(cFiles * sizeof(char*));
+        if (tw->szFiles == NULL) {
+            tw->cFiles = 0;
+            return;
+        }
+        memset(tw->szFiles, 0x00, cFiles * sizeof(char*));
+        tw->cFiles = cFiles;
+    }
     for (i=0; i<cFiles; i++) {
         Len = DragQueryFile(hdrop, i, NULL, 0);
-        szFile = (TCHAR *)malloc((Len+1)*sizeof(TCHAR));
-        if (szFile != 0) {
-            error = DragQueryFile(hdrop, i, szFile, Len+1);
+        tw->szFiles[i] = (TCHAR *)malloc((Len+1)*sizeof(TCHAR));
+        if (tw->szFiles[i] != 0) {
+            error = DragQueryFile(hdrop, i, tw->szFiles[i], Len+1);
             if (error != 0) {
-                for (p=tw->DragPre; *p; p++)
-                    SendMessage(tw->hwnd,WM_CHAR,*p,1L);
-                for (t=szFile; *t; t++) {
-                    if (*t == '\\')
-                        SendMessage(tw->hwnd,WM_CHAR,'/',1L);
-                    else
-                        SendMessage(tw->hwnd,WM_CHAR,*t,1L);
+                code = dwmain_add_file_control_path(tw->szFiles[i]);
+                if (code >= 0) {
+                    for (p=tw->DragPre; *p; p++)
+                        SendMessage(tw->hwnd,WM_CHAR,*p,1L);
+                    for (t=tw->szFiles[i]; *t; t++) {
+                        if (*t == '\\')
+                            SendMessage(tw->hwnd,WM_CHAR,'/',1L);
+                        else
+                            SendMessage(tw->hwnd,WM_CHAR,*t,1L);
+                    }
+                    for (p=tw->DragPost; *p; p++)
+                        SendMessage(tw->hwnd,WM_CHAR,*p,1L);
                 }
-                for (p=tw->DragPost; *p; p++)
-                    SendMessage(tw->hwnd,WM_CHAR,*p,1L);
             }
-            free(szFile);
         }
     }
     DragFinish(hdrop);
@@ -1155,6 +1178,17 @@ WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
             if (tw->hfont)
                 DeleteFont(tw->hfont);
             tw->hfont = (HFONT)0;
+            {/* Remove left over drag'n'drop file names */
+                int i;
+                for (i = 0; tw->szFiles != NULL && i < tw->cFiles; i++) {
+                    dwmain_remove_file_control_path(tw->szFiles[i]);
+                    free(tw->szFiles[i]);
+                    tw->szFiles[i] = NULL;
+                }
+                free(tw->szFiles);
+                tw->szFiles = NULL;
+                tw->cFiles = 0;
+            }
             tw->quitnow = TRUE;
             PostQuitMessage(0);
             break;
diff --git a/psi/dwtext.h b/psi/dwtext.h
index 46b8e23..4a02d5c 100644
--- a/psi/dwtext.h
+++ b/psi/dwtext.h
@@ -72,6 +72,8 @@ typedef struct TEXTWINDOW_S {
 
     int x, y, cx, cy;	/* window position */
     int utf8shift;
+    TCHAR** szFiles;
+    int cFiles;
 } TW;
 
 /* Create new TW structure */


Summary of changes:
 psi/dwimg.c   | 71 +++++++++++++++++++++++++++++++++++++++++++++--------------
 psi/dwmain.c  | 39 ++++++++++++++++++++++++++++++++
 psi/dwmainc.c | 38 ++++++++++++++++++++++++++++++++
 psi/dwtext.c  | 64 ++++++++++++++++++++++++++++++++++++++++-------------
 psi/dwtext.h  |  2 ++
 5 files changed, 182 insertions(+), 32 deletions(-)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.