Copy to pasteboard support for MacOS

This commit is contained in:
Thomas BERNARD 2019-01-05 00:04:37 +01:00
parent d556df556d
commit 379dc4a092
5 changed files with 91 additions and 5 deletions

View File

@ -168,6 +168,7 @@ void Test_TIFF(T_IO_Context *, FILE *);
void Load_TIFF(T_IO_Context *); void Load_TIFF(T_IO_Context *);
void Save_TIFF(T_IO_Context *); void Save_TIFF(T_IO_Context *);
void Load_TIFF_from_memory(T_IO_Context *, const void *, unsigned long); void Load_TIFF_from_memory(T_IO_Context *, const void *, unsigned long);
void Save_TIFF_to_memory(T_IO_Context *, void * *, unsigned long *);
#endif #endif
/// @} /// @}

View File

@ -1736,10 +1736,8 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context
#if defined(WIN32) || defined(__macosx__) || 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) if (load)
Window_set_normal_button(62,180,115,14,"From Clipboard",0,1,SHORTCUT_PASTE); // 14 Window_set_normal_button(62,180,115,14,"From Clipboard",0,1,SHORTCUT_PASTE); // 14
#if !defined(__macosx__)
else else
Window_set_normal_button(62,180,115,14,"To Clipboard",0,1,SHORTCUT_COPY); // 14 Window_set_normal_button(62,180,115,14,"To Clipboard",0,1,SHORTCUT_COPY); // 14
#endif
#endif #endif
Change_directory(context->File_directory); Change_directory(context->File_directory);

View File

@ -88,6 +88,7 @@ extern Window X11_window;
#if defined(__macosx__) #if defined(__macosx__)
const void * get_tiff_paste_board(unsigned long * size); const void * get_tiff_paste_board(unsigned long * size);
int set_tiff_paste_board(const void * tiff, unsigned long size);
#endif #endif
@ -1583,6 +1584,18 @@ static void Save_ClipBoard_Image(T_IO_Context * context)
} }
} }
CloseClipboard(); CloseClipboard();
#elif defined(__macosx__)
void * tiff = NULL;
unsigned long size = 0;
Save_TIFF_to_memory(context, &tiff, &size);
if (File_error == 0 && tiff != NULL)
{
if(!set_tiff_paste_board(tiff, size))
File_error = 1;
}
free(tiff);
#elif defined(USE_X11) || (defined(SDL_VIDEO_DRIVER_X11) && !defined(NO_X11)) #elif defined(USE_X11) || (defined(SDL_VIDEO_DRIVER_X11) && !defined(NO_X11))
Atom selection; Atom selection;
#if defined(SDL_VIDEO_DRIVER_X11) #if defined(SDL_VIDEO_DRIVER_X11)

View File

@ -35,3 +35,17 @@ const void * get_tiff_paste_board(unsigned long * size)
*size = [data length]; *size = [data length];
return [data bytes]; return [data bytes];
} }
int set_tiff_paste_board(const void * tiff, unsigned long size)
{
if (tiff == NULL || size == 0)
return 0;
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard declareTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil];
NSData *data = [[NSData alloc] initWithBytes:tiff length:size];
BOOL b = [pasteboard setData:data forType:NSTIFFPboardType];
if (!b)
NSLog(@"Failed to set data in pasteboard");
[data release];
return (int)b;
}

View File

@ -396,6 +396,7 @@ struct memory_buffer
char * buffer; char * buffer;
unsigned long offset; unsigned long offset;
unsigned long size; unsigned long size;
unsigned long alloc_size;
}; };
tmsize_t lTIFF_read(thandle_t p, void * data, tmsize_t size) tmsize_t lTIFF_read(thandle_t p, void * data, tmsize_t size)
@ -409,15 +410,29 @@ tmsize_t lTIFF_read(thandle_t p, void * data, tmsize_t size)
tmsize_t lTIFF_write(thandle_t p, void * data, tmsize_t size) tmsize_t lTIFF_write(thandle_t p, void * data, tmsize_t size)
{ {
//struct memory_buffer * mbuffer = (struct memory_buffer *)p; struct memory_buffer * mbuffer = (struct memory_buffer *)p;
GFX2_Log(GFX2_DEBUG, "lTIFF_write(%p, %p, %u)\n", p, data, size); GFX2_Log(GFX2_DEBUG, "lTIFF_write(%p, %p, %u)\n", p, data, size);
return -1; if (mbuffer->offset + size > mbuffer->alloc_size)
{
char * tmp = realloc(mbuffer->buffer, mbuffer->offset + size + 1024);
if (tmp == NULL)
{
GFX2_Log(GFX2_ERROR, "lTIFF_write() failed to allocate %u bytes of memory\n", mbuffer->offset + size + 1024);
return -1;
}
mbuffer->buffer = tmp;
mbuffer->alloc_size = mbuffer->offset + size + 1024;
}
memcpy(mbuffer->buffer + mbuffer->offset, data, size);
mbuffer->offset += size;
if (mbuffer->offset > mbuffer->size)
mbuffer->size = mbuffer->offset;
return size;
} }
toff_t lTIFF_seek(thandle_t p, toff_t offset, int whence) toff_t lTIFF_seek(thandle_t p, toff_t offset, int whence)
{ {
struct memory_buffer * mbuffer = (struct memory_buffer *)p; struct memory_buffer * mbuffer = (struct memory_buffer *)p;
GFX2_Log(GFX2_DEBUG, "lTIFF_seek(%p, %u, %d)\n", p, offset, whence);
switch (whence) switch (whence)
{ {
case SEEK_SET: case SEEK_SET:
@ -432,6 +447,25 @@ toff_t lTIFF_seek(thandle_t p, toff_t offset, int whence)
default: default:
return -1; return -1;
} }
GFX2_Log(GFX2_DEBUG, "lTIFF_seek(%p, %u, %d) new offset=%u (size=%u)\n",
p, offset, whence, mbuffer->offset, mbuffer->size);
if (mbuffer->offset > mbuffer->alloc_size)
{
char * tmp = realloc(mbuffer->buffer, mbuffer->offset + 1024);
if (tmp == NULL)
{
GFX2_Log(GFX2_ERROR, "lTIFF_seek() failed to allocate %u bytes of memory\n", mbuffer->offset + 1024);
return -1;
}
mbuffer->buffer = tmp;
mbuffer->alloc_size = mbuffer->offset + 1024;
}
if (mbuffer->offset > mbuffer->size)
{
memset(mbuffer->buffer + mbuffer->size, 0, mbuffer->offset - mbuffer->size);
GFX2_Log(GFX2_ERROR, " seeking %d bytes after end of buffer, filling with 0s\n", mbuffer->offset - mbuffer->size);
mbuffer->size = mbuffer->offset;
}
return mbuffer->offset; return mbuffer->offset;
} }
@ -439,6 +473,7 @@ toff_t lTIFF_seek(thandle_t p, toff_t offset, int whence)
toff_t lTIFF_size(thandle_t p) toff_t lTIFF_size(thandle_t p)
{ {
struct memory_buffer * mbuffer = (struct memory_buffer *)p; struct memory_buffer * mbuffer = (struct memory_buffer *)p;
GFX2_Log(GFX2_DEBUG, "lTIFF_size(%p) = %u\n", p, mbuffer->size);
return mbuffer->size; return mbuffer->size;
} }
@ -472,6 +507,7 @@ void Load_TIFF_from_memory(T_IO_Context * context, const void * buffer, unsigned
memory_buffer.buffer = (char *)buffer; memory_buffer.buffer = (char *)buffer;
memory_buffer.offset = 0; memory_buffer.offset = 0;
memory_buffer.size = size; memory_buffer.size = size;
memory_buffer.alloc_size = 0; // unused for read
TIFF_Init(); TIFF_Init();
tif = TIFFClientOpen("memory.tiff", "r", &memory_buffer, tif = TIFFClientOpen("memory.tiff", "r", &memory_buffer,
@ -610,6 +646,30 @@ void Save_TIFF_Sub(T_IO_Context * context, TIFF * tif)
} }
} }
/// Save TIFF to memory
void Save_TIFF_to_memory(T_IO_Context * context, void * * buffer, unsigned long * size)
{
TIFF * tif;
struct memory_buffer memory_buffer;
memory_buffer.buffer = NULL;
memory_buffer.offset = 0;
memory_buffer.size = 0;
memory_buffer.alloc_size = 0;
TIFF_Init();
tif = TIFFClientOpen("memory.tiff", "w", &memory_buffer,
lTIFF_read, lTIFF_write, lTIFF_seek, lTIFF_close,
lTIFF_size, lTIFF_map, lTIFF_unmap);
if (tif != NULL)
{
Save_TIFF_Sub(context, tif);
TIFFClose(tif);
*buffer = memory_buffer.buffer;
*size = memory_buffer.size;
}
}
/// Save TIFF /// Save TIFF
void Save_TIFF(T_IO_Context * context) void Save_TIFF(T_IO_Context * context)
{ {