Implementation of the copy/Paste on X11

This commit is contained in:
Edouard Dupin 2012-04-05 16:16:47 +02:00
parent 7642565b03
commit af4d77e5bb
8 changed files with 323 additions and 39 deletions

View File

@ -255,6 +255,23 @@ const etk::UString& etk::UString::operator= (etk::VectorType<char> inputData)
return *this;
}
/**
* @brief
*
* @param[in,out]
*
* @return
*
*/
const etk::UString& etk::UString::operator= (etk::VectorType<int8_t> inputData)
{
etk::VectorType<uniChar_t> output_Unicode;
unicode::convertUtf8ToUnicode(inputData, output_Unicode);
*this = output_Unicode;
return *this;
}
/**
* @brief
*

View File

@ -52,6 +52,7 @@ namespace etk
*****************************************************/
const etk::UString& operator= (const etk::UString &etkS );
const etk::UString& operator= (etk::VectorType<char> inputData);
const etk::UString& operator= (etk::VectorType<int8_t> inputData);
const etk::UString& operator= (etk::VectorType<uniChar_t> inputData);
/*****************************************************
* == operator

View File

@ -101,15 +101,67 @@ void unicode::convertUnicodeToIso(charset_te inputCharset, uniChar_t input_Unico
int32_t unicode::convertIsoToUnicode(charset_te inputCharset, etk::VectorType<char>& input_ISO, etk::VectorType<uniChar_t>& output_Unicode)
{
TK_WARNING("TODO : not coded...");
return 0;
output_Unicode.Clear();
uniChar_t output;
for(int32_t iii=0; iii<input_ISO.Size(); iii++) {
convertIsoToUnicode(inputCharset, (char)input_ISO[iii], output);
output_Unicode.PushBack(output);
}
if (output_Unicode.Size() == 0) {
output_Unicode.PushBack(0);
} else if (output_Unicode[output_Unicode.Size()-1] != 0) {
output_Unicode.PushBack(0);
}
return output_Unicode.Size();
}
int32_t unicode::convertIsoToUnicode(charset_te inputCharset, etk::VectorType<int8_t>& input_ISO, etk::VectorType<uniChar_t>& output_Unicode)
{
output_Unicode.Clear();
uniChar_t output;
for(int32_t iii=0; iii<input_ISO.Size(); iii++) {
convertIsoToUnicode(inputCharset, (char)input_ISO[iii], output);
output_Unicode.PushBack(output);
}
if (output_Unicode.Size() == 0) {
output_Unicode.PushBack(0);
} else if (output_Unicode[output_Unicode.Size()-1] != 0) {
output_Unicode.PushBack(0);
}
return output_Unicode.Size();
}
int32_t unicode::convertUnicodeToIso(charset_te inputCharset, etk::VectorType<uniChar_t>& input_Unicode, etk::VectorType<char>& output_ISO)
{
TK_WARNING("TODO : not coded...");
return 0;
output_ISO.Clear();
char output[10];
for(int32_t iii=0; iii<input_Unicode.Size(); iii++) {
convertUnicodeToUtf8(input_Unicode[iii], output);
char * tmp = output;
while(*tmp != '\0') {
output_ISO.PushBack(*tmp);
tmp++;
}
}
output_ISO.PushBack(0);
return output_ISO.Size();
}
int32_t unicode::convertUnicodeToIso(charset_te inputCharset, etk::VectorType<uniChar_t>& input_Unicode, etk::VectorType<int8_t>& output_ISO)
{
output_ISO.Clear();
char output[10];
for(int32_t iii=0; iii<input_Unicode.Size(); iii++) {
convertUnicodeToUtf8(input_Unicode[iii], output);
char * tmp = output;
while(*tmp != '\0') {
output_ISO.PushBack(*tmp);
tmp++;
}
}
output_ISO.PushBack(0);
return output_ISO.Size();
}
@ -218,6 +270,22 @@ int32_t unicode::convertUnicodeToUtf8(const etk::VectorType<uniChar_t>& input_Un
return output_UTF8.Size()-1;
}
int32_t unicode::convertUnicodeToUtf8(const etk::VectorType<uniChar_t>& input_Unicode, etk::VectorType<int8_t>& output_UTF8)
{
char output[10];
for (int32_t iii=0; iii<input_Unicode.Size(); iii++) {
unicode::convertUnicodeToUtf8(input_Unicode[iii], output);
char * tmp = output ;
while (*tmp != '\0') {
output_UTF8.PushBack((int8_t)*tmp);
tmp++;
}
}
output_UTF8.PushBack('\0');
return output_UTF8.Size()-1;
}
int32_t unicode::convertUtf8ToUnicode(etk::VectorType<char>& input_UTF8, etk::VectorType<uniChar_t>& output_Unicode)
{
@ -270,6 +338,57 @@ int32_t unicode::convertUtf8ToUnicode(etk::VectorType<char>& input_UTF8, etk::Ve
return 0;
}
int32_t unicode::convertUtf8ToUnicode(etk::VectorType<int8_t>& input_UTF8, etk::VectorType<uniChar_t>& output_Unicode)
{
char tmpData[20];
int32_t pos = 0;
while (pos < input_UTF8.Size()) {
int32_t lenMax = input_UTF8.Size() - pos;
//4 case
if( 1<=lenMax
&& 0x00 == (input_UTF8[pos+0] & 0x80) )
{
tmpData[0] = input_UTF8[pos+0];
tmpData[1] = '\0';
pos += 1;
} else if( 2<=lenMax
&& 0xC0 == (input_UTF8[pos+0] & 0xE0)
&& 0x80 == (input_UTF8[pos+1] & 0xC0) ) {
tmpData[0] = input_UTF8[pos+0];
tmpData[1] = input_UTF8[pos+1];
tmpData[2] = '\0';
pos += 2;
} else if( 3<=lenMax
&& 0xE0 == (input_UTF8[pos+0] & 0xF0)
&& 0x80 == (input_UTF8[pos+1] & 0xC0)
&& 0x80 == (input_UTF8[pos+2] & 0xC0)) {
tmpData[0] = input_UTF8[pos+0];
tmpData[1] = input_UTF8[pos+1];
tmpData[2] = input_UTF8[pos+2];
tmpData[3] = '\0';
pos += 3;
} else if( 4<=lenMax
&& 0xF0 == (input_UTF8[pos+0] & 0xF8)
&& 0x80 == (input_UTF8[pos+1] & 0xC0)
&& 0x80 == (input_UTF8[pos+2] & 0xC0)
&& 0x80 == (input_UTF8[pos+3] & 0xC0)) {
tmpData[0] = input_UTF8[pos+0];
tmpData[1] = input_UTF8[pos+1];
tmpData[2] = input_UTF8[pos+2];
tmpData[3] = input_UTF8[pos+3];
tmpData[4] = '\0';
pos += 4;
} else {
tmpData[0] = '\0';
pos += 1;
}
uniChar_t tmpUnicode;
convertUtf8ToUnicode(tmpData, tmpUnicode);
output_Unicode.PushBack(tmpUnicode);
}
return 0;
}
int32_t unicode::convertUtf8ToUnicode(char * input_UTF8, etk::VectorType<uniChar_t>& output_Unicode)
{
char tmpData[20];

View File

@ -50,12 +50,16 @@ namespace unicode {
void convertIsoToUnicode(charset_te inputCharset, char input_ISO, uniChar_t & output_Unicode);
void convertUnicodeToIso(charset_te inputCharset, uniChar_t input_Unicode, char & output_ISO);
int32_t convertIsoToUnicode(charset_te inputCharset, etk::VectorType<char>& input_ISO, etk::VectorType<uniChar_t>& output_Unicode);
int32_t convertIsoToUnicode(charset_te inputCharset, etk::VectorType<int8_t>& input_ISO, etk::VectorType<uniChar_t>& output_Unicode);
int32_t convertUnicodeToIso(charset_te inputCharset, etk::VectorType<uniChar_t>& input_Unicode, etk::VectorType<char>& output_ISO);
int32_t convertUnicodeToIso(charset_te inputCharset, etk::VectorType<uniChar_t>& input_Unicode, etk::VectorType<int8_t>& output_ISO);
// Transform UTF-8 <==> Unicode
void convertUnicodeToUtf8( uniChar_t input_Unicode, char * output_UTF8);
void convertUtf8ToUnicode( char * input_UTF8, uniChar_t& output_Unicode);
int32_t convertUnicodeToUtf8( const etk::VectorType<uniChar_t>& input_Unicode, etk::VectorType<char>& output_UTF8);
int32_t convertUnicodeToUtf8( const etk::VectorType<uniChar_t>& input_Unicode, etk::VectorType<int8_t>& output_UTF8);
int32_t convertUtf8ToUnicode( etk::VectorType<char>& input_UTF8, etk::VectorType<uniChar_t>& output_Unicode);
int32_t convertUtf8ToUnicode( etk::VectorType<int8_t>& input_UTF8, etk::VectorType<uniChar_t>& output_Unicode);
int32_t convertUtf8ToUnicode( char * input_UTF8, etk::VectorType<uniChar_t>& output_Unicode);
// Transform ISO <==> UTF-8
void convertIsoToUtf8( charset_te inputCharset, char input_ISO, char * output_UTF8);

View File

@ -24,6 +24,7 @@
#include <ewol/Debug.h>
#include <ewol/ClipBoard.h>
#include <ewol/base/gui.h>
#undef __class__
#define __class__ "ClipBoard"
@ -64,39 +65,24 @@ void ewol::clipBoard::Set(uint8_t clipboardID, etk::UString &data)
} else if(0 == data.Size()) {
EWOL_INFO("request a copy of nothing");
} else if (ewol::clipBoard::CLIPBOARD_STD == clipboardID) {
//GtkClipboard * clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
//gtk_clipboard_set_text(clipboard, (const gchar*)&data[0], data.Size() );
guiAbstraction::ClipBoardSet(data, guiAbstraction::CLIPBOARD_MODE_STD);
} else if (ewol::clipBoard::CLIPBOARD_SELECTION == clipboardID) {
//GtkClipboard * clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
//gtk_clipboard_set_text(clipboard, (const gchar*)&data[0], data.Size() );
guiAbstraction::ClipBoardSet(data, guiAbstraction::CLIPBOARD_MODE_PRIMARY);
}
// Copy datas ...
mesCopy[clipboardID] = data;
}
void ewol::clipBoard::Get(uint8_t clipboardID, etk::UString &data)
{
if(clipboardID >= ewol::clipBoard::TOTAL_OF_CLICKBOARD) {
EWOL_WARNING("request ClickBoard id error");
} else if (ewol::clipBoard::CLIPBOARD_STD == clipboardID) {
/*
GtkClipboard * clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD );
gchar *text = gtk_clipboard_wait_for_text(clipboard);
if (text != NULL) {
mesCopy[COPY_STD].Clear();
mesCopy[COPY_STD].PushBack((int8_t*)text, strlen(text) );
}
*/
guiAbstraction::ClipBoardGet(data, guiAbstraction::CLIPBOARD_MODE_STD);
return;
} else if (ewol::clipBoard::CLIPBOARD_SELECTION == clipboardID) {
/*
GtkClipboard * clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY );
gchar *text = gtk_clipboard_wait_for_text(clipboard);
if (text != NULL) {
mesCopy[COPY_MIDDLE_BUTTON].Clear();
mesCopy[COPY_MIDDLE_BUTTON].PushBack((int8_t*)text, strlen(text) );
}
*/
guiAbstraction::ClipBoardGet(data, guiAbstraction::CLIPBOARD_MODE_PRIMARY);
return;
}
// Copy datas ...
data = mesCopy[clipboardID];

View File

@ -33,6 +33,7 @@
#include <ewol/Texture.h>
#include <ewol/Texture/TextureBMP.h>
#include <ewol/base/MainThread.h>
#include <ewol/threadMsg.h>
#include <unistd.h>
#include <stdlib.h>
@ -126,8 +127,12 @@ int32_t offsetMoveClickedDouble = 20;
bool inputIsPressed[20];
// internal copy of the clipBoard ...
static etk::UString l_clipBoardPrimary("");
static etk::UString l_clipBoardStd("");
static ewol::simpleMsg::simpleMsg_ts l_clipboardMessage;
static bool l_clipBoardRequestPrimary = false;
static bool l_clipBoardOwnerPrimary = false;
static etk::UString l_clipBoardPrimary("");
static bool l_clipBoardOwnerStd = false;
static etk::UString l_clipBoardStd("");
// Atom access...
static Atom XAtomeSelection = 0;
static Atom XAtomeClipBoard = 0;
@ -434,8 +439,12 @@ void X11_Init(void)
CreateX11Context();
CreateOGlContext();
// reset clipBoard
l_clipBoardRequestPrimary = false;
l_clipBoardOwnerPrimary = false;
l_clipBoardOwnerStd = false;
l_clipBoardPrimary = "";
l_clipBoardStd = "";
ewol::simpleMsg::Init(l_clipboardMessage);
// reset the Atom properties ...
XAtomeSelection = XInternAtom(m_display, "PRIMARY", 0);
XAtomeClipBoard = XInternAtom(m_display, "CLIPBOARD", 0);
@ -478,17 +487,24 @@ void X11_Run(void)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
case SelectionClear:
// Selection has been done on an other program ==> clear ours ...
EWOL_DEBUG("X11 event SelectionClear");
EWOL_VERBOSE("X11 event SelectionClear");
{
XSelectionRequestEvent *req=&(event.xselectionrequest);
EWOL_DEBUG(" property: \"" << XGetAtomName(m_display, req->property) << "\"");
EWOL_DEBUG(" target: \"" << XGetAtomName(m_display, req->target) << "\"");
EWOL_VERBOSE(" property: \"" << XGetAtomName(m_display, req->property) << "\"");
EWOL_VERBOSE(" target: \"" << XGetAtomName(m_display, req->target) << "\"");
if (true == l_clipBoardOwnerPrimary) {
l_clipBoardOwnerPrimary = false;
} else if (true == l_clipBoardOwnerStd) {
l_clipBoardOwnerStd = false;
} else {
EWOL_ERROR("X11 event SelectionClear ==> but no selection requested anymore ...");
}
}
break;
case SelectionNotify:
EWOL_DEBUG("X11 event SelectionNotify");
EWOL_VERBOSE("X11 event SelectionNotify");
if (event.xselection.property == None) {
EWOL_DEBUG(" ==> no data ...");
EWOL_VERBOSE(" ==> no data ...");
} else {
unsigned char *buf = 0;
Atom type;
@ -507,14 +523,22 @@ void X11_Run(void)
&bytes, // *bytes_after_return
&buf// **prop_return);
);
EWOL_DEBUG(" ==> data : " << buf);
if (true == l_clipBoardRequestPrimary) {
l_clipBoardPrimary = (char*)buf;
ewol::simpleMsg::SendMessage(l_clipboardMessage, 4);
EWOL_VERBOSE(" ==> data : " << l_clipBoardPrimary);
} else {
l_clipBoardStd = (char*)buf;
ewol::simpleMsg::SendMessage(l_clipboardMessage, 2);
EWOL_VERBOSE(" ==> data : " << l_clipBoardStd);
}
}
break;
case SelectionRequest:
EWOL_DEBUG("X11 event SelectionRequest");
EWOL_VERBOSE("X11 event SelectionRequest");
{
XSelectionRequestEvent *req=&(event.xselectionrequest);
EWOL_DEBUG(" from: " << XGetAtomName(m_display, req->property) << " request=" << XGetAtomName(m_display, req->selection) << " in " << XGetAtomName(m_display, req->target));
EWOL_VERBOSE(" from: " << XGetAtomName(m_display, req->property) << " request=" << XGetAtomName(m_display, req->selection) << " in " << XGetAtomName(m_display, req->target));
const char * magatTextToSend = NULL;
if (req->selection == XAtomeSelection) {
@ -577,6 +601,7 @@ void X11_Run(void)
respond.xselection.target= req->target;
respond.xselection.time = req->time;
XSendEvent (m_display, req->requestor,0,0,&respond);
// Flush the message on the pipe ...
XFlush (m_display);
}
break;
@ -878,17 +903,49 @@ void X11_GetAbsPos(int32_t & x, int32_t & y)
// ClipBoard AREA :
// ClipBoard AREA :
void guiAbstraction::ClipBoardGet(etk::UString &newData, clipBoardMode_te mode)
{
EWOL_INFO("Request Get of a clipboard : " << mode << " size=" << newData.Size() );
newData = "";
switch (mode)
{
case CLIPBOARD_MODE_PRIMARY:
if (false == l_clipBoardOwnerPrimary) {
l_clipBoardRequestPrimary = true;
XConvertSelection(m_display,
XAtomeSelection,// atom,
XAtomeTargetStringUTF8, // type?
XAtomeEWOL, // prop,
WindowHandle,
CurrentTime);
// wait the event ...
int32_t waitTmp = ewol::simpleMsg::WaitingMessage(l_clipboardMessage, 5000);
if (waitTmp == 0) {
EWOL_ERROR("Timeout when waiting the current selection");
}
}
// get our own buffer ...
newData = l_clipBoardPrimary;
break;
case CLIPBOARD_MODE_STD:
if (false == l_clipBoardOwnerStd) {
l_clipBoardRequestPrimary = false;
XConvertSelection(m_display,
XAtomeClipBoard,// atom,
XAtomeTargetStringUTF8, // type?
XAtomeEWOL, // prop,
WindowHandle,
CurrentTime);
// wait the event ...
int32_t waitTmp = ewol::simpleMsg::WaitingMessage(l_clipboardMessage, 5000);
if (waitTmp == 0) {
EWOL_ERROR("Timeout when waiting the current copy buffer");
}
}
// get our own buffer ...
newData = l_clipBoardStd;
break;
default:
EWOL_ERROR("Request an unknow ClipBoard ...");
@ -898,6 +955,7 @@ void guiAbstraction::ClipBoardGet(etk::UString &newData, clipBoardMode_te mode)
void guiAbstraction::ClipBoardSet(etk::UString &newData, clipBoardMode_te mode)
{
EWOL_VERBOSE("Request set of a clipboard : " << mode << " size=" << newData.Size() );
switch (mode)
{
case CLIPBOARD_MODE_PRIMARY:
@ -905,7 +963,10 @@ void guiAbstraction::ClipBoardSet(etk::UString &newData, clipBoardMode_te mode)
// copy it ...
l_clipBoardPrimary = newData;
// Request the selection :
XSetSelectionOwner(m_display, XAtomeSelection, WindowHandle, CurrentTime);
if (false == l_clipBoardOwnerPrimary) {
XSetSelectionOwner(m_display, XAtomeSelection, WindowHandle, CurrentTime);
l_clipBoardOwnerPrimary = true;
}
}
break;
case CLIPBOARD_MODE_STD:
@ -913,7 +974,10 @@ void guiAbstraction::ClipBoardSet(etk::UString &newData, clipBoardMode_te mode)
// copy it ...
l_clipBoardStd = newData;
// Request the clipBoard :
XSetSelectionOwner(m_display, XAtomeClipBoard, WindowHandle, CurrentTime);
if (false == l_clipBoardOwnerStd) {
XSetSelectionOwner(m_display, XAtomeClipBoard, WindowHandle, CurrentTime);
l_clipBoardOwnerStd = true;
}
}
break;
default:

View File

@ -184,3 +184,82 @@ void ewol::threadMsg::SendDisplayDone(threadMsg_ts& messageData)
{
}
#include <sys/time.h>
void ewol::simpleMsg::Init(ewol::simpleMsg::simpleMsg_ts& handle)
{
// create interface mutex :
int ret = pthread_mutex_init(&handle.mutex, NULL);
EWOL_ASSERT(ret == 0, "Error creating Mutex ...");
// create contition :
ret = pthread_cond_init(&handle.condition, NULL);
EWOL_ASSERT(ret == 0, "Error creating Condition ...");
if (ret != 0) {
ret = pthread_mutex_destroy(&handle.mutex);
EWOL_ASSERT(ret == 0, "Error destroying Mutex ...");
} else {
handle.messageValue = 0;
}
handle.isInit = true;
}
void ewol::simpleMsg::UnInit(ewol::simpleMsg::simpleMsg_ts& handle)
{
if (true == handle.isInit) {
// Remove Mutex
int ret = pthread_cond_destroy(&handle.condition);
EWOL_ASSERT(ret == 0, "Error destroying Condition ...");
// Remove condition
ret = pthread_mutex_destroy(&handle.mutex);
EWOL_ASSERT(ret == 0, "Error destroying Mutex ...");
// remove data ????
handle.isInit = false;
}
}
uint32_t ewol::simpleMsg::WaitingMessage(ewol::simpleMsg::simpleMsg_ts& handle, int32_t timeOut)
{
if (false == handle.isInit) {
return 0;
}
pthread_mutex_lock(&handle.mutex);
if (0 == handle.messageValue) {
if (timeOut == 0) {
pthread_cond_wait(&handle.condition, &handle.mutex);
} else {
struct timeval now;
struct timespec timeout;
gettimeofday(&now, NULL);
timeout.tv_sec = now.tv_sec + timeOut/1000;
timeout.tv_nsec = now.tv_usec * 1000 + timeOut%1000;
pthread_cond_timedwait(&handle.condition, &handle.mutex, &timeout);
}
}
// copy message
int32_t messageCopy = handle.messageValue;
// reset it ...
handle.messageValue = 0;
pthread_mutex_unlock(&handle.mutex);
return messageCopy;
}
void ewol::simpleMsg::SendMessage(ewol::simpleMsg::simpleMsg_ts& handle, uint32_t message)
{
if (false == handle.isInit) {
return;
}
pthread_mutex_lock(&handle.mutex);
handle.messageValue = message;
pthread_cond_broadcast(&handle.condition);
pthread_mutex_unlock(&handle.mutex);
}

View File

@ -66,6 +66,20 @@ namespace ewol {
bool SendMessage(threadMsg_ts& messageData, uint32_t type, msgPriority_te prio = MSG_PRIO_NONE, void * data = NULL, uint32_t size = 0);
void SendDisplayDone(threadMsg_ts& messageData);
};
namespace simpleMsg {
typedef struct {
bool isInit;
pthread_mutex_t mutex;
pthread_cond_t condition;
uint32_t messageValue;
} simpleMsg_ts;
void Init( simpleMsg_ts& handle);
void UnInit( simpleMsg_ts& handle);
uint32_t WaitingMessage(simpleMsg_ts& handle, int32_t timeOut=0);
void SendMessage( simpleMsg_ts& handle, uint32_t message);
};
};
#endif