diff options
| author | Cecilio Pardo | 2024-10-28 22:18:13 +0100 |
|---|---|---|
| committer | Eli Zaretskii | 2024-11-03 15:12:20 +0200 |
| commit | 8e7f5f97db647ce6e9606364dc15d8bbd7ef6016 (patch) | |
| tree | aa033dc97c284c7842dc291c6a9f7fbcd044fce8 /src/w32image.c | |
| parent | 5ee56b86938b7759dd92f507d03907280f48ffca (diff) | |
| download | emacs-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.c | 104 |
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 | |||
| 43 | typedef GpStatus (WINGDIPAPI *GdiplusStartup_Proc) | ||
| 44 | (ULONG_PTR *, GdiplusStartupInput *, GdiplusStartupOutput *); | ||
| 45 | typedef VOID (WINGDIPAPI *GdiplusShutdown_Proc) (ULONG_PTR); | ||
| 46 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItemSize_Proc) | ||
| 47 | (GpImage *, PROPID, UINT *); | ||
| 48 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItem_Proc) | ||
| 49 | (GpImage *, PROPID, UINT, PropertyItem *); | ||
| 50 | typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsCount_Proc) | ||
| 51 | (GpImage *, UINT *); | ||
| 52 | typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsList_Proc) | ||
| 53 | (GpImage *, GUID *, UINT); | ||
| 54 | typedef GpStatus (WINGDIPAPI *GdipImageGetFrameCount_Proc) | ||
| 55 | (GpImage *, GDIPCONST GUID *, UINT *); | ||
| 56 | typedef GpStatus (WINGDIPAPI *GdipImageSelectActiveFrame_Proc) | ||
| 57 | (GpImage*, GDIPCONST GUID *, UINT); | ||
| 58 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromFile_Proc) | ||
| 59 | (WCHAR *, GpBitmap **); | ||
| 60 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromStream_Proc) | ||
| 61 | (IStream *, GpBitmap **); | ||
| 62 | typedef IStream * (WINAPI *SHCreateMemStream_Proc) (const BYTE *, UINT); | ||
| 63 | typedef GpStatus (WINGDIPAPI *GdipCreateHBITMAPFromBitmap_Proc) | ||
| 64 | (GpBitmap *, HBITMAP *, ARGB); | ||
| 65 | typedef GpStatus (WINGDIPAPI *GdipDisposeImage_Proc) (GpImage *); | ||
| 66 | typedef GpStatus (WINGDIPAPI *GdipGetImageHeight_Proc) (GpImage *, UINT *); | ||
| 67 | typedef GpStatus (WINGDIPAPI *GdipGetImageWidth_Proc) (GpImage *, UINT *); | ||
| 68 | typedef GpStatus (WINGDIPAPI *GdipGetImageEncodersSize_Proc) (UINT *, UINT *); | ||
| 69 | typedef GpStatus (WINGDIPAPI *GdipGetImageEncoders_Proc) | ||
| 70 | (UINT, UINT, ImageCodecInfo *); | ||
| 71 | typedef GpStatus (WINGDIPAPI *GdipLoadImageFromFile_Proc) | ||
| 72 | (GDIPCONST WCHAR *,GpImage **); | ||
| 73 | typedef GpStatus (WINGDIPAPI *GdipGetImageThumbnail_Proc) | ||
| 74 | (GpImage *, UINT, UINT, GpImage**, GetThumbnailImageAbort, VOID *); | ||
| 75 | typedef GpStatus (WINGDIPAPI *GdipSaveImageToFile_Proc) | ||
| 76 | (GpImage *, GDIPCONST WCHAR *, GDIPCONST CLSID *, | ||
| 77 | GDIPCONST EncoderParameters *); | ||
| 78 | |||
| 79 | GdiplusStartup_Proc fn_GdiplusStartup; | 43 | GdiplusStartup_Proc fn_GdiplusStartup; |
| 80 | GdiplusShutdown_Proc fn_GdiplusShutdown; | 44 | GdiplusShutdown_Proc fn_GdiplusShutdown; |
| 81 | GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; | 45 | GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; |
| @@ -86,6 +50,7 @@ GdipImageGetFrameCount_Proc fn_GdipImageGetFrameCount; | |||
| 86 | GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame; | 50 | GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame; |
| 87 | GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile; | 51 | GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile; |
| 88 | GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream; | 52 | GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream; |
| 53 | GdipCreateBitmapFromScan0_Proc fn_GdipCreateBitmapFromScan0; | ||
| 89 | SHCreateMemStream_Proc fn_SHCreateMemStream; | 54 | SHCreateMemStream_Proc fn_SHCreateMemStream; |
| 90 | GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; | 55 | GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; |
| 91 | GdipDisposeImage_Proc fn_GdipDisposeImage; | 56 | GdipDisposeImage_Proc fn_GdipDisposeImage; |
| @@ -96,6 +61,7 @@ GdipGetImageEncoders_Proc fn_GdipGetImageEncoders; | |||
| 96 | GdipLoadImageFromFile_Proc fn_GdipLoadImageFromFile; | 61 | GdipLoadImageFromFile_Proc fn_GdipLoadImageFromFile; |
| 97 | GdipGetImageThumbnail_Proc fn_GdipGetImageThumbnail; | 62 | GdipGetImageThumbnail_Proc fn_GdipGetImageThumbnail; |
| 98 | GdipSaveImageToFile_Proc fn_GdipSaveImageToFile; | 63 | GdipSaveImageToFile_Proc fn_GdipSaveImageToFile; |
| 64 | GdipImageRotateFlip_Proc fn_GdipImageRotateFlip; | ||
| 99 | 65 | ||
| 100 | static bool | 66 | static bool |
| 101 | gdiplus_init (void) | 67 | gdiplus_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 | ||
| 247 | static int gdip_initialized; | 179 | static 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. */ |
| 255 | static bool | 187 | bool |
| 256 | gdiplus_startup (void) | 188 | w32_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 | ||
| 311 | enum PropertyItem_type { | 243 | enum PropertyItem_type { |
| @@ -549,8 +481,8 @@ static struct thumb_type_data thumb_types [] = | |||
| 549 | }; | 481 | }; |
| 550 | 482 | ||
| 551 | 483 | ||
| 552 | static int | 484 | int |
| 553 | get_encoder_clsid (const char *type, CLSID *clsid) | 485 | w32_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]; |