aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2020-04-19 21:09:20 +0300
committerEli Zaretskii2020-04-19 21:09:20 +0300
commit423089d18b6a8528dc3c70dce28c7011680e18be (patch)
tree35aee5f364df6829f69c7f4ef5b2e4d6de9b2f44 /src
parent3f8b771da96f9a55dd5ed322104135a0c2c6f2e4 (diff)
downloademacs-423089d18b6a8528dc3c70dce28c7011680e18be.tar.gz
emacs-423089d18b6a8528dc3c70dce28c7011680e18be.zip
Rework how GDI+ functions are loaded dynamically in w32image.c
* src/w32image.c: Define correct WINGDIPAPI typedefs for GDI+ functions. We cannot use DEF_DLL_FN, since that is for functions with C calling conventions, whereas GDI+ functions are __stdcall. (gdiplus_init): Load functions from DLL manually, not via LOAD_DLL_FN, as the latter is for __cdecl functions. (w32_frame_delay): Initialize delay with a negative value, as zero is a valid delay.
Diffstat (limited to 'src')
-rw-r--r--src/w32image.c145
1 files changed, 102 insertions, 43 deletions
diff --git a/src/w32image.c b/src/w32image.c
index 31c9b852ace..085a5db3abd 100644
--- a/src/w32image.c
+++ b/src/w32image.c
@@ -40,28 +40,47 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
40 40
41#ifdef WINDOWSNT 41#ifdef WINDOWSNT
42 42
43DEF_DLL_FN (GpStatus, GdiplusStartup, 43typedef GpStatus (WINGDIPAPI *GdiplusStartup_Proc)
44 (ULONG_PTR *, GdiplusStartupInput *, GdiplusStartupOutput *)); 44 (ULONG_PTR *, GdiplusStartupInput *, GdiplusStartupOutput *);
45DEF_DLL_FN (VOID, GdiplusShutdown, (ULONG_PTR)); 45typedef VOID (WINGDIPAPI *GdiplusShutdown_Proc) (ULONG_PTR);
46DEF_DLL_FN (GpStatus, GdipGetPropertyItemSize, 46typedef GpStatus (WINGDIPAPI *GdipGetPropertyItemSize_Proc)
47 (GpImage *, PROPID, UINT *)); 47 (GpImage *, PROPID, UINT *);
48DEF_DLL_FN (GpStatus, GdipGetPropertyItem, 48typedef GpStatus (WINGDIPAPI *GdipGetPropertyItem_Proc)
49 (GpImage *, PROPID, UINT, PropertyItem *)); 49 (GpImage *, PROPID, UINT, PropertyItem *);
50DEF_DLL_FN (GpStatus, GdipImageGetFrameDimensionsCount, (GpImage *, UINT *)); 50typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsCount_Proc)
51DEF_DLL_FN (GpStatus, GdipImageGetFrameDimensionsList, 51 (GpImage *, UINT *);
52 (GpImage *, GUID *, UINT)); 52typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsList_Proc)
53DEF_DLL_FN (GpStatus, GdipImageGetFrameCount, 53 (GpImage *, GUID *, UINT);
54 (GpImage *, GDIPCONST GUID *, UINT *)); 54typedef GpStatus (WINGDIPAPI *GdipImageGetFrameCount_Proc)
55DEF_DLL_FN (GpStatus, GdipImageSelectActiveFrame, 55 (GpImage *, GDIPCONST GUID *, UINT *);
56 (GpImage*, GDIPCONST GUID *, UINT)); 56typedef GpStatus (WINGDIPAPI *GdipImageSelectActiveFrame_Proc)
57DEF_DLL_FN (GpStatus, GdipCreateBitmapFromFile, (WCHAR *, GpBitmap **)); 57 (GpImage*, GDIPCONST GUID *, UINT);
58DEF_DLL_FN (GpStatus, GdipCreateBitmapFromStream, (IStream *, GpBitmap **)); 58typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromFile_Proc)
59DEF_DLL_FN (IStream *, SHCreateMemStream, (const BYTE *pInit, UINT cbInit)); 59 (WCHAR *, GpBitmap **);
60DEF_DLL_FN (GpStatus, GdipCreateHBITMAPFromBitmap, 60typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromStream_Proc)
61 (GpBitmap *, HBITMAP *, ARGB)); 61 (IStream *, GpBitmap **);
62DEF_DLL_FN (GpStatus, GdipDisposeImage, (GpImage *)); 62typedef IStream * (WINAPI *SHCreateMemStream_Proc) (const BYTE *, UINT);
63DEF_DLL_FN (GpStatus, GdipGetImageHeight, (GpImage *, UINT *)); 63typedef GpStatus (WINGDIPAPI *GdipCreateHBITMAPFromBitmap_Proc)
64DEF_DLL_FN (GpStatus, GdipGetImageWidth, (GpImage *, UINT *)); 64 (GpBitmap *, HBITMAP *, ARGB);
65typedef GpStatus (WINGDIPAPI *GdipDisposeImage_Proc) (GpImage *);
66typedef GpStatus (WINGDIPAPI *GdipGetImageHeight_Proc) (GpImage *, UINT *);
67typedef GpStatus (WINGDIPAPI *GdipGetImageWidth_Proc) (GpImage *, UINT *);
68
69GdiplusStartup_Proc fn_GdiplusStartup;
70GdiplusShutdown_Proc fn_GdiplusShutdown;
71GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize;
72GdipGetPropertyItem_Proc fn_GdipGetPropertyItem;
73GdipImageGetFrameDimensionsCount_Proc fn_GdipImageGetFrameDimensionsCount;
74GdipImageGetFrameDimensionsList_Proc fn_GdipImageGetFrameDimensionsList;
75GdipImageGetFrameCount_Proc fn_GdipImageGetFrameCount;
76GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame;
77GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile;
78GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream;
79SHCreateMemStream_Proc fn_SHCreateMemStream;
80GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap;
81GdipDisposeImage_Proc fn_GdipDisposeImage;
82GdipGetImageHeight_Proc fn_GdipGetImageHeight;
83GdipGetImageWidth_Proc fn_GdipGetImageWidth;
65 84
66static bool 85static bool
67gdiplus_init (void) 86gdiplus_init (void)
@@ -72,33 +91,73 @@ gdiplus_init (void)
72 && (shlwapi_lib = w32_delayed_load (Qshlwapi)))) 91 && (shlwapi_lib = w32_delayed_load (Qshlwapi))))
73 return false; 92 return false;
74 93
75 LOAD_DLL_FN (gdiplus_lib, GdiplusStartup); 94 fn_GdiplusStartup = (GdiplusStartup_Proc)
76 LOAD_DLL_FN (gdiplus_lib, GdiplusShutdown); 95 get_proc_addr (gdiplus_lib, "GdiplusStartup");
77 LOAD_DLL_FN (gdiplus_lib, GdipGetPropertyItemSize); 96 if (!fn_GdiplusStartup)
78 LOAD_DLL_FN (gdiplus_lib, GdipGetPropertyItem); 97 return false;
79 LOAD_DLL_FN (gdiplus_lib, GdipImageGetFrameDimensionsCount); 98 fn_GdiplusShutdown = (GdiplusShutdown_Proc)
80 LOAD_DLL_FN (gdiplus_lib, GdipImageGetFrameDimensionsList); 99 get_proc_addr (gdiplus_lib, "GdiplusShutdown");
81 LOAD_DLL_FN (gdiplus_lib, GdipImageGetFrameCount); 100 if (!fn_GdiplusShutdown)
82 LOAD_DLL_FN (gdiplus_lib, GdipImageSelectActiveFrame); 101 return false;
83 LOAD_DLL_FN (gdiplus_lib, GdipCreateBitmapFromFile); 102 fn_GdipGetPropertyItemSize = (GdipGetPropertyItemSize_Proc)
84 LOAD_DLL_FN (gdiplus_lib, GdipCreateBitmapFromStream); 103 get_proc_addr (gdiplus_lib, "GdipGetPropertyItemSize");
85 LOAD_DLL_FN (gdiplus_lib, GdipCreateHBITMAPFromBitmap); 104 if (!fn_GdipGetPropertyItemSize)
86 LOAD_DLL_FN (gdiplus_lib, GdipDisposeImage); 105 return false;
87 LOAD_DLL_FN (gdiplus_lib, GdipGetImageHeight); 106 fn_GdipGetPropertyItem = (GdipGetPropertyItem_Proc)
88 LOAD_DLL_FN (gdiplus_lib, GdipGetImageWidth); 107 get_proc_addr (gdiplus_lib, "GdipGetPropertyItem");
108 if (!fn_GdipGetPropertyItem)
109 return false;
110 fn_GdipImageGetFrameDimensionsCount = (GdipImageGetFrameDimensionsCount_Proc)
111 get_proc_addr (gdiplus_lib, "GdipImageGetFrameDimensionsCount");
112 if (!fn_GdipImageGetFrameDimensionsCount)
113 return false;
114 fn_GdipImageGetFrameDimensionsList = (GdipImageGetFrameDimensionsList_Proc)
115 get_proc_addr (gdiplus_lib, "GdipImageGetFrameDimensionsList");
116 if (!fn_GdipImageGetFrameDimensionsList)
117 return false;
118 fn_GdipImageGetFrameCount = (GdipImageGetFrameCount_Proc)
119 get_proc_addr (gdiplus_lib, "GdipImageGetFrameCount");
120 if (!fn_GdipImageGetFrameCount)
121 return false;
122 fn_GdipImageSelectActiveFrame = (GdipImageSelectActiveFrame_Proc)
123 get_proc_addr (gdiplus_lib, "GdipImageSelectActiveFrame");
124 if (!fn_GdipImageSelectActiveFrame)
125 return false;
126 fn_GdipCreateBitmapFromFile = (GdipCreateBitmapFromFile_Proc)
127 get_proc_addr (gdiplus_lib, "GdipCreateBitmapFromFile");
128 if (!fn_GdipCreateBitmapFromFile)
129 return false;
130 fn_GdipCreateBitmapFromStream = (GdipCreateBitmapFromStream_Proc)
131 get_proc_addr (gdiplus_lib, "GdipCreateBitmapFromStream");
132 if (!fn_GdipCreateBitmapFromStream)
133 return false;
134 fn_GdipCreateHBITMAPFromBitmap = (GdipCreateHBITMAPFromBitmap_Proc)
135 get_proc_addr (gdiplus_lib, "GdipCreateHBITMAPFromBitmap");
136 if (!fn_GdipCreateHBITMAPFromBitmap)
137 return false;
138 fn_GdipDisposeImage = (GdipDisposeImage_Proc)
139 get_proc_addr (gdiplus_lib, "GdipDisposeImage");
140 if (!fn_GdipDisposeImage)
141 return false;
142 fn_GdipGetImageHeight = (GdipGetImageHeight_Proc)
143 get_proc_addr (gdiplus_lib, "GdipGetImageHeight");
144 if (!fn_GdipGetImageHeight)
145 return false;
146 fn_GdipGetImageWidth = (GdipGetImageWidth_Proc)
147 get_proc_addr (gdiplus_lib, "GdipGetImageWidth");
148 if (!fn_GdipGetImageWidth)
149 return false;
89 /* LOAD_DLL_FN (shlwapi_lib, SHCreateMemStream); */ 150 /* LOAD_DLL_FN (shlwapi_lib, SHCreateMemStream); */
90 151
91 /* The following terrible kludge is required to use native image API 152 /* The following terrible kludge is required to use native image API
92 on Windows before Vista, because SHCreateMemStream was not 153 on Windows before Vista, because SHCreateMemStream was not
93 exported by name in those versions, only by ordinal number. */ 154 exported by name in those versions, only by ordinal number. */
94 fn_SHCreateMemStream = 155 fn_SHCreateMemStream = (SHCreateMemStream_Proc)
95 (W32_PFN_SHCreateMemStream) get_proc_addr (shlwapi_lib, 156 get_proc_addr (shlwapi_lib, "SHCreateMemStream");
96 "SHCreateMemStream");
97 if (!fn_SHCreateMemStream) 157 if (!fn_SHCreateMemStream)
98 { 158 {
99 fn_SHCreateMemStream = 159 fn_SHCreateMemStream = (SHCreateMemStream_Proc)
100 (W32_PFN_SHCreateMemStream) get_proc_addr (shlwapi_lib, 160 get_proc_addr (shlwapi_lib, MAKEINTRESOURCEA (12));
101 MAKEINTRESOURCEA (12));
102 if (!fn_SHCreateMemStream) 161 if (!fn_SHCreateMemStream)
103 return false; 162 return false;
104 } 163 }
@@ -293,7 +352,7 @@ w32_select_active_frame (GpBitmap *pBitmap, int frame, int *nframes,
293 352
294 status = GdipImageGetFrameDimensionsCount (pBitmap, &count); 353 status = GdipImageGetFrameDimensionsCount (pBitmap, &count);
295 frameCount = *nframes = 0; 354 frameCount = *nframes = 0;
296 *delay = 0.0; 355 *delay = -1.0;
297 if (count) 356 if (count)
298 { 357 {
299 /* The following call will fill pDimensionIDs[0] with the 358 /* The following call will fill pDimensionIDs[0] with the