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 | |
| 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')
| -rw-r--r-- | src/w32gdiplus.h | 112 | ||||
| -rw-r--r-- | src/w32gui.h | 2 | ||||
| -rw-r--r-- | src/w32image.c | 104 | ||||
| -rw-r--r-- | src/w32select.c | 194 |
4 files changed, 303 insertions, 109 deletions
diff --git a/src/w32gdiplus.h b/src/w32gdiplus.h new file mode 100644 index 00000000000..9d05ae6c190 --- /dev/null +++ b/src/w32gdiplus.h | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | #ifdef WINDOWSNT | ||
| 2 | typedef GpStatus (WINGDIPAPI *GdiplusStartup_Proc) | ||
| 3 | (ULONG_PTR *, GdiplusStartupInput *, GdiplusStartupOutput *); | ||
| 4 | typedef VOID (WINGDIPAPI *GdiplusShutdown_Proc) (ULONG_PTR); | ||
| 5 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItemSize_Proc) | ||
| 6 | (GpImage *, PROPID, UINT *); | ||
| 7 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItem_Proc) | ||
| 8 | (GpImage *, PROPID, UINT, PropertyItem *); | ||
| 9 | typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsCount_Proc) | ||
| 10 | (GpImage *, UINT *); | ||
| 11 | typedef GpStatus (WINGDIPAPI *GdipImageGetFrameDimensionsList_Proc) | ||
| 12 | (GpImage *, GUID *, UINT); | ||
| 13 | typedef GpStatus (WINGDIPAPI *GdipImageGetFrameCount_Proc) | ||
| 14 | (GpImage *, GDIPCONST GUID *, UINT *); | ||
| 15 | typedef GpStatus (WINGDIPAPI *GdipImageSelectActiveFrame_Proc) | ||
| 16 | (GpImage*, GDIPCONST GUID *, UINT); | ||
| 17 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromFile_Proc) | ||
| 18 | (WCHAR *, GpBitmap **); | ||
| 19 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromStream_Proc) | ||
| 20 | (IStream *, GpBitmap **); | ||
| 21 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromScan0_Proc) | ||
| 22 | (INT, INT, INT, PixelFormat, BYTE*, GpBitmap**); | ||
| 23 | typedef IStream * (WINAPI *SHCreateMemStream_Proc) (const BYTE *, UINT); | ||
| 24 | typedef GpStatus (WINGDIPAPI *GdipCreateHBITMAPFromBitmap_Proc) | ||
| 25 | (GpBitmap *, HBITMAP *, ARGB); | ||
| 26 | typedef GpStatus (WINGDIPAPI *GdipDisposeImage_Proc) (GpImage *); | ||
| 27 | typedef GpStatus (WINGDIPAPI *GdipGetImageHeight_Proc) (GpImage *, UINT *); | ||
| 28 | typedef GpStatus (WINGDIPAPI *GdipGetImageWidth_Proc) (GpImage *, UINT *); | ||
| 29 | typedef GpStatus (WINGDIPAPI *GdipGetImageEncodersSize_Proc) (UINT *, UINT *); | ||
| 30 | typedef GpStatus (WINGDIPAPI *GdipGetImageEncoders_Proc) | ||
| 31 | (UINT, UINT, ImageCodecInfo *); | ||
| 32 | typedef GpStatus (WINGDIPAPI *GdipLoadImageFromFile_Proc) | ||
| 33 | (GDIPCONST WCHAR *,GpImage **); | ||
| 34 | typedef GpStatus (WINGDIPAPI *GdipGetImageThumbnail_Proc) | ||
| 35 | (GpImage *, UINT, UINT, GpImage**, GetThumbnailImageAbort, VOID *); | ||
| 36 | typedef GpStatus (WINGDIPAPI *GdipSaveImageToFile_Proc) | ||
| 37 | (GpImage *, GDIPCONST WCHAR *, GDIPCONST CLSID *, | ||
| 38 | GDIPCONST EncoderParameters *); | ||
| 39 | typedef GpStatus (WINGDIPAPI *GdipImageRotateFlip_Proc) | ||
| 40 | (GpImage *image, RotateFlipType rfType); | ||
| 41 | |||
| 42 | extern GdiplusStartup_Proc fn_GdiplusStartup; | ||
| 43 | extern GdiplusShutdown_Proc fn_GdiplusShutdown; | ||
| 44 | extern GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; | ||
| 45 | extern GdipGetPropertyItem_Proc fn_GdipGetPropertyItem; | ||
| 46 | extern GdipImageGetFrameDimensionsCount_Proc fn_GdipImageGetFrameDimensionsCount; | ||
| 47 | extern GdipImageGetFrameDimensionsList_Proc fn_GdipImageGetFrameDimensionsList; | ||
| 48 | extern GdipImageGetFrameCount_Proc fn_GdipImageGetFrameCount; | ||
| 49 | extern GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame; | ||
| 50 | extern GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile; | ||
| 51 | extern GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream; | ||
| 52 | extern GdipCreateBitmapFromScan0_Proc fn_GdipCreateBitmapFromScan0; | ||
| 53 | extern SHCreateMemStream_Proc fn_SHCreateMemStream; | ||
| 54 | extern GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; | ||
| 55 | extern GdipDisposeImage_Proc fn_GdipDisposeImage; | ||
| 56 | extern GdipGetImageHeight_Proc fn_GdipGetImageHeight; | ||
| 57 | extern GdipGetImageWidth_Proc fn_GdipGetImageWidth; | ||
| 58 | extern GdipGetImageEncodersSize_Proc fn_GdipGetImageEncodersSize; | ||
| 59 | extern GdipGetImageEncoders_Proc fn_GdipGetImageEncoders; | ||
| 60 | extern GdipLoadImageFromFile_Proc fn_GdipLoadImageFromFile; | ||
| 61 | extern GdipGetImageThumbnail_Proc fn_GdipGetImageThumbnail; | ||
| 62 | extern GdipSaveImageToFile_Proc fn_GdipSaveImageToFile; | ||
| 63 | extern GdipImageRotateFlip_Proc fn_GdipImageRotateFlip; | ||
| 64 | |||
| 65 | # undef GdiplusStartup | ||
| 66 | # undef GdiplusShutdown | ||
| 67 | # undef GdipGetPropertyItemSize | ||
| 68 | # undef GdipGetPropertyItem | ||
| 69 | # undef GdipImageGetFrameDimensionsCount | ||
| 70 | # undef GdipImageGetFrameDimensionsList | ||
| 71 | # undef GdipImageGetFrameCount | ||
| 72 | # undef GdipImageSelectActiveFrame | ||
| 73 | # undef GdipCreateBitmapFromFile | ||
| 74 | # undef GdipCreateBitmapFromStream | ||
| 75 | # undef GdipCreateBitmapFromScan0 | ||
| 76 | # undef SHCreateMemStream | ||
| 77 | # undef GdipCreateHBITMAPFromBitmap | ||
| 78 | # undef GdipDisposeImage | ||
| 79 | # undef GdipGetImageHeight | ||
| 80 | # undef GdipGetImageWidth | ||
| 81 | # undef GdipGetImageEncodersSize | ||
| 82 | # undef GdipGetImageEncoders | ||
| 83 | # undef GdipLoadImageFromFile | ||
| 84 | # undef GdipGetImageThumbnail | ||
| 85 | # undef GdipSaveImageToFile | ||
| 86 | # undef GdipSaveImageRotateFlip | ||
| 87 | |||
| 88 | # define GdiplusStartup fn_GdiplusStartup | ||
| 89 | # define GdiplusShutdown fn_GdiplusShutdown | ||
| 90 | # define GdipGetPropertyItemSize fn_GdipGetPropertyItemSize | ||
| 91 | # define GdipGetPropertyItem fn_GdipGetPropertyItem | ||
| 92 | # define GdipImageGetFrameDimensionsCount fn_GdipImageGetFrameDimensionsCount | ||
| 93 | # define GdipImageGetFrameDimensionsList fn_GdipImageGetFrameDimensionsList | ||
| 94 | # define GdipImageGetFrameCount fn_GdipImageGetFrameCount | ||
| 95 | # define GdipImageSelectActiveFrame fn_GdipImageSelectActiveFrame | ||
| 96 | # define GdipCreateBitmapFromFile fn_GdipCreateBitmapFromFile | ||
| 97 | # define GdipCreateBitmapFromStream fn_GdipCreateBitmapFromStream | ||
| 98 | # define GdipCreateBitmapFromScan0 fn_GdipCreateBitmapFromScan0 | ||
| 99 | # define SHCreateMemStream fn_SHCreateMemStream | ||
| 100 | # define GdipCreateHBITMAPFromBitmap fn_GdipCreateHBITMAPFromBitmap | ||
| 101 | # define GdipDisposeImage fn_GdipDisposeImage | ||
| 102 | # define GdipGetImageHeight fn_GdipGetImageHeight | ||
| 103 | # define GdipGetImageWidth fn_GdipGetImageWidth | ||
| 104 | # define GdipGetImageEncodersSize fn_GdipGetImageEncodersSize | ||
| 105 | # define GdipGetImageEncoders fn_GdipGetImageEncoders | ||
| 106 | # define GdipLoadImageFromFile fn_GdipLoadImageFromFile | ||
| 107 | # define GdipGetImageThumbnail fn_GdipGetImageThumbnail | ||
| 108 | # define GdipSaveImageToFile fn_GdipSaveImageToFile | ||
| 109 | # define GdipImageRotateFlip fn_GdipImageRotateFlip | ||
| 110 | #endif | ||
| 111 | |||
| 112 | int w32_gdip_get_encoder_clsid (const char *type, CLSID *clsid); | ||
diff --git a/src/w32gui.h b/src/w32gui.h index 739a790911e..26565dcae6b 100644 --- a/src/w32gui.h +++ b/src/w32gui.h | |||
| @@ -45,7 +45,9 @@ struct image; | |||
| 45 | extern int w32_load_image (struct frame *f, struct image *img, | 45 | extern int w32_load_image (struct frame *f, struct image *img, |
| 46 | Lisp_Object spec_file, Lisp_Object spec_data); | 46 | Lisp_Object spec_file, Lisp_Object spec_data); |
| 47 | extern bool w32_can_use_native_image_api (Lisp_Object); | 47 | extern bool w32_can_use_native_image_api (Lisp_Object); |
| 48 | extern bool w32_gdiplus_startup (void); | ||
| 48 | extern void w32_gdiplus_shutdown (void); | 49 | extern void w32_gdiplus_shutdown (void); |
| 50 | |||
| 49 | extern size_t w32_image_size (Emacs_Pixmap); | 51 | extern size_t w32_image_size (Emacs_Pixmap); |
| 50 | 52 | ||
| 51 | #define FACE_DEFAULT (~0) | 53 | #define FACE_DEFAULT (~0) |
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]; |
diff --git a/src/w32select.c b/src/w32select.c index 006bf408b47..7e8dc3f0702 100644 --- a/src/w32select.c +++ b/src/w32select.c | |||
| @@ -73,12 +73,22 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 73 | */ | 73 | */ |
| 74 | 74 | ||
| 75 | #include <config.h> | 75 | #include <config.h> |
| 76 | #include <windows.h> | ||
| 77 | #include <wingdi.h> | ||
| 78 | #include <wtypes.h> | ||
| 79 | #include <gdiplus.h> | ||
| 80 | #ifndef CF_DIBV5 | ||
| 81 | # define CF_DIBV5 17 | ||
| 82 | # undef CF_MAX | ||
| 83 | # define CF_MAX 18 | ||
| 84 | #endif | ||
| 76 | #include "lisp.h" | 85 | #include "lisp.h" |
| 77 | #include "w32common.h" /* os_subtype */ | 86 | #include "w32common.h" /* os_subtype */ |
| 78 | #include "w32term.h" /* for all of the w32 includes */ | 87 | #include "w32term.h" /* for all of the w32 includes */ |
| 79 | #include "w32select.h" | 88 | #include "w32select.h" |
| 80 | #include "blockinput.h" | 89 | #include "blockinput.h" |
| 81 | #include "coding.h" | 90 | #include "coding.h" |
| 91 | #include "w32gdiplus.h" | ||
| 82 | 92 | ||
| 83 | #ifdef CYGWIN | 93 | #ifdef CYGWIN |
| 84 | #include <string.h> | 94 | #include <string.h> |
| @@ -787,6 +797,166 @@ DEFUN ("w32-set-clipboard-data", Fw32_set_clipboard_data, | |||
| 787 | return (ok ? string : Qnil); | 797 | return (ok ? string : Qnil); |
| 788 | } | 798 | } |
| 789 | 799 | ||
| 800 | /* Xlib-like names for standard Windows clipboard data formats. | ||
| 801 | They are in upper-case to mimic xselect.c. A couple of the names | ||
| 802 | were changed to be more like their X counterparts. */ | ||
| 803 | static const char *stdfmt_name[] = { | ||
| 804 | "UNDEFINED", | ||
| 805 | "STRING", | ||
| 806 | "BITMAP", | ||
| 807 | "METAFILE", | ||
| 808 | "SYMLINK", | ||
| 809 | "DIF", | ||
| 810 | "TIFF", | ||
| 811 | "OEM_STRING", | ||
| 812 | "DIB", | ||
| 813 | "PALETTE", | ||
| 814 | "PENDATA", | ||
| 815 | "RIFF", | ||
| 816 | "WAVE", | ||
| 817 | "UTF8_STRING", | ||
| 818 | "ENHMETAFILE", | ||
| 819 | "FILE_NAMES", /* DND */ | ||
| 820 | "LOCALE", /* not used */ | ||
| 821 | "DIBV5" | ||
| 822 | }; | ||
| 823 | |||
| 824 | /* Must be called with block_input() active. */ | ||
| 825 | static bool | ||
| 826 | convert_dibv5_to_png (char *data, int size, char *temp_file) | ||
| 827 | { | ||
| 828 | CLSID clsid_png; | ||
| 829 | |||
| 830 | if (!w32_gdiplus_startup () | ||
| 831 | || !w32_gdip_get_encoder_clsid ("png", &clsid_png)) | ||
| 832 | return false; | ||
| 833 | |||
| 834 | BITMAPV5HEADER *bmi = (void *) data; | ||
| 835 | int stride = bmi->bV5SizeImage / bmi->bV5Height; | ||
| 836 | long offset = bmi->bV5Size + bmi->bV5ClrUsed * sizeof (RGBQUAD); | ||
| 837 | if (bmi->bV5Compression == BI_BITFIELDS) | ||
| 838 | offset += 12; | ||
| 839 | BYTE *scan0 = data + offset; | ||
| 840 | |||
| 841 | GpBitmap *bitmap = NULL; | ||
| 842 | |||
| 843 | GpStatus status | ||
| 844 | = GdipCreateBitmapFromScan0 (bmi->bV5Width, bmi->bV5Height, stride, | ||
| 845 | PixelFormat32bppARGB, scan0, &bitmap); | ||
| 846 | |||
| 847 | if (status != Ok) | ||
| 848 | return false; | ||
| 849 | |||
| 850 | /* The bitmap comes upside down. */ | ||
| 851 | GdipImageRotateFlip (bitmap, RotateNoneFlipY); | ||
| 852 | |||
| 853 | WCHAR wide_filename[MAX_PATH]; | ||
| 854 | filename_to_utf16 (temp_file, wide_filename); | ||
| 855 | |||
| 856 | status = GdipSaveImageToFile (bitmap, wide_filename, &clsid_png, NULL); | ||
| 857 | GdipDisposeImage (bitmap); | ||
| 858 | if (status != Ok) | ||
| 859 | return false; | ||
| 860 | return true; | ||
| 861 | } | ||
| 862 | |||
| 863 | static int | ||
| 864 | get_clipboard_format_name (int format_index, char *name) | ||
| 865 | { | ||
| 866 | *name = 0; | ||
| 867 | format_index = EnumClipboardFormats (format_index); | ||
| 868 | if (format_index == 0) | ||
| 869 | return 0; | ||
| 870 | if (format_index < CF_MAX) | ||
| 871 | strcpy (name, stdfmt_name[format_index]); | ||
| 872 | GetClipboardFormatName (format_index, name, 256); | ||
| 873 | return format_index; | ||
| 874 | } | ||
| 875 | |||
| 876 | DEFUN ("w32--get-clipboard-data-media", Fw32__get_clipboard_data_media, | ||
| 877 | Sw32__get_clipboard_data_media, 3, 3, 0, | ||
| 878 | doc: /* Gets media (not plain text) clipboard data in one of the given formats. | ||
| 879 | |||
| 880 | FORMATS is a list of formats. | ||
| 881 | TEMP-FILE-IN is the name of the file to store the data. | ||
| 882 | |||
| 883 | Elements in FORMATS are symbols naming a format, such a image/png, or | ||
| 884 | image/jpeg. For compatibility with X systems, some conventional | ||
| 885 | format names are translated to equivalent MIME types, as configured with | ||
| 886 | the variable 'w32--selection-target-translations'. | ||
| 887 | |||
| 888 | The file named in TEMP-FILE-IN must be created by the caller, and also | ||
| 889 | deleted if required. | ||
| 890 | |||
| 891 | Returns nil it there is no such format, or something failed. | ||
| 892 | If it returns t, then the caller should read the file to get the data. | ||
| 893 | If it returns a string, then that is the data and the file is not used. | ||
| 894 | |||
| 895 | When returning a string, it will be unibyte if IS-TEXTUAL is nil (the | ||
| 896 | content is binary data). */) | ||
| 897 | (Lisp_Object formats, Lisp_Object temp_file_in, Lisp_Object is_textual) | ||
| 898 | { | ||
| 899 | CHECK_LIST (formats); | ||
| 900 | CHECK_STRING (temp_file_in); | ||
| 901 | |||
| 902 | temp_file_in = Fexpand_file_name (temp_file_in, Qnil); | ||
| 903 | char *temp_file = SSDATA (ENCODE_FILE (temp_file_in)); | ||
| 904 | |||
| 905 | Lisp_Object result = Qnil; | ||
| 906 | |||
| 907 | block_input(); | ||
| 908 | if (!OpenClipboard (NULL)) | ||
| 909 | { | ||
| 910 | unblock_input(); | ||
| 911 | return Qnil; | ||
| 912 | } | ||
| 913 | |||
| 914 | for (int format_index = 0;;) | ||
| 915 | { | ||
| 916 | static char name[256]; | ||
| 917 | format_index = get_clipboard_format_name (format_index, name); | ||
| 918 | if (format_index == 0) | ||
| 919 | break; | ||
| 920 | |||
| 921 | /* If name doesn't match any of the formats, try the next format. */ | ||
| 922 | bool match = false; | ||
| 923 | for (Lisp_Object tail = formats; CONSP (tail); tail = XCDR (tail)) | ||
| 924 | if (strcmp (name, SSDATA (SYMBOL_NAME (XCAR (tail)))) == 0) | ||
| 925 | match = true; | ||
| 926 | if (!match) | ||
| 927 | continue; | ||
| 928 | |||
| 929 | /* Of the standard formats, only DIBV5 is supported. */ | ||
| 930 | if (format_index < CF_MAX && format_index != CF_DIBV5) | ||
| 931 | continue; | ||
| 932 | |||
| 933 | /* Found the format. */ | ||
| 934 | HANDLE d = GetClipboardData (format_index); | ||
| 935 | if (!d) | ||
| 936 | break; | ||
| 937 | int size = GlobalSize (d); | ||
| 938 | char *data = GlobalLock (d); | ||
| 939 | if (!data) | ||
| 940 | break; | ||
| 941 | if (strcmp (name, "DIBV5") == 0) | ||
| 942 | { | ||
| 943 | if (convert_dibv5_to_png (data, size, temp_file)) | ||
| 944 | result = Qt; | ||
| 945 | } | ||
| 946 | else | ||
| 947 | { | ||
| 948 | if (NILP (is_textual)) | ||
| 949 | result = make_unibyte_string (data, size); | ||
| 950 | else | ||
| 951 | result = make_string (data, size); | ||
| 952 | } | ||
| 953 | GlobalUnlock (d); | ||
| 954 | break; | ||
| 955 | } | ||
| 956 | CloseClipboard (); | ||
| 957 | unblock_input (); | ||
| 958 | return result; | ||
| 959 | } | ||
| 790 | 960 | ||
| 791 | DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, | 961 | DEFUN ("w32-get-clipboard-data", Fw32_get_clipboard_data, |
| 792 | Sw32_get_clipboard_data, 0, 1, 0, | 962 | Sw32_get_clipboard_data, 0, 1, 0, |
| @@ -1069,29 +1239,6 @@ for `CLIPBOARD'. The return value is a vector of symbols, each symbol | |||
| 1069 | representing a data format that is currently available in the clipboard. */) | 1239 | representing a data format that is currently available in the clipboard. */) |
| 1070 | (Lisp_Object selection, Lisp_Object terminal) | 1240 | (Lisp_Object selection, Lisp_Object terminal) |
| 1071 | { | 1241 | { |
| 1072 | /* Xlib-like names for standard Windows clipboard data formats. | ||
| 1073 | They are in upper-case to mimic xselect.c. A couple of the names | ||
| 1074 | were changed to be more like their X counterparts. */ | ||
| 1075 | static const char *stdfmt_name[] = { | ||
| 1076 | "UNDEFINED", | ||
| 1077 | "STRING", | ||
| 1078 | "BITMAP", | ||
| 1079 | "METAFILE", | ||
| 1080 | "SYMLINK", | ||
| 1081 | "DIF", | ||
| 1082 | "TIFF", | ||
| 1083 | "OEM_STRING", | ||
| 1084 | "DIB", | ||
| 1085 | "PALETTE", | ||
| 1086 | "PENDATA", | ||
| 1087 | "RIFF", | ||
| 1088 | "WAVE", | ||
| 1089 | "UTF8_STRING", | ||
| 1090 | "ENHMETAFILE", | ||
| 1091 | "FILE_NAMES", /* DND */ | ||
| 1092 | "LOCALE", /* not used */ | ||
| 1093 | "DIBV5" | ||
| 1094 | }; | ||
| 1095 | CHECK_SYMBOL (selection); | 1242 | CHECK_SYMBOL (selection); |
| 1096 | 1243 | ||
| 1097 | /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check | 1244 | /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check |
| @@ -1166,6 +1313,7 @@ syms_of_w32select (void) | |||
| 1166 | { | 1313 | { |
| 1167 | defsubr (&Sw32_set_clipboard_data); | 1314 | defsubr (&Sw32_set_clipboard_data); |
| 1168 | defsubr (&Sw32_get_clipboard_data); | 1315 | defsubr (&Sw32_get_clipboard_data); |
| 1316 | defsubr (&Sw32__get_clipboard_data_media); | ||
| 1169 | defsubr (&Sw32_selection_exists_p); | 1317 | defsubr (&Sw32_selection_exists_p); |
| 1170 | defsubr (&Sw32_selection_targets); | 1318 | defsubr (&Sw32_selection_targets); |
| 1171 | 1319 | ||