aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32image.c
diff options
context:
space:
mode:
authorCecilio Pardo2024-10-28 22:18:13 +0100
committerEli Zaretskii2024-11-03 15:12:20 +0200
commit8e7f5f97db647ce6e9606364dc15d8bbd7ef6016 (patch)
treeaa033dc97c284c7842dc291c6a9f7fbcd044fce8 /src/w32image.c
parent5ee56b86938b7759dd92f507d03907280f48ffca (diff)
downloademacs-8e7f5f97db647ce6e9606364dc15d8bbd7ef6016.tar.gz
emacs-8e7f5f97db647ce6e9606364dc15d8bbd7ef6016.zip
Add support for 'yank-media' on MS-Windows
Adds the capacity to handle types different from strings to the clipboard management functions on MS-Windows, and some logic required to convert media types names and content to be what yank-media and the modes that use it expect (bug#71909). * lisp/term/w32-win.el (w32--selection-target-translations): New variable that holds the name translations for media types. (w32--translate-selection-target): New function, translate the name of a media type. (w32--translate-reverse-selection-target): New function, reverse translation. (w32--get-selection): Modified to translate target names when asked for targets, and retrieve media types when asked for them. (w32--mime-type-textual-p): New function, checks if a MIME type is textual. * lisp/textmodes/sgml-mode.el (html-mode--image-yank-handler): Fixed the image save mechanism, that added line feed characters on MS-Windows, breaking binary formats. * src/w32image.c (gdiplus_init): Modified to fetch more functions fromm gdiplus. (get_encoder_clsid): Renamed to 'w32_gdip_get_encoder_clsid' and made nonstatic. (gdiplus_startup): Renamed to 'w32_gdiplus_startup' and made nonstatic. * src/w32select.c (stdfmt_name): Made global, was static function. (convert_dibv5_to_png): New function to convert DIBV5 clipboard format to PNG. (get_clipboard_format_name): New function get the name of a format given its index. (Fw32__get_clipboard_data_media): New function, retrieves and converts media content. (syms_of_w32select): Export new lisp functions. * src/w32gdiplus.h: New file, for definitions in w32image.c * doc/lispref/frames.texi: Updated with MS-Windows support. * etc/NEWS: Added entry about new feature.
Diffstat (limited to 'src/w32image.c')
-rw-r--r--src/w32image.c104
1 files changed, 18 insertions, 86 deletions
diff --git a/src/w32image.c b/src/w32image.c
index 359a4fa3a72..44eed087528 100644
--- a/src/w32image.c
+++ b/src/w32image.c
@@ -38,44 +38,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
38#include "frame.h" 38#include "frame.h"
39#include "coding.h" 39#include "coding.h"
40 40
41#include "w32gdiplus.h"
41#ifdef WINDOWSNT 42#ifdef WINDOWSNT
42
43typedef GpStatus (WINGDIPAPI *GdiplusStartup_Proc)
44 (ULONG_PTR *, GdiplusStartupInput *, GdiplusStartupOutput *);
45typedef VOID (WINGDIPAPI *GdiplusShutdown_Proc) (ULONG_PTR);
46typedef GpStatus (WINGDIPAPI *GdipGetPropertyItemSize_Proc)
47 (GpImage *, PROPID, UINT *);
48typedef GpStatus (WINGDIPAPI *GdipGetPropertyItem_Proc)
49 (GpImage *, PROPID, UINT, PropertyItem *);
50typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsCount_Proc)
51 (GpImage *, UINT *);
52typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsList_Proc)
53 (GpImage *, GUID *, UINT);
54typedef GpStatus (WINGDIPAPI *GdipImageGetFrameCount_Proc)
55 (GpImage *, GDIPCONST GUID *, UINT *);
56typedef GpStatus (WINGDIPAPI *GdipImageSelectActiveFrame_Proc)
57 (GpImage*, GDIPCONST GUID *, UINT);
58typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromFile_Proc)
59 (WCHAR *, GpBitmap **);
60typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromStream_Proc)
61 (IStream *, GpBitmap **);
62typedef IStream * (WINAPI *SHCreateMemStream_Proc) (const BYTE *, UINT);
63typedef GpStatus (WINGDIPAPI *GdipCreateHBITMAPFromBitmap_Proc)
64 (GpBitmap *, HBITMAP *, ARGB);
65typedef GpStatus (WINGDIPAPI *GdipDisposeImage_Proc) (GpImage *);
66typedef GpStatus (WINGDIPAPI *GdipGetImageHeight_Proc) (GpImage *, UINT *);
67typedef GpStatus (WINGDIPAPI *GdipGetImageWidth_Proc) (GpImage *, UINT *);
68typedef GpStatus (WINGDIPAPI *GdipGetImageEncodersSize_Proc) (UINT *, UINT *);
69typedef GpStatus (WINGDIPAPI *GdipGetImageEncoders_Proc)
70 (UINT, UINT, ImageCodecInfo *);
71typedef GpStatus (WINGDIPAPI *GdipLoadImageFromFile_Proc)
72 (GDIPCONST WCHAR *,GpImage **);
73typedef GpStatus (WINGDIPAPI *GdipGetImageThumbnail_Proc)
74 (GpImage *, UINT, UINT, GpImage**, GetThumbnailImageAbort, VOID *);
75typedef GpStatus (WINGDIPAPI *GdipSaveImageToFile_Proc)
76 (GpImage *, GDIPCONST WCHAR *, GDIPCONST CLSID *,
77 GDIPCONST EncoderParameters *);
78
79GdiplusStartup_Proc fn_GdiplusStartup; 43GdiplusStartup_Proc fn_GdiplusStartup;
80GdiplusShutdown_Proc fn_GdiplusShutdown; 44GdiplusShutdown_Proc fn_GdiplusShutdown;
81GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; 45GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize;
@@ -86,6 +50,7 @@ GdipImageGetFrameCount_Proc fn_GdipImageGetFrameCount;
86GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame; 50GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame;
87GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile; 51GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile;
88GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream; 52GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream;
53GdipCreateBitmapFromScan0_Proc fn_GdipCreateBitmapFromScan0;
89SHCreateMemStream_Proc fn_SHCreateMemStream; 54SHCreateMemStream_Proc fn_SHCreateMemStream;
90GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; 55GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap;
91GdipDisposeImage_Proc fn_GdipDisposeImage; 56GdipDisposeImage_Proc fn_GdipDisposeImage;
@@ -96,6 +61,7 @@ GdipGetImageEncoders_Proc fn_GdipGetImageEncoders;
96GdipLoadImageFromFile_Proc fn_GdipLoadImageFromFile; 61GdipLoadImageFromFile_Proc fn_GdipLoadImageFromFile;
97GdipGetImageThumbnail_Proc fn_GdipGetImageThumbnail; 62GdipGetImageThumbnail_Proc fn_GdipGetImageThumbnail;
98GdipSaveImageToFile_Proc fn_GdipSaveImageToFile; 63GdipSaveImageToFile_Proc fn_GdipSaveImageToFile;
64GdipImageRotateFlip_Proc fn_GdipImageRotateFlip;
99 65
100static bool 66static bool
101gdiplus_init (void) 67gdiplus_init (void)
@@ -146,6 +112,10 @@ gdiplus_init (void)
146 get_proc_addr (gdiplus_lib, "GdipCreateBitmapFromStream"); 112 get_proc_addr (gdiplus_lib, "GdipCreateBitmapFromStream");
147 if (!fn_GdipCreateBitmapFromStream) 113 if (!fn_GdipCreateBitmapFromStream)
148 return false; 114 return false;
115 fn_GdipCreateBitmapFromScan0 = (GdipCreateBitmapFromScan0_Proc)
116 get_proc_addr (gdiplus_lib, "GdipCreateBitmapFromScan0");
117 if (!fn_GdipCreateBitmapFromScan0)
118 return false;
149 fn_GdipCreateHBITMAPFromBitmap = (GdipCreateHBITMAPFromBitmap_Proc) 119 fn_GdipCreateHBITMAPFromBitmap = (GdipCreateHBITMAPFromBitmap_Proc)
150 get_proc_addr (gdiplus_lib, "GdipCreateHBITMAPFromBitmap"); 120 get_proc_addr (gdiplus_lib, "GdipCreateHBITMAPFromBitmap");
151 if (!fn_GdipCreateHBITMAPFromBitmap) 121 if (!fn_GdipCreateHBITMAPFromBitmap)
@@ -196,52 +166,14 @@ gdiplus_init (void)
196 get_proc_addr (gdiplus_lib, "GdipSaveImageToFile"); 166 get_proc_addr (gdiplus_lib, "GdipSaveImageToFile");
197 if (!fn_GdipSaveImageToFile) 167 if (!fn_GdipSaveImageToFile)
198 return false; 168 return false;
169 fn_GdipImageRotateFlip = (GdipImageRotateFlip_Proc)
170 get_proc_addr (gdiplus_lib, "GdipImageRotateFlip");
171 if (!fn_GdipImageRotateFlip)
172 return false;
199 173
200 return true; 174 return true;
201} 175}
202 176
203# undef GdiplusStartup
204# undef GdiplusShutdown
205# undef GdipGetPropertyItemSize
206# undef GdipGetPropertyItem
207# undef GdipImageGetFrameDimensionsCount
208# undef GdipImageGetFrameDimensionsList
209# undef GdipImageGetFrameCount
210# undef GdipImageSelectActiveFrame
211# undef GdipCreateBitmapFromFile
212# undef GdipCreateBitmapFromStream
213# undef SHCreateMemStream
214# undef GdipCreateHBITMAPFromBitmap
215# undef GdipDisposeImage
216# undef GdipGetImageHeight
217# undef GdipGetImageWidth
218# undef GdipGetImageEncodersSize
219# undef GdipGetImageEncoders
220# undef GdipLoadImageFromFile
221# undef GdipGetImageThumbnail
222# undef GdipSaveImageToFile
223
224# define GdiplusStartup fn_GdiplusStartup
225# define GdiplusShutdown fn_GdiplusShutdown
226# define GdipGetPropertyItemSize fn_GdipGetPropertyItemSize
227# define GdipGetPropertyItem fn_GdipGetPropertyItem
228# define GdipImageGetFrameDimensionsCount fn_GdipImageGetFrameDimensionsCount
229# define GdipImageGetFrameDimensionsList fn_GdipImageGetFrameDimensionsList
230# define GdipImageGetFrameCount fn_GdipImageGetFrameCount
231# define GdipImageSelectActiveFrame fn_GdipImageSelectActiveFrame
232# define GdipCreateBitmapFromFile fn_GdipCreateBitmapFromFile
233# define GdipCreateBitmapFromStream fn_GdipCreateBitmapFromStream
234# define SHCreateMemStream fn_SHCreateMemStream
235# define GdipCreateHBITMAPFromBitmap fn_GdipCreateHBITMAPFromBitmap
236# define GdipDisposeImage fn_GdipDisposeImage
237# define GdipGetImageHeight fn_GdipGetImageHeight
238# define GdipGetImageWidth fn_GdipGetImageWidth
239# define GdipGetImageEncodersSize fn_GdipGetImageEncodersSize
240# define GdipGetImageEncoders fn_GdipGetImageEncoders
241# define GdipLoadImageFromFile fn_GdipLoadImageFromFile
242# define GdipGetImageThumbnail fn_GdipGetImageThumbnail
243# define GdipSaveImageToFile fn_GdipSaveImageToFile
244
245#endif /* WINDOWSNT */ 177#endif /* WINDOWSNT */
246 178
247static int gdip_initialized; 179static int gdip_initialized;
@@ -252,8 +184,8 @@ static GdiplusStartupOutput output;
252 184
253 185
254/* Initialize GDI+, return true if successful. */ 186/* Initialize GDI+, return true if successful. */
255static bool 187bool
256gdiplus_startup (void) 188w32_gdiplus_startup (void)
257{ 189{
258 GpStatus status; 190 GpStatus status;
259 191
@@ -305,7 +237,7 @@ w32_can_use_native_image_api (Lisp_Object type)
305 But we don't yet support these in image.c. */ 237 But we don't yet support these in image.c. */
306 return false; 238 return false;
307 } 239 }
308 return gdiplus_startup (); 240 return w32_gdiplus_startup ();
309} 241}
310 242
311enum PropertyItem_type { 243enum PropertyItem_type {
@@ -549,8 +481,8 @@ static struct thumb_type_data thumb_types [] =
549 }; 481 };
550 482
551 483
552static int 484int
553get_encoder_clsid (const char *type, CLSID *clsid) 485w32_gdip_get_encoder_clsid (const char *type, CLSID *clsid)
554{ 486{
555 /* A simple cache based on the assumptions that many thumbnails will 487 /* A simple cache based on the assumptions that many thumbnails will
556 be generated using the same TYPE. */ 488 be generated using the same TYPE. */
@@ -625,7 +557,7 @@ Return non-nil if thumbnail creation succeeds, nil otherwise. */)
625 557
626 if (!gdiplus_started) 558 if (!gdiplus_started)
627 { 559 {
628 if (!gdiplus_startup ()) 560 if (!w32_gdiplus_startup ())
629 return Qnil; 561 return Qnil;
630 } 562 }
631 563
@@ -649,7 +581,7 @@ Return non-nil if thumbnail creation succeeds, nil otherwise. */)
649 CLSID thumb_clsid; 581 CLSID thumb_clsid;
650 if (status == Ok 582 if (status == Ok
651 /* Get the GUID of the TYPE's encoder. */ 583 /* Get the GUID of the TYPE's encoder. */
652 && get_encoder_clsid (SSDATA (type), &thumb_clsid) >= 0) 584 && w32_gdip_get_encoder_clsid (SSDATA (type), &thumb_clsid) >= 0)
653 { 585 {
654 /* Save the thumbnail image to a file of specified TYPE. */ 586 /* Save the thumbnail image to a file of specified TYPE. */
655 wchar_t thumb_file_w[MAX_PATH]; 587 wchar_t thumb_file_w[MAX_PATH];