/* Haiku window system selection support. Hey Emacs, this is -*- C++ -*-
Copyright (C) 2021 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs 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, either version 3 of the License, or (at
your option) any later version.
GNU Emacs 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 GNU Emacs. If not, see . */
#include
#include
#include
#include
#include "haikuselect.h"
static BClipboard *primary = NULL;
static BClipboard *secondary = NULL;
static BClipboard *system_clipboard = NULL;
int selection_state_flag;
static char *
BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len)
{
if (!cb->Lock ())
return 0;
BMessage *dat = cb->Data ();
if (!dat)
{
cb->Unlock ();
return 0;
}
const char *ptr;
ssize_t bt;
dat->FindData (type, B_MIME_TYPE, (const void **) &ptr, &bt);
if (!ptr)
{
cb->Unlock ();
return NULL;
}
if (len)
*len = bt;
cb->Unlock ();
return strndup (ptr, bt);
}
static void
BClipboard_get_targets (BClipboard *cb, char **buf, int buf_size)
{
BMessage *data;
char *name;
int32 count_found;
type_code type;
int32 i;
int index;
if (!cb->Lock ())
{
buf[0] = NULL;
return;
}
data = cb->Data ();
index = 0;
if (!data)
{
buf[0] = NULL;
cb->Unlock ();
return;
}
for (i = 0; (data->GetInfo (B_ANY_TYPE, i, &name,
&type, &count_found)
== B_OK); ++i)
{
if (type == B_MIME_TYPE)
{
if (index < (buf_size - 1))
{
buf[index++] = strdup (name);
if (!buf[index - 1])
break;
}
}
}
buf[index] = NULL;
cb->Unlock ();
}
static void
BClipboard_set_data (BClipboard *cb, const char *type, const char *dat,
ssize_t len, bool clear)
{
if (!cb->Lock ())
return;
if (clear)
cb->Clear ();
BMessage *mdat = cb->Data ();
if (!mdat)
{
cb->Unlock ();
return;
}
if (dat)
{
if (mdat->ReplaceData (type, B_MIME_TYPE, dat, len)
== B_NAME_NOT_FOUND)
mdat->AddData (type, B_MIME_TYPE, dat, len);
}
else
mdat->RemoveName (type);
cb->Commit ();
cb->Unlock ();
}
char *
BClipboard_find_system_data (const char *type, ssize_t *len)
{
if (!system_clipboard)
return 0;
return BClipboard_find_data (system_clipboard, type, len);
}
char *
BClipboard_find_primary_selection_data (const char *type, ssize_t *len)
{
if (!primary)
return 0;
return BClipboard_find_data (primary, type, len);
}
char *
BClipboard_find_secondary_selection_data (const char *type, ssize_t *len)
{
if (!secondary)
return 0;
return BClipboard_find_data (secondary, type, len);
}
void
BClipboard_set_system_data (const char *type, const char *data,
ssize_t len, bool clear)
{
if (!system_clipboard)
return;
BClipboard_set_data (system_clipboard, type, data, len, clear);
}
void
BClipboard_set_primary_selection_data (const char *type, const char *data,
ssize_t len, bool clear)
{
if (!primary)
return;
BClipboard_set_data (primary, type, data, len, clear);
}
void
BClipboard_set_secondary_selection_data (const char *type, const char *data,
ssize_t len, bool clear)
{
if (!secondary)
return;
BClipboard_set_data (secondary, type, data, len, clear);
}
void
BClipboard_free_data (void *ptr)
{
std::free (ptr);
}
void
BClipboard_system_targets (char **buf, int len)
{
BClipboard_get_targets (system_clipboard, buf, len);
}
void
BClipboard_primary_targets (char **buf, int len)
{
BClipboard_get_targets (primary, buf, len);
}
void
BClipboard_secondary_targets (char **buf, int len)
{
BClipboard_get_targets (secondary, buf, len);
}
void
init_haiku_select (void)
{
system_clipboard = new BClipboard ("system");
primary = new BClipboard ("primary");
secondary = new BClipboard ("secondary");
}