2010-12-20 03:09:19 -08:00
# ifdef HAVE_CONFIG_H
# include "elementary_config.h"
# endif
2010-06-17 01:06:07 -07:00
# include <Elementary.h>
# include "elm_priv.h"
2011-11-20 06:56:12 -08:00
# ifdef HAVE_MMAN_H
# include <sys / mman.h>
# endif
2010-06-17 01:06:07 -07:00
2012-06-19 16:33:57 -07:00
/*
TODO : MUST FIX BUGS
elm_cnp must detect the environment of each engine the window is
running , maybe associate it more with the elm_win code .
It should only call X11 code for X11 windows ! Right now it will call
them whenever Elementary is compiled with Ecore_X , but it ' s not in
use ! The recommendation is to make a " engine " structure with
function pointers on what to do for each engine ( X11 , Wayland ,
DirectFB . . . ) and call only those . Splitting different CNP engines to
different files should help detect problems .
At least for X11 it ' s handled per xwin . We have a single xwin per
window ( as opposed of GTK that have ( had ? ) it per widget . But our
high - level code is mapped to widget / objects , then we must
reference - count the actions we enable - disable per window
( dnd - aware ) , as well as operate on sets ( add / del ) of supported
formats . It should be possible to have a single window with
different widgets being drop - target , one just for text , one for
image . It should be possible to start - drag from this window without
breaking drop later .
And the dispatch should be abstracted ! Right now it ' s assuming
elm_entry : - (
*/
2010-12-20 03:09:19 -08:00
# ifdef HAVE_ELEMENTARY_X
2010-06-25 04:56:02 -07:00
2010-12-20 03:09:19 -08:00
# define ARRAYINIT(foo) [foo] =
2010-06-17 01:06:07 -07:00
2012-06-25 04:16:25 -07:00
//#define DEBUGON 1
2011-01-07 20:55:31 -08:00
2010-12-20 03:09:19 -08:00
# ifdef DEBUGON
# define cnp_debug(x...) fprintf(stderr, __FILE__": " x)
2010-06-30 06:20:58 -07:00
# else
2010-12-20 03:09:19 -08:00
# define cnp_debug(x...)
2010-06-30 06:20:58 -07:00
# endif
2010-12-20 03:09:19 -08:00
typedef struct _Cnp_Selection Cnp_Selection ;
typedef struct _Escape Escape ;
typedef struct _Tmp_Info Tmp_Info ;
typedef struct _Cnp_Atom Cnp_Atom ;
typedef struct _Saved_Type Saved_Type ;
typedef struct _Dropable Dropable ;
2010-06-17 01:06:07 -07:00
2010-12-20 03:09:19 -08:00
typedef Eina_Bool ( * Converter_Fn_Cb ) ( char * target , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype , int * typesize ) ;
typedef int ( * Response_Handler_Cb ) ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * ) ;
typedef int ( * Notify_Handler_Cb ) ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * ) ;
2010-06-17 01:06:07 -07:00
2010-12-20 03:09:19 -08:00
enum
{
CNP_ATOM_TARGETS = 0 ,
2011-09-27 23:48:44 -07:00
CNP_ATOM_ATOM ,
CNP_ATOM_LISTING_ATOMS = CNP_ATOM_ATOM ,
2010-12-20 03:09:19 -08:00
CNP_ATOM_text_uri ,
CNP_ATOM_text_urilist ,
CNP_ATOM_text_x_vcard ,
CNP_ATOM_image_png ,
CNP_ATOM_image_jpeg ,
CNP_ATOM_image_bmp ,
CNP_ATOM_image_gif ,
CNP_ATOM_image_tiff ,
CNP_ATOM_image_svg ,
CNP_ATOM_image_xpm ,
CNP_ATOM_image_tga ,
CNP_ATOM_image_ppm ,
CNP_ATOM_XELM ,
CNP_ATOM_text_html_utf8 ,
CNP_ATOM_text_html ,
CNP_ATOM_UTF8STRING ,
CNP_ATOM_STRING ,
CNP_ATOM_TEXT ,
CNP_ATOM_text_plain_utf8 ,
CNP_ATOM_text_plain ,
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
CNP_N_ATOMS ,
} ;
2010-06-17 01:06:07 -07:00
2010-12-20 03:09:19 -08:00
struct _Cnp_Selection
{
2012-05-09 01:43:45 -07:00
const char * debug ;
Evas_Object * widget ;
char * selbuf ;
Evas_Object * requestwidget ;
void * udata ;
Elm_Sel_Format requestformat ;
Elm_Drop_Cb datacb ;
Eina_Bool ( * set ) ( Ecore_X_Window , const void * data , int size ) ;
Eina_Bool ( * clear ) ( void ) ;
void ( * request ) ( Ecore_X_Window , const char * target ) ;
2012-06-25 04:16:25 -07:00
Elm_Selection_Loss_Cb loss_cb ;
void * loss_data ;
2012-05-09 01:43:45 -07:00
Elm_Sel_Format format ;
Ecore_X_Selection ecore_sel ;
2012-06-19 16:33:57 -07:00
Ecore_X_Window xwin ;
2012-05-09 01:43:45 -07:00
Eina_Bool active : 1 ;
2010-06-17 01:06:07 -07:00
} ;
2010-12-20 03:09:19 -08:00
struct _Escape
{
2010-06-17 01:06:07 -07:00
const char * escape ;
2011-12-27 03:24:13 -08:00
const char * value ;
2010-06-17 01:06:07 -07:00
} ;
2010-12-20 03:09:19 -08:00
struct _Tmp_Info
{
2010-09-21 21:42:41 -07:00
char * filename ;
void * map ;
2010-12-20 03:09:19 -08:00
int fd ;
int len ;
2010-09-21 21:42:41 -07:00
} ;
2010-12-20 03:09:19 -08:00
struct _Cnp_Atom
{
2012-05-09 01:43:45 -07:00
const char * name ;
Elm_Sel_Format formats ;
2010-12-20 03:09:19 -08:00
/* Called by ecore to do conversion */
Converter_Fn_Cb converter ;
Response_Handler_Cb response ;
Notify_Handler_Cb notify ;
/* Atom */
Ecore_X_Atom atom ;
} ;
struct _Saved_Type
{
const char * * types ;
2011-06-20 00:13:50 -07:00
char * imgfile ;
2010-12-20 03:09:19 -08:00
int ntypes ;
int x , y ;
Eina_Bool textreq : 1 ;
} ;
2010-09-21 21:42:41 -07:00
2010-12-20 03:09:19 -08:00
struct _Dropable
{
2012-05-09 01:43:45 -07:00
Evas_Object * obj ;
2010-12-20 03:09:19 -08:00
/* FIXME: Cache window */
2011-12-27 03:24:13 -08:00
Elm_Sel_Format types ;
2012-05-09 01:43:45 -07:00
Elm_Drop_Cb dropcb ;
void * cbdata ;
2010-12-20 03:09:19 -08:00
} ;
static Tmp_Info * elm_cnp_tempfile_create ( int size ) ;
static int tmpinfo_free ( Tmp_Info * tmp ) ;
2010-06-17 01:06:07 -07:00
static Eina_Bool _elm_cnp_init ( void ) ;
2010-06-25 02:58:14 -07:00
static Eina_Bool selection_clear ( void * udata __UNUSED__ , int type , void * event ) ;
static Eina_Bool selection_notify ( void * udata __UNUSED__ , int type , void * event ) ;
2010-06-23 01:02:35 -07:00
2010-09-27 11:45:38 -07:00
static Eina_Bool targets_converter ( char * target , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype , int * typesize ) ;
static Eina_Bool text_converter ( char * target , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype , int * typesize ) ;
2011-08-25 19:39:28 -07:00
static Eina_Bool general_converter ( char * target , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype , int * typesize ) ;
2010-12-20 03:09:19 -08:00
static Eina_Bool image_converter ( char * target , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype , int * typesize ) ;
2010-09-27 11:45:38 -07:00
static Eina_Bool vcard_send ( char * target , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype , int * typesize ) ;
2010-06-17 01:06:07 -07:00
2010-12-20 03:09:19 -08:00
static int response_handler_targets ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * ) ;
static int notify_handler_targets ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify ) ;
static int notify_handler_text ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify ) ;
static int notify_handler_image ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify ) ;
static int notify_handler_uri ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify ) ;
static int notify_handler_html ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify ) ;
static int vcard_receive ( Cnp_Selection * sed , Ecore_X_Event_Selection_Notify * notify ) ;
2011-06-20 00:13:50 -07:00
static Eina_Bool pasteimage_append ( char * file , Evas_Object * entry ) ;
2010-12-20 03:09:19 -08:00
static Cnp_Atom atoms [ CNP_N_ATOMS ] = {
2012-06-25 04:16:25 -07:00
[ CNP_ATOM_TARGETS ] = {
" TARGETS " ,
ELM_SEL_FORMAT_TARGETS ,
targets_converter ,
response_handler_targets ,
notify_handler_targets ,
0
} ,
[ CNP_ATOM_ATOM ] = {
" ATOM " , // for opera browser
ELM_SEL_FORMAT_TARGETS ,
targets_converter ,
response_handler_targets ,
notify_handler_targets ,
0
} ,
[ CNP_ATOM_XELM ] = {
" application/x-elementary-markup " ,
ELM_SEL_FORMAT_MARKUP ,
general_converter ,
NULL ,
NULL ,
0
} ,
[ CNP_ATOM_text_uri ] = {
" text/uri " ,
ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE , /* Either images or entries */
general_converter ,
NULL ,
notify_handler_uri ,
0
} ,
[ CNP_ATOM_text_urilist ] = {
" text/uri-list " ,
ELM_SEL_FORMAT_IMAGE ,
general_converter ,
NULL ,
notify_handler_uri ,
0
} ,
[ CNP_ATOM_text_x_vcard ] = {
" text/x-vcard " ,
ELM_SEL_FORMAT_VCARD ,
vcard_send , NULL ,
vcard_receive , 0
} ,
[ CNP_ATOM_image_png ] = {
" image/png " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image ,
0
} ,
[ CNP_ATOM_image_jpeg ] = {
" image/jpeg " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_image_bmp ] = {
" image/x-ms-bmp " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_image_gif ] = {
" image/gif " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_image_tiff ] = {
" image/tiff " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_image_svg ] = {
" image/svg+xml " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_image_xpm ] = {
" image/x-xpixmap " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_image_tga ] = {
" image/x-tga " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_image_ppm ] = {
" image/x-portable-pixmap " ,
ELM_SEL_FORMAT_IMAGE ,
image_converter ,
NULL ,
notify_handler_image , /* Raw image data is the same */
0
} ,
[ CNP_ATOM_text_html_utf8 ] = {
" text/html;charset=utf-8 " ,
ELM_SEL_FORMAT_HTML ,
general_converter ,
NULL ,
notify_handler_html ,
0
} ,
[ CNP_ATOM_text_html ] = {
" text/html " ,
ELM_SEL_FORMAT_HTML ,
general_converter ,
NULL ,
notify_handler_html , /* No encoding: Webkit only */
0
} ,
[ CNP_ATOM_UTF8STRING ] = {
" UTF8_STRING " ,
ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML ,
text_converter ,
NULL ,
notify_handler_text ,
0
} ,
[ CNP_ATOM_STRING ] = {
" STRING " ,
ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML ,
text_converter ,
NULL ,
notify_handler_text ,
0
} ,
[ CNP_ATOM_TEXT ] = {
" TEXT " ,
ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML ,
text_converter ,
NULL ,
NULL ,
0
} ,
[ CNP_ATOM_text_plain_utf8 ] = {
" text/plain;charset=utf-8 " ,
ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML ,
text_converter ,
NULL ,
NULL ,
0
} ,
[ CNP_ATOM_text_plain ] = {
" text/plain " ,
ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML ,
text_converter ,
NULL ,
NULL ,
0
} ,
2010-06-17 01:06:07 -07:00
} ;
2012-02-22 18:52:07 -08:00
static Cnp_Selection selections [ ELM_SEL_TYPE_CLIPBOARD + 1 ] = {
2012-06-25 04:16:25 -07:00
ARRAYINIT ( ELM_SEL_TYPE_PRIMARY ) {
. debug = " Primary " ,
. ecore_sel = ECORE_X_SELECTION_PRIMARY ,
. set = ecore_x_selection_primary_set ,
. clear = ecore_x_selection_primary_clear ,
. request = ecore_x_selection_primary_request ,
} ,
ARRAYINIT ( ELM_SEL_TYPE_SECONDARY ) {
. debug = " Secondary " ,
. ecore_sel = ECORE_X_SELECTION_SECONDARY ,
. set = ecore_x_selection_secondary_set ,
. clear = ecore_x_selection_secondary_clear ,
. request = ecore_x_selection_secondary_request ,
} ,
ARRAYINIT ( ELM_SEL_TYPE_XDND ) {
. debug = " XDnD " ,
. ecore_sel = ECORE_X_SELECTION_XDND ,
. request = ecore_x_selection_xdnd_request ,
} ,
ARRAYINIT ( ELM_SEL_TYPE_CLIPBOARD ) {
. debug = " Clipboard " ,
. ecore_sel = ECORE_X_SELECTION_CLIPBOARD ,
. set = ecore_x_selection_clipboard_set ,
. clear = ecore_x_selection_clipboard_clear ,
. request = ecore_x_selection_clipboard_request ,
} ,
2010-06-17 01:06:07 -07:00
} ;
2010-09-06 23:56:16 -07:00
/* Data for DND in progress */
2010-12-20 03:09:19 -08:00
static Saved_Type savedtypes = { NULL , NULL , 0 , 0 , 0 , EINA_FALSE } ;
2012-06-19 16:33:57 -07:00
/* TODO BUG: should NEVER have these as globals! They should be per context (window). */
2010-12-20 03:09:19 -08:00
static void ( * dragdonecb ) ( void * data , Evas_Object * obj ) = NULL ;
static void * dragdonedata = NULL ;
2010-09-10 01:24:21 -07:00
2010-06-17 01:06:07 -07:00
static int _elm_cnp_init_count = 0 ;
2010-09-16 22:39:00 -07:00
/**
* Drag & Drop functions
*/
2010-12-20 03:09:19 -08:00
/* FIXME: Way too many globals */
static Eina_List * drops = NULL ;
static Evas_Object * dragwin = NULL ;
static int _dragx = 0 , _dragy = 0 ;
static Ecore_Event_Handler * handler_pos = NULL ;
static Ecore_Event_Handler * handler_drop = NULL ;
static Ecore_Event_Handler * handler_enter = NULL ;
static Ecore_Event_Handler * handler_status = NULL ;
2010-09-16 22:39:00 -07:00
2010-06-25 05:14:34 -07:00
# endif
2010-09-06 23:56:16 -07:00
/* Stringshared, so I can just compare pointers later */
static const char * text_uri ;
2010-06-17 01:06:07 -07:00
2011-08-08 00:51:02 -07:00
Eina_Bool
elm_selection_selection_has_owner ( void )
{
# ifdef HAVE_ELEMENTARY_X
2011-08-09 04:55:00 -07:00
return ! ! ecore_x_selection_owner_get ( ECORE_X_ATOM_SELECTION_CLIPBOARD ) ;
2011-08-08 00:51:02 -07:00
# else
return EINA_FALSE ;
# endif
}
2010-06-25 05:14:34 -07:00
# ifdef HAVE_ELEMENTARY_X
2012-06-19 16:33:57 -07:00
static Ecore_X_Window
_elm_widget_xwin_get ( const Evas_Object * obj )
{
Evas_Object * top ;
Ecore_X_Window xwin = 0 ;
2012-06-25 04:16:25 -07:00
2012-06-19 16:33:57 -07:00
top = elm_widget_top_get ( obj ) ;
if ( ! top ) top = elm_widget_top_get ( elm_widget_parent_widget_get ( obj ) ) ;
2012-06-25 04:16:25 -07:00
2011-04-14 06:51:12 -07:00
if ( top ) xwin = elm_win_xwindow_get ( top ) ;
2012-06-25 04:16:25 -07:00
2012-05-23 21:34:53 -07:00
if ( ! xwin )
{
2012-06-19 16:33:57 -07:00
Ecore_Evas * ee ;
2012-05-23 21:34:53 -07:00
Evas * evas = evas_object_evas_get ( obj ) ;
2012-06-19 16:33:57 -07:00
if ( ! evas ) return 0 ;
ee = ecore_evas_ecore_evas_get ( evas ) ;
if ( ! ee ) return 0 ;
2012-07-11 04:53:29 -07:00
xwin = _elm_ee_xwin_get ( ee ) ;
2012-05-23 21:34:53 -07:00
}
2012-06-19 16:33:57 -07:00
return xwin ;
}
# endif
2012-06-25 04:16:25 -07:00
# ifdef HAVE_ELEMENTARY_X
static void
_sel_obj_del ( void * data , Evas * e __UNUSED__ , Evas_Object * obj , void * event_info __UNUSED__ )
{
Cnp_Selection * sel = data ;
if ( sel - > widget = = obj ) sel - > widget = NULL ;
}
static void
_sel_obj_del2 ( void * data , Evas * e __UNUSED__ , Evas_Object * obj , void * event_info __UNUSED__ )
{
Cnp_Selection * sel = data ;
if ( sel - > requestwidget = = obj ) sel - > requestwidget = NULL ;
}
# endif
2012-06-19 16:33:57 -07:00
EAPI Eina_Bool
elm_cnp_selection_set ( Evas_Object * obj , Elm_Sel_Type selection ,
Elm_Sel_Format format , const void * selbuf , size_t buflen )
{
# ifdef HAVE_ELEMENTARY_X
Ecore_X_Window xwin = _elm_widget_xwin_get ( obj ) ;
Cnp_Selection * sel ;
2012-06-25 04:16:25 -07:00
2012-02-22 18:52:07 -08:00
if ( ( ! xwin ) | | ( selection > ELM_SEL_TYPE_CLIPBOARD ) )
2011-12-27 03:24:13 -08:00
return EINA_FALSE ;
2010-06-17 01:06:07 -07:00
if ( ! _elm_cnp_init_count ) _elm_cnp_init ( ) ;
2010-10-22 14:41:22 -07:00
if ( ( ! selbuf ) & & ( format ! = ELM_SEL_FORMAT_IMAGE ) )
2012-02-22 18:52:11 -08:00
return elm_object_cnp_selection_clear ( obj , selection ) ;
2010-06-17 01:06:07 -07:00
sel = selections + selection ;
2012-06-25 04:16:25 -07:00
if ( sel - > loss_cb ) sel - > loss_cb ( sel - > loss_data , selection ) ;
if ( sel - > widget )
evas_object_event_callback_del_full ( sel - > widget , EVAS_CALLBACK_DEL ,
_sel_obj_del , sel ) ;
sel - > widget = NULL ;
2011-12-20 00:37:26 -08:00
sel - > active = EINA_TRUE ;
2012-02-15 23:06:13 -08:00
sel - > widget = obj ;
2012-06-19 16:33:57 -07:00
sel - > xwin = xwin ;
2011-04-14 03:48:43 -07:00
sel - > set ( xwin , & selection , sizeof ( Elm_Sel_Type ) ) ;
2010-06-17 01:06:07 -07:00
sel - > format = format ;
2012-06-25 04:16:25 -07:00
sel - > loss_cb = NULL ;
sel - > loss_data = NULL ;
2011-12-27 03:24:13 -08:00
2012-06-25 04:16:25 -07:00
evas_object_event_callback_add
( sel - > widget , EVAS_CALLBACK_DEL , _sel_obj_del , sel ) ;
2011-12-27 03:24:13 -08:00
if ( selbuf )
{
if ( format = = ELM_SEL_FORMAT_IMAGE )
{
2012-04-13 03:19:45 -07:00
// selbuf is actual image data, not text/string
sel - > selbuf = malloc ( buflen ) ;
2012-05-21 21:42:45 -07:00
if ( ! sel - > selbuf )
{
elm_object_cnp_selection_clear ( obj , selection ) ;
return EINA_FALSE ;
}
2011-12-27 03:24:13 -08:00
memcpy ( sel - > selbuf , selbuf , buflen ) ;
}
else
sel - > selbuf = strdup ( ( char * ) selbuf ) ;
}
else
sel - > selbuf = NULL ;
2010-06-25 05:14:34 -07:00
return EINA_TRUE ;
# else
return EINA_FALSE ;
# endif
2010-06-17 01:06:07 -07:00
}
2012-06-25 04:16:25 -07:00
EAPI void
elm_cnp_selection_loss_callback_set ( Elm_Sel_Type selection , Elm_Selection_Loss_Cb func , const void * data )
{
# ifdef HAVE_ELEMENTARY_X
Cnp_Selection * sel ;
if ( selection > ELM_SEL_TYPE_CLIPBOARD ) return ;
sel = selections + selection ;
sel - > loss_cb = func ;
sel - > loss_data = ( void * ) data ;
# endif
}
2012-02-15 23:06:13 -08:00
EAPI Eina_Bool
2012-02-22 18:52:11 -08:00
elm_object_cnp_selection_clear ( Evas_Object * obj , Elm_Sel_Type selection )
2010-06-25 05:14:34 -07:00
{
# ifdef HAVE_ELEMENTARY_X
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2010-06-17 01:06:07 -07:00
2012-02-22 18:52:07 -08:00
if ( ( unsigned int ) selection > ( unsigned int ) ELM_SEL_TYPE_CLIPBOARD )
2011-12-27 03:24:13 -08:00
return EINA_FALSE ;
2010-06-17 01:06:07 -07:00
if ( ! _elm_cnp_init_count ) _elm_cnp_init ( ) ;
sel = selections + selection ;
/* No longer this selection: Consider it gone! */
2012-02-15 23:06:13 -08:00
if ( ( ! sel - > active ) | | ( sel - > widget ! = obj ) ) return EINA_TRUE ;
2010-06-17 01:06:07 -07:00
2012-06-25 04:16:25 -07:00
if ( sel - > widget )
evas_object_event_callback_del_full ( sel - > widget , EVAS_CALLBACK_DEL ,
_sel_obj_del , sel ) ;
if ( sel - > requestwidget )
evas_object_event_callback_del_full ( sel - > requestwidget , EVAS_CALLBACK_DEL ,
_sel_obj_del2 , sel ) ;
2010-06-17 01:06:07 -07:00
sel - > widget = NULL ;
2012-06-25 04:16:25 -07:00
sel - > requestwidget = NULL ;
sel - > loss_cb = NULL ;
sel - > loss_data = NULL ;
sel - > active = EINA_FALSE ;
2011-12-27 03:24:13 -08:00
if ( sel - > selbuf )
2011-12-28 04:54:59 -08:00
{
free ( sel - > selbuf ) ;
sel - > selbuf = NULL ;
}
2010-06-17 01:06:07 -07:00
sel - > clear ( ) ;
2010-06-25 05:14:34 -07:00
return EINA_TRUE ;
# else
return EINA_FALSE ;
# endif
2010-06-17 01:06:07 -07:00
}
2012-02-15 23:06:13 -08:00
EAPI Eina_Bool
2012-02-27 22:17:22 -08:00
elm_cnp_selection_get ( Evas_Object * obj , Elm_Sel_Type selection ,
Elm_Sel_Format format , Elm_Drop_Cb datacb , void * udata )
2010-06-25 05:14:34 -07:00
{
# ifdef HAVE_ELEMENTARY_X
2012-06-19 16:33:57 -07:00
Ecore_X_Window xwin = _elm_widget_xwin_get ( obj ) ;
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2010-06-23 01:02:35 -07:00
2012-02-22 18:52:07 -08:00
if ( selection > ELM_SEL_TYPE_CLIPBOARD )
2011-12-27 03:24:13 -08:00
return EINA_FALSE ;
2010-06-23 01:02:35 -07:00
if ( ! _elm_cnp_init_count ) _elm_cnp_init ( ) ;
sel = selections + selection ;
2012-05-23 21:34:53 -07:00
if ( ! xwin ) return EINA_FALSE ;
2010-06-23 01:02:35 -07:00
2012-06-25 04:16:25 -07:00
if ( sel - > requestwidget )
evas_object_event_callback_del_full ( sel - > requestwidget , EVAS_CALLBACK_DEL ,
_sel_obj_del2 , sel ) ;
sel - > requestwidget = NULL ;
2010-06-23 01:02:35 -07:00
sel - > requestformat = format ;
2012-02-15 23:06:13 -08:00
sel - > requestwidget = obj ;
2012-06-19 16:33:57 -07:00
sel - > xwin = xwin ;
2012-05-23 21:34:53 -07:00
sel - > request ( xwin , ECORE_X_SELECTION_TARGET_TARGETS ) ;
2010-10-17 21:48:54 -07:00
sel - > datacb = datacb ;
sel - > udata = udata ;
2010-06-23 01:02:35 -07:00
2012-06-25 04:16:25 -07:00
evas_object_event_callback_add
( sel - > requestwidget , EVAS_CALLBACK_DEL , _sel_obj_del2 , sel ) ;
2010-06-23 01:02:35 -07:00
return EINA_TRUE ;
2010-06-25 05:14:34 -07:00
# else
return EINA_FALSE ;
# endif
2010-06-23 01:02:35 -07:00
}
2010-06-25 05:14:34 -07:00
# ifdef HAVE_ELEMENTARY_X
2010-06-17 01:06:07 -07:00
static Eina_Bool
2010-12-20 03:09:19 -08:00
_elm_cnp_init ( void )
{
2010-06-17 01:06:07 -07:00
int i ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
if ( _elm_cnp_init_count + + ) return EINA_TRUE ;
for ( i = 0 ; i < CNP_N_ATOMS ; i + + )
2010-06-17 01:06:07 -07:00
{
2011-04-01 04:35:07 -07:00
atoms [ i ] . atom = ecore_x_atom_get ( atoms [ i ] . name ) ;
ecore_x_selection_converter_atom_add ( atoms [ i ] . atom ,
2010-12-20 03:09:19 -08:00
atoms [ i ] . converter ) ;
2010-06-17 01:06:07 -07:00
}
2010-12-20 03:09:19 -08:00
ecore_event_handler_add ( ECORE_X_EVENT_SELECTION_CLEAR , selection_clear , NULL ) ;
ecore_event_handler_add ( ECORE_X_EVENT_SELECTION_NOTIFY , selection_notify , NULL ) ;
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
text_uri = eina_stringshare_add ( " text/uri-list " ) ;
return EINA_TRUE ;
2010-06-17 01:06:07 -07:00
}
2010-06-25 02:58:14 -07:00
static Eina_Bool
2010-12-20 03:09:19 -08:00
selection_clear ( void * udata __UNUSED__ , int type __UNUSED__ , void * event )
{
2010-06-17 01:06:07 -07:00
Ecore_X_Event_Selection_Clear * ev = event ;
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2012-05-22 19:15:56 -07:00
unsigned int i ;
2011-04-01 04:35:07 -07:00
2012-05-22 19:15:56 -07:00
for ( i = ELM_SEL_TYPE_PRIMARY ; i < = ELM_SEL_TYPE_CLIPBOARD ; i + + )
2010-06-17 01:06:07 -07:00
{
2011-04-01 04:35:07 -07:00
if ( selections [ i ] . ecore_sel = = ev - > selection ) break ;
2010-06-17 01:06:07 -07:00
}
2010-12-20 03:09:19 -08:00
cnp_debug ( " selection %d clear \n " , i ) ;
2010-06-17 01:06:07 -07:00
/* Not me... Don't care */
2012-02-22 18:52:07 -08:00
if ( i > ELM_SEL_TYPE_CLIPBOARD ) return ECORE_CALLBACK_PASS_ON ;
2010-06-17 01:06:07 -07:00
sel = selections + i ;
2012-06-25 04:16:25 -07:00
if ( sel - > loss_cb ) sel - > loss_cb ( sel - > loss_data , i ) ;
if ( sel - > widget )
evas_object_event_callback_del_full ( sel - > widget , EVAS_CALLBACK_DEL ,
_sel_obj_del , sel ) ;
if ( sel - > requestwidget )
evas_object_event_callback_del_full ( sel - > requestwidget , EVAS_CALLBACK_DEL ,
_sel_obj_del2 , sel ) ;
sel - > widget = NULL ;
sel - > requestwidget = NULL ;
2011-12-27 03:24:13 -08:00
sel - > active = EINA_FALSE ;
2010-06-17 01:06:07 -07:00
sel - > widget = NULL ;
2011-12-27 03:24:13 -08:00
if ( sel - > selbuf )
2011-12-28 04:54:59 -08:00
{
free ( sel - > selbuf ) ;
sel - > selbuf = NULL ;
}
2010-06-17 01:06:07 -07:00
2010-06-25 02:58:14 -07:00
return ECORE_CALLBACK_PASS_ON ;
2010-06-17 01:06:07 -07:00
}
2010-06-30 06:20:58 -07:00
/*
* Response to a selection notify :
2012-05-22 19:15:56 -07:00
* - So we have asked for the selection list .
* - If it ' s the targets list , parse it , and fire of what we want ,
* else it ' s the data we want .
2010-06-23 01:02:35 -07:00
*/
2010-06-25 02:58:14 -07:00
static Eina_Bool
2010-12-20 03:09:19 -08:00
selection_notify ( void * udata __UNUSED__ , int type __UNUSED__ , void * event )
{
2010-06-23 01:02:35 -07:00
Ecore_X_Event_Selection_Notify * ev = event ;
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2010-06-23 01:02:35 -07:00
int i ;
2011-04-01 04:35:07 -07:00
2010-06-30 06:20:58 -07:00
cnp_debug ( " selection notify callback: %d \n " , ev - > selection ) ;
2010-12-20 03:09:19 -08:00
switch ( ev - > selection )
{
2010-06-23 01:02:35 -07:00
case ECORE_X_SELECTION_PRIMARY :
2011-12-27 03:24:13 -08:00
sel = selections + ELM_SEL_TYPE_PRIMARY ;
2011-04-01 04:35:07 -07:00
break ;
2010-06-23 01:02:35 -07:00
case ECORE_X_SELECTION_SECONDARY :
2011-12-27 03:24:13 -08:00
sel = selections + ELM_SEL_TYPE_SECONDARY ;
2011-04-01 04:35:07 -07:00
break ;
2010-09-06 23:56:16 -07:00
case ECORE_X_SELECTION_XDND :
2011-12-27 03:24:13 -08:00
sel = selections + ELM_SEL_TYPE_XDND ;
2011-04-01 04:35:07 -07:00
break ;
2012-02-22 18:52:07 -08:00
case ECORE_X_SELECTION_CLIPBOARD :
sel = selections + ELM_SEL_TYPE_CLIPBOARD ;
break ;
2010-06-23 01:02:35 -07:00
default :
2011-04-01 04:35:07 -07:00
return ECORE_CALLBACK_PASS_ON ;
2010-12-20 03:09:19 -08:00
}
cnp_debug ( " Target is %s \n " , ev - > target ) ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
for ( i = 0 ; i < CNP_N_ATOMS ; i + + )
2010-06-23 01:02:35 -07:00
{
2011-04-01 04:35:07 -07:00
if ( ! strcmp ( ev - > target , atoms [ i ] . name ) )
{
if ( atoms [ i ] . notify )
2010-12-20 03:09:19 -08:00
{
cnp_debug ( " Found something: %s \n " , atoms [ i ] . name ) ;
2011-04-01 04:35:07 -07:00
atoms [ i ] . notify ( sel , ev ) ;
}
else
2010-12-20 03:09:19 -08:00
{
2011-04-01 04:35:07 -07:00
cnp_debug ( " Ignored: No handler! \n " ) ;
2010-12-20 03:09:19 -08:00
}
2011-04-01 04:35:07 -07:00
}
2010-06-23 01:02:35 -07:00
}
2010-06-25 02:58:14 -07:00
return ECORE_CALLBACK_PASS_ON ;
2010-06-23 01:02:35 -07:00
}
2011-12-20 00:37:26 -08:00
static Elm_Sel_Format
_get_selection_type ( void * data , int size )
{
if ( size = = sizeof ( Elm_Sel_Type ) )
{
2012-05-22 19:15:56 -07:00
unsigned int seltype = * ( ( unsigned int * ) data ) ;
if ( seltype > ELM_SEL_TYPE_CLIPBOARD )
return ELM_SEL_FORMAT_NONE ;
Cnp_Selection * sel = selections + seltype ;
2011-12-20 19:49:53 -08:00
if ( sel - > active & &
2011-12-27 03:24:13 -08:00
( sel - > format > = ELM_SEL_FORMAT_TARGETS ) & &
2012-02-22 18:52:07 -08:00
( sel - > format < = ELM_SEL_FORMAT_HTML ) )
2011-12-20 00:37:26 -08:00
return sel - > format ;
}
return ELM_SEL_FORMAT_NONE ;
}
2010-06-30 06:20:58 -07:00
2010-09-27 11:45:38 -07:00
static Eina_Bool
2011-09-10 12:43:46 -07:00
targets_converter ( char * target __UNUSED__ , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype , int * typesize )
2010-12-20 03:09:19 -08:00
{
2010-06-17 01:06:07 -07:00
int i , count ;
Ecore_X_Atom * aret ;
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2011-12-20 19:49:53 -08:00
Elm_Sel_Format seltype ;
2011-04-01 04:35:07 -07:00
2010-09-27 11:45:38 -07:00
if ( ! data_ret ) return EINA_FALSE ;
2010-06-17 01:06:07 -07:00
2011-12-20 00:37:26 -08:00
if ( _get_selection_type ( data , size ) = = ELM_SEL_FORMAT_NONE )
2011-09-10 12:43:46 -07:00
{
2011-12-20 19:49:53 -08:00
/* TODO : fallback into precise type */
seltype = ELM_SEL_FORMAT_TEXT ;
}
else
{
sel = selections + * ( ( int * ) data ) ;
seltype = sel - > format ;
2011-09-10 12:43:46 -07:00
}
2010-06-17 01:06:07 -07:00
2010-12-20 03:09:19 -08:00
for ( i = 0 , count = 0 ; i < CNP_N_ATOMS ; i + + )
{
2011-12-20 19:49:53 -08:00
if ( seltype & atoms [ i ] . formats ) count + + ;
2010-12-20 03:09:19 -08:00
}
2010-06-17 01:06:07 -07:00
aret = malloc ( sizeof ( Ecore_X_Atom ) * count ) ;
2012-05-21 21:42:45 -07:00
if ( ! aret ) return EINA_FALSE ;
2010-12-20 03:09:19 -08:00
for ( i = 0 , count = 0 ; i < CNP_N_ATOMS ; i + + )
{
2011-12-20 19:49:53 -08:00
if ( seltype & atoms [ i ] . formats ) aret [ count + + ] = atoms [ i ] . atom ;
2010-12-20 03:09:19 -08:00
}
2010-06-17 01:06:07 -07:00
2010-07-13 19:20:30 -07:00
* data_ret = aret ;
2010-06-17 01:06:07 -07:00
if ( typesize ) * typesize = 32 /* urk */ ;
2010-12-20 03:09:19 -08:00
if ( ttype ) * ttype = ECORE_X_ATOM_ATOM ;
2010-06-17 01:06:07 -07:00
if ( size_ret ) * size_ret = count ;
2010-09-27 11:45:38 -07:00
return EINA_TRUE ;
2010-06-17 01:06:07 -07:00
}
2010-09-27 11:45:38 -07:00
static Eina_Bool
2010-12-20 03:09:19 -08:00
image_converter ( char * target __UNUSED__ , void * data __UNUSED__ , int size __UNUSED__ , void * * data_ret __UNUSED__ , int * size_ret __UNUSED__ , Ecore_X_Atom * ttype __UNUSED__ , int * typesize __UNUSED__ )
2010-08-18 12:18:42 -07:00
{
2010-12-20 03:09:19 -08:00
cnp_debug ( " Image converter called \n " ) ;
2010-09-27 11:45:38 -07:00
return EINA_TRUE ;
2010-06-30 06:20:58 -07:00
}
2010-09-27 11:45:38 -07:00
static Eina_Bool
2010-12-20 03:09:19 -08:00
vcard_send ( char * target __UNUSED__ , void * data __UNUSED__ , int size __UNUSED__ , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype __UNUSED__ , int * typesize __UNUSED__ )
2010-09-16 22:39:00 -07:00
{
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2010-09-21 21:42:36 -07:00
2010-12-20 03:09:19 -08:00
cnp_debug ( " Vcard send called \n " ) ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
sel = selections + * ( ( int * ) data ) ;
2010-09-21 21:42:36 -07:00
if ( data_ret ) * data_ret = strdup ( sel - > selbuf ) ;
if ( size_ret ) * size_ret = strlen ( sel - > selbuf ) ;
2010-09-27 11:45:38 -07:00
return EINA_TRUE ;
2010-09-16 22:39:00 -07:00
}
2011-06-22 22:52:40 -07:00
static Eina_Bool
is_uri_type_data ( Cnp_Selection * sel __UNUSED__ , Ecore_X_Event_Selection_Notify * notify )
{
Ecore_X_Selection_Data * data ;
char * p ;
data = notify - > data ;
cnp_debug ( " data->format is %d %p %p \n " , data - > format , notify , data ) ;
if ( data - > content = = ECORE_X_SELECTION_CONTENT_FILES ) return EINA_TRUE ;
2011-12-28 04:54:59 -08:00
p = ( char * ) data - > data ;
2011-06-22 22:52:40 -07:00
if ( ! p ) return EINA_TRUE ;
2011-12-28 04:54:59 -08:00
2011-06-22 22:52:40 -07:00
cnp_debug ( " Got %s \n " , p ) ;
if ( strncmp ( p , " file:// " , 7 ) )
{
if ( * p ! = ' / ' ) return EINA_FALSE ;
}
return EINA_TRUE ;
}
2010-06-30 06:20:58 -07:00
/*
* Callback to handle a targets response on a selection request :
* So pick the format we ' d like ; and then request it .
*/
static int
2010-12-20 03:09:19 -08:00
notify_handler_targets ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify )
2010-08-18 12:18:42 -07:00
{
2010-06-30 06:20:58 -07:00
Ecore_X_Selection_Data_Targets * targets ;
Ecore_X_Atom * atomlist ;
2010-12-20 03:09:19 -08:00
int i , j ;
2011-04-01 04:35:07 -07:00
2010-06-30 06:20:58 -07:00
targets = notify - > data ;
atomlist = ( Ecore_X_Atom * ) ( targets - > data . data ) ;
2011-09-27 23:48:44 -07:00
for ( j = ( CNP_ATOM_LISTING_ATOMS + 1 ) ; j < CNP_N_ATOMS ; j + + )
2010-06-30 06:20:58 -07:00
{
2011-04-01 04:35:07 -07:00
cnp_debug ( " \t %s %d \n " , atoms [ j ] . name , atoms [ j ] . atom ) ;
if ( ! ( atoms [ j ] . formats & sel - > requestformat ) ) continue ;
for ( i = 0 ; i < targets - > data . length ; i + + )
{
if ( ( atoms [ j ] . atom = = atomlist [ i ] ) & & ( atoms [ j ] . notify ) )
{
2011-06-22 22:52:40 -07:00
if ( ( j = = CNP_ATOM_text_uri ) | |
( j = = CNP_ATOM_text_urilist ) )
{
2012-03-29 04:09:45 -07:00
if ( ! is_uri_type_data ( sel , notify ) ) continue ;
2011-06-22 22:52:40 -07:00
}
2011-04-01 04:35:07 -07:00
cnp_debug ( " Atom %s matches \n " , atoms [ j ] . name ) ;
goto done ;
}
}
2010-06-30 06:20:58 -07:00
}
cnp_debug ( " Couldn't find anything that matches \n " ) ;
return ECORE_CALLBACK_PASS_ON ;
2011-04-01 04:35:07 -07:00
done :
2012-06-19 16:33:57 -07:00
cnp_debug ( " Sending request for %s, xwin=%#llx \n " ,
atoms [ j ] . name , ( unsigned long long ) sel - > xwin ) ;
sel - > request ( sel - > xwin , atoms [ j ] . name ) ;
2010-06-30 06:20:58 -07:00
return ECORE_CALLBACK_PASS_ON ;
}
2010-06-17 01:06:07 -07:00
2010-06-23 01:02:35 -07:00
static int
2010-12-20 03:09:19 -08:00
response_handler_targets ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify )
2010-08-18 12:18:42 -07:00
{
2010-06-23 01:02:35 -07:00
Ecore_X_Selection_Data_Targets * targets ;
Ecore_X_Atom * atomlist ;
int i , j ;
targets = notify - > data ;
atomlist = ( Ecore_X_Atom * ) ( targets - > data . data ) ;
2011-12-28 04:54:59 -08:00
for ( j = ( CNP_ATOM_LISTING_ATOMS + 1 ) ; j < CNP_N_ATOMS ; j + + )
2010-06-23 01:02:35 -07:00
{
2011-04-01 04:35:07 -07:00
if ( ! ( atoms [ j ] . formats & sel - > requestformat ) ) continue ;
for ( i = 0 ; i < targets - > data . length ; i + + )
{
if ( ( atoms [ j ] . atom = = atomlist [ i ] ) & & ( atoms [ j ] . response ) )
2010-12-20 03:09:19 -08:00
{
2011-04-01 04:35:07 -07:00
/* Found a match: Use it */
goto found ;
2010-12-20 03:09:19 -08:00
}
}
2010-06-23 01:02:35 -07:00
}
2011-12-28 04:54:59 -08:00
cnp_debug ( " No matching type found \n " ) ;
return 0 ;
2011-04-01 04:35:07 -07:00
2011-12-28 04:54:59 -08:00
found :
2012-06-19 16:33:57 -07:00
sel - > request ( sel - > xwin , atoms [ j ] . name ) ;
2010-06-23 01:02:35 -07:00
return 0 ;
}
2010-06-30 06:20:58 -07:00
2010-06-23 01:02:35 -07:00
static int
2010-12-20 03:09:19 -08:00
notify_handler_text ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify )
2010-08-18 12:18:42 -07:00
{
2010-06-30 06:20:58 -07:00
Ecore_X_Selection_Data * data ;
2012-05-22 19:15:56 -07:00
char * stripstr , * mkupstr ;
2011-04-01 04:35:07 -07:00
2010-06-30 06:20:58 -07:00
data = notify - > data ;
2012-05-22 19:15:56 -07:00
stripstr = malloc ( data - > length + 1 ) ;
if ( ! stripstr ) return 0 ;
strncpy ( stripstr , ( char * ) data - > data , data - > length ) ;
stripstr [ data - > length ] = ' \0 ' ;
2011-06-20 00:13:50 -07:00
if ( sel - > datacb )
{
Elm_Selection_Data ddata ;
ddata . x = ddata . y = 0 ;
ddata . format = ELM_SEL_FORMAT_TEXT ;
ddata . data = data - > data ;
ddata . len = data - > length ;
sel - > datacb ( sel - > udata , sel - > widget , & ddata ) ;
2012-05-22 19:15:56 -07:00
free ( stripstr ) ;
2011-06-20 00:13:50 -07:00
return 0 ;
}
2012-04-09 01:06:33 -07:00
cnp_debug ( " Notify handler text %d %d %p \n " , data - > format ,
data - > length , data - > data ) ;
2012-05-22 19:15:56 -07:00
mkupstr = _elm_util_text_to_mkup ( ( const char * ) stripstr ) ;
cnp_debug ( " String is %s (from %s) \n " , stripstr , data - > data ) ;
2012-06-19 16:33:57 -07:00
/* TODO BUG: should never NEVER assume it's an elm_entry! */
2012-04-05 22:58:50 -07:00
_elm_entry_entry_paste ( sel - > requestwidget , mkupstr ) ;
2012-05-22 19:15:56 -07:00
free ( stripstr ) ;
2012-04-05 22:58:50 -07:00
free ( mkupstr ) ;
2010-06-23 01:02:35 -07:00
return 0 ;
}
2010-06-30 06:20:58 -07:00
/**
* So someone is pasting an image into my entry or widget . . .
*/
static int
2010-12-20 03:09:19 -08:00
notify_handler_uri ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify )
2010-06-30 06:20:58 -07:00
{
Ecore_X_Selection_Data * data ;
2010-09-06 23:56:16 -07:00
Ecore_X_Selection_Data_Files * files ;
2011-09-30 01:48:25 -07:00
char * p , * stripstr ;
2010-06-30 06:20:58 -07:00
data = notify - > data ;
2010-12-20 03:09:19 -08:00
cnp_debug ( " data->format is %d %p %p \n " , data - > format , notify , data ) ;
2010-09-06 23:56:16 -07:00
if ( data - > content = = ECORE_X_SELECTION_CONTENT_FILES )
{
cnp_debug ( " got a files list \n " ) ;
files = notify - > data ;
if ( files - > num_files > 1 )
{
/* Don't handle many items */
cnp_debug ( " more then one file: Bailing \n " ) ;
return 0 ;
}
2011-09-30 01:48:25 -07:00
stripstr = p = strdup ( files - > files [ 0 ] ) ;
2010-09-06 23:56:16 -07:00
}
2011-03-31 05:29:20 -07:00
else
{
2012-05-22 17:53:07 -07:00
stripstr = p = malloc ( data - > length + 1 ) ;
2012-05-21 21:42:45 -07:00
if ( ! stripstr ) return 0 ;
2011-10-20 21:32:27 -07:00
memcpy ( stripstr , data - > data , data - > length ) ;
stripstr [ data - > length ] = 0 ;
2011-03-31 05:29:20 -07:00
}
2010-09-06 23:56:16 -07:00
if ( ! p )
{
cnp_debug ( " Couldn't find a file \n " ) ;
return 0 ;
2010-12-20 03:09:19 -08:00
}
2012-05-22 19:15:56 -07:00
cnp_debug ( " Got %s \n " , p ) ;
2010-10-22 14:41:27 -07:00
if ( strncmp ( p , " file:// " , 7 ) )
2010-09-06 23:56:16 -07:00
{
2010-09-10 00:24:10 -07:00
/* Try and continue if it looks sane */
2011-09-30 01:48:25 -07:00
if ( * p ! = ' / ' )
{
free ( p ) ;
return 0 ;
}
2010-09-06 23:56:16 -07:00
}
2011-03-31 05:29:20 -07:00
else
2010-09-06 23:56:16 -07:00
{
2011-03-31 05:29:20 -07:00
p + = strlen ( " file:// " ) ;
2010-09-06 23:56:16 -07:00
}
2010-06-30 06:20:58 -07:00
2011-06-20 00:13:50 -07:00
if ( savedtypes . imgfile ) free ( ( void * ) savedtypes . imgfile ) ;
2010-09-06 23:56:16 -07:00
if ( savedtypes . textreq )
{
savedtypes . textreq = 0 ;
2011-06-20 00:13:50 -07:00
savedtypes . imgfile = strdup ( p ) ;
2010-09-06 23:56:16 -07:00
}
else
{
2011-06-20 00:13:50 -07:00
pasteimage_append ( p , sel - > requestwidget ) ;
2010-09-06 23:56:16 -07:00
}
2011-09-30 01:48:25 -07:00
free ( stripstr ) ;
2010-06-30 06:20:58 -07:00
return 0 ;
}
2010-09-16 22:39:00 -07:00
/**
* Just receieved an vcard , either through cut and paste , or dnd .
*/
static int
2010-12-20 03:09:19 -08:00
vcard_receive ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify )
2010-09-16 22:39:00 -07:00
{
2010-12-20 03:09:19 -08:00
Dropable * dropable ;
2010-09-16 22:39:00 -07:00
Eina_List * l ;
Ecore_X_Selection_Data * data ;
data = notify - > data ;
cnp_debug ( " vcard receive \n " ) ;
2011-12-27 03:24:13 -08:00
if ( sel = = ( selections + ELM_SEL_TYPE_XDND ) )
2010-10-17 21:49:00 -07:00
{
2010-10-17 21:48:44 -07:00
Elm_Selection_Data ddata ;
2011-04-01 04:35:07 -07:00
2010-09-16 22:39:00 -07:00
cnp_debug ( " drag & drop \n " ) ;
/* FIXME: this needs to be generic: Used for all receives */
EINA_LIST_FOREACH ( drops , l , dropable )
2010-12-20 03:09:19 -08:00
{
if ( dropable - > obj = = sel - > requestwidget ) break ;
}
2010-09-16 22:39:00 -07:00
if ( ! dropable )
{
cnp_debug ( " Unable to find drop object " ) ;
ecore_x_dnd_send_finished ( ) ;
return 0 ;
2010-12-20 03:09:19 -08:00
}
2010-10-14 07:12:26 -07:00
dropable = eina_list_data_get ( l ) ;
2010-09-16 22:39:00 -07:00
ddata . x = savedtypes . x ;
ddata . y = savedtypes . y ;
ddata . format = ELM_SEL_FORMAT_VCARD ;
ddata . data = data - > data ;
ddata . len = data - > length ;
dropable - > dropcb ( dropable - > cbdata , dropable - > obj , & ddata ) ;
ecore_x_dnd_send_finished ( ) ;
2010-10-17 21:49:00 -07:00
}
else if ( sel - > datacb )
{
Elm_Selection_Data ddata ;
ddata . x = ddata . y = 0 ;
2012-07-11 03:08:46 -07:00
ddata . format = ELM_SEL_FORMAT_VCARD ;
2010-10-17 21:49:00 -07:00
ddata . data = data - > data ;
ddata . len = data - > length ;
sel - > datacb ( sel - > udata , sel - > widget , & ddata ) ;
}
else
{
2010-09-16 22:39:00 -07:00
cnp_debug ( " Paste request \n " ) ;
2010-12-20 03:09:19 -08:00
}
2011-04-01 04:35:07 -07:00
2010-09-16 22:39:00 -07:00
return 0 ;
}
2010-06-30 06:20:58 -07:00
static int
2010-12-20 03:09:19 -08:00
notify_handler_image ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify )
2010-06-30 06:20:58 -07:00
{
2010-09-06 23:56:16 -07:00
Ecore_X_Selection_Data * data ;
2010-12-20 03:09:19 -08:00
Tmp_Info * tmp ;
2011-04-01 04:35:07 -07:00
2011-12-28 04:54:59 -08:00
cnp_debug ( " got a image file! \n " ) ;
2010-09-06 23:56:16 -07:00
data = notify - > data ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
cnp_debug ( " Size if %d \n " , data - > length ) ;
2010-09-06 23:56:16 -07:00
2010-10-17 21:49:00 -07:00
if ( sel - > datacb )
{
2010-12-20 03:09:19 -08:00
Elm_Selection_Data ddata ;
2011-04-01 04:35:07 -07:00
2010-10-17 21:49:00 -07:00
ddata . x = ddata . y = 0 ;
ddata . format = ELM_SEL_FORMAT_IMAGE ;
ddata . data = data - > data ;
ddata . len = data - > length ;
sel - > datacb ( sel - > udata , sel - > widget , & ddata ) ;
return 0 ;
}
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
/* generate tmp name */
2010-09-21 21:42:41 -07:00
tmp = elm_cnp_tempfile_create ( data - > length ) ;
memcpy ( tmp - > map , data - > data , data - > length ) ;
2011-12-28 04:54:59 -08:00
munmap ( tmp - > map , data - > length ) ;
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
/* FIXME: Add to paste image data to clean up */
2011-06-20 00:13:50 -07:00
pasteimage_append ( tmp - > filename , sel - > requestwidget ) ;
2010-09-06 23:56:16 -07:00
2010-09-21 21:42:41 -07:00
tmpinfo_free ( tmp ) ;
2010-09-26 21:25:26 -07:00
return 0 ;
}
/**
* Warning : Generic text / html can ' ; t handle it sanely .
* Firefox sends ucs2 ( i think ) .
* chrome sends utf8 . . . blerg
*/
static int
2010-12-20 03:09:19 -08:00
notify_handler_html ( Cnp_Selection * sel , Ecore_X_Event_Selection_Notify * notify )
{
2010-09-26 21:25:26 -07:00
Ecore_X_Selection_Data * data ;
2011-04-01 04:35:07 -07:00
2010-09-26 21:25:26 -07:00
cnp_debug ( " Got some HTML: Checking encoding is useful \n " ) ;
data = notify - > data ;
2012-05-22 17:53:07 -07:00
char * stripstr = malloc ( data - > length + 1 ) ;
2012-05-21 21:42:45 -07:00
if ( ! stripstr ) return 0 ;
2012-05-21 18:35:12 -07:00
strncpy ( stripstr , ( char * ) data - > data , data - > length ) ;
stripstr [ data - > length ] = ' \0 ' ;
2011-04-01 04:35:07 -07:00
2010-10-17 21:49:00 -07:00
if ( sel - > datacb )
{
Elm_Selection_Data ddata ;
ddata . x = ddata . y = 0 ;
ddata . format = ELM_SEL_FORMAT_HTML ;
2012-05-21 18:35:12 -07:00
ddata . data = stripstr ;
2010-10-17 21:49:00 -07:00
ddata . len = data - > length ;
sel - > datacb ( sel - > udata , sel - > widget , & ddata ) ;
2012-05-22 18:05:22 -07:00
free ( stripstr ) ;
2010-10-17 21:49:00 -07:00
return 0 ;
}
2010-12-20 03:09:19 -08:00
cnp_debug ( " String is %s (%d bytes) \n " , stripstr , data - > length ) ;
2012-06-19 16:33:57 -07:00
/* TODO BUG: should never NEVER assume it's an elm_entry! */
2011-08-03 02:00:36 -07:00
_elm_entry_entry_paste ( sel - > requestwidget , stripstr ) ;
2010-12-20 01:47:30 -08:00
free ( stripstr ) ;
2010-08-18 12:18:42 -07:00
return 0 ;
2010-06-30 06:20:58 -07:00
}
2010-09-27 11:45:38 -07:00
static Eina_Bool
2011-08-25 19:43:48 -07:00
text_converter ( char * target __UNUSED__ , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype __UNUSED__ , int * typesize __UNUSED__ )
2010-08-18 12:18:42 -07:00
{
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2010-06-17 01:06:07 -07:00
2010-09-06 23:56:16 -07:00
cnp_debug ( " text converter \n " ) ;
2011-12-20 00:37:26 -08:00
if ( _get_selection_type ( data , size ) = = ELM_SEL_FORMAT_NONE )
2011-08-25 19:43:48 -07:00
{
2011-10-20 21:32:27 -07:00
if ( data_ret )
{
2011-10-20 21:38:21 -07:00
* data_ret = malloc ( size * sizeof ( char ) + 1 ) ;
2012-05-21 21:42:45 -07:00
if ( ! * data_ret ) return EINA_FALSE ;
2011-10-20 21:32:27 -07:00
memcpy ( * data_ret , data , size ) ;
( ( char * * ) ( data_ret ) ) [ 0 ] [ size ] = 0 ;
}
2011-09-10 12:43:46 -07:00
if ( size_ret ) * size_ret = size ;
2011-08-25 19:43:48 -07:00
return EINA_TRUE ;
}
2010-12-20 03:09:19 -08:00
sel = selections + * ( ( int * ) data ) ;
2010-09-27 11:45:38 -07:00
if ( ! sel - > active ) return EINA_TRUE ;
2011-04-01 04:35:07 -07:00
2011-01-13 15:04:04 -08:00
if ( ( sel - > format & ELM_SEL_FORMAT_MARKUP ) | |
( sel - > format & ELM_SEL_FORMAT_HTML ) )
2010-10-20 15:33:58 -07:00
{
2012-01-29 00:52:34 -08:00
* data_ret = _elm_util_mkup_to_text ( sel - > selbuf ) ;
if ( size_ret ) * size_ret = strlen ( * data_ret ) ;
2010-10-20 15:33:58 -07:00
}
2011-01-13 15:04:04 -08:00
else if ( sel - > format & ELM_SEL_FORMAT_TEXT )
2010-10-20 15:33:58 -07:00
{
2010-09-26 23:19:12 -07:00
* data_ret = strdup ( sel - > selbuf ) ;
* size_ret = strlen ( sel - > selbuf ) ;
2010-10-20 15:33:58 -07:00
}
2011-01-13 15:04:04 -08:00
else if ( sel - > format & ELM_SEL_FORMAT_IMAGE )
2010-10-20 15:33:58 -07:00
{
2011-04-01 04:35:07 -07:00
cnp_debug ( " Image %s \n " , evas_object_type_get ( sel - > widget ) ) ;
cnp_debug ( " Elm type: %s \n " , elm_object_widget_type_get ( sel - > widget ) ) ;
2011-12-28 04:54:59 -08:00
evas_object_image_file_get ( elm_photocam_internal_image_get ( sel - > widget ) ,
( const char * * ) data_ret , NULL ) ;
2011-04-01 04:35:07 -07:00
if ( ! * data_ret ) * data_ret = strdup ( " No file " ) ;
else * data_ret = strdup ( * data_ret ) ;
* size_ret = strlen ( * data_ret ) ;
2010-10-20 15:33:58 -07:00
}
2010-09-27 11:45:38 -07:00
return EINA_TRUE ;
2010-06-17 01:06:07 -07:00
}
2010-09-27 11:45:38 -07:00
static Eina_Bool
2011-08-25 19:39:28 -07:00
general_converter ( char * target __UNUSED__ , void * data , int size , void * * data_ret , int * size_ret , Ecore_X_Atom * ttype __UNUSED__ , int * typesize __UNUSED__ )
2010-08-18 12:18:42 -07:00
{
2011-12-20 00:37:26 -08:00
if ( _get_selection_type ( data , size ) = = ELM_SEL_FORMAT_NONE )
2011-08-25 19:32:49 -07:00
{
2011-10-20 21:32:27 -07:00
if ( data_ret )
{
2011-10-20 21:38:21 -07:00
* data_ret = malloc ( size * sizeof ( char ) + 1 ) ;
2012-05-21 21:42:45 -07:00
if ( ! * data_ret ) return EINA_FALSE ;
2011-10-20 21:32:27 -07:00
memcpy ( * data_ret , data , size ) ;
( ( char * * ) ( data_ret ) ) [ 0 ] [ size ] = 0 ;
}
2011-09-10 12:43:46 -07:00
if ( size_ret ) * size_ret = size ;
2011-08-25 19:32:49 -07:00
}
2011-12-20 00:37:26 -08:00
else
{
2011-12-28 04:54:59 -08:00
Cnp_Selection * sel = selections + * ( ( int * ) data ) ;
2011-12-20 00:37:26 -08:00
if ( data_ret ) * data_ret = strdup ( sel - > selbuf ) ;
if ( size_ret ) * size_ret = strlen ( sel - > selbuf ) ;
}
2010-09-27 11:45:38 -07:00
return EINA_TRUE ;
2010-06-17 01:06:07 -07:00
}
2010-12-20 03:09:19 -08:00
static Eina_Bool
2011-06-20 00:13:50 -07:00
pasteimage_append ( char * file , Evas_Object * entry )
2010-09-06 23:56:16 -07:00
{
2011-01-07 20:55:31 -08:00
char * entrytag ;
int len ;
2012-06-19 16:33:57 -07:00
/* TODO BUG: shouldn't define absize=240x180. Prefer data:// instead of href:// -- may need support for evas. See http://dataurl.net/ */
2011-01-07 20:55:31 -08:00
static const char * tagstring = " <item absize=240x180 href=file://%s></item> " ;
2011-12-28 04:54:59 -08:00
if ( ( ! file ) | | ( ! entry ) ) return EINA_FALSE ;
2010-09-06 23:56:16 -07:00
2011-06-20 00:13:50 -07:00
len = strlen ( tagstring ) + strlen ( file ) ;
2011-01-07 20:55:31 -08:00
entrytag = alloca ( len + 1 ) ;
2011-06-20 00:13:50 -07:00
snprintf ( entrytag , len + 1 , tagstring , file ) ;
2012-06-19 16:33:57 -07:00
/* TODO BUG: should never NEVER assume it's an elm_entry! */
2011-08-03 02:00:36 -07:00
_elm_entry_entry_paste ( entry , entrytag ) ;
2010-09-06 23:56:16 -07:00
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
}
static Eina_Bool
2010-10-19 11:24:27 -07:00
_dnd_enter ( void * data __UNUSED__ , int etype __UNUSED__ , void * ev )
2010-09-06 23:56:16 -07:00
{
Ecore_X_Event_Xdnd_Enter * enter = ev ;
int i ;
/* Skip it */
2012-06-19 16:33:57 -07:00
cnp_debug ( " enter %p \n " , enter ) ;
cnp_debug ( " enter types=%p (%d) \n " , enter - > types , enter - > num_types ) ;
2010-10-22 14:41:22 -07:00
if ( ( ! enter ) | | ( ! enter - > num_types ) | | ( ! enter - > types ) ) return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
cnp_debug ( " Types \n " ) ;
savedtypes . ntypes = enter - > num_types ;
if ( savedtypes . types ) free ( savedtypes . types ) ;
savedtypes . types = malloc ( sizeof ( char * ) * enter - > num_types ) ;
2010-12-20 03:09:19 -08:00
if ( ! savedtypes . types ) return EINA_FALSE ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
for ( i = 0 ; i < enter - > num_types ; i + + )
2010-09-06 23:56:16 -07:00
{
savedtypes . types [ i ] = eina_stringshare_add ( enter - > types [ i ] ) ;
2010-12-20 03:09:19 -08:00
cnp_debug ( " Type is %s %p %p \n " , enter - > types [ i ] ,
2010-09-06 23:56:16 -07:00
savedtypes . types [ i ] , text_uri ) ;
if ( savedtypes . types [ i ] = = text_uri )
{
/* Request it, so we know what it is */
cnp_debug ( " Sending uri request \n " ) ;
savedtypes . textreq = 1 ;
2011-06-20 00:13:50 -07:00
if ( savedtypes . imgfile ) free ( ( void * ) savedtypes . imgfile ) ;
savedtypes . imgfile = NULL ;
2010-09-06 23:56:16 -07:00
ecore_x_selection_xdnd_request ( enter - > win , text_uri ) ;
}
}
/* FIXME: Find an object and make it current */
2010-10-18 11:15:59 -07:00
return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
}
static Eina_Bool
2010-10-19 11:24:27 -07:00
_dnd_drop ( void * data __UNUSED__ , int etype __UNUSED__ , void * ev )
2010-09-06 23:56:16 -07:00
{
struct _Ecore_X_Event_Xdnd_Drop * drop ;
2010-12-20 03:09:19 -08:00
Dropable * dropable ;
2010-09-06 23:56:16 -07:00
Eina_List * l ;
2010-09-07 21:55:12 -07:00
Ecore_Evas * ee ;
2010-09-06 23:56:16 -07:00
Ecore_X_Window xwin ;
2010-10-17 21:48:44 -07:00
Elm_Selection_Data ddata ;
2010-12-20 03:09:19 -08:00
int x , y , w , h ;
int i , j ;
2010-09-06 23:56:16 -07:00
drop = ev ;
2012-06-19 16:33:57 -07:00
cnp_debug ( " drops %p (%d) \n " , drops , eina_list_count ( drops ) ) ;
2010-09-06 23:56:16 -07:00
// check we still have something to drop
2010-12-20 03:09:19 -08:00
if ( ! drops ) return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
/* Find any widget in our window; then work out geometry rel to our window */
2010-12-20 03:09:19 -08:00
for ( l = drops ; l ; l = l - > next )
2010-09-06 23:56:16 -07:00
{
dropable = l - > data ;
2012-06-19 16:33:57 -07:00
xwin = _elm_widget_xwin_get ( dropable - > obj ) ;
2010-12-20 03:09:19 -08:00
if ( xwin = = drop - > win ) break ;
2010-09-06 23:56:16 -07:00
}
/* didn't find a window */
2010-12-20 03:09:19 -08:00
if ( ! l ) return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
/* Calculate real (widget relative) position */
2010-12-20 03:09:19 -08:00
// - window position
// - widget position
2010-09-07 21:55:12 -07:00
ee = ecore_evas_ecore_evas_get ( evas_object_evas_get ( dropable - > obj ) ) ;
ecore_evas_geometry_get ( ee , & x , & y , NULL , NULL ) ;
2010-09-06 23:56:16 -07:00
savedtypes . x = drop - > position . x - x ;
savedtypes . y = drop - > position . y - y ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
cnp_debug ( " Drop position is %d,%d \n " , savedtypes . x , savedtypes . y ) ;
2010-09-06 23:56:16 -07:00
2010-12-20 03:09:19 -08:00
for ( ; l ; l = l - > next )
2010-09-06 23:56:16 -07:00
{
dropable = l - > data ;
evas_object_geometry_get ( dropable - > obj , & x , & y , & w , & h ) ;
2010-10-22 14:41:22 -07:00
if ( ( savedtypes . x > = x ) & & ( savedtypes . y > = y ) & &
( savedtypes . x < x + w ) & & ( savedtypes . y < y + h ) )
2011-04-01 04:35:07 -07:00
break ; /* found! */
2010-09-06 23:56:16 -07:00
}
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
if ( ! l ) return EINA_TRUE ; /* didn't find one */
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
evas_object_geometry_get ( dropable - > obj , & x , & y , NULL , NULL ) ;
savedtypes . x - = x ;
savedtypes . y - = y ;
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
/* Find our type from the previous list */
2010-12-20 03:09:19 -08:00
for ( i = 0 ; i < CNP_N_ATOMS ; i + + )
2010-09-06 23:56:16 -07:00
{
2011-04-01 04:35:07 -07:00
for ( j = 0 ; j < savedtypes . ntypes ; j + + )
2010-09-06 23:56:16 -07:00
{
2010-12-20 03:09:19 -08:00
if ( ! strcmp ( savedtypes . types [ j ] , atoms [ i ] . name ) ) goto found ;
2010-09-06 23:56:16 -07:00
}
}
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
cnp_debug ( " Didn't find a target \n " ) ;
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
found :
2010-12-20 03:09:19 -08:00
cnp_debug ( " Found a target we'd like: %s \n " , atoms [ i ] . name ) ;
cnp_debug ( " 0x%x \n " , xwin ) ;
2011-04-01 04:35:07 -07:00
2010-09-06 23:56:16 -07:00
if ( i = = CNP_ATOM_text_urilist )
{
2011-01-07 20:55:31 -08:00
cnp_debug ( " We found a URI... (%scached) %s \n " ,
2011-06-20 00:13:50 -07:00
savedtypes . imgfile ? " " : " not " ,
savedtypes . imgfile ) ;
if ( savedtypes . imgfile )
2010-09-06 23:56:16 -07:00
{
2011-01-07 20:55:31 -08:00
char * entrytag ;
static const char * tagstring = " <item absize=240x180 href= "
2011-04-01 04:35:07 -07:00
" file://%s></item> " ;
2010-09-06 23:56:16 -07:00
ddata . x = savedtypes . x ;
ddata . y = savedtypes . y ;
2010-09-07 21:55:16 -07:00
2011-01-13 15:04:04 -08:00
/* If it's markup that also supports images */
if ( ( dropable - > types & ELM_SEL_FORMAT_MARKUP ) & &
2011-04-01 04:35:07 -07:00
( dropable - > types & ELM_SEL_FORMAT_IMAGE ) )
2010-09-07 21:55:16 -07:00
{
2011-01-07 20:55:31 -08:00
int len ;
2010-09-07 21:55:16 -07:00
ddata . format = ELM_SEL_FORMAT_MARKUP ;
2011-01-07 20:55:31 -08:00
2011-06-20 00:13:50 -07:00
len = strlen ( tagstring ) + strlen ( savedtypes . imgfile ) ;
2011-01-07 20:55:31 -08:00
entrytag = alloca ( len + 1 ) ;
2011-06-20 00:13:50 -07:00
snprintf ( entrytag , len + 1 , tagstring , savedtypes . imgfile ) ;
2010-09-07 21:55:16 -07:00
ddata . data = entrytag ;
2010-12-20 03:09:19 -08:00
cnp_debug ( " Insert %s \n " , ( char * ) ddata . data ) ;
2010-09-07 21:55:16 -07:00
dropable - > dropcb ( dropable - > cbdata , dropable - > obj , & ddata ) ;
ecore_x_dnd_send_finished ( ) ;
2011-06-20 00:13:50 -07:00
if ( savedtypes . imgfile ) free ( ( void * ) savedtypes . imgfile ) ;
savedtypes . imgfile = NULL ;
2011-07-03 00:49:02 -07:00
2011-01-13 15:04:04 -08:00
return EINA_TRUE ;
}
else if ( dropable - > types & ELM_SEL_FORMAT_IMAGE )
{
2011-06-20 00:13:50 -07:00
cnp_debug ( " Doing image insert (%s) \n " , savedtypes . imgfile ) ;
2011-01-13 15:04:04 -08:00
ddata . format = ELM_SEL_FORMAT_IMAGE ;
2011-06-20 00:13:50 -07:00
ddata . data = ( char * ) savedtypes . imgfile ;
2011-01-13 15:04:04 -08:00
dropable - > dropcb ( dropable - > cbdata , dropable - > obj , & ddata ) ;
ecore_x_dnd_send_finished ( ) ;
2011-06-20 00:13:50 -07:00
if ( savedtypes . imgfile ) free ( ( void * ) savedtypes . imgfile ) ;
savedtypes . imgfile = NULL ;
2011-01-13 15:04:04 -08:00
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-07 21:55:16 -07:00
}
2011-01-07 20:55:31 -08:00
else
{
2011-01-13 15:04:04 -08:00
cnp_debug ( " Item doesn't support images... passing \n " ) ;
return EINA_TRUE ;
2011-01-07 20:55:31 -08:00
}
2010-09-06 23:56:16 -07:00
}
else if ( savedtypes . textreq )
{
2010-09-08 17:35:43 -07:00
/* Already asked: Pretend we asked now, and paste immediately when
2010-09-06 23:56:16 -07:00
* it comes in */
savedtypes . textreq = 0 ;
ecore_x_dnd_send_finished ( ) ;
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
}
}
2010-09-07 21:55:16 -07:00
cnp_debug ( " doing a request then \n " ) ;
2012-06-19 16:33:57 -07:00
selections [ ELM_SEL_TYPE_XDND ] . xwin = xwin ;
2011-12-27 03:24:13 -08:00
selections [ ELM_SEL_TYPE_XDND ] . requestwidget = dropable - > obj ;
selections [ ELM_SEL_TYPE_XDND ] . requestformat = ELM_SEL_FORMAT_MARKUP ;
selections [ ELM_SEL_TYPE_XDND ] . active = EINA_TRUE ;
2010-09-06 23:56:16 -07:00
ecore_x_selection_xdnd_request ( xwin , atoms [ i ] . name ) ;
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
}
static Eina_Bool
2010-10-19 11:24:27 -07:00
_dnd_position ( void * data __UNUSED__ , int etype __UNUSED__ , void * ev )
2010-09-08 20:09:42 -07:00
{
struct _Ecore_X_Event_Xdnd_Position * pos ;
Ecore_X_Rectangle rect ;
2011-01-07 20:55:15 -08:00
2010-09-08 20:09:42 -07:00
pos = ev ;
2011-01-07 20:55:15 -08:00
2010-09-08 20:09:42 -07:00
/* Need to send a status back */
/* FIXME: Should check I can drop here */
/* FIXME: Should highlight widget */
rect . x = pos - > position . x - 5 ;
rect . y = pos - > position . y - 5 ;
rect . width = 10 ;
rect . height = 10 ;
2010-12-20 03:09:19 -08:00
ecore_x_dnd_send_status ( EINA_TRUE , EINA_FALSE , rect , pos - > action ) ;
2010-09-08 20:09:42 -07:00
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
}
2010-09-13 02:16:01 -07:00
/**
* When dragging this is callback response from the destination .
* The important thing we care about : Can we drop ; thus update cursor
* appropriately .
*/
static Eina_Bool
2010-10-19 11:24:27 -07:00
_dnd_status ( void * data __UNUSED__ , int etype __UNUSED__ , void * ev )
2010-09-13 02:16:01 -07:00
{
struct _Ecore_X_Event_Xdnd_Status * status = ev ;
2010-12-20 03:09:19 -08:00
if ( ! status ) return EINA_TRUE ;
2011-04-01 04:35:07 -07:00
2010-09-13 02:16:01 -07:00
/* Only thing we care about: will accept */
if ( status - > will_accept )
{
2010-12-20 03:09:19 -08:00
cnp_debug ( " Will accept \n " ) ;
2010-09-13 02:16:01 -07:00
}
else
{ /* Won't accept */
2010-12-20 03:09:19 -08:00
cnp_debug ( " Won't accept accept \n " ) ;
2010-09-13 02:16:01 -07:00
}
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-13 02:16:01 -07:00
}
2010-09-06 23:56:16 -07:00
/**
* Add a widget as drop target .
*/
2012-06-19 13:17:46 -07:00
EAPI Eina_Bool
2010-12-20 03:09:19 -08:00
elm_drop_target_add ( Evas_Object * obj , Elm_Sel_Type format , Elm_Drop_Cb dropcb , void * cbdata )
2010-09-06 23:56:16 -07:00
{
2010-12-20 03:09:19 -08:00
Dropable * drop ;
2010-09-08 20:09:42 -07:00
Ecore_X_Window xwin ;
2011-01-13 15:04:14 -08:00
Eina_List * item ;
2010-09-08 20:09:42 -07:00
int first ;
2011-01-13 15:04:14 -08:00
2010-12-20 03:09:19 -08:00
if ( ! obj ) return EINA_FALSE ;
2012-06-19 16:33:57 -07:00
xwin = _elm_widget_xwin_get ( obj ) ;
if ( ! xwin ) return EINA_FALSE ;
2010-09-08 20:09:42 -07:00
if ( ! _elm_cnp_init_count ) _elm_cnp_init ( ) ;
2011-01-13 15:04:14 -08:00
2012-06-19 16:33:57 -07:00
/* TODO: check if obj is already a drop target. Do not add twice! */
2010-09-08 20:09:42 -07:00
/* Is this the first? */
2010-10-22 14:41:22 -07:00
first = ( ! drops ) ? 1 : 0 ;
2011-01-13 15:04:14 -08:00
EINA_LIST_FOREACH ( drops , item , drop )
{
if ( drop - > obj = = obj )
{
/* Update: Not a new one */
drop - > dropcb = dropcb ;
drop - > cbdata = cbdata ;
drop - > types = format ;
return EINA_TRUE ;
}
}
/* Create new drop */
2010-12-20 03:09:19 -08:00
drop = calloc ( 1 , sizeof ( Dropable ) ) ;
if ( ! drop ) return EINA_FALSE ;
2010-09-08 20:09:42 -07:00
/* FIXME: Check for eina's deranged error method */
drops = eina_list_append ( drops , drop ) ;
2011-01-13 15:04:14 -08:00
2010-09-08 20:09:42 -07:00
if ( ! drops /* || or other error */ )
{
free ( drop ) ;
2010-12-20 03:09:19 -08:00
return EINA_FALSE ;
2010-09-08 20:09:42 -07:00
}
2011-01-13 15:04:14 -08:00
drop - > dropcb = dropcb ;
drop - > cbdata = cbdata ;
2010-09-08 20:09:42 -07:00
drop - > types = format ;
2011-01-13 15:04:14 -08:00
drop - > obj = obj ;
2010-09-08 20:09:42 -07:00
evas_object_event_callback_add ( obj , EVAS_CALLBACK_DEL ,
/* I love C and varargs */
( Evas_Object_Event_Cb ) elm_drop_target_del ,
obj ) ;
/* FIXME: Handle resizes */
2011-01-13 15:04:14 -08:00
2012-06-19 16:33:57 -07:00
/* TODO BUG: should handle dnd-aware per window, not just the first window that requested it! */
2010-09-08 20:09:42 -07:00
/* If not the first: We're done */
2010-12-20 03:09:19 -08:00
if ( ! first ) return EINA_TRUE ;
2011-01-13 15:04:14 -08:00
2010-12-20 03:09:19 -08:00
ecore_x_dnd_aware_set ( xwin , EINA_TRUE ) ;
2011-04-01 04:35:07 -07:00
2012-06-19 16:33:57 -07:00
cnp_debug ( " Adding drop target calls xwin=%#llx \n " , ( unsigned long long ) xwin ) ;
2010-09-08 20:09:42 -07:00
handler_enter = ecore_event_handler_add ( ECORE_X_EVENT_XDND_ENTER ,
_dnd_enter , NULL ) ;
2010-09-13 02:16:01 -07:00
handler_pos = ecore_event_handler_add ( ECORE_X_EVENT_XDND_POSITION ,
_dnd_position , NULL ) ;
handler_drop = ecore_event_handler_add ( ECORE_X_EVENT_XDND_DROP ,
_dnd_drop , NULL ) ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
}
2012-06-19 13:17:46 -07:00
EAPI Eina_Bool
2010-09-08 20:09:42 -07:00
elm_drop_target_del ( Evas_Object * obj )
{
2010-12-20 03:09:19 -08:00
Dropable * drop , * del ;
2010-09-08 20:09:42 -07:00
Eina_List * item ;
Ecore_X_Window xwin ;
2011-04-01 04:35:07 -07:00
2010-09-08 20:09:42 -07:00
del = NULL ;
EINA_LIST_FOREACH ( drops , item , drop )
{
if ( drop - > obj = = obj )
{
drops = eina_list_remove_list ( drops , item ) ;
del = drop ;
break ;
}
}
2010-12-20 03:09:19 -08:00
if ( ! del ) return EINA_FALSE ;
2011-04-01 04:35:07 -07:00
2010-09-08 20:09:42 -07:00
evas_object_event_callback_del ( obj , EVAS_CALLBACK_FREE ,
( Evas_Object_Event_Cb ) elm_drop_target_del ) ;
free ( drop ) ;
2012-06-19 16:33:57 -07:00
/* TODO BUG: we should handle dnd-aware per window, not just the last that reelased it */
2010-09-08 20:09:42 -07:00
/* If still drops there: All fine.. continue */
2010-12-20 03:09:19 -08:00
if ( drops ) return EINA_TRUE ;
2011-04-01 04:35:07 -07:00
2010-09-09 01:59:38 -07:00
cnp_debug ( " Disabling DND \n " ) ;
2012-06-19 16:33:57 -07:00
xwin = _elm_widget_xwin_get ( obj ) ;
2010-12-20 03:09:19 -08:00
ecore_x_dnd_aware_set ( xwin , EINA_FALSE ) ;
2011-04-01 04:35:07 -07:00
2010-09-08 20:09:42 -07:00
ecore_event_handler_del ( handler_pos ) ;
ecore_event_handler_del ( handler_drop ) ;
ecore_event_handler_del ( handler_enter ) ;
2011-04-01 04:35:07 -07:00
2011-06-20 00:13:50 -07:00
if ( savedtypes . imgfile ) free ( ( void * ) savedtypes . imgfile ) ;
savedtypes . imgfile = NULL ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-06 23:56:16 -07:00
}
2010-09-10 00:23:56 -07:00
static void
2012-01-02 03:04:40 -08:00
_drag_mouse_up ( void * un __UNUSED__ , Evas * e __UNUSED__ , Evas_Object * obj , void * data )
2010-09-10 00:23:56 -07:00
{
2012-01-02 03:04:40 -08:00
Ecore_X_Window xwin = * ( ( Ecore_X_Window * ) data ) ;
2010-09-10 00:23:56 -07:00
evas_object_event_callback_del ( obj , EVAS_CALLBACK_MOUSE_UP , _drag_mouse_up ) ;
ecore_x_dnd_drop ( ) ;
2012-06-19 16:33:57 -07:00
cnp_debug ( " mouse up, xwin=%#llx \n " , ( unsigned long long ) xwin ) ;
/* TODO BUG: should not revert to FALSE if xwin is a drop target! */
2012-01-02 03:04:40 -08:00
ecore_x_dnd_aware_set ( xwin , EINA_FALSE ) ;
2010-09-10 01:24:21 -07:00
if ( dragdonecb )
{
2012-01-02 20:44:48 -08:00
dragdonecb ( dragdonedata , selections [ ELM_SEL_TYPE_XDND ] . widget ) ;
2010-09-10 01:24:21 -07:00
dragdonecb = NULL ;
}
2010-09-13 02:16:01 -07:00
if ( dragwin )
{
evas_object_del ( dragwin ) ;
dragwin = NULL ;
}
}
static void
2010-12-20 03:09:19 -08:00
_drag_move ( void * data __UNUSED__ , Ecore_X_Xdnd_Position * pos )
{
2011-04-01 04:35:07 -07:00
evas_object_move ( dragwin ,
pos - > position . x - _dragx ,
2010-09-13 02:16:05 -07:00
pos - > position . y - _dragy ) ;
2010-09-10 00:23:56 -07:00
}
2012-06-19 13:17:46 -07:00
EAPI Eina_Bool
2010-12-20 03:09:19 -08:00
elm_drag_start ( Evas_Object * obj , Elm_Sel_Format format , const char * data , void ( * dragdone ) ( void * data , Evas_Object * ) , void * donecbdata )
2010-09-09 01:59:42 -07:00
{
Ecore_X_Window xwin ;
2010-12-20 03:09:19 -08:00
Cnp_Selection * sel ;
2011-12-27 03:24:13 -08:00
Elm_Sel_Type xdnd = ELM_SEL_TYPE_XDND ;
2010-09-13 02:16:05 -07:00
Ecore_Evas * ee ;
2010-12-20 03:09:19 -08:00
int x , y , x2 , y2 , x3 , y3 ;
2010-09-13 02:16:01 -07:00
Evas_Object * icon ;
2010-12-20 03:09:19 -08:00
int w , h ;
2011-04-01 04:35:07 -07:00
2010-09-09 01:59:42 -07:00
if ( ! _elm_cnp_init_count ) _elm_cnp_init ( ) ;
2011-04-01 04:35:07 -07:00
2012-06-19 16:33:57 -07:00
xwin = _elm_widget_xwin_get ( obj ) ;
2010-09-09 01:59:42 -07:00
cnp_debug ( " starting drag... \n " ) ;
2012-01-02 20:44:48 -08:00
if ( dragwin )
{
cnp_debug ( " another obj is dragging... \n " ) ;
return EINA_FALSE ;
}
ecore_x_dnd_type_set ( xwin , " text/uri-list " , EINA_TRUE ) ;
2011-12-27 03:24:13 -08:00
sel = selections + ELM_SEL_TYPE_XDND ;
2012-01-02 20:44:48 -08:00
sel - > active = EINA_TRUE ;
2010-09-09 01:59:42 -07:00
sel - > widget = obj ;
sel - > format = format ;
2010-09-09 02:37:19 -07:00
sel - > selbuf = data ? strdup ( data ) : NULL ;
2012-06-19 16:33:57 -07:00
/* TODO BUG: should NEVER have these as globals! They should be per context (window). */
2010-09-10 01:24:21 -07:00
dragdonecb = dragdone ;
dragdonedata = donecbdata ;
2011-04-01 04:35:07 -07:00
2012-06-19 16:33:57 -07:00
/* TODO BUG: should increase dnd-awareness, in case it's drop target as well. See _drag_mouse_up() */
2012-01-02 03:04:40 -08:00
ecore_x_dnd_aware_set ( xwin , EINA_TRUE ) ;
2010-09-13 02:16:05 -07:00
ecore_x_dnd_callback_pos_update_set ( _drag_move , NULL ) ;
2010-09-14 23:29:49 -07:00
ecore_x_dnd_begin ( xwin , ( unsigned char * ) & xdnd , sizeof ( Elm_Sel_Type ) ) ;
2010-09-10 00:23:56 -07:00
evas_object_event_callback_add ( obj , EVAS_CALLBACK_MOUSE_UP ,
2012-02-24 21:12:57 -08:00
_drag_mouse_up , ( void * ) ( long ) xwin ) ;
2011-04-01 04:35:07 -07:00
2010-09-13 02:16:01 -07:00
handler_status = ecore_event_handler_add ( ECORE_X_EVENT_XDND_STATUS ,
_dnd_status , NULL ) ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
dragwin = elm_win_add ( NULL , " Elm Drag Object " , ELM_WIN_UTILITY ) ;
2012-01-02 20:44:48 -08:00
elm_win_override_set ( dragwin , EINA_TRUE ) ;
2011-04-01 04:35:07 -07:00
2010-09-13 02:16:01 -07:00
/* FIXME: Images only */
icon = elm_icon_add ( dragwin ) ;
2012-05-28 14:50:11 -07:00
elm_image_file_set ( icon , data + 7 , NULL ) ; /* 7!? "file://" */
2012-01-02 20:44:48 -08:00
elm_win_resize_object_add ( dragwin , icon ) ;
2010-12-20 03:09:19 -08:00
evas_object_size_hint_weight_set ( icon , EVAS_HINT_EXPAND , EVAS_HINT_EXPAND ) ;
2010-09-13 02:16:01 -07:00
evas_object_size_hint_align_set ( icon , EVAS_HINT_FILL , EVAS_HINT_FILL ) ;
/* Position subwindow appropriately */
2010-09-13 02:16:05 -07:00
ee = ecore_evas_ecore_evas_get ( evas_object_evas_get ( obj ) ) ;
ecore_evas_geometry_get ( ee , & x , & y , NULL , NULL ) ;
2010-09-13 02:16:09 -07:00
evas_object_geometry_get ( obj , & x2 , & y2 , & w , & h ) ;
2010-09-13 02:16:05 -07:00
x + = x2 ;
y + = y2 ;
evas_object_move ( dragwin , x , y ) ;
2010-12-20 03:09:19 -08:00
evas_object_resize ( icon , w , h ) ;
evas_object_resize ( dragwin , w , h ) ;
2011-04-01 04:35:07 -07:00
2010-09-13 02:16:09 -07:00
evas_object_show ( icon ) ;
evas_object_show ( dragwin ) ;
2010-09-13 02:16:05 -07:00
evas_pointer_canvas_xy_get ( evas_object_evas_get ( obj ) , & x3 , & y3 ) ;
_dragx = x3 - x2 ;
_dragy = y3 - y2 ;
2010-09-10 01:24:21 -07:00
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-09 01:59:42 -07:00
}
2010-09-06 23:56:16 -07:00
2012-06-19 16:33:57 -07:00
/* TODO: this should not be an actual tempfile, but rather encode the object as http://dataurl.net/ if it's an image or similar. Evas should support decoding it as memfile. */
2010-12-20 03:09:19 -08:00
static Tmp_Info *
elm_cnp_tempfile_create ( int size )
{
2011-11-20 06:56:12 -08:00
# ifdef HAVE_MMAN_H
2010-12-20 03:09:19 -08:00
Tmp_Info * info ;
2010-10-20 10:15:14 -07:00
const char * tmppath ;
2010-09-21 21:42:41 -07:00
int len ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
info = malloc ( sizeof ( Tmp_Info ) ) ;
2010-09-21 21:42:41 -07:00
if ( ! info ) return NULL ;
2011-04-01 04:35:07 -07:00
2010-09-21 21:42:41 -07:00
tmppath = getenv ( " TMP " ) ;
if ( ! tmppath ) tmppath = P_tmpdir ;
2010-12-20 03:09:19 -08:00
len = snprintf ( NULL , 0 , " %s/%sXXXXXX " , tmppath , " elmcnpitem- " ) ;
2010-09-21 21:42:41 -07:00
if ( len < 0 )
{
free ( info ) ;
return NULL ;
}
2010-12-20 03:09:19 -08:00
len + + ;
2010-09-21 21:42:41 -07:00
info - > filename = malloc ( len ) ;
2010-10-14 07:11:15 -07:00
if ( ! info - > filename )
2010-09-21 21:42:41 -07:00
{
free ( info ) ;
return NULL ;
}
2010-12-20 03:09:19 -08:00
snprintf ( info - > filename , len , " %s/%sXXXXXX " , tmppath , " elmcnpitem- " ) ;
2011-04-01 04:35:07 -07:00
2010-09-21 21:42:41 -07:00
info - > fd = mkstemp ( info - > filename ) ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
# ifdef __linux__
{
char * tmp ;
/* And before someone says anything see POSIX 1003.1-2008 page 400 */
long pid ;
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
pid = ( long ) getpid ( ) ;
/* Use pid instead of /proc/self: That way if can be passed around */
len = snprintf ( NULL , 0 , " /proc/%li/fd/%i " , pid , info - > fd ) ;
len + + ;
tmp = malloc ( len ) ;
if ( tmp )
{
snprintf ( tmp , len , " /proc/%li/fd/%i " , pid , info - > fd ) ;
unlink ( info - > filename ) ;
free ( info - > filename ) ;
info - > filename = tmp ;
}
}
# endif
2011-04-01 04:35:07 -07:00
2010-12-20 03:09:19 -08:00
cnp_debug ( " filename is %s \n " , info - > filename ) ;
2010-09-21 21:42:41 -07:00
if ( size < 1 )
{
/* Set map to NULL and return */
info - > map = NULL ;
info - > len = 0 ;
return info ;
2010-12-20 03:09:19 -08:00
}
2011-04-01 04:35:07 -07:00
2010-09-21 21:42:41 -07:00
/* Map it in */
if ( ftruncate ( info - > fd , size ) )
{
perror ( " ftruncate " ) ;
info - > map = NULL ;
info - > len = 0 ;
return info ;
}
2011-04-01 04:35:07 -07:00
2011-07-04 04:04:26 -07:00
eina_mmap_safety_enabled_set ( EINA_TRUE ) ;
2011-07-05 09:59:23 -07:00
2010-12-20 03:09:19 -08:00
info - > map = mmap ( NULL , size , PROT_READ | PROT_WRITE , MAP_SHARED , info - > fd , 0 ) ;
2010-09-21 21:42:41 -07:00
if ( info - > map = = MAP_FAILED )
{
perror ( " mmap " ) ;
info - > map = NULL ;
info - > len = 0 ;
}
2011-04-01 04:35:07 -07:00
2010-09-21 21:42:41 -07:00
return info ;
2011-11-20 06:56:12 -08:00
# else
( void ) size ;
return NULL ;
# endif
2010-09-21 21:42:41 -07:00
}
static int
2010-12-20 03:09:19 -08:00
tmpinfo_free ( Tmp_Info * info )
2010-09-21 21:42:41 -07:00
{
if ( ! info ) return 0 ;
free ( info - > filename ) ;
free ( info ) ;
return 0 ;
}
2010-09-09 01:59:38 -07:00
# else
/* Stubs for windows */
Eina_Bool
2010-12-20 03:09:19 -08:00
elm_drag_start ( Evas_Object * o , Elm_Sel_Format f , const char * d , void ( * donecb ) ( void * , Evas_Object * ) , void * cbdata )
2010-09-09 01:59:38 -07:00
{
2010-12-20 03:09:19 -08:00
return EINA_FALSE ;
2010-09-09 01:59:38 -07:00
}
2010-12-20 03:09:19 -08:00
2010-09-09 01:59:38 -07:00
Eina_Bool
2010-12-20 03:09:19 -08:00
elm_drop_target_add ( Evas_Object * obj , Elm_Sel_Type format , Elm_Drop_Cb dropcb , void * cbdata )
{
return EINA_FALSE ;
2010-09-09 01:59:38 -07:00
}
Eina_Bool
2010-09-10 02:03:05 -07:00
elm_drop_target_del ( Evas_Object * o )
2010-09-09 01:59:38 -07:00
{
2010-12-20 03:09:19 -08:00
return EINA_TRUE ;
2010-09-09 01:59:38 -07:00
}
2010-06-25 04:56:02 -07:00
# endif
2010-09-09 01:59:38 -07:00
2011-06-26 19:54:41 -07:00
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/