From 8c03202df64bdf3cdbdb15845dbb4968b100e670 Mon Sep 17 00:00:00 2001 From: Thomas BERNARD Date: Fri, 4 Jan 2019 22:43:30 +0100 Subject: [PATCH] Support for Pasting from macOS PasteBoard --- src/Makefile | 7 ++-- src/fileformats.h | 1 + src/filesel.c | 4 +- src/loadsave.c | 13 +++++++ src/pasteboard.m | 37 +++++++++++++++++++ src/tifformat.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 src/pasteboard.m diff --git a/src/Makefile b/src/Makefile index 34f294cc..1af67b51 100644 --- a/src/Makefile +++ b/src/Makefile @@ -279,8 +279,9 @@ endif # Use gcc for compiling. Use ncc to build a callgraph and analyze the code. #CC = nccgen -ncgcc -ncld -ncfabs OBJDIR = ../obj/macosx + PLATFORMOBJ = pasteboard.o ifeq ($(API),sdl) - PLATFORMOBJ = SDLMain.o + PLATFORMOBJ += SDLMain.o endif FCLOPT = MACAPPEXE = Grafx2.app/Contents/MacOS/Grafx2 @@ -860,7 +861,7 @@ release : $(BIN) # .tgz archive with source only files SRCARCH = ../src-$(VERSIONTAG).tgz -$(SRCARCH): $(wildcard *.c) $(wildcard *.cpp) $(wildcard *.h) Makefile Makefile.dep gfx2.ico Grafx2_Prefix.pch SDLMain.m gfx2.rc +$(SRCARCH): $(wildcard *.c) $(wildcard *.cpp) $(wildcard *.h) Makefile Makefile.dep gfx2.ico Grafx2_Prefix.pch $(wildcard *.m) gfx2.rc cd .. && $(TAR) czf $(SRCARCH:../%=%) $(addprefix src/,$^) ifeq ($(PLATFORM),Darwin) @@ -887,7 +888,7 @@ ifeq ($(PLATFORM),Darwin) endif $(TAR) czf "../grafx2-$(VERSIONTAG)-src.tgz" $(TARTRANSFORM) \ ../src/*.c ../src/*.cpp ../src/*.h ../src/Makefile ../src/Makefile.dep \ - ../src/Grafx2_Prefix.pch ../src/SDLMain.m ../src/gfx2.rc ../src/gfx2.ico \ + ../src/Grafx2_Prefix.pch ../src/*.m ../src/gfx2.rc ../src/gfx2.ico \ ../src/Grafx2.icns ../src/English.lproj/* ../src/Info.plist \ ../share/grafx2/gfx2def.ini $(SCRIPT_FILES) $(SKIN_FILES) \ ../share/grafx2/gfx2.gif ../share/grafx2/gfx2.png ../share/icons/grafx2.svg \ diff --git a/src/fileformats.h b/src/fileformats.h index a510eb32..c1525836 100644 --- a/src/fileformats.h +++ b/src/fileformats.h @@ -167,6 +167,7 @@ void Save_HGR(T_IO_Context *); void Test_TIFF(T_IO_Context *, FILE *); void Load_TIFF(T_IO_Context *); void Save_TIFF(T_IO_Context *); +void Load_TIFF_from_memory(T_IO_Context *, const void *, unsigned long); #endif /// @} diff --git a/src/filesel.c b/src/filesel.c index d09fa7f3..c4ec3cb5 100644 --- a/src/filesel.c +++ b/src/filesel.c @@ -1733,11 +1733,13 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context Display_bookmark(bookmark_dropdown[temp],temp); } -#if defined(WIN32) || defined(USE_X11) || (defined(SDL_VIDEO_DRIVER_X11) && !defined(NO_X11)) +#if defined(WIN32) || defined(__macosx__) || defined(USE_X11) || (defined(SDL_VIDEO_DRIVER_X11) && !defined(NO_X11)) if (load) Window_set_normal_button(62,180,115,14,"From Clipboard",0,1,SHORTCUT_PASTE); // 14 +#if !defined(__macosx__) else Window_set_normal_button(62,180,115,14,"To Clipboard",0,1,SHORTCUT_COPY); // 14 +#endif #endif Change_directory(context->File_directory); diff --git a/src/loadsave.c b/src/loadsave.c index b6b9d8e3..6f489c84 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -86,6 +86,11 @@ extern Window X11_window; #endif #endif +#if defined(__macosx__) +const void * get_tiff_paste_board(unsigned long * size); +#endif + + #if defined(USE_SDL) || defined(USE_SDL2) // -- SDL_Image ------------------------------------------------------------- // (TGA, BMP, PNM, XPM, XCF, PCX, GIF, JPG, TIF, IFF, PNG, ICO) @@ -1438,6 +1443,14 @@ static void Load_ClipBoard_Image(T_IO_Context * context) } } CloseClipboard(); +#elif defined(__macosx__) + unsigned long size; + const void * tiff = get_tiff_paste_board(&size); + + GFX2_Log(GFX2_DEBUG, "TIFF pasteboard : %p (%lu bytes)\n", tiff, size); + if (tiff != NULL) + Load_TIFF_from_memory(context, tiff, size); + #elif defined(USE_X11) || (defined(SDL_VIDEO_DRIVER_X11) && !defined(NO_X11)) int i; Atom selection; diff --git a/src/pasteboard.m b/src/pasteboard.m new file mode 100644 index 00000000..ba04a5d4 --- /dev/null +++ b/src/pasteboard.m @@ -0,0 +1,37 @@ +/* vim:expandtab:ts=2 sw=2: +*/ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2018 Thomas Bernard + Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see +*/ + +///@file pasteboard.m +/// Support for Mac OS X PasteBoard +/// + +#import + +const void * get_tiff_paste_board(unsigned long * size) +{ + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; + NSLog(@"types in pasteboard : %@", [pasteboard types]); + NSData *data = [pasteboard dataForType:NSTIFFPboardType]; + if (data == nil) + return NULL; + *size = [data length]; + return [data bytes]; +} diff --git a/src/tifformat.c b/src/tifformat.c index 97403ac8..01db814a 100644 --- a/src/tifformat.c +++ b/src/tifformat.c @@ -383,6 +383,99 @@ void Load_TIFF_Sub(T_IO_Context * context, TIFF * tif, unsigned long file_size) } } +struct memory_buffer +{ + char * buffer; + unsigned long offset; + unsigned long size; +}; + +tmsize_t lTIFF_read(thandle_t p, void * data, tmsize_t size) +{ + struct memory_buffer * mbuffer = (struct memory_buffer *)p; + GFX2_Log(GFX2_DEBUG, "lTIFF_read(%p, %p, %u)\n", p, data, size); + memcpy(data, mbuffer->buffer + mbuffer->offset, size); + mbuffer->offset += size; + return size; +} + +tmsize_t lTIFF_write(thandle_t p, void * data, tmsize_t size) +{ + struct memory_buffer * mbuffer = (struct memory_buffer *)p; + GFX2_Log(GFX2_DEBUG, "lTIFF_write(%p, %p, %u)\n", p, data, size); + return -1; +} + +toff_t lTIFF_seek(thandle_t p, toff_t offset, whence) +{ + struct memory_buffer * mbuffer = (struct memory_buffer *)p; + GFX2_Log(GFX2_DEBUG, "lTIFF_seek(%p, %u, %d)\n", p, offset, whence); + switch (whence) + { + case SEEK_SET: + mbuffer->offset = offset; + break; + case SEEK_CUR: + mbuffer->offset += offset; + break; + case SEEK_END: + mbuffer->offset = mbuffer->size - offset; + break; + default: + return -1; + } + return mbuffer->offset; +} + + +toff_t lTIFF_size(thandle_t p) +{ + struct memory_buffer * mbuffer = (struct memory_buffer *)p; + return mbuffer->size; +} + +int lTIFF_close(thandle_t p) +{ + (void)p; + return 0; +} + +int lTIFF_map(thandle_t p, void ** base, toff_t * size) +{ + struct memory_buffer * mbuffer = (struct memory_buffer *)p; + GFX2_Log(GFX2_DEBUG, "lTIFF_map(%p, %p, %p)\n", p, base, size); + *base = mbuffer->buffer; + *size = mbuffer->size; + return 1; +} + +void lTIFF_unmap(thandle_t p, void *base, toff_t size) +{ + GFX2_Log(GFX2_DEBUG, "lTIFF_unmap(%p, %p, %u)\n", p, base, size); + return; +} + +/// Load TIFF from memory +void Load_TIFF_from_memory(T_IO_Context * context, const void * buffer, unsigned long size) +{ + TIFF * tif; + struct memory_buffer memory_buffer; + + memory_buffer.buffer = (char *)buffer; + memory_buffer.offset = 0; + memory_buffer.size = size; + + TIFF_Init(); + tif = TIFFClientOpen("memory.tiff", "r", &memory_buffer, + lTIFF_read, lTIFF_write, lTIFF_seek, lTIFF_close, + lTIFF_size, lTIFF_map, lTIFF_unmap); + if (tif != NULL) + { + Load_TIFF_Sub(context, tif, size); + TIFFClose(tif); + } +} + /// Load TIFF from file void Load_TIFF(T_IO_Context * context) {