Big giant "rework" commit to redo the UI code (faster, easier to

manage).

Signed-off-by: Chris Michael <devilhorns@comcast.net>
This commit is contained in:
Chris Michael 2014-01-19 11:11:32 +00:00
parent 83aec7d775
commit b9a63f145d
43 changed files with 3223 additions and 2221 deletions

View File

@ -20,12 +20,35 @@ express_CPPFLAGS = \
@EXP_CFLAGS@
EXPRESSHEADERS = \
private.h
private.h \
config.h \
theme.h \
utils.h \
window.h \
channel.h \
grid.h \
selector.h \
options.h \
options_general.h \
options_font.h \
options_video.h \
options_networks.h \
options_network.h \
options_servers.h \
options_channels.h \
options_tools.h
express_SOURCES = \
$(EXPRESSHEADERS) \
utils.c \
config.c \
main.c \
theme.c \
utils.c \
window.c \
channel.c \
grid.c \
selector.c \
options.c \
options_general.c \
options_font.c \
options_video.c \
@ -33,12 +56,7 @@ express_SOURCES = \
options_network.c \
options_servers.c \
options_channels.c \
options_tools.c \
options.c \
selector.c \
grid.c \
window.c \
main.c
options_tools.c
express_LDADD = @EXPRESS_LIBS@ @LTLIBINTL@ $(top_srcdir)/src/lib/libexpress.la
express_LDFLAGS = -export-dynamic @EXP_LDFLAGS@

431
src/bin/channel.c Normal file
View File

@ -0,0 +1,431 @@
#include "private.h"
#include "channel.h"
#include "config.h"
#include "theme.h"
#include "window.h"
#include "grid.h"
struct _Channel
{
const char *name;
Evas *evas;
Evas_Object *o_base;
Evas_Object *o_bg;
Evas_Object *o_grid;
Evas_Object *o_spacer;
Evas_Object *o_img;
int step_x, step_y;
int min_w, min_h;
int req_w, req_h;
Eina_Bool size_done : 1;
Eina_Bool translucent : 1;
Eina_Bool focused : 1;
Eina_Bool unswallowed : 1;
Eina_Bool missed : 1;
};
/* local functions */
static void
_cb_theme_reload(Channel *chl)
{
if (chl->translucent == _ex_cfg->gui.translucent) return;
chl->translucent = _ex_cfg->gui.translucent;
if (chl->translucent)
{
edje_object_signal_emit(chl->o_bg, "translucent,on", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "translucent,on", PACKAGE_NAME);
}
else
{
edje_object_signal_emit(chl->o_bg, "translucent,off", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "translucent,off", PACKAGE_NAME);
}
}
static void
_cb_size_hint(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
{
Channel *chl;
Evas_Coord mw, mh, rw, rh, w = 0, h = 0;
chl = data;
evas_object_size_hint_min_get(obj, &mw, &mh);
evas_object_size_hint_request_get(obj, &rw, &rh);
edje_object_size_min_calc(chl->o_base, &w, &h);
evas_object_size_hint_min_set(chl->o_base, w, h);
edje_object_size_min_calc(chl->o_bg, &w, &h);
evas_object_size_hint_min_set(chl->o_bg, w, h);
chl->step_x = mw;
chl->step_y = mh;
chl->min_w = (w - mw);
chl->min_h = (h - mh);
chl->req_w = (w - mw + rw);
chl->req_h = (h - mh + rh);
}
static void
_cb_prev(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl, *pchl = NULL;
chl = data;
if (chl->focused)
{
if ((pchl = _window_channel_previous_get(chl)))
_window_channel_switch(chl, pchl);
}
}
static void
_cb_next(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl, *nchl = NULL;
chl = data;
if (chl->focused)
{
if ((nchl = _window_channel_next_get(chl)))
_window_channel_switch(chl, nchl);
}
}
static void
_cb_count_go(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
Channel *chl;
chl = data;
_window_channel_switch(chl, chl);
}
static void
_cb_count_prev(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
_cb_prev(data, NULL, NULL);
}
static void
_cb_count_next(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *source EINA_UNUSED)
{
_cb_next(data, NULL, NULL);
}
static void
_cb_options_done(void *data)
{
Channel *chl;
chl = data;
if (chl->focused) elm_object_focus_set(chl->o_grid, EINA_TRUE);
}
static void
_cb_options(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl;
chl = data;
_window_options_toggle(chl->o_grid, _cb_options_done, chl);
}
/* external functions */
Channel *
_channel_create(Evas *evas, const char *name)
{
Channel *chl;
/* try to allocate space for channel structure */
if (!(chl = calloc(1, sizeof(Channel)))) return NULL;
/* set channel to the opposite of config translucent
* NB: This is done so that first time through the signals get sent */
chl->translucent = !_ex_cfg->gui.translucent;
chl->evas = evas;
/* store channel name */
if (name) chl->name = eina_stringshare_add(name);
/* add base object */
chl->o_base = edje_object_add(evas);
_theme_apply(chl->o_base, "express/channel");
_theme_reload_enable(chl->o_base);
evas_object_data_set(chl->o_base, "theme_reload_func", _cb_theme_reload);
evas_object_data_set(chl->o_base, "theme_reload_func_data", chl);
/* add bg object */
chl->o_bg = edje_object_add(evas);
WEIGHT_SET(chl->o_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(chl->o_bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
_theme_apply(chl->o_bg, "express/background");
_theme_reload_enable(chl->o_bg);
evas_object_data_set(chl->o_bg, "theme_reload_func", _cb_theme_reload);
evas_object_data_set(chl->o_bg, "theme_reload_func_data", chl);
/* add grid */
chl->o_grid = _grid_add(evas);
WEIGHT_SET(chl->o_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(chl->o_grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_event_callback_add(chl->o_grid,
EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_cb_size_hint, chl);
evas_object_smart_callback_add(chl->o_grid, "options", _cb_options, chl);
evas_object_smart_callback_add(chl->o_grid, "prev", _cb_prev, chl);
evas_object_smart_callback_add(chl->o_grid, "next", _cb_next, chl);
/* swallow parts */
edje_object_part_swallow(chl->o_base, "channel.content", chl->o_grid);
edje_object_part_swallow(chl->o_bg, "background.content", chl->o_base);
/* add handlers for chlcount signals */
edje_object_signal_callback_add(chl->o_bg, "chlcount,go", PACKAGE_NAME,
_cb_count_go, chl);
edje_object_signal_callback_add(chl->o_bg, "chlcount,prev", PACKAGE_NAME,
_cb_count_prev, chl);
edje_object_signal_callback_add(chl->o_bg, "chlcount,next", PACKAGE_NAME,
_cb_count_next, chl);
return chl;
}
void
_channel_destroy(Channel *chl)
{
/* delete channel name */
if (chl->name) eina_stringshare_del(chl->name);
/* free allocated channel structure */
free(chl);
}
void
_channel_update(Channel *chl)
{
chl->size_done = EINA_FALSE;
/* update channel transparency */
_cb_theme_reload(chl);
/* update grid config */
_grid_update(chl->o_grid);
}
void
_channel_focused_set(Channel *chl, Eina_Bool focus)
{
chl->focused = focus;
}
Eina_Bool
_channel_focused_get(Channel *chl)
{
return chl->focused;
}
void
_channel_focus(Channel *chl)
{
edje_object_signal_emit(chl->o_bg, "focus,in", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "focus,in", PACKAGE_NAME);
elm_object_focus_set(chl->o_grid, EINA_TRUE);
chl->missed = EINA_FALSE;
}
void
_channel_unfocus(Channel *chl)
{
elm_object_focus_set(chl->o_grid, EINA_FALSE);
edje_object_signal_emit(chl->o_bg, "focus,out", PACKAGE_NAME);
edje_object_signal_emit(chl->o_base, "focus,out", PACKAGE_NAME);
}
const char *
_channel_name_get(Channel *chl)
{
return chl->name;
}
void
_channel_size_update(Channel *chl)
{
_cb_size_hint(chl, NULL, chl->o_grid, NULL);
}
void
_channel_size_min_get(Channel *chl, int *w, int *h)
{
evas_object_size_hint_min_get(chl->o_bg, w, h);
}
void
_channel_size_step_get(Channel *chl, int *w, int *h)
{
if (w) *w = chl->step_x;
if (h) *h = chl->step_y;
}
void
_channel_size_request_get(Channel *chl, int *w, int *h)
{
if (w) *w = chl->req_w;
if (h) *h = chl->req_h;
}
void
_channel_size_done_set(Channel *chl, Eina_Bool done)
{
chl->size_done = done;
}
Eina_Bool
_channel_size_done_get(Channel *chl)
{
return chl->size_done;
}
Evas_Object *
_channel_background_get(Channel *chl)
{
return chl->o_bg;
}
void
_channel_background_hide(Channel *chl)
{
evas_object_hide(chl->o_bg);
}
void
_channel_background_show(Channel *chl)
{
evas_object_show(chl->o_bg);
}
Evas_Object *
_channel_base_get(Channel *chl)
{
return chl->o_base;
}
void
_channel_base_unswallow(Channel *chl)
{
edje_object_part_unswallow(chl->o_bg, chl->o_base);
evas_object_lower(chl->o_base);
evas_object_move(chl->o_base, -9999, -9999);
evas_object_show(chl->o_base);
evas_object_clip_unset(chl->o_base);
#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
evas_object_image_source_visible_set(chl->o_img, EINA_FALSE);
#endif
chl->unswallowed = EINA_TRUE;
}
Evas_Object *
_channel_image_get(Channel *chl)
{
return chl->o_img;
}
void
_channel_image_unset(Channel *chl)
{
#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
evas_object_image_source_visible_set(chl->o_img, EINA_TRUE);
#endif
chl->o_img = NULL;
}
void
_channel_image_create(Channel *chl)
{
Evas_Coord w = 0, h = 0;
chl->o_img = evas_object_image_filled_add(chl->evas);
evas_object_image_source_set(chl->o_img, chl->o_base);
evas_object_geometry_get(chl->o_base, NULL, NULL, &w, &h);
evas_object_resize(chl->o_img, w, h);
evas_object_data_set(chl->o_img, "grid", chl->o_grid);
}
Eina_Bool
_channel_missed_get(Channel *chl)
{
return chl->missed;
}
void
_channel_missed_set(Channel *chl, Eina_Bool missed)
{
chl->missed = missed;
}
void
_channel_missed_count_set(Channel *chl, int count)
{
if (count > 0)
{
char buff[32];
snprintf(buff, sizeof(buff), "%i", count);
edje_object_part_text_set(chl->o_bg, "chlmissed.label", buff);
edje_object_signal_emit(chl->o_bg, "chlmissed,on", PACKAGE_NAME);
}
else
edje_object_signal_emit(chl->o_bg, "chlmissed,off", PACKAGE_NAME);
}
void
_channel_count_set(Channel *chl, int count, int total)
{
if (total > 1)
{
char buff[32];
snprintf(buff, sizeof(buff), "%i/%i", count, total);
edje_object_part_text_set(chl->o_bg, "chlcount.label", buff);
edje_object_signal_emit(chl->o_bg, "chlcount,on", PACKAGE_NAME);
}
else
edje_object_signal_emit(chl->o_bg, "chlcount,off", PACKAGE_NAME);
}
Eina_Bool
_channel_unswallowed_get(Channel *chl)
{
return chl->unswallowed;
}
void
_channel_unswallowed_set(Channel *chl, Eina_Bool swallowed)
{
chl->unswallowed = swallowed;
if (!swallowed)
{
edje_object_part_swallow(chl->o_base, "channel.content", chl->o_grid);
edje_object_part_swallow(chl->o_bg, "background.content", chl->o_base);
}
}
void
_channel_spacer_create(Channel *chl)
{
Evas_Coord w = 0, h = 0;
if (!chl->o_spacer)
{
chl->o_spacer = evas_object_rectangle_add(chl->evas);
evas_object_color_set(chl->o_spacer, 0, 0, 0, 0);
}
elm_coords_finger_size_adjust(1, &w, 1, &h);
evas_object_size_hint_min_set(chl->o_spacer, w, h);
edje_object_part_swallow(chl->o_bg, "chlcount.control", chl->o_spacer);
}

42
src/bin/channel.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef _CHANNEL_H_
# define _CHANNEL_H_ 1
Channel *_channel_create(Evas *evas, const char *name);
void _channel_destroy(Channel *chl);
void _channel_update(Channel *chl);
void _channel_focused_set(Channel *chl, Eina_Bool focus);
Eina_Bool _channel_focused_get(Channel *chl);
void _channel_focus(Channel *chl);
void _channel_unfocus(Channel *chl);
const char *_channel_name_get(Channel *chl);
void _channel_size_update(Channel *chl);
void _channel_size_min_get(Channel *chl, int *w, int *h);
void _channel_size_step_get(Channel *chl, int *w, int *h);
void _channel_size_request_get(Channel *chl, int *w, int *h);
Eina_Bool _channel_size_done_get(Channel *chl);
void _channel_size_done_set(Channel *chl, Eina_Bool done);
Evas_Object *_channel_background_get(Channel *chl);
void _channel_background_hide(Channel *chl);
void _channel_background_show(Channel *chl);
Evas_Object *_channel_base_get(Channel *chl);
void _channel_base_unswallow(Channel *chl);
Evas_Object *_channel_image_get(Channel *chl);
void _channel_image_unset(Channel *chl);
void _channel_image_create(Channel *chl);
Eina_Bool _channel_missed_get(Channel *chl);
void _channel_missed_set(Channel *chl, Eina_Bool missed);
void _channel_missed_count_set(Channel *chl, int count);
void _channel_count_set(Channel *chl, int count, int total);
Eina_Bool _channel_unswallowed_get(Channel *chl);
void _channel_unswallowed_set(Channel *chl, Eina_Bool swallowed);
void _channel_spacer_create(Channel *chl);
#endif

471
src/bin/colors.c Normal file
View File

@ -0,0 +1,471 @@
#include "private.h"
#include "colors.h"
typedef struct _Color Color;
struct _Color
{
unsigned char r, g, b, a;
};
static const Color colors[2][2][12] =
{
{ // normal
{ // normal
{ 0xaa, 0xaa, 0xaa, 0xff }, // COL_DEF
{ 0x00, 0x00, 0x00, 0xff }, // COL_BLACK
{ 0xc0, 0x00, 0x00, 0xff }, // COL_RED
{ 0x00, 0xc0, 0x00, 0xff }, // COL_GREEN
{ 0xc0, 0xc0, 0x00, 0xff }, // COL_YELLOW
{ 0x00, 0x00, 0xc0, 0xff }, // COL_BLUE
{ 0xc0, 0x00, 0xc0, 0xff }, // COL_MAGENTA
{ 0x00, 0xc0, 0xc0, 0xff }, // COL_CYAN
{ 0xc0, 0xc0, 0xc0, 0xff }, // COL_WHITE
{ 0x00, 0x00, 0x00, 0x00 }, // COL_INVIS
{ 0x22, 0x22, 0x22, 0xff }, // COL_INVERSE
{ 0xaa, 0xaa, 0xaa, 0xff }, // COL_INVERSEBG
},
{ // bright/bold
{ 0xee, 0xee, 0xee, 0xff }, // COL_DEF
{ 0xcc, 0xcc, 0xcc, 0xff }, // COL_BLACK
{ 0xcc, 0x88, 0x88, 0xff }, // COL_RED
{ 0x88, 0xcc, 0x88, 0xff }, // COL_GREEN
{ 0xcc, 0xaa, 0x88, 0xff }, // COL_YELLOW
{ 0x88, 0x88, 0xcc, 0xff }, // COL_BLUE
{ 0xcc, 0x88, 0xcc, 0xff }, // COL_MAGENTA
{ 0x88, 0xcc, 0xcc, 0xff }, // COL_CYAN
{ 0xcc, 0xcc, 0xcc, 0xff }, // COL_WHITE
{ 0x00, 0x00, 0x00, 0x00 }, // COL_INVIS
{ 0x11, 0x11, 0x11, 0xff }, // COL_INVERSE
{ 0xee, 0xee, 0xee, 0xff }, // COL_INVERSEBG
},
},
{ // intense
{ // normal
{ 0xdd, 0xdd, 0xdd, 0xff }, // COL_DEF
{ 0x80, 0x80, 0x80, 0xff }, // COL_BLACK
{ 0xff, 0x80, 0x80, 0xff }, // COL_RED
{ 0x80, 0xff, 0x80, 0xff }, // COL_GREEN
{ 0xff, 0xff, 0x80, 0xff }, // COL_YELLOW
{ 0x80, 0x80, 0xff, 0xff }, // COL_BLUE
{ 0xff, 0x80, 0xff, 0xff }, // COL_MAGENTA
{ 0x80, 0xff, 0xff, 0xff }, // COL_CYAN
{ 0xff, 0xff, 0xff, 0xff }, // COL_WHITE
{ 0x00, 0x00, 0x00, 0x00 }, // COL_INVIS
{ 0x11, 0x11, 0x11, 0xff }, // COL_INVERSE
{ 0xcc, 0xcc, 0xcc, 0xff }, // COL_INVERSEBG
},
{ // bright/bold
{ 0xff, 0xff, 0xff, 0xff }, // COL_DEF
{ 0xcc, 0xcc, 0xcc, 0xff }, // COL_BLACK
{ 0xff, 0xcc, 0xcc, 0xff }, // COL_RED
{ 0xcc, 0xff, 0xcc, 0xff }, // COL_GREEN
{ 0xff, 0xff, 0xcc, 0xff }, // COL_YELLOW
{ 0xcc, 0xcc, 0xff, 0xff }, // COL_BLUE
{ 0xff, 0xcc, 0xff, 0xff }, // COL_MAGENTA
{ 0xcc, 0xff, 0xff, 0xff }, // COL_CYAN
{ 0xff, 0xff, 0xff, 0xff }, // COL_WHITE
{ 0x00, 0x00, 0x00, 0x00 }, // COL_INVIS
{ 0x00, 0x00, 0x00, 0xff }, // COL_INVERSE
{ 0xff, 0xff, 0xff, 0xff }, // COL_INVERSEBG
}
}
};
static const Color colors256[256] =
{
// basic 16 repeated
{ 0x00, 0x00, 0x00, 0xff }, // COL_BLACK
{ 0xc0, 0x00, 0x00, 0xff }, // COL_RED
{ 0x00, 0xc0, 0x00, 0xff }, // COL_GREEN
{ 0xc0, 0xc0, 0x00, 0xff }, // COL_YELLOW
{ 0x00, 0x00, 0xc0, 0xff }, // COL_BLUE
{ 0xc0, 0x00, 0xc0, 0xff }, // COL_MAGENTA
{ 0x00, 0xc0, 0xc0, 0xff }, // COL_CYAN
{ 0xc0, 0xc0, 0xc0, 0xff }, // COL_WHITE
{ 0x80, 0x80, 0x80, 0xff }, // COL_BLACK
{ 0xff, 0x80, 0x80, 0xff }, // COL_RED
{ 0x80, 0xff, 0x80, 0xff }, // COL_GREEN
{ 0xff, 0xff, 0x80, 0xff }, // COL_YELLOW
{ 0x80, 0x80, 0xff, 0xff }, // COL_BLUE
{ 0xff, 0x80, 0xff, 0xff }, // COL_MAGENTA
{ 0x80, 0xff, 0xff, 0xff }, // COL_CYAN
{ 0xff, 0xff, 0xff, 0xff }, // COL_WHITE
// pure 6x6x6 colorcube
{ 0x00, 0x00, 0x00, 0xff },
{ 0x00, 0x00, 0x2a, 0xff },
{ 0x00, 0x00, 0x55, 0xff },
{ 0x00, 0x00, 0x7f, 0xff },
{ 0x00, 0x00, 0xaa, 0xff },
{ 0x00, 0x00, 0xd4, 0xff },
{ 0x00, 0x2a, 0x00, 0xff },
{ 0x00, 0x2a, 0x2a, 0xff },
{ 0x00, 0x2a, 0x55, 0xff },
{ 0x00, 0x2a, 0x7f, 0xff },
{ 0x00, 0x2a, 0xaa, 0xff },
{ 0x00, 0x2a, 0xd4, 0xff },
{ 0x00, 0x55, 0x00, 0xff },
{ 0x00, 0x55, 0x2a, 0xff },
{ 0x00, 0x55, 0x55, 0xff },
{ 0x00, 0x55, 0x7f, 0xff },
{ 0x00, 0x55, 0xaa, 0xff },
{ 0x00, 0x55, 0xd4, 0xff },
{ 0x00, 0x7f, 0x00, 0xff },
{ 0x00, 0x7f, 0x2a, 0xff },
{ 0x00, 0x7f, 0x55, 0xff },
{ 0x00, 0x7f, 0x7f, 0xff },
{ 0x00, 0x7f, 0xaa, 0xff },
{ 0x00, 0x7f, 0xd4, 0xff },
{ 0x00, 0xaa, 0x00, 0xff },
{ 0x00, 0xaa, 0x2a, 0xff },
{ 0x00, 0xaa, 0x55, 0xff },
{ 0x00, 0xaa, 0x7f, 0xff },
{ 0x00, 0xaa, 0xaa, 0xff },
{ 0x00, 0xaa, 0xd4, 0xff },
{ 0x00, 0xd4, 0x00, 0xff },
{ 0x00, 0xd4, 0x2a, 0xff },
{ 0x00, 0xd4, 0x55, 0xff },
{ 0x00, 0xd4, 0x7f, 0xff },
{ 0x00, 0xd4, 0xaa, 0xff },
{ 0x00, 0xd4, 0xd4, 0xff },
{ 0x2a, 0x00, 0x00, 0xff },
{ 0x2a, 0x00, 0x2a, 0xff },
{ 0x2a, 0x00, 0x55, 0xff },
{ 0x2a, 0x00, 0x7f, 0xff },
{ 0x2a, 0x00, 0xaa, 0xff },
{ 0x2a, 0x00, 0xd4, 0xff },
{ 0x2a, 0x2a, 0x00, 0xff },
{ 0x2a, 0x2a, 0x2a, 0xff },
{ 0x2a, 0x2a, 0x55, 0xff },
{ 0x2a, 0x2a, 0x7f, 0xff },
{ 0x2a, 0x2a, 0xaa, 0xff },
{ 0x2a, 0x2a, 0xd4, 0xff },
{ 0x2a, 0x55, 0x00, 0xff },
{ 0x2a, 0x55, 0x2a, 0xff },
{ 0x2a, 0x55, 0x55, 0xff },
{ 0x2a, 0x55, 0x7f, 0xff },
{ 0x2a, 0x55, 0xaa, 0xff },
{ 0x2a, 0x55, 0xd4, 0xff },
{ 0x2a, 0x7f, 0x00, 0xff },
{ 0x2a, 0x7f, 0x2a, 0xff },
{ 0x2a, 0x7f, 0x55, 0xff },
{ 0x2a, 0x7f, 0x7f, 0xff },
{ 0x2a, 0x7f, 0xaa, 0xff },
{ 0x2a, 0x7f, 0xd4, 0xff },
{ 0x2a, 0xaa, 0x00, 0xff },
{ 0x2a, 0xaa, 0x2a, 0xff },
{ 0x2a, 0xaa, 0x55, 0xff },
{ 0x2a, 0xaa, 0x7f, 0xff },
{ 0x2a, 0xaa, 0xaa, 0xff },
{ 0x2a, 0xaa, 0xd4, 0xff },
{ 0x2a, 0xd4, 0x00, 0xff },
{ 0x2a, 0xd4, 0x2a, 0xff },
{ 0x2a, 0xd4, 0x55, 0xff },
{ 0x2a, 0xd4, 0x7f, 0xff },
{ 0x2a, 0xd4, 0xaa, 0xff },
{ 0x2a, 0xd4, 0xd4, 0xff },
{ 0x55, 0x00, 0x00, 0xff },
{ 0x55, 0x00, 0x2a, 0xff },
{ 0x55, 0x00, 0x55, 0xff },
{ 0x55, 0x00, 0x7f, 0xff },
{ 0x55, 0x00, 0xaa, 0xff },
{ 0x55, 0x00, 0xd4, 0xff },
{ 0x55, 0x2a, 0x00, 0xff },
{ 0x55, 0x2a, 0x2a, 0xff },
{ 0x55, 0x2a, 0x55, 0xff },
{ 0x55, 0x2a, 0x7f, 0xff },
{ 0x55, 0x2a, 0xaa, 0xff },
{ 0x55, 0x2a, 0xd4, 0xff },
{ 0x55, 0x55, 0x00, 0xff },
{ 0x55, 0x55, 0x2a, 0xff },
{ 0x55, 0x55, 0x55, 0xff },
{ 0x55, 0x55, 0x7f, 0xff },
{ 0x55, 0x55, 0xaa, 0xff },
{ 0x55, 0x55, 0xd4, 0xff },
{ 0x55, 0x7f, 0x00, 0xff },
{ 0x55, 0x7f, 0x2a, 0xff },
{ 0x55, 0x7f, 0x55, 0xff },
{ 0x55, 0x7f, 0x7f, 0xff },
{ 0x55, 0x7f, 0xaa, 0xff },
{ 0x55, 0x7f, 0xd4, 0xff },
{ 0x55, 0xaa, 0x00, 0xff },
{ 0x55, 0xaa, 0x2a, 0xff },
{ 0x55, 0xaa, 0x55, 0xff },
{ 0x55, 0xaa, 0x7f, 0xff },
{ 0x55, 0xaa, 0xaa, 0xff },
{ 0x55, 0xaa, 0xd4, 0xff },
{ 0x55, 0xd4, 0x00, 0xff },
{ 0x55, 0xd4, 0x2a, 0xff },
{ 0x55, 0xd4, 0x55, 0xff },
{ 0x55, 0xd4, 0x7f, 0xff },
{ 0x55, 0xd4, 0xaa, 0xff },
{ 0x55, 0xd4, 0xd4, 0xff },
{ 0x7f, 0x00, 0x00, 0xff },
{ 0x7f, 0x00, 0x2a, 0xff },
{ 0x7f, 0x00, 0x55, 0xff },
{ 0x7f, 0x00, 0x7f, 0xff },
{ 0x7f, 0x00, 0xaa, 0xff },
{ 0x7f, 0x00, 0xd4, 0xff },
{ 0x7f, 0x2a, 0x00, 0xff },
{ 0x7f, 0x2a, 0x2a, 0xff },
{ 0x7f, 0x2a, 0x55, 0xff },
{ 0x7f, 0x2a, 0x7f, 0xff },
{ 0x7f, 0x2a, 0xaa, 0xff },
{ 0x7f, 0x2a, 0xd4, 0xff },
{ 0x7f, 0x55, 0x00, 0xff },
{ 0x7f, 0x55, 0x2a, 0xff },
{ 0x7f, 0x55, 0x55, 0xff },
{ 0x7f, 0x55, 0x7f, 0xff },
{ 0x7f, 0x55, 0xaa, 0xff },
{ 0x7f, 0x55, 0xd4, 0xff },
{ 0x7f, 0x7f, 0x00, 0xff },
{ 0x7f, 0x7f, 0x2a, 0xff },
{ 0x7f, 0x7f, 0x55, 0xff },
{ 0x7f, 0x7f, 0x7f, 0xff },
{ 0x7f, 0x7f, 0xaa, 0xff },
{ 0x7f, 0x7f, 0xd4, 0xff },
{ 0x7f, 0xaa, 0x00, 0xff },
{ 0x7f, 0xaa, 0x2a, 0xff },
{ 0x7f, 0xaa, 0x55, 0xff },
{ 0x7f, 0xaa, 0x7f, 0xff },
{ 0x7f, 0xaa, 0xaa, 0xff },
{ 0x7f, 0xaa, 0xd4, 0xff },
{ 0x7f, 0xd4, 0x00, 0xff },
{ 0x7f, 0xd4, 0x2a, 0xff },
{ 0x7f, 0xd4, 0x55, 0xff },
{ 0x7f, 0xd4, 0x7f, 0xff },
{ 0x7f, 0xd4, 0xaa, 0xff },
{ 0x7f, 0xd4, 0xd4, 0xff },
{ 0xaa, 0x00, 0x00, 0xff },
{ 0xaa, 0x00, 0x2a, 0xff },
{ 0xaa, 0x00, 0x55, 0xff },
{ 0xaa, 0x00, 0x7f, 0xff },
{ 0xaa, 0x00, 0xaa, 0xff },
{ 0xaa, 0x00, 0xd4, 0xff },
{ 0xaa, 0x2a, 0x00, 0xff },
{ 0xaa, 0x2a, 0x2a, 0xff },
{ 0xaa, 0x2a, 0x55, 0xff },
{ 0xaa, 0x2a, 0x7f, 0xff },
{ 0xaa, 0x2a, 0xaa, 0xff },
{ 0xaa, 0x2a, 0xd4, 0xff },
{ 0xaa, 0x55, 0x00, 0xff },
{ 0xaa, 0x55, 0x2a, 0xff },
{ 0xaa, 0x55, 0x55, 0xff },
{ 0xaa, 0x55, 0x7f, 0xff },
{ 0xaa, 0x55, 0xaa, 0xff },
{ 0xaa, 0x55, 0xd4, 0xff },
{ 0xaa, 0x7f, 0x00, 0xff },
{ 0xaa, 0x7f, 0x2a, 0xff },
{ 0xaa, 0x7f, 0x55, 0xff },
{ 0xaa, 0x7f, 0x7f, 0xff },
{ 0xaa, 0x7f, 0xaa, 0xff },
{ 0xaa, 0x7f, 0xd4, 0xff },
{ 0xaa, 0xaa, 0x00, 0xff },
{ 0xaa, 0xaa, 0x2a, 0xff },
{ 0xaa, 0xaa, 0x55, 0xff },
{ 0xaa, 0xaa, 0x7f, 0xff },
{ 0xaa, 0xaa, 0xaa, 0xff },
{ 0xaa, 0xaa, 0xd4, 0xff },
{ 0xaa, 0xd4, 0x00, 0xff },
{ 0xaa, 0xd4, 0x2a, 0xff },
{ 0xaa, 0xd4, 0x55, 0xff },
{ 0xaa, 0xd4, 0x7f, 0xff },
{ 0xaa, 0xd4, 0xaa, 0xff },
{ 0xaa, 0xd4, 0xd4, 0xff },
{ 0xd4, 0x00, 0x00, 0xff },
{ 0xd4, 0x00, 0x2a, 0xff },
{ 0xd4, 0x00, 0x55, 0xff },
{ 0xd4, 0x00, 0x7f, 0xff },
{ 0xd4, 0x00, 0xaa, 0xff },
{ 0xd4, 0x00, 0xd4, 0xff },
{ 0xd4, 0x2a, 0x00, 0xff },
{ 0xd4, 0x2a, 0x2a, 0xff },
{ 0xd4, 0x2a, 0x55, 0xff },
{ 0xd4, 0x2a, 0x7f, 0xff },
{ 0xd4, 0x2a, 0xaa, 0xff },
{ 0xd4, 0x2a, 0xd4, 0xff },
{ 0xd4, 0x55, 0x00, 0xff },
{ 0xd4, 0x55, 0x2a, 0xff },
{ 0xd4, 0x55, 0x55, 0xff },
{ 0xd4, 0x55, 0x7f, 0xff },
{ 0xd4, 0x55, 0xaa, 0xff },
{ 0xd4, 0x55, 0xd4, 0xff },
{ 0xd4, 0x7f, 0x00, 0xff },
{ 0xd4, 0x7f, 0x2a, 0xff },
{ 0xd4, 0x7f, 0x55, 0xff },
{ 0xd4, 0x7f, 0x7f, 0xff },
{ 0xd4, 0x7f, 0xaa, 0xff },
{ 0xd4, 0x7f, 0xd4, 0xff },
{ 0xd4, 0xaa, 0x00, 0xff },
{ 0xd4, 0xaa, 0x2a, 0xff },
{ 0xd4, 0xaa, 0x55, 0xff },
{ 0xd4, 0xaa, 0x7f, 0xff },
{ 0xd4, 0xaa, 0xaa, 0xff },
{ 0xd4, 0xaa, 0xd4, 0xff },
{ 0xd4, 0xd4, 0x00, 0xff },
{ 0xd4, 0xd4, 0x2a, 0xff },
{ 0xd4, 0xd4, 0x55, 0xff },
{ 0xd4, 0xd4, 0x7f, 0xff },
{ 0xd4, 0xd4, 0xaa, 0xff },
{ 0xd4, 0xd4, 0xd4, 0xff },
// greyscale ramp (24 not including black and white, so 26 if included)
{ 0x08, 0x08, 0x08, 0xff },
{ 0x12, 0x12, 0x12, 0xff },
{ 0x1c, 0x1c, 0x1c, 0xff },
{ 0x26, 0x26, 0x26, 0xff },
{ 0x30, 0x30, 0x30, 0xff },
{ 0x3a, 0x3a, 0x3a, 0xff },
{ 0x44, 0x44, 0x44, 0xff },
{ 0x4e, 0x4e, 0x4e, 0xff },
{ 0x58, 0x58, 0x58, 0xff },
{ 0x62, 0x62, 0x62, 0xff },
{ 0x6c, 0x6c, 0x6c, 0xff },
{ 0x76, 0x76, 0x76, 0xff },
{ 0x80, 0x80, 0x80, 0xff },
{ 0x8a, 0x8a, 0x8a, 0xff },
{ 0x94, 0x94, 0x94, 0xff },
{ 0x9e, 0x9e, 0x9e, 0xff },
{ 0xa8, 0xa8, 0xa8, 0xff },
{ 0xb2, 0xb2, 0xb2, 0xff },
{ 0xbc, 0xbc, 0xbc, 0xff },
{ 0xc6, 0xc6, 0xc6, 0xff },
{ 0xd0, 0xd0, 0xd0, 0xff },
{ 0xda, 0xda, 0xda, 0xff },
{ 0xe4, 0xe4, 0xe4, 0xff },
{ 0xee, 0xee, 0xee, 0xff },
};
void
_colors_init(Evas_Object *obj, Evas_Object *bg)
{
int c, n;
int r, g, b, a;
char buf[32];
for (c = 0; c < 4 * 12; c++)
{
snprintf(buf, sizeof(buf) - 1, "c%i", c);
n = c + (24 * (c / 24));
if (edje_object_color_class_get(bg, buf,
&r, &g, &b, &a,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL))
{
/* normal */
evas_object_textgrid_palette_set(obj,
EVAS_TEXTGRID_PALETTE_STANDARD,
n, r, g, b, a);
/* faint */
evas_object_textgrid_palette_set(obj,
EVAS_TEXTGRID_PALETTE_STANDARD,
n + 24,
r / 2, g / 2, b / 2, a / 2);
}
else
{
Color color;
color = colors[c / 24][(c % 24) / 12][c % 12];
/* normal */
evas_object_textgrid_palette_set(obj,
EVAS_TEXTGRID_PALETTE_STANDARD,
n, color.r, color.g, color.b,
color.a);
/* faint */
evas_object_textgrid_palette_set(obj,
EVAS_TEXTGRID_PALETTE_STANDARD,
n + 24,
color.r / 2, color.g / 2,
color.b / 2, color.a / 2);
}
}
for (c = 0; c < 256; c++)
{
snprintf(buf, sizeof(buf) - 1, "C%i", c);
if (edje_object_color_class_get(bg, buf,
&r, &g, &b, &a,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL))
{
evas_object_textgrid_palette_set(obj,
EVAS_TEXTGRID_PALETTE_EXTENDED,
c, r, g, b, a);
}
else
{
Color color;
color = colors256[c];
evas_object_textgrid_palette_set(obj,
EVAS_TEXTGRID_PALETTE_EXTENDED,
c, color.r, color.g, color.b,
color.a);
}
}
}
void
_colors_standard_get(int set, int col, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)
{
if ((set >= 0) && (set < 4))
{
int s1, s2;
s1 = set / 2;
s2 = set % 2;
*r = colors[s1][s2][col].r;
*g = colors[s1][s2][col].g;
*b = colors[s1][s2][col].b;
*a = colors[s1][s2][col].a;
return;
}
*r = 0;
*g = 0;
*b = 0;
*a = 0;
}

7
src/bin/colors.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _COLORS_H_
# define _COLORS_H_ 1
void _colors_init(Evas_Object *obj, Evas_Object *bg);
void _colors_standard_get(int set, int col, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a);
#endif

View File

@ -1,4 +1,35 @@
#include "private.h"
#include "config.h"
#include "utils.h"
#include "window.h"
# define EX_CONFIG_LIMIT(v, min, max) \
if (v > max) v = max; else if (v < min) v = min;
# define EX_CONFIG_DD_NEW(str, typ) \
_config_descriptor_new(str, sizeof(typ))
# define EX_CONFIG_DD_FREE(eed) \
if (eed) { eet_data_descriptor_free(eed); (eed) = NULL; }
# define EX_CONFIG_VAL(edd, type, member, dtype) \
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
# define EX_CONFIG_SUB(edd, type, member, eddtype) \
EET_DATA_DESCRIPTOR_ADD_SUB(edd, type, #member, member, eddtype)
# define EX_CONFIG_LIST(edd, type, member, eddtype) \
EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
# define EX_CONFIG_HASH(edd, type, member, eddtype) \
EET_DATA_DESCRIPTOR_ADD_HASH(edd, type, #member, member, eddtype)
# define EX_CONFIG_FILE_EPOCH 0x0001
# define EX_CONFIG_FILE_GENERATION 0x008d
# define EX_CONFIG_FILE_VERSION \
((EX_CONFIG_FILE_EPOCH << 16) | EX_CONFIG_FILE_GENERATION)
typedef Eet_Data_Descriptor Ex_Config_DD;
/* local variables */
static Ex_Config_DD *_ex_cfg_edd = NULL;
@ -10,6 +41,18 @@ static Ex_Config_DD *_ex_cfg_chl_edd = NULL;
Config *_ex_cfg = NULL;
/* local functions */
static Ex_Config_DD *
_config_descriptor_new(const char *name, int size)
{
Eet_Data_Descriptor_Class eddc;
if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(eddc),
name, size))
return NULL;
return (Ex_Config_DD *)eet_data_descriptor_stream_new(&eddc);
}
static void
_config_cb_free(void)
{
@ -44,6 +87,7 @@ _config_cb_free(void)
if (_ex_cfg->name) eina_stringshare_del(_ex_cfg->name);
free(_ex_cfg);
_ex_cfg = NULL;
}
static void *
@ -67,7 +111,7 @@ _config_domain_load(const char *domain, Ex_Config_DD *edd)
return NULL;
}
static int
static Eina_Bool
_config_domain_save(const char *domain, Ex_Config_DD *edd, const void *data)
{
Eet_File *ef;
@ -147,10 +191,10 @@ _config_init(void)
EX_CONFIG_VAL(D, T, font.bitmap, EET_T_UCHAR);
EX_CONFIG_VAL(D, T, gui.translucent, EET_T_UCHAR);
EX_CONFIG_VAL(D, T, gui.zoom, EET_T_DOUBLE);
EX_CONFIG_VAL(D, T, gui.scrollback, EET_T_INT);
EX_CONFIG_LIST(D, T, networks, _ex_cfg_net_edd);
_config_load();
_config_save();
return EINA_TRUE;
}
@ -173,26 +217,33 @@ _config_shutdown(void)
void
_config_load(void)
{
_ex_cfg = _config_domain_load("express", _ex_cfg_edd);
Eina_Bool save = EINA_FALSE;
_ex_cfg = _config_domain_load(PACKAGE_NAME, _ex_cfg_edd);
if (_ex_cfg)
{
int reload;
Eina_Bool reload = EINA_FALSE;
if ((_ex_cfg->version >> 16) < EX_CONFIG_FILE_EPOCH)
{
/* config too old */
reload = 1;
reload = EINA_TRUE;
}
else if (_ex_cfg->version > EX_CONFIG_FILE_VERSION)
{
/* config too new, WTF ? */
reload = 1;
reload = EINA_TRUE;
}
if (reload)
_ex_cfg = _config_domain_load("express", _ex_cfg_edd);
/* if too old or too new, clear it so we can create new */
if (reload) _config_cb_free();
}
if (!_ex_cfg) _ex_cfg = malloc(sizeof(Config));
if (!_ex_cfg)
{
_ex_cfg = malloc(sizeof(Config));
save = EINA_TRUE;
}
/* define some convenient macros */
#define IFCFG(v) if ((_ex_cfg->version & 0xffff) < (v)) {
@ -216,30 +267,26 @@ _config_load(void)
_ex_cfg->font.name = eina_stringshare_add("nexus.pcf");
_ex_cfg->gui.translucent = EINA_TRUE;
_ex_cfg->gui.zoom = 0.5;
_ex_cfg->gui.scrollback = 2000;
_ex_cfg->networks = NULL;
IFCFGEND;
/* limit config values so they are sane */
EX_CONFIG_LIMIT(_ex_cfg->font.size, 3, 400);
EX_CONFIG_LIMIT(_ex_cfg->gui.zoom, 0.1, 1.0);
EX_CONFIG_LIMIT(_ex_cfg->gui.scrollback, 0, 200000);
_ex_cfg->version = EX_CONFIG_FILE_VERSION;
if (save) _config_save();
}
int
void
_config_save(void)
{
return _config_domain_save("express", _ex_cfg_edd, _ex_cfg);
}
Ex_Config_DD *
_config_descriptor_new(const char *name, int size)
{
Eet_Data_Descriptor_Class eddc;
if (!eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(eddc),
name, size))
return NULL;
return (Ex_Config_DD *)eet_data_descriptor_stream_new(&eddc);
if (_config_domain_save(PACKAGE_NAME, _ex_cfg_edd, _ex_cfg))
{
/* update window, channels, etc */
_window_update();
}
}

63
src/bin/config.h Normal file
View File

@ -0,0 +1,63 @@
#ifndef _CONFIG_H_
# define _CONFIG_H_ 1
typedef struct _Config_Channel Config_Channel;
typedef struct _Config_Server Config_Server;
typedef struct _Config_Network Config_Network;
typedef struct _Config Config;
struct _Config_Channel
{
const char *name;
};
struct _Config_Server
{
const char *name;
int port;
};
struct _Config_Network
{
const char *name;
const char *nick_passwd;
const char *server_passwd;
Eina_Bool autoconnect;
Eina_Bool bypass_proxy;
Eina_Bool use_ssl;
Eina_List *servers;
Eina_List *channels;
};
struct _Config
{
int version;
const char *nick;
const char *name;
struct
{
const char *name;
int size;
Eina_Bool bitmap;
} font;
struct
{
Eina_Bool translucent;
double zoom;
int scrollback;
} gui;
Eina_List *networks;
};
extern Config *_ex_cfg;
Eina_Bool _config_init(void);
Eina_Bool _config_shutdown(void);
void _config_load(void);
void _config_save(void);
#endif

File diff suppressed because it is too large Load Diff

7
src/bin/grid.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _GRID_H_
# define _GRID_H_ 1
Evas_Object *_grid_add(Evas *evas);
void _grid_update(Evas_Object *obj);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,10 @@
#include "private.h"
#include "options.h"
#include "options_general.h"
#include "options_font.h"
#include "options_video.h"
#include "options_networks.h"
#include "options_tools.h"
/* local variables */
static Evas_Object *o_win = NULL;
@ -82,7 +88,7 @@ _cb_details_done(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_
break;
}
edje_object_signal_emit(o_base, "options,details,show", "express");
edje_object_signal_emit(o_base, "options,details,show", PACKAGE_NAME);
}
static void
@ -94,7 +100,7 @@ _cb_details_done2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const ch
_cb_del_delay(NULL);
edje_object_signal_callback_del(o_base, "options,details,hide,done",
"express", _cb_details_done2);
PACKAGE_NAME, _cb_details_done2);
}
static void
@ -104,7 +110,7 @@ _cb_option(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
if (_mode == mode) return;
_mode = mode;
edje_object_signal_emit(o_base, "options,details,hide", "express");
edje_object_signal_emit(o_base, "options,details,hide", PACKAGE_NAME);
}
/* external functions */
@ -164,7 +170,7 @@ _options_toggle(Evas_Object *win, Evas_Object *base, Evas_Object *grid, void (*c
elm_toolbar_item_selected_set(o_itm, EINA_TRUE);
TB_APPEND("preferences-desktop-font", "Font", FONT);
TB_APPEND("applications-multimedia", "Video", VIDEO);
TB_APPEND("video-display", "Video", VIDEO);
TB_APPEND("preferences-system-network", "Networks", NETWORKS);
#undef TB_APPEND
@ -179,14 +185,14 @@ _options_toggle(Evas_Object *win, Evas_Object *base, Evas_Object *grid, void (*c
{
edje_object_part_swallow(base, "options_details", o_box);
edje_object_part_swallow(base, "options", o_frame);
edje_object_signal_emit(base, "options,details,show", "express");
edje_object_signal_emit(base, "options,show", "express");
edje_object_signal_emit(base, "options,details,show", PACKAGE_NAME);
edje_object_signal_emit(base, "options,show", PACKAGE_NAME);
}
if (!_opts_out)
{
edje_object_signal_callback_add(base, "options,details,hide,done",
"express", _cb_details_done, grid);
PACKAGE_NAME, _cb_details_done, grid);
o_dismiss = evas_object_rectangle_add(evas_object_evas_get(win));
evas_object_color_set(o_dismiss, 0, 0, 0, 0);
@ -200,8 +206,8 @@ _options_toggle(Evas_Object *win, Evas_Object *base, Evas_Object *grid, void (*c
_opts_cb_done = cb_done;
_opts_cb_data = data;
edje_object_signal_emit(base, "options,details,hide", "express");
edje_object_signal_emit(base, "options,show", "express");
edje_object_signal_emit(base, "options,details,hide", PACKAGE_NAME);
edje_object_signal_emit(base, "options,show", PACKAGE_NAME);
elm_object_focus_set(o_tbr, EINA_TRUE);
_opts_out = EINA_TRUE;
@ -211,9 +217,9 @@ _options_toggle(Evas_Object *win, Evas_Object *base, Evas_Object *grid, void (*c
else
{
edje_object_signal_callback_del(o_base, "options,details,hide,done",
"express", _cb_details_done);
PACKAGE_NAME, _cb_details_done);
edje_object_signal_callback_add(o_base, "options,details,hide,done",
"express", _cb_details_done2, NULL);
PACKAGE_NAME, _cb_details_done2, NULL);
elm_object_focus_set(o_box, EINA_FALSE);
elm_object_focus_set(o_tbr, EINA_FALSE);
@ -224,8 +230,8 @@ _options_toggle(Evas_Object *win, Evas_Object *base, Evas_Object *grid, void (*c
if (o_dismiss) evas_object_del(o_dismiss);
o_dismiss = NULL;
edje_object_signal_emit(o_base, "options,hide", "express");
edje_object_signal_emit(o_base, "options,details,hide", "express");
edje_object_signal_emit(o_base, "options,hide", PACKAGE_NAME);
edje_object_signal_emit(o_base, "options,details,hide", PACKAGE_NAME);
_opts_out = EINA_FALSE;
if (_opts_del_timer) ecore_timer_del(_opts_del_timer);

6
src/bin/options.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _OPTIONS_H_
# define _OPTIONS_H_ 1
void _options_toggle(Evas_Object *win, Evas_Object *base, Evas_Object *grid, void (*cb_done)(void *data), void *data);
#endif

View File

@ -1,4 +1,6 @@
#include "private.h"
#include "options_channels.h"
#include "config.h"
/* local variables */
static Evas_Object *o_list = NULL;

View File

@ -0,0 +1,8 @@
#ifndef _OPTIONS_CHANNELS_H_
# define _OPTIONS_CHANNELS_H_ 1
# include "config.h"
void _options_channels(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
#endif

View File

@ -1,4 +1,7 @@
#include "private.h"
#include "options_font.h"
#include "config.h"
#include "theme.h"
#define TEST_STRING "oislOIS.015!|,"

6
src/bin/options_font.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _OPTIONS_FONT_H_
# define _OPTIONS_FONT_H_ 1
void _options_font(Evas_Object *box, Evas_Object *grid);
#endif

View File

@ -1,4 +1,6 @@
#include "private.h"
#include "options_general.h"
#include "config.h"
static void
_cb_translucent(void *data EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
@ -8,10 +10,18 @@ _cb_translucent(void *data EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSE
/* TODO */
}
static void
_cb_scrollback(void *data EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
{
_ex_cfg->gui.scrollback = elm_slider_value_get(obj) + 0.5;
_config_save();
/* TODO */
}
void
_options_general(Evas_Object *box, Evas_Object *grid EINA_UNUSED)
{
Evas_Object *o, *o_frame, *tb;
Evas_Object *o, *o_frame, *tb, *vbox;
/* general frame */
o_frame = elm_frame_add(box);
@ -93,5 +103,32 @@ _options_general(Evas_Object *box, Evas_Object *grid EINA_UNUSED)
elm_object_text_set(o_frame, "Other Options");
evas_object_show(o_frame);
vbox = elm_box_add(box);
/* elm_box_horizontal_set(vbox, EINA_FALSE); */
elm_box_homogeneous_set(vbox, EINA_FALSE);
evas_object_size_hint_weight_set(vbox, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(vbox, EVAS_HINT_FILL, 0.0);
elm_object_content_set(o_frame, vbox);
evas_object_show(vbox);
o = elm_label_add(box);
elm_object_text_set(o, "Scrollback:");
evas_object_size_hint_weight_set(o, 0.0, 0.0);
evas_object_size_hint_align_set(o, 0.0, 0.5);
elm_box_pack_end(vbox, o);
evas_object_show(o);
o = elm_slider_add(box);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.0);
elm_slider_span_size_set(o, 40);
elm_slider_unit_format_set(o, "%1.0f");
elm_slider_indicator_format_set(o, "%1.0f");
elm_slider_min_max_set(o, 0, 10000);
elm_slider_value_set(o, _ex_cfg->gui.scrollback);
evas_object_smart_callback_add(o, "delay,changed", _cb_scrollback, NULL);
elm_box_pack_end(vbox, o);
evas_object_show(o);
elm_box_pack_end(box, o_frame);
}

View File

@ -0,0 +1,6 @@
#ifndef _OPTIONS_GENERAL_H_
# define _OPTIONS_GENERAL_H_ 1
void _options_general(Evas_Object *box, Evas_Object *grid);
#endif

View File

@ -1,4 +1,6 @@
#include "private.h"
#include "options_network.h"
#include "config.h"
static void
_cb_name_changed(void *data, Evas_Object *obj, void *event EINA_UNUSED)

View File

@ -0,0 +1,8 @@
#ifndef _OPTIONS_NETWORK_H_
# define _OPTIONS_NETWORK_H_ 1
# include "config.h"
void _options_network(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
#endif

View File

@ -1,4 +1,7 @@
#include "private.h"
#include "options_networks.h"
#include "config.h"
#include "options_tools.h"
/* local variables */
static Evas_Object *o_box = NULL;

View File

@ -0,0 +1,6 @@
#ifndef _OPTIONS_NETWORKS_H_
# define _OPTIONS_NETWORKS_H_ 1
void _options_networks(Evas_Object *box, Evas_Object *base);
#endif

View File

@ -1,4 +1,6 @@
#include "private.h"
#include "options_servers.h"
#include "config.h"
/* local variables */
static Evas_Object *o_list = NULL;

View File

@ -0,0 +1,8 @@
#ifndef _OPTIONS_SERVERS_H_
# define _OPTIONS_SERVERS_H_ 1
# include "config.h"
void _options_servers(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
#endif

View File

@ -1,4 +1,8 @@
#include "private.h"
#include "options_tools.h"
#include "options_network.h"
#include "options_servers.h"
#include "options_channels.h"
/* local variables */
static Evas_Object *o_base = NULL;

8
src/bin/options_tools.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _OPTIONS_TOOLS_H_
# define _OPTIONS_TOOLS_H_ 1
# include "config.h"
void _options_tools(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
#endif

View File

@ -1,4 +1,5 @@
#include "private.h"
#include "options_video.h"
void
_options_video(Evas_Object *box, Evas_Object *grid EINA_UNUSED)

6
src/bin/options_video.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _OPTIONS_VIDEO_H_
# define _OPTIONS_VIDEO_H_ 1
void _options_video(Evas_Object *box, Evas_Object *grid);
#endif

View File

@ -25,126 +25,31 @@ extern int _log_dom;
#define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
#define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
# define EX_CONFIG_LIMIT(v, min, max) \
if (v > max) v = max; else if (v < min) v = min;
#define WEIGHT_SET(OBJ, WIDTH, HEIGHT) \
evas_object_size_hint_weight_set(OBJ, WIDTH, HEIGHT)
# define EX_CONFIG_DD_NEW(str, typ) \
_config_descriptor_new(str, sizeof(typ))
#define FILL_SET(OBJ, WIDTH, HEIGHT) \
evas_object_size_hint_fill_set(OBJ, WIDTH, HEIGHT)
# define EX_CONFIG_DD_FREE(eed) \
if (eed) { eet_data_descriptor_free(eed); (eed) = NULL; }
# define EX_CONFIG_VAL(edd, type, member, dtype) \
EET_DATA_DESCRIPTOR_ADD_BASIC(edd, type, #member, member, dtype)
# define EX_CONFIG_SUB(edd, type, member, eddtype) \
EET_DATA_DESCRIPTOR_ADD_SUB(edd, type, #member, member, eddtype)
# define EX_CONFIG_LIST(edd, type, member, eddtype) \
EET_DATA_DESCRIPTOR_ADD_LIST(edd, type, #member, member, eddtype)
# define EX_CONFIG_HASH(edd, type, member, eddtype) \
EET_DATA_DESCRIPTOR_ADD_HASH(edd, type, #member, member, eddtype)
# define EX_CONFIG_FILE_EPOCH 0x0001
# define EX_CONFIG_FILE_GENERATION 0x008d
# define EX_CONFIG_FILE_VERSION \
((EX_CONFIG_FILE_EPOCH << 16) | EX_CONFIG_FILE_GENERATION)
typedef struct _Color Color;
typedef struct _Window Window;
typedef struct _Channel Channel;
typedef struct _Config_Channel Config_Channel;
typedef struct _Config_Server Config_Server;
typedef struct _Config_Network Config_Network;
typedef struct _Config Config;
typedef Eet_Data_Descriptor Ex_Config_DD;
#define SUPPORT_ITALIC 1
//#define SUPPORT_DBLWIDTH 1
//#define SUPPORT_80_132_COLUMNS 1
struct _Config_Channel
{
const char *name;
};
/* struct _Window */
/* { */
/* Evas_Object *o_sel; */
/* Evas_Object *o_sel_bg; */
struct _Config_Server
{
const char *name;
int port;
};
/* Evas_Object *o_opts; */
struct _Config_Network
{
const char *name;
const char *nick_passwd;
const char *server_passwd;
Eina_Bool autoconnect;
Eina_Bool bypass_proxy;
Eina_Bool use_ssl;
Eina_List *servers;
Eina_List *channels;
};
/* Eina_Bool focused : 1; */
struct _Config
{
int version;
/* Ecore_Idler *idler; */
/* }; */
const char *nick;
const char *name;
struct
{
const char *name;
int size;
Eina_Bool bitmap;
} font;
struct
{
Eina_Bool translucent;
double zoom;
} gui;
Eina_List *networks;
};
extern Config *_ex_cfg;
/* internal functions */
Evas_Object *_window_new(void);
const char *_theme_default_get(void);
void _theme_reload(Evas_Object *obj);
Eina_Bool _theme_apply(Evas_Object *obj, const char *group);
void _theme_reload_enable(Evas_Object *obj);
Evas_Object *_grid_add(Evas_Object *parent, const char *name);
void _grid_colors_init(Evas_Object *obj, Evas_Object *bg);
const char *_grid_name_get(Evas_Object *obj);
Evas_Object *_selector_add(Evas_Object *parent);
void _selector_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Eina_Bool bell);
void _selector_entry_selected_set(Evas_Object *obj, Evas_Object *entry, Eina_Bool keep);
void _selector_zoom_set(Evas_Object *obj, double zoom);
void _selector_zoom(Evas_Object *obj, double zoom);
void _selector_go(Evas_Object *obj);
void _selector_exit(Evas_Object *obj);
Eina_Bool _config_init(void);
Eina_Bool _config_shutdown(void);
void _config_load(void);
int _config_save(void);
Ex_Config_DD *_config_descriptor_new(const char *name, int size);
const char *_util_user_dir_get(void);
char *_util_user_name_get(void);
char *_util_user_fullname_get(void);
void _options_toggle(Evas_Object *win, Evas_Object *base, Evas_Object *grid, void (*cb_done)(void *data), void *data);
void _options_general(Evas_Object *box, Evas_Object *grid);
void _options_font(Evas_Object *box, Evas_Object *grid);
void _options_video(Evas_Object *box, Evas_Object *grid);
void _options_networks(Evas_Object *box, Evas_Object *base);
void _options_network(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
void _options_tools(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
void _options_servers(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
void _options_channels(Evas_Object *box, Evas_Object *base, Config_Network *cfg_net);
/* void _main_window_selector_restore(Window *win); */
/* void _main_window_flush(void); */

View File

@ -1,4 +1,8 @@
#include "private.h"
#include "selector.h"
#include "config.h"
#include "theme.h"
#include "channel.h"
typedef struct _Selector Selector;
typedef struct _Entry Entry;
@ -44,7 +48,8 @@ struct _Entry
{
Evas_Object *obj;
Evas_Object *o_bg;
Evas_Object *o_grid;
Channel *chl;
Eina_Bool selected : 1;
Eina_Bool before : 1;
@ -56,22 +61,19 @@ struct _Entry
static Evas_Smart *_smart = NULL;
static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
static void _selector_transit(Evas_Object *obj, double t);
/* local functions */
static void
_selector_layout(Evas_Object *obj)
_cb_layout(Evas_Object *obj, Selector *sd)
{
Selector *sd;
Entry *en;
Eina_List *l;
Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
Evas_Coord w = 0, h = 0, px = 0, py = 0;
int count = 0, ew = 0, eh = 0, x = 0, y = 0;
if (!(sd = evas_object_smart_data_get(obj))) return;
count = eina_list_count(sd->entries);
if (count < 1) return;
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
ew = sqrt(count);
@ -154,21 +156,21 @@ _selector_layout(Evas_Object *obj)
EINA_LIST_FOREACH(sd->entries, l, en)
{
if ((!en->was_selected) && (en->selected))
edje_object_signal_emit(en->o_bg, "selected", "express");
edje_object_signal_emit(en->o_bg, "selected", PACKAGE_NAME);
else if ((en->was_selected) && (!en->selected))
edje_object_signal_emit(en->o_bg, "unselected", "express");
edje_object_signal_emit(en->o_bg, "unselected", PACKAGE_NAME);
}
}
}
static Eina_Bool
_selector_cb_anim(void *data)
_cb_anim(void *data)
{
Evas_Object *obj;
Selector *sd;
double t = 1.0;
if (!(obj = data)) return EINA_FALSE;
obj = data;
if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
if (sd->total > 0.0)
@ -180,7 +182,7 @@ _selector_cb_anim(void *data)
sd->interp = ecore_animator_pos_map(t, ECORE_POS_MAP_DECELERATE, 0, 0);
sd->zoom = sd->zoom0 + ((sd->zoom1 - sd->zoom0) * sd->interp);
_selector_layout(obj);
_cb_layout(obj, sd);
if (t >= 1.0)
{
@ -206,10 +208,13 @@ _selector_cb_anim(void *data)
EINA_LIST_FOREACH(sd->entries, l, en)
{
if (en->selected) entry = en->obj;
if (en->selected)
{
entry = en->obj;
evas_object_smart_callback_call(obj, "selected", entry);
break;
}
}
if (entry)
evas_object_smart_callback_call(obj, "selected", entry);
}
else if (sd->exit_me)
evas_object_smart_callback_call(obj, "exit", NULL);
@ -221,21 +226,73 @@ _selector_cb_anim(void *data)
}
static void
_selector_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
_cb_transit(Evas_Object *obj, Selector *sd, double t)
{
sd->px0 = sd->px;
sd->py0 = sd->py;
sd->zoom0 = sd->zoom;
sd->start = ecore_loop_time_get();
sd->total = t;
sd->interp = 0.0;
if (!sd->anim) sd->anim = ecore_animator_add(_cb_anim, obj);
}
static void
_cb_entry_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Entry *en;
en = data;
if (en->obj)
evas_object_event_callback_del_full(en->obj, EVAS_CALLBACK_DEL,
_cb_entry_del, en);
en->obj = NULL;
}
static Eina_Bool
_cb_autozoom_reset(void *data)
{
Selector *sd;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(data))) return EINA_FALSE;
sd->autozoom = NULL;
_selector_zoom(data, sd->orig_zoom);
return EINA_FALSE;
}
static void
_cb_autozoom(Evas_Object *obj, Selector *sd)
{
double t = 0.0;
t = ecore_loop_time_get();
if ((t - sd->last_time) < 0.5)
_selector_zoom(obj, (sd->zoom * 0.9));
sd->last_time = t;
if (sd->autozoom) ecore_timer_del(sd->autozoom);
sd->autozoom = ecore_timer_add(0.5, _cb_autozoom_reset, obj);
}
static void
_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
{
Selector *sd;
Evas_Event_Mouse_Up *ev;
Evas_Coord dx, dy, size;
ev = event;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(data))) return;
if (!sd->mouse.down) return;
sd->mouse.down = EINA_FALSE;
dx = abs(ev->canvas.x - sd->mouse.x);
dy = abs(ev->canvas.y - sd->mouse.y);
size = elm_config_finger_size_get();
if ((dx <= size) && (dy <= size))
{
Entry *en;
@ -249,7 +306,7 @@ _selector_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_
evas_object_geometry_get(en->o_bg, &ox, &oy, &ow, &oh);
if (ELM_RECTS_INTERSECT(ox, oy, ow, oh, x, y, 1, 1))
{
_selector_entry_selected_set(data, en->obj, EINA_FALSE);
_selector_channel_selected_set(data, en->chl, EINA_FALSE);
sd->select = EINA_TRUE;
sd->exit_me = EINA_FALSE;
if (sd->autozoom)
@ -267,14 +324,13 @@ _selector_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_
}
static void
_selector_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
{
Selector *sd;
Evas_Event_Mouse_Down *ev;
sd = data;
ev = event;
if (!(sd = evas_object_smart_data_get(data))) return;
if (sd->mouse.down) return;
if (ev->button != 1) return;
sd->mouse.x = ev->canvas.x;
@ -283,7 +339,7 @@ _selector_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN
}
static void
_selector_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
{
Selector *sd;
Evas_Event_Mouse_Move *ev;
@ -292,16 +348,19 @@ _selector_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN
int ew = 0, eh = 0, count = 0;
ev = event;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(data))) return;
if ((sd->exit_me) || (sd->exit_now) || (sd->select)) return;
if ((sd->exit_me) || (sd->exit_now) || (sd->select) || (sd->anim)) return;
count = eina_list_count(sd->entries);
if (count < 1) return;
ew = sqrt(count);
if (ew < 1) ew = 1;
eh = (count + (ew - 1)) / ew;
if (ew < 1) ew = 1;
if (eh < 1) eh = 1;
evas_object_geometry_get(data, &x, &y, &w, &h);
sw = w * sd->zoom;
@ -310,7 +369,7 @@ _selector_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN
{
if ((w > 0) && (h > 0))
{
_selector_transit(data, 0.5);
_cb_transit(data, sd, 0.5);
sd->px1 = ((ev->cur.canvas.x - x) * ((ew - 1) * sw)) / w;
sd->py1 = ((ev->cur.canvas.y - y) * ((eh - 1) * sh)) / h;
sd->use_px = EINA_TRUE;
@ -318,36 +377,8 @@ _selector_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EIN
}
}
static Eina_Bool
_selector_autozoom_reset(void *data)
{
Selector *sd;
if (!(sd = evas_object_smart_data_get(data))) return EINA_FALSE;
sd->autozoom = NULL;
_selector_zoom(data, sd->orig_zoom);
return EINA_FALSE;
}
static void
_selector_autozoom(Evas_Object *obj)
{
Selector *sd;
double t = 0.0;
if (!(sd = evas_object_smart_data_get(obj))) return;
t = ecore_loop_time_get();
if ((t - sd->last_time) < 0.5)
{
_selector_zoom(obj, sd->zoom * 0.9);
}
sd->last_time = t;
if (sd->autozoom) ecore_timer_del(sd->autozoom);
sd->autozoom = ecore_timer_add(0.5, _selector_autozoom_reset, obj);
}
static void
_selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
{
Selector *sd;
Evas_Event_Key_Down *ev;
@ -355,8 +386,12 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
Entry *en;
ev = event;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(data))) return;
if ((sd->exit_me) || (sd->exit_now) || (sd->select)) return;
if ((!strcmp(ev->key, "Next")) || (!strcmp(ev->key, "Right")))
{
EINA_LIST_FOREACH(sd->entries, l, en)
@ -364,12 +399,12 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
if ((en->selected) && (l->next))
{
en = l->next->data;
_selector_entry_selected_set(obj, en->obj, EINA_FALSE);
_selector_channel_selected_set(obj, en->chl, EINA_FALSE);
break;
}
}
sd->exit_now = EINA_FALSE;
_selector_autozoom(data);
_cb_autozoom(data, sd);
}
else if ((!strcmp(ev->key, "Prior")) || (!strcmp(ev->key, "Left")))
{
@ -378,12 +413,12 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
if ((en->selected) && (l->prev))
{
en = l->prev->data;
_selector_entry_selected_set(obj, en->obj, EINA_FALSE);
_selector_channel_selected_set(obj, en->chl, EINA_FALSE);
break;
}
}
sd->exit_now = EINA_FALSE;
_selector_autozoom(data);
_cb_autozoom(data, sd);
}
else if (!strcmp(ev->key, "Up"))
{
@ -402,8 +437,8 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
evas_object_geometry_get(en->o_bg, &x, &y, &w, &h);
if (ELM_RECTS_INTERSECT(x, y, w, h, sx, sy, 1, 1))
{
_selector_entry_selected_set(obj, en->obj,
EINA_FALSE);
_selector_channel_selected_set(obj, en->chl,
EINA_FALSE);
break;
}
}
@ -411,7 +446,7 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
}
}
sd->exit_now = EINA_FALSE;
_selector_autozoom(data);
_cb_autozoom(data, sd);
}
else if (!strcmp(ev->key, "Down"))
{
@ -430,8 +465,8 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
evas_object_geometry_get(en->o_bg, &x, &y, &w, &h);
if (ELM_RECTS_INTERSECT(x, y, w, h, sx, sy, 1, 1))
{
_selector_entry_selected_set(obj, en->obj,
EINA_FALSE);
_selector_channel_selected_set(obj, en->chl,
EINA_FALSE);
break;
}
}
@ -439,7 +474,7 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
}
}
sd->exit_now = EINA_FALSE;
_selector_autozoom(data);
_cb_autozoom(data, sd);
}
else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")) ||
(!strcmp(ev->key, "space")))
@ -456,13 +491,15 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
}
else if (!strcmp(ev->key, "Escape"))
{
Evas_Object *entry = NULL;
EINA_LIST_FOREACH(sd->entries, l, en)
{
if (en->orig) entry = en->obj;
if (en->orig)
{
_selector_channel_selected_set(obj, en->chl, EINA_FALSE);
break;
}
}
if (entry) _selector_entry_selected_set(obj, entry, EINA_FALSE);
sd->select = EINA_FALSE;
sd->exit_me = EINA_TRUE;
if (sd->autozoom)
@ -475,76 +512,19 @@ _selector_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void
}
}
static void
_selector_entry_grid_cb_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Entry *en;
if (!(en = data)) return;
if (en->o_grid)
evas_object_event_callback_del_full(en->o_grid, EVAS_CALLBACK_DEL,
_selector_entry_grid_cb_del, en);
en->o_grid = NULL;
}
static void
_selector_entry_cb_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Entry *en;
if (!(en = data)) return;
if (en->obj)
evas_object_event_callback_del_full(en->obj, EVAS_CALLBACK_DEL,
_selector_entry_cb_del, en);
en->obj = NULL;
if (en->o_grid)
{
/* TODO: callbacks del for bell, title, icon */
evas_object_event_callback_del_full(en->o_grid, EVAS_CALLBACK_DEL,
_selector_entry_grid_cb_del, en);
}
en->o_grid = NULL;
}
static void
_selector_transit(Evas_Object *obj, double t)
{
Selector *sd;
if (!(sd = evas_object_smart_data_get(obj))) return;
sd->px0 = sd->px;
sd->py0 = sd->py;
sd->zoom0 = sd->zoom;
sd->start = ecore_loop_time_get();
sd->total = t;
sd->interp = 0.0;
if (!sd->anim) sd->anim = ecore_animator_add(_selector_cb_anim, obj);
}
static void
_selector_label_redo(Entry *en)
{
const char *n;
if (!en->obj) return;
if (!en->o_grid) return;
if ((n = _grid_name_get(en->o_grid)))
edje_object_part_text_set(en->o_bg, "label", n);
}
static void
_smart_add(Evas_Object *obj)
{
Selector *sd;
/* try to allocate space for selector structure */
if (!(sd = calloc(1, sizeof(Selector)))) return;
evas_object_smart_data_set(obj, sd);
_parent_sc.add(obj);
sd->evas = evas_object_evas_get(obj);
sd->o_clip = evas_object_rectangle_add(sd->evas);
evas_object_color_set(sd->o_clip, 255, 255, 255, 255);
evas_object_smart_member_add(sd->o_clip, obj);
@ -556,28 +536,20 @@ _smart_del(Evas_Object *obj)
Selector *sd;
Entry *en;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
if (sd->o_clip) evas_object_del(sd->o_clip);
if (sd->o_event) evas_object_del(sd->o_event);
if (sd->anim) ecore_animator_del(sd->anim);
if (sd->autozoom) ecore_timer_del(sd->autozoom);
EINA_LIST_FREE(sd->entries, en)
{
if (en->o_grid)
{
/* TODO: callbacks del for bell, title, icon */
evas_object_event_callback_del_full(en->o_grid,
EVAS_CALLBACK_DEL,
_selector_entry_grid_cb_del,
en);
}
if (en->obj)
{
evas_object_event_callback_del_full(en->obj, EVAS_CALLBACK_DEL,
_selector_entry_cb_del, en);
_cb_entry_del, en);
evas_object_del(en->obj);
}
if (en->o_bg) evas_object_del(en->o_bg);
@ -588,24 +560,24 @@ _smart_del(Evas_Object *obj)
}
static void
_smart_move(Evas_Object *obj, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED)
_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
{
Selector *sd;
/* Selector *sd; */
Evas_Coord ow = 0, oh = 0;
/* try to get the objects smart data */
/* if (!(sd = evas_object_smart_data_get(obj))) return; */
/* get geometry of the object */
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
if ((ow == w) && (oh == h)) return;
if (!(sd = evas_object_smart_data_get(obj))) return;
evas_object_smart_changed(obj);
}
static void
_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
_smart_move(Evas_Object *obj, Evas_Coord x EINA_UNUSED, Evas_Coord y EINA_UNUSED)
{
Selector *sd;
Evas_Coord ow = 0, oh = 0;
if (!(sd = evas_object_smart_data_get(obj))) return;
evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
if ((ow == w) && (oh == h)) return;
evas_object_smart_changed(obj);
}
@ -615,16 +587,21 @@ _smart_calculate(Evas_Object *obj)
Selector *sd;
Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
if ((sd->w == ow) && (sd->h == oh)) return;
sd->w = ow;
sd->h = oh;
evas_object_move(sd->o_clip, ox, oy);
evas_object_resize(sd->o_clip, ow, oh);
evas_object_move(sd->o_event, ox, oy);
evas_object_resize(sd->o_event, ow, oh);
_selector_layout(obj);
_cb_layout(obj, sd);
}
static void
@ -648,18 +625,16 @@ _smart_init(void)
/* external functions */
Evas_Object *
_selector_add(Evas_Object *parent)
_selector_create(Evas *evas)
{
Evas_Object *obj;
Selector *sd;
Evas *evas;
if (!parent) return NULL;
if (!(evas = evas_object_evas_get(parent))) return NULL;
if (!_smart) _smart_init();
obj = evas_object_smart_add(evas, _smart);
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return obj;
sd->o_event = evas_object_rectangle_add(evas);
@ -670,13 +645,14 @@ _selector_add(Evas_Object *parent)
evas_object_show(sd->o_event);
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_UP,
_selector_cb_mouse_up, obj);
_cb_mouse_up, obj);
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_DOWN,
_selector_cb_mouse_down, obj);
_cb_mouse_down, sd);
evas_object_event_callback_add(sd->o_event, EVAS_CALLBACK_MOUSE_MOVE,
_selector_cb_mouse_move, obj);
_cb_mouse_move, obj);
evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
_selector_cb_key_down, obj);
_cb_key_down, obj);
sd->zoom = 1.0;
@ -684,22 +660,30 @@ _selector_add(Evas_Object *parent)
}
void
_selector_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Eina_Bool bell)
_selector_channel_add(Evas_Object *obj, Channel *chl, Eina_Bool selected)
{
Selector *sd;
Entry *en;
Eina_Bool bell = EINA_FALSE;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
/* try to allocate space for the Entry structure */
if (!(en = calloc(1, sizeof(Entry)))) return;
/* add this entry to the list */
sd->entries = eina_list_append(sd->entries, en);
en->obj = entry;
bell = _channel_missed_get(chl);
en->chl = chl;
en->obj = _channel_image_get(chl);
en->selected = selected;
en->before = selected;
en->orig = selected;
/* create entry background */
en->o_bg = edje_object_add(evas_object_evas_get(obj));
_theme_apply(en->o_bg, "express/selector/entry");
evas_object_smart_member_add(en->o_bg, obj);
@ -709,42 +693,41 @@ _selector_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Ei
evas_object_stack_below(en->o_bg, sd->o_event);
if (en->selected)
edje_object_signal_emit(en->o_bg, "selected,start", "express");
edje_object_signal_emit(en->o_bg, "selected,start", PACKAGE_NAME);
if (bell)
edje_object_signal_emit(en->o_bg, "bell", "express");
edje_object_signal_emit(en->o_bg, "bell", PACKAGE_NAME);
if ((en->selected) || (bell))
edje_object_message_signal_process(en->o_bg);
sd->interp = 1.0;
if ((en->o_grid = evas_object_data_get(en->obj, "grid")))
{
/* TODO: callbacks add for bell, title, icon */
_selector_label_redo(en);
evas_object_event_callback_add(en->o_grid, EVAS_CALLBACK_DEL,
_selector_entry_grid_cb_del, en);
}
edje_object_part_text_set(en->o_bg, "label", _channel_name_get(chl));
/* TODO: callbacks add for bell, title, icon ?? */
evas_object_event_callback_add(en->obj, EVAS_CALLBACK_DEL,
_selector_entry_cb_del, en);
_cb_entry_del, en);
}
void
_selector_entry_selected_set(Evas_Object *obj, Evas_Object *entry, Eina_Bool keep)
_selector_channel_selected_set(Evas_Object *obj, Channel *chl, Eina_Bool keep)
{
Selector *sd;
Entry *en;
Eina_List *l;
Evas_Object *img;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
img = _channel_image_get(chl);
EINA_LIST_FOREACH(sd->entries, l, en)
{
if (en->obj == entry)
if (en->obj == img)
{
if ((sd->w > 0) && (sd->h > 0))
edje_object_signal_emit(en->o_bg, "selected", "express");
edje_object_signal_emit(en->o_bg, "selected", PACKAGE_NAME);
else
sd->pending = EINA_TRUE;
@ -753,12 +736,13 @@ _selector_entry_selected_set(Evas_Object *obj, Evas_Object *entry, Eina_Bool kee
en->was_selected = EINA_FALSE;
en->selected = EINA_TRUE;
}
else if (en->obj != entry)
else if (en->obj != img)
{
if (en->selected)
{
if ((sd->w > 0) && (sd->h > 0))
edje_object_signal_emit(en->o_bg, "unselected", "express");
edje_object_signal_emit(en->o_bg,
"unselected", PACKAGE_NAME);
else
{
en->was_selected = EINA_TRUE;
@ -772,7 +756,7 @@ _selector_entry_selected_set(Evas_Object *obj, Evas_Object *entry, Eina_Bool kee
}
sd->use_px = EINA_FALSE;
_selector_transit(obj, _ex_cfg->gui.zoom);
_cb_transit(obj, sd, _ex_cfg->gui.zoom);
}
void
@ -780,6 +764,7 @@ _selector_zoom_set(Evas_Object *obj, double zoom)
{
Selector *sd;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
sd->orig_zoom = zoom;
}
@ -789,9 +774,10 @@ _selector_zoom(Evas_Object *obj, double zoom)
{
Selector *sd;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
sd->zoom1 = zoom;
_selector_transit(obj, _ex_cfg->gui.zoom);
_cb_transit(obj, sd, _ex_cfg->gui.zoom);
}
void
@ -801,9 +787,10 @@ _selector_go(Evas_Object *obj)
Entry *en;
Eina_List *l;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
_selector_layout(obj);
_cb_layout(obj, sd);
evas_object_show(sd->o_clip);
EINA_LIST_FOREACH(sd->entries, l, en)
@ -821,6 +808,7 @@ _selector_exit(Evas_Object *obj)
{
Selector *sd;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
sd->exit_on_sel = EINA_TRUE;
}

12
src/bin/selector.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef _SELECTOR_H_
# define _SELECTOR_H_ 1
Evas_Object *_selector_create(Evas *evas);
void _selector_channel_add(Evas_Object *obj, Channel *chl, Eina_Bool selected);
void _selector_channel_selected_set(Evas_Object *obj, Channel *chl, Eina_Bool keep);
void _selector_zoom_set(Evas_Object *obj, double zoom);
void _selector_zoom(Evas_Object *obj, double zoom);
void _selector_go(Evas_Object *obj);
void _selector_exit(Evas_Object *obj);
#endif

62
src/bin/theme.c Normal file
View File

@ -0,0 +1,62 @@
#include "private.h"
#include "theme.h"
static void
_theme_cb_reload(void *data EINA_UNUSED, Evas_Object *obj, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
{
void (*func)(void *d);
void *func_data;
_theme_reload(obj);
func = evas_object_data_get(obj, "theme_reload_func");
func_data = evas_object_data_get(obj, "theme_reload_func_data");
if (func) func(func_data);
}
/* external functions */
const char *
_theme_default_get(void)
{
static char path[PATH_MAX];
if (path[0]) return path;
/* FIXME: make themes configurable */
snprintf(path, sizeof(path),
"%s/themes/default.edj", elm_app_data_dir_get());
return path;
}
void
_theme_reload(Evas_Object *obj)
{
const char *file, *group;
edje_object_file_get(obj, &file, &group);
edje_object_file_set(obj, file, group);
}
Eina_Bool
_theme_apply(Evas_Object *obj, const char *group)
{
/* check for valid object and group */
if ((!obj) || (!group)) return EINA_FALSE;
/* try to set the theme for this object */
if (edje_object_file_set(obj, _theme_default_get(), group))
return EINA_TRUE;
return EINA_FALSE;
}
void
_theme_reload_enable(Evas_Object *obj)
{
/* check for valid object */
if (!obj) return;
/* catch edje file change signal */
edje_object_signal_callback_add(obj, "edje,change,file", "edje",
_theme_cb_reload, NULL);
}

9
src/bin/theme.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _THEME_H_
# define _THEME_H_ 1
const char *_theme_default_get(void);
void _theme_reload(Evas_Object *obj);
Eina_Bool _theme_apply(Evas_Object *obj, const char *group);
void _theme_reload_enable(Evas_Object *obj);
#endif

View File

@ -1,65 +1,5 @@
#include "private.h"
/* local functions */
static void
_theme_cb_reload(void *data EINA_UNUSED, Evas_Object *obj, const char *emission EINA_UNUSED, const char *source EINA_UNUSED)
{
void (*func)(void *d);
void *func_data;
_theme_reload(obj);
func = evas_object_data_get(obj, "theme_reload_func");
func_data = evas_object_data_get(obj, "theme_reload_func_data");
if (func) func(func_data);
}
/* external functions */
const char *
_theme_default_get(void)
{
static char path[PATH_MAX];
if (path[0]) return path;
/* FIXME: make themes configurable */
snprintf(path, sizeof(path),
"%s/themes/default.edj", elm_app_data_dir_get());
return path;
}
void
_theme_reload(Evas_Object *obj)
{
const char *file, *group;
edje_object_file_get(obj, &file, &group);
edje_object_file_set(obj, file, group);
}
Eina_Bool
_theme_apply(Evas_Object *obj, const char *group)
{
/* check for valid object and group */
if ((!obj) || (!group)) return EINA_FALSE;
/* try to set the theme for this object */
if (edje_object_file_set(obj, _theme_default_get(), group))
return EINA_TRUE;
return EINA_FALSE;
}
void
_theme_reload_enable(Evas_Object *obj)
{
/* check for valid object */
if (!obj) return;
/* catch edje file change signal */
edje_object_signal_callback_add(obj, "edje,change,file", "edje",
_theme_cb_reload, NULL);
}
#include "utils.h"
const char *
_util_user_dir_get(void)

8
src/bin/utils.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _UTILS_H_
# define _UTILS_H_ 1
const char *_util_user_dir_get(void);
char *_util_user_name_get(void);
char *_util_user_fullname_get(void);
#endif

View File

@ -1,25 +1,192 @@
#include "private.h"
#include "window.h"
#include "config.h"
#include "theme.h"
#include "channel.h"
#include "selector.h"
#include "options.h"
struct _Window
{
Evas *evas;
Evas_Object *o_win;
Evas_Object *o_bg;
Evas_Object *o_conform;
Evas_Object *o_base;
Evas_Object *o_opts;
Evas_Object *o_sel;
Evas_Object *o_sel_bg;
Eina_List *channels;
Eina_Bool focused : 1;
};
/* local variables */
static Window *_win = NULL;
static Ecore_Job *_size_job = NULL;
/* local functions */
static void
_window_cb_delete_request(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
_cb_delete_request(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
elm_exit();
}
Evas_Object *
static void
_cb_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Window *win;
if (!(win = data)) return;
/* window object is already deleted at this point */
win->o_win = NULL;
/* cleanup window structure */
_window_destroy();
}
static void
_cb_size_job(void *data EINA_UNUSED)
{
Eina_List *l = NULL;
Channel *chl;
Evas_Coord mw = 0, mh = 0;
Evas_Coord sx = 0, sy = 0;
_size_job = NULL;
/* try to get the focused channel */
EINA_LIST_FOREACH(_win->channels, l, chl)
{
if (!_channel_focused_get(chl)) continue;
/* get minimum size of the channel */
_channel_size_min_get(chl, &mw, &mh);
/* get step size of the channel */
_channel_size_step_get(chl, &sx, &sy);
/* set main window base size */
elm_win_size_base_set(_win->o_win, (mw - sx), (mh - sy));
/* set main window step size */
elm_win_size_step_set(_win->o_win, sx, sy);
/* set min size on bg */
evas_object_size_hint_min_set(_win->o_bg, mw, mh);
if (!_channel_size_done_get(chl))
{
Evas_Coord rw, rh;
_channel_size_done_set(chl, EINA_TRUE);
/* get requested size of the channel */
_channel_size_request_get(chl, &rw, &rh);
/* resize window */
evas_object_resize(_win->o_win, rw, rh);
}
break;
}
}
static void
_cb_selector_selected(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
{
Channel *chl;
Eina_List *l;
EINA_LIST_FOREACH(_win->channels, l, chl)
{
if (event == _channel_image_get(chl))
{
/* focus this channel */
_window_channel_focus(chl);
/* swallow this channel */
_window_channel_swallow(chl);
/* destroy selector */
_window_selector_destroy();
break;
}
}
}
static void
_cb_selector_exit(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl;
Eina_List *l;
/* destroy selector */
_window_selector_destroy();
EINA_LIST_FOREACH(_win->channels, l, chl)
{
if (_channel_focused_get(chl))
{
/* focus this channel */
_window_channel_focus(chl);
/* swallow this channel */
_window_channel_swallow(chl);
break;
}
}
}
static void
_cb_selector_ending(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
edje_object_signal_emit(_win->o_sel_bg, "end", PACKAGE_NAME);
}
static void
_cb_focus_in(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl;
if (!_win->focused) elm_win_urgent_set(_win->o_win, EINA_FALSE);
_win->focused = EINA_TRUE;
elm_win_keyboard_mode_set(_win->o_win, ELM_WIN_KEYBOARD_TERMINAL);
if ((chl = _window_channel_focused_get()))
_channel_focus(chl);
}
static void
_cb_focus_out(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
Channel *chl;
_win->focused = EINA_FALSE;
elm_win_keyboard_mode_set(_win->o_win, ELM_WIN_KEYBOARD_OFF);
if ((chl = _window_channel_focused_get()))
_channel_unfocus(chl);
}
static Evas_Object *
_window_new(void)
{
Evas_Object *win, *icon;
char buff[PATH_MAX];
/* create new elm window */
win = elm_win_add(NULL, "express", ELM_WIN_BASIC);
win = elm_win_add(NULL, PACKAGE_NAME, ELM_WIN_BASIC);
elm_win_title_set(win, "Express");
elm_win_icon_name_set(win, "Express");
/* set function to call on a delete request */
evas_object_smart_callback_add(win, "delete,request",
_window_cb_delete_request, win);
_cb_delete_request, win);
/* create window icon */
icon = evas_object_image_add(evas_object_evas_get(win));
@ -32,3 +199,367 @@ _window_new(void)
return win;
}
/* external functions */
Eina_Bool
_window_create(void)
{
Channel *chl;
/* try to allocate space for new window */
if (!(_win = calloc(1, sizeof(Window)))) return EINA_FALSE;
/* create window object */
_win->o_win = _window_new();
evas_object_smart_callback_add(_win->o_win, "focus,in", _cb_focus_in, NULL);
evas_object_smart_callback_add(_win->o_win, "focus,out",
_cb_focus_out, NULL);
/* store the canvas for easy reuse */
_win->evas = evas_object_evas_get(_win->o_win);
/* add a callback when this window gets deleted */
evas_object_event_callback_add(_win->o_win,
EVAS_CALLBACK_DEL, _cb_del, _win);
/* add window background */
_win->o_bg = evas_object_rectangle_add(_win->evas);
WEIGHT_SET(_win->o_bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(_win->o_bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_color_set(_win->o_bg, 0, 0, 0, 255);
elm_win_resize_object_add(_win->o_win, _win->o_bg);
evas_object_show(_win->o_bg);
/* add a conformant here */
_win->o_conform = elm_conformant_add(_win->evas);
WEIGHT_SET(_win->o_conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(_win->o_conform, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_win_resize_object_add(_win->o_win, _win->o_conform);
evas_object_show(_win->o_conform);
/* add base object */
_win->o_base = edje_object_add(_win->evas);
_theme_apply(_win->o_base, "express/base");
WEIGHT_SET(_win->o_base, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
FILL_SET(_win->o_base, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_content_set(_win->o_conform, _win->o_base);
evas_object_show(_win->o_base);
/* try to create a default channel */
if ((chl = _channel_create(_win->evas, "Default")))
{
/* add channel to list */
_win->channels = eina_list_append(_win->channels, chl);
/* force channel size update */
_channel_size_update(chl);
/* swallow channel background */
_window_channel_swallow(chl);
/* focus this channel */
_window_channel_focus(chl);
/* update channel count */
_window_channel_count_update(chl);
}
/* FIXME: Remove. Only for testing */
if ((chl = _channel_create(_win->evas, "Test")))
{
_win->channels = eina_list_append(_win->channels, chl);
_channel_size_update(chl);
_window_channel_count_update(chl);
}
/* update window transparency from config */
_window_update();
/* show the window */
evas_object_show(_win->o_win);
return EINA_TRUE;
}
Eina_Bool
_window_destroy(void)
{
Channel *chl;
if (!_win) return EINA_TRUE;
/* delete any pending size job */
if (_size_job) ecore_job_del(_size_job);
_size_job = NULL;
/* delete channels */
EINA_LIST_FREE(_win->channels, chl)
_channel_destroy(chl);
/* delete the base */
if (_win->o_base) evas_object_del(_win->o_base);
/* delete conformant */
if (_win->o_conform) evas_object_del(_win->o_conform);
/* delete the background */
if (_win->o_bg) evas_object_del(_win->o_bg);
/* delete window object */
if (_win->o_win)
{
evas_object_event_callback_del_full(_win->o_win,
EVAS_CALLBACK_DEL, _cb_del, _win);
evas_object_del(_win->o_win);
}
/* free allocated window structure */
free(_win);
_win = NULL;
return EINA_TRUE;
}
void
_window_update(void)
{
Eina_List *l = NULL;
Channel *chl;
/* set window alpha based on config */
elm_win_alpha_set(_win->o_win, _ex_cfg->gui.translucent);
/* show/hide window background based on config */
if (!_ex_cfg->gui.translucent) evas_object_show(_win->o_bg);
else evas_object_hide(_win->o_bg);
/* loop window channels and update */
EINA_LIST_FOREACH(_win->channels, l, chl)
_channel_update(chl);
_window_size_update();
}
void
_window_size_update(void)
{
/* delete previous size job */
if (_size_job) ecore_job_del(_size_job);
/* add a new job to update window size */
_size_job = ecore_job_add(_cb_size_job, NULL);
}
void
_window_channel_swallow(Channel *chl)
{
Evas_Object *bg;
bg = _channel_background_get(chl);
edje_object_part_swallow(_win->o_base, "base.content", bg);
evas_object_show(bg);
}
void
_window_channel_unswallow(Channel *chl)
{
Evas_Object *bg;
bg = _channel_background_get(chl);
edje_object_part_unswallow(_win->o_base, bg);
}
void
_window_channel_focus(Channel *chl)
{
Eina_List *l = NULL;
Channel *pchl;
char buff[PATH_MAX];
/* unfocus any previously focused channels */
EINA_LIST_FOREACH(_win->channels, l, pchl)
{
if (pchl != chl)
{
if (_channel_focused_get(pchl))
{
_channel_focused_set(pchl, EINA_FALSE);
_channel_unfocus(pchl);
}
}
}
/* focus this channel */
_channel_focused_set(chl, EINA_TRUE);
_channel_focus(chl);
/* set window title */
snprintf(buff, sizeof(buff), "%s - %s", elm_app_name_get(),
_channel_name_get(chl));
elm_win_title_set(_win->o_win, buff);
}
Channel *
_window_channel_focused_get(void)
{
Channel *chl;
Eina_List *l;
EINA_LIST_FOREACH(_win->channels, l, chl)
if (_channel_focused_get(chl)) return chl;
return NULL;
}
Channel *
_window_channel_previous_get(Channel *chl)
{
Eina_List *l;
l = eina_list_data_find_list(_win->channels, chl);
if ((l) && (l->prev)) return l->prev->data;
return NULL;
}
Channel *
_window_channel_next_get(Channel *chl)
{
Eina_List *l;
l = eina_list_data_find_list(_win->channels, chl);
if ((l) && (l->next)) return l->next->data;
return NULL;
}
void
_window_channel_switch(Channel *chl, Channel *new_chl)
{
Channel *pchl;
Eina_List *l = NULL;
double z = 1.0;
int count = 0;
/* delete old selector objects */
if (_win->o_sel_bg) evas_object_del(_win->o_sel_bg);
if (_win->o_sel) evas_object_del(_win->o_sel);
/* hide channel background */
_channel_background_hide(chl);
/* create selector background */
_win->o_sel_bg = edje_object_add(_win->evas);
_theme_apply(_win->o_sel_bg, "express/selector/background");
if (_ex_cfg->gui.translucent)
edje_object_signal_emit(_win->o_sel_bg, "translucent,on", PACKAGE_NAME);
else
edje_object_signal_emit(_win->o_sel_bg, "translucent,off", PACKAGE_NAME);
edje_object_signal_emit(_win->o_sel_bg, "begin", PACKAGE_NAME);
/* create selector */
if (!(_win->o_sel = _selector_create(_win->evas)))
{
evas_object_del(_win->o_sel_bg);
_win->o_sel_bg = NULL;
return;
}
/* loop channels, creating an img to represent each one */
EINA_LIST_FOREACH(_win->channels, l, pchl)
{
_channel_base_unswallow(pchl);
/* create an image to represent this channel */
_channel_image_create(pchl);
/* add this channel to the selector */
_selector_channel_add(_win->o_sel, pchl, (pchl == chl));
}
edje_object_part_swallow(_win->o_sel_bg, "content", _win->o_sel);
evas_object_show(_win->o_sel);
edje_object_part_swallow(_win->o_base, "base.content", _win->o_sel_bg);
evas_object_show(_win->o_sel_bg);
evas_object_smart_callback_add(_win->o_sel, "selected",
_cb_selector_selected, NULL);
evas_object_smart_callback_add(_win->o_sel, "exit",
_cb_selector_exit, NULL);
evas_object_smart_callback_add(_win->o_sel, "ending",
_cb_selector_ending, NULL);
_selector_go(_win->o_sel);
/* calculate zoom based on number of channels */
count = eina_list_count(_win->channels);
if (count >= 1)
z = (1.0 / (sqrt(count)) * 0.8);
if (z > 1.0) z = 1.0;
/* set selector zoom */
_selector_zoom_set(_win->o_sel, z);
_selector_zoom(_win->o_sel, z);
if (chl != new_chl)
{
_selector_channel_selected_set(_win->o_sel, new_chl, EINA_TRUE);
_selector_exit(_win->o_sel);
}
elm_object_focus_set(_win->o_sel, EINA_TRUE);
}
void
_window_channel_count_update(Channel *chl)
{
Eina_List *l = NULL;
Channel *pchl;
int missed = 0, cnt = 0, chl_cnt = 0, n = 0;
n = eina_list_count(_win->channels);
if (n <= 1) return;
EINA_LIST_FOREACH(_win->channels, l, pchl)
{
if (_channel_missed_get(pchl)) missed++;
cnt++;
if (pchl == chl) chl_cnt = cnt;
}
EINA_LIST_FOREACH(_win->channels, l, pchl)
{
_channel_spacer_create(pchl);
_channel_count_set(pchl, chl_cnt, n);
_channel_missed_count_set(pchl, missed);
}
}
void
_window_selector_destroy(void)
{
Channel *chl;
Eina_List *l;
EINA_LIST_FOREACH(_win->channels, l, chl)
{
if (_channel_unswallowed_get(chl))
{
_channel_image_unset(chl);
_channel_unswallowed_set(chl, EINA_FALSE);
}
}
evas_object_del(_win->o_sel_bg);
_win->o_sel_bg = NULL;
evas_object_del(_win->o_sel);
_win->o_sel = NULL;
}
void
_window_options_toggle(Evas_Object *grid, void (*cb_done)(void *data), void *data)
{
_options_toggle(_win->o_win, _win->o_base, grid, cb_done, data);
}

23
src/bin/window.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _WINDOW_H_
# define _WINDOW_H_ 1
Eina_Bool _window_create(void);
Eina_Bool _window_destroy(void);
void _window_update(void);
void _window_size_update(void);
void _window_channel_swallow(Channel *chl);
void _window_channel_unswallow(Channel *chl);
void _window_channel_focus(Channel *chl);
Channel *_window_channel_focused_get(void);
Channel *_window_channel_previous_get(Channel *chl);
Channel *_window_channel_next_get(Channel *chl);
void _window_channel_switch(Channel *chl, Channel *new_chl);
void _window_channel_count_update(Channel *chl);
void _window_selector_destroy(void);
void _window_options_toggle(Evas_Object *grid, void (*cb_done)(void *data), void *data);
#endif

View File

@ -22,18 +22,149 @@
/* extern "C" { */
/* # endif */
# define EXPRESS_BUFF_SIZE 2050
typedef struct _Express_Network Express_Network;
typedef struct _Express_Server Express_Server;
typedef struct _Express_Callbacks Express_Callbacks;
typedef void (*Express_Event_Callback)(Express_Network *net, const char *event, const char *source, const char **params, unsigned int count, void *data);
typedef void (*Express_Event_Numeric_Callback)(Express_Network *net, unsigned int event, const char *source, const char **params, unsigned int count, void *data);
/* NB: See http://irchelp.org/irchelp/rfc/chapter4.html for parameters */
typedef struct _Express_Callbacks
{
/* source: server which was connected
* params: none */
Express_Event_Callback connect;
Express_Event_Callback motd;
/* source: person who changed nick
* params[0]: new nick */
Express_Event_Callback nick;
/* source: who quit
* params[0]: (optional) reason */
Express_Event_Callback quit;
/* source: person who joined
* params[0]: channel they joined */
Express_Event_Callback join;
/* source: person who left
* params[0]: (optional) reason */
Express_Event_Callback part;
/* source: person who changed channel mode
* params[0]: channel name
* params[1]: changed mode
* params[2]: (optional) mode argument or user who got ops */
Express_Event_Callback mode;
/* source: person who changed user mode
* params[0]: the changed mode */
Express_Event_Callback user_mode;
/* source: the person who changed the topic
* params[0]: channel name
* params[1]: new topic (optional) */
Express_Event_Callback topic;
/* source: the person who kicked your arse
* params[0]: channel name
* params[1]: you nick (optional)
* params[2]: kick reason */
Express_Event_Callback kick;
/* source: person who sent the message
* params[0]: channel name
* params[1]: message (optional) */
Express_Event_Callback channel_msg;
/* source: person who sent the message
* params[0]: your nick
* params[1]: message (optional) */
Express_Event_Callback priv_msg;
/* source: who generated the message
* params[0]: target nick name
* params[1]: message (optional) */
Express_Event_Callback notice;
/* source: who generated the message
* params[0]: channel name
* params[1]: message (optional) */
Express_Event_Callback channel_notice;
/* source: who did the inviting
* params[0]: your nick
* params[1]: channel name you were invited to */
Express_Event_Callback invite;
/* source: who generated the message
* params[0]: ctcp message */
Express_Event_Callback ctcp_request;
/* source: who generated the message
* params[0]: ctcp message */
Express_Event_Callback ctcp_reply;
/* source: who generated the message
* params[0]: ctcp message */
Express_Event_Callback ctcp_action;
/* TODO */
Express_Event_Callback unknown;
Express_Event_Numeric_Callback numeric;
Express_Event_Callback dcc_chat_request;
Express_Event_Callback dcc_send_request;
void *data;
} Express_Callbacks;
EXAPI int express_init(void);
EXAPI int express_shutdown(void);
EXAPI Express_Server *express_server_find(const char *name);
EXAPI Express_Server *express_server_create(const char *name, const char *nick, const char *user, const char *pass, int port, Eina_Bool use_ssl, Eina_Bool bypass_proxy);
EXAPI void express_server_destroy(Express_Server *server);
EXAPI void express_server_connect(Express_Server *server);
EXAPI void express_server_disconnect(Express_Server *server);
EXAPI Eina_Bool express_server_connecting_get(Express_Server *server);
EXAPI Eina_Bool express_server_connected_get(Express_Server *server);
EXAPI Express_Network *express_network_find(const char *name);
EXAPI Express_Network *express_network_create(Express_Callbacks *callbacks, const char *name);
EXAPI void express_network_destroy(Express_Network *net);
EXAPI void express_network_name_set(Express_Network *net, const char *name);
EXAPI const char *express_network_name_get(Express_Network *net);
EXAPI void express_network_username_set(Express_Network *net, const char *name);
EXAPI const char *express_network_username_get(Express_Network *net);
EXAPI void express_network_username_send(Express_Network *net);
EXAPI void express_network_nickname_set(Express_Network *net, const char *name);
EXAPI const char *express_network_nickname_get(Express_Network *net);
EXAPI void express_network_nickname_send(Express_Network *net);
EXAPI void express_network_nick_password_set(Express_Network *net, const char *passwd);
EXAPI void express_network_nick_password_send(Express_Network *net);
EXAPI void express_network_nick_strip(const char *buff, char *nick, size_t size);
EXAPI void express_network_server_password_set(Express_Network *net, const char *passwd);
EXAPI void express_network_server_password_send(Express_Network *net);
EXAPI void express_network_autoconnect_set(Express_Network *net, Eina_Bool autoconnect);
EXAPI Eina_Bool express_network_autoconnect_get(Express_Network *net);
EXAPI void express_network_bypass_proxy_set(Express_Network *net, Eina_Bool bypass);
EXAPI Eina_Bool express_network_bypass_proxy_get(Express_Network *net);
EXAPI void express_network_use_ssl_set(Express_Network *net, Eina_Bool use_ssl);
EXAPI Eina_Bool express_network_use_ssl_get(Express_Network *net);
EXAPI Eina_Bool express_network_connecting_get(Express_Network *net);
EXAPI Eina_Bool express_network_connected_get(Express_Network *net);
EXAPI void express_network_connect(Express_Network *net);
EXAPI void express_network_disconnect(Express_Network *net);
EXAPI Express_Server *express_network_server_find(Express_Network *net, const char *server_name);
EXAPI Express_Server *express_network_server_add(Express_Network *net, const char *server_name, int port);
EXAPI void express_network_server_del(Express_Network *net, const char *server_name);
EXAPI void express_network_data_send(Express_Network *net, const char *data, int len);
/* # ifdef __cplusplus */
/* } */

View File

@ -15,7 +15,7 @@ pkg_LTLIBRARIES = libexpress.la
libexpress_la_SOURCES = \
private.h \
server.c \
network.c \
main.c
libexpress_la_LDFLAGS = -version-info 0:1:0 @EXP_LDFLAGS@

View File

@ -2,63 +2,59 @@
/* local variables */
static int_least8_t _init_count = 0;
static int_least8_t _events[15];
/* external variables */
int _exp_log_dom = -1;
Eina_Hash *_servers = NULL;
Eina_Hash *_networks = NULL;
static void
_events_init(void)
_cb_networks_free(void *data)
{
uint_least8_t i;
Express_Network *net;
if (_events[0] != 0) return;
if (!(net = data)) return;
for (i = 0; i < sizeof(_events); i++)
_events[i] = ecore_event_type_new();
}
if (net->servers) eina_hash_free(net->servers);
net->servers = NULL;
static void
_events_shutdown(void)
{
uint_least8_t i;
if (net->name) eina_stringshare_del(net->name);
if (net->user) eina_stringshare_del(net->user);
if (net->nick) eina_stringshare_del(net->nick);
if (net->nick_pass) eina_stringshare_del(net->nick_pass);
if (net->server_pass) eina_stringshare_del(net->server_pass);
for (i = 0; i < sizeof(_events); i++)
_events[i] = 0;
}
static void
_cb_servers_free(void *data)
{
Express_Server *srv;
if (!(srv = data)) return;
if (srv->connected) express_server_disconnect(srv);
if (srv->name) eina_stringshare_del(srv->name);
if (srv->nick) eina_stringshare_del(srv->nick);
if (srv->user) eina_stringshare_del(srv->user);
if (srv->pass) eina_stringshare_del(srv->pass);
free(srv);
free(net);
}
static Eina_Bool
_cb_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Con_Event_Server_Data *ev;
Express_Server *srv;
Ecore_Con_Event_Server_Add *ev;
Express_Network *net;
const char *server;
ev = event;
srv = ecore_con_server_data_get(ev->server);
srv->connecting = EINA_FALSE;
srv->connected = EINA_TRUE;
if (!(net = ecore_con_server_data_get(ev->server)))
return ECORE_CALLBACK_RENEW;
_server_pass_send(srv);
_server_user_send(srv);
_server_nick_send(srv);
server = ecore_con_server_name_get(ev->server);
DBG("Server Added %s %s", net->name, server);
net->connecting = EINA_FALSE;
net->connected = ecore_con_server_connected_get(ev->server);
if (net->connected)
{
if (net->callbacks.connect)
(*net->callbacks.connect)(net, "CONNECT", server, NULL, 0,
net->callbacks.data);
/* NB: RFC says send Pass, Nick, User to register */
/* express_network_server_password_send(net); */
/* express_network_nick_password_send(net); */
/* express_network_nickname_send(net); */
/* express_network_username_send(net); */
}
return ECORE_CALLBACK_RENEW;
}
@ -66,33 +62,110 @@ _cb_server_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
static Eina_Bool
_cb_server_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Con_Event_Server_Data *ev;
Express_Server *srv;
Ecore_Con_Event_Server_Del *ev;
Express_Network *net;
ev = event;
srv = ecore_con_server_data_get(ev->server);
srv->connecting = EINA_FALSE;
srv->connected = EINA_FALSE;
if (!(net = ecore_con_server_data_get(ev->server)))
return ECORE_CALLBACK_RENEW;
DBG("Server Del Message: %s %s",
net->name, ecore_con_server_name_get(net->conn));
net->connected = EINA_FALSE;
if ((net->connecting) && (net->autoconnect))
{
Express_Server *srv;
const char *server_name;
/* get name of failed server */
server_name = ecore_con_server_name_get(ev->server);
DBG("Connection to %s Failed", server_name);
/* delete existing connection */
if (net->conn) ecore_con_server_del(net->conn);
net->conn = NULL;
/* find this server in the network list */
if ((srv = express_network_server_find(net, server_name)))
srv->skip = EINA_TRUE;
/* try the next server
* NB: This function will iterate existing servers and ignore
* any with the 'skip' flag set */
express_network_connect(net);
}
return ECORE_CALLBACK_RENEW;
}
static int
_find_crlf(const char *data, const int len)
{
int o = 0;
for (; o < len; o++)
{
if ((data[o] == 0x0D) && (o < len - 1) && (data[o + 1] == 0x0A))
return o;
if (data[o] == 0x0A) return o;
}
return 0;
}
static int
_find_crlf_offset(const char *data, int offset, const int len)
{
for (; offset < len; offset++)
{
if ((data[offset] != 0x0D) && (data[offset] != 0x0A))
break;
}
return offset;
}
static Eina_Bool
_cb_server_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
Ecore_Con_Event_Server_Data *ev;
Express_Server *srv;
Express_Network *net;
int offset = 0;
char *msg;
// max 512 len per line (510 without \r\n)
ev = event;
srv = ecore_con_server_data_get(ev->server);
if (ev->size <= 0) return ECORE_CALLBACK_RENEW;
if (!(net = ecore_con_server_data_get(ev->server)))
return ECORE_CALLBACK_RENEW;
if (!net->connected) return ECORE_CALLBACK_RENEW;
DBG("Server Data Message: %s %s %d",
net->name, ecore_con_server_name_get(net->conn), ev->size);
DBG("%s", (char *)ev->data);
msg = calloc((ev->size + 1), sizeof(char));
strncpy(msg, ev->data, ev->size);
DBG("Server %s Data", srv->name);
DBG("\t%s", msg);
net->offset = ev->size;
// net->offset += ev->size;
while ((offset = _find_crlf(msg, net->offset)) > 0)
{
_express_network_data_process(net, msg, offset);
offset = _find_crlf_offset(msg, offset, net->offset);
if ((net->offset - offset) > 0)
memmove(msg, msg + offset, net->offset - offset);
net->offset -= offset;
}
net->offset = 0;
free(msg);
return ECORE_CALLBACK_RENEW;
@ -126,13 +199,14 @@ express_init(void)
goto conn_err;
}
_events_init();
_networks = eina_hash_string_small_new(_cb_networks_free);
_servers = eina_hash_string_superfast_new(_cb_servers_free);
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _cb_server_add, NULL);
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _cb_server_del, NULL);
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _cb_server_data, NULL);
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD,
_cb_server_add, NULL);
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL,
_cb_server_del, NULL);
ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA,
_cb_server_data, NULL);
return _init_count;
@ -151,10 +225,8 @@ express_shutdown(void)
{
if (--_init_count != 0) return _init_count;
if (_servers) eina_hash_free(_servers);
_servers = NULL;
_events_shutdown();
if (_networks) eina_hash_free(_networks);
_networks = NULL;
ecore_con_shutdown();

639
src/lib/network.c Normal file
View File

@ -0,0 +1,639 @@
#include "private.h"
#include <ctype.h>
#include <unistd.h>
static void
_cb_server_free(void *data)
{
Express_Server *srv;
if (!(srv = data)) return;
if (srv->name) eina_stringshare_del(srv->name);
free(srv);
}
void
_express_network_data_process(Express_Network *net, const char *data, int offset)
{
char buff[1024], *ptr, *str, *end;
const char *params[11]; // RFC 1459 says Max 15 params
const char *prefix = 0, *cmd = 0;
int index = 0, code = 0;
if ((size_t)offset > sizeof(buff))
{
ERR("Len greater than buffer: %d %d",
(int)(size_t)offset, (int)sizeof(buff));
return;
}
end = (buff + offset);
memcpy(buff, data, offset);
buff[offset] = '\0';
/* DBG("\tProcessing Message: %d %s", offset, buff); */
memset((char *)params, 0, sizeof(params));
ptr = buff;
/* strip prefix */
if (buff[0] == ':')
{
while ((*ptr) && (*ptr != ' '))
ptr++;
*ptr++ = '\0';
/* skip leading colon */
prefix = buff + 1;
/* strip nick from message */
for (str = (buff + 1); *str; str++)
{
if ((*str == '@') || (*str == '!'))
{
*str = '\0';
break;
}
}
}
else
{
/* hack for cases where ecore_con is stripping off the
* beginning of our message and passing us only partial
* prefix messages.
*
* For this case, we just strip the remaining prefix up until the
* numeric IRC code */
while ((*ptr) && (!isdigit(*ptr)))
ptr++;
}
/* parse any commands */
if ((isdigit(ptr[0]) && (isdigit(ptr[1])) && (isdigit(ptr[2]))))
{
ptr[3] = '\0';
code = atoi(ptr);
ptr += 4;
}
else
{
str = ptr;
while ((*ptr) && (*ptr != ' '))
ptr++;
*ptr++ = '\0';
cmd = str;
}
/* parse message params (RFC 1459 says Max 15 params) */
while ((*ptr) && (index < 10))
{
if (*ptr == ':')
{
params[index++] = ptr + 1;
break;
}
for (str = ptr; ((*ptr) && (*ptr != ' ')); ptr++) ;
params[index++] = str;
if (!*ptr) break;
*ptr++ = '\0';
}
/* deal with ping */
if ((cmd) && (!strncmp(cmd, "PING", end - cmd)) && (params[0]))
{
char data[512];
int len = 0;
len = snprintf(data, sizeof(data), "PONG %s", params[0]);
express_network_data_send(net, data, len);
return;
}
if (code)
{
if ((code == 4) || (code == 5) ||
((code >= 252) && (code <= 255)) ||
((code == 741) || (code == 742) || (code == 266))) return;
DBG("\tGot Code %d", code);
/* if ((code == 1) || (code == 376) || (code == 422)) */
{
if (net->callbacks.motd)
(*net->callbacks.motd)(net, "MOTD", prefix, params, index,
net->callbacks.data);
}
if (net->callbacks.numeric)
(*net->callbacks.numeric)(net, code, prefix, params, index,
net->callbacks.data);
}
else
{
/* handle various commands */
if (!strncmp(cmd, "NICK", end - cmd))
{
char nick[256];
express_network_nick_strip(prefix, nick, sizeof(nick));
if ((!strncmp(nick, net->nick, strlen(net->nick))) &&
(index > 0))
{
eina_stringshare_replace(&net->nick, params[0]);
}
if (net->callbacks.nick)
(*net->callbacks.nick)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else if (!strncmp(cmd, "QUIT", end - cmd))
{
if (net->callbacks.quit)
(*net->callbacks.quit)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else if (!strncmp(cmd, "JOIN", end - cmd))
{
if (net->callbacks.join)
(*net->callbacks.join)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else if (!strncmp(cmd, "PART", end - cmd))
{
if (net->callbacks.part)
(*net->callbacks.part)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else if (!strncmp(cmd, "MODE", end - cmd))
{
if ((index > 0) &&
(!strncmp(params[0], net->nick, strlen(net->nick))))
{
params[0] = params[1];
index = 1;
if (net->callbacks.user_mode)
(*net->callbacks.user_mode)(net, cmd, prefix,
params, index,
net->callbacks.data);
}
else
{
if (net->callbacks.mode)
(*net->callbacks.mode)(net, cmd, prefix, params, index,
net->callbacks.data);
}
}
else if (!strncmp(cmd, "TOPIC", end - cmd))
{
if (net->callbacks.topic)
(*net->callbacks.topic)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else if (!strncmp(cmd, "KICK", end - cmd))
{
if (net->callbacks.kick)
(*net->callbacks.kick)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else if (!strncmp(cmd, "PRIVMSG", end - cmd))
{
if (index > 1)
{
size_t len;
len = strlen(params[1]);
if ((params[1][0] == 0x01) && (params[1][1] == 0x01))
{
char ctcp[128];
len -= 2;
if (len > (sizeof(ctcp) - 1)) len = (sizeof(ctcp) - 1);
memcpy(ctcp, params[1] + 1, len);
ctcp[len] = '\0';
if (!strncasecmp(ctcp, "DCC", len))
{
/* TODO: Dcc Request */
DBG("\tDeal with dcc request");
}
else if ((!strncasecmp(ctcp, "ACTION", len)) &&
(net->callbacks.ctcp_action))
{
params[1] = ctcp + 7;
index = 2;
(*net->callbacks.ctcp_action)
(net, "ACTION", prefix, params, index,
net->callbacks.data);
}
else if (net->callbacks.ctcp_request)
{
params[0] = ctcp;
index = 1;
(*net->callbacks.ctcp_request)
(net, "CTCP", prefix, params, index,
net->callbacks.data);
}
}
else if (!strncasecmp(params[0],
net->nick, strlen(net->nick)))
{
if (net->callbacks.priv_msg)
(*net->callbacks.priv_msg)(net, "PRIVMSG", prefix,
params, index,
net->callbacks.data);
}
else
{
if (net->callbacks.channel_msg)
(*net->callbacks.channel_msg)(net, "CHANNEL",
prefix, params, index,
net->callbacks.data);
}
}
}
else if (!strncmp(cmd, "NOTICE", end - cmd))
{
size_t len;
len = strlen(params[1]);
if ((index > 1) &&
(params[1][0] == 0x01) && (params[1][len - 1] == 0x01))
{
char ctcp[512];
len -= 2;
if (len > (sizeof(ctcp) - 1)) len = (sizeof(ctcp) - 1);
DBG("\tCTCP Message");
memcpy(ctcp, params[1] + 1, len);
ctcp[len] = '\0';
params[0] = ctcp;
index = 1;
if (net->callbacks.ctcp_reply)
(*net->callbacks.ctcp_reply)(net, "CTCP", prefix, params,
index, net->callbacks.data);
}
else if (!strncasecmp(params[0], net->nick, strlen(net->nick)))
{
if (net->callbacks.notice)
(*net->callbacks.notice)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else
{
if (net->callbacks.channel_notice)
(*net->callbacks.channel_notice)(net, cmd, prefix, params,
index,
net->callbacks.data);
}
}
else if (!strncmp(cmd, "INVITE", end - cmd))
{
if (net->callbacks.invite)
(*net->callbacks.invite)(net, cmd, prefix, params, index,
net->callbacks.data);
}
else if (!strncmp(cmd, "KILL", end - cmd))
{
/* ignored */
DBG("\tKill Message");
}
else
{
if (net->callbacks.unknown)
(*net->callbacks.unknown)(net, cmd, prefix, params, index,
net->callbacks.data);
}
}
}
EXAPI Express_Network *
express_network_find(const char *name)
{
if (!name) return NULL;
return eina_hash_find(_networks, name);
}
EXAPI Express_Network *
express_network_create(Express_Callbacks *callbacks, const char *name)
{
Express_Network *net;
if (!name) return NULL;
/* try to allocate space for network structure */
if (!(net = malloc(sizeof(Express_Network)))) return NULL;
memset(net, 0, sizeof(Express_Network));
/* set callbacks */
memcpy(&net->callbacks, callbacks, sizeof(Express_Callbacks));
net->connecting = EINA_FALSE;
net->connected = EINA_FALSE;
net->name = eina_stringshare_add(name);
/* create server hash */
net->servers = eina_hash_string_small_new(_cb_server_free);
/* if (!net->callbacks.ctcp_request) */
/* { */
/* DBG("TODO: Setup default ctcp request callback"); */
/* } */
/* add this network to the hash */
eina_hash_direct_add(_networks, net->name, net);
return net;
}
EXAPI void
express_network_destroy(Express_Network *net)
{
if (!net) return;
eina_hash_del_by_key(_networks, net->name);
}
EXAPI void
express_network_name_set(Express_Network *net, const char *name)
{
if (!net) return;
eina_stringshare_replace(&net->name, name);
}
EXAPI const char *
express_network_name_get(Express_Network *net)
{
if (!net) return NULL;
return net->name;
}
EXAPI void
express_network_username_set(Express_Network *net, const char *name)
{
if (!net) return;
eina_stringshare_replace(&net->user, name);
}
EXAPI const char *
express_network_username_get(Express_Network *net)
{
if (!net) return NULL;
return net->user;
}
EXAPI void
express_network_username_send(Express_Network *net)
{
char data[512], host[64];
int len = 0;
if ((!net) || (!net->conn)) return;
if (gethostname(host, sizeof(host)) < 0)
strcpy(host, "unknown");
len = snprintf(data, sizeof(data), "USER %s %s %s :%s\r\n",
net->nick ? net->nick : "express_user", host, host,
net->user ? net->user : "nobody");
express_network_data_send(net, data, len);
}
EXAPI void
express_network_nickname_set(Express_Network *net, const char *name)
{
if (!net) return;
eina_stringshare_replace(&net->nick, name);
}
EXAPI const char *
express_network_nickname_get(Express_Network *net)
{
if (!net) return NULL;
return net->nick;
}
EXAPI void
express_network_nickname_send(Express_Network *net)
{
char data[512];
int len = 0;
if ((!net) || (!net->conn) || (!net->nick)) return;
len = snprintf(data, sizeof(data), "NICK %s\r\n", net->nick);
express_network_data_send(net, data, len);
}
EXAPI void
express_network_nick_password_set(Express_Network *net, const char *passwd)
{
if (!net) return;
eina_stringshare_replace(&net->nick_pass, passwd);
}
EXAPI void
express_network_nick_password_send(Express_Network *net)
{
char data[512];
int len = 0;
if ((!net) || (!net->conn) || (!net->nick)) return;
len = snprintf(data, sizeof(data), "PASS %s\r\n", net->nick_pass);
express_network_data_send(net, data, len);
}
EXAPI void
express_network_nick_strip(const char *buff, char *nick, size_t size)
{
unsigned int len;
char *p;
if (!buff) return;
p = strstr(buff, "!");
if (p) len = (p - buff);
else len = strlen(buff);
if (len > (size - 1)) len = (size - 1);
memcpy(nick, buff, len);
nick[len] = '\0';
}
EXAPI void
express_network_server_password_set(Express_Network *net, const char *passwd)
{
if (!net) return;
eina_stringshare_replace(&net->server_pass, passwd);
}
EXAPI void
express_network_server_password_send(Express_Network *net)
{
char data[512];
int len = 0;
if ((!net) || (!net->conn) || (!net->server_pass)) return;
len = snprintf(data, sizeof(data), "PASS %s\r\n", net->server_pass);
express_network_data_send(net, data, len);
}
EXAPI void
express_network_autoconnect_set(Express_Network *net, Eina_Bool autoconnect)
{
if (!net) return;
net->autoconnect = autoconnect;
}
EXAPI Eina_Bool
express_network_autoconnect_get(Express_Network *net)
{
if (!net) return EINA_FALSE;
return net->autoconnect;
}
EXAPI void
express_network_bypass_proxy_set(Express_Network *net, Eina_Bool bypass)
{
if (!net) return;
net->bypass_proxy = bypass;
}
EXAPI Eina_Bool
express_network_bypass_proxy_get(Express_Network *net)
{
if (!net) return EINA_FALSE;
return net->bypass_proxy;
}
EXAPI void
express_network_use_ssl_set(Express_Network *net, Eina_Bool use_ssl)
{
if (!net) return;
net->use_ssl = use_ssl;
}
EXAPI Eina_Bool
express_network_use_ssl_get(Express_Network *net)
{
if (!net) return EINA_FALSE;
return net->use_ssl;
}
EXAPI Eina_Bool
express_network_connecting_get(Express_Network *net)
{
if (!net) return EINA_FALSE;
return net->connecting;
}
EXAPI Eina_Bool
express_network_connected_get(Express_Network *net)
{
if (!net) return EINA_FALSE;
return net->connected;
}
EXAPI void
express_network_connect(Express_Network *net)
{
Eina_Iterator *iter;
Express_Server *srv;
int flags = 0;
if (!net) return;
/* if we are already connected, get out */
if ((net->conn) && (ecore_con_server_connected_get(net->conn))) return;
/* set connection flags */
flags = ECORE_CON_REMOTE_TCP | ECORE_CON_REMOTE_NODELAY;
if (net->use_ssl) flags |= ECORE_CON_USE_MIXED;
if (net->bypass_proxy) flags |= ECORE_CON_NO_PROXY;
net->connecting = EINA_TRUE;
net->connected = EINA_FALSE;
iter = eina_hash_iterator_data_new(net->servers);
EINA_ITERATOR_FOREACH(iter, srv)
{
if (srv->skip) continue;
net->conn = ecore_con_server_connect(flags, srv->name, srv->port, net);
if (net->conn)
{
express_network_server_password_send(net);
express_network_nickname_send(net);
express_network_username_send(net);
break;
}
}
eina_iterator_free(iter);
}
EXAPI void
express_network_disconnect(Express_Network *net)
{
if (!net) return;
if (ecore_con_server_connected_get(net->conn))
{
char buff[512];
int len = 0;
len = snprintf(buff, sizeof(buff), "QUIT\r\n");
express_network_data_send(net, buff, len);
ecore_con_server_del(net->conn);
net->conn = NULL;
}
net->connected = EINA_FALSE;
net->connecting = EINA_FALSE;
}
EXAPI Express_Server *
express_network_server_find(Express_Network *net, const char *server_name)
{
if ((!net) || (!server_name)) return NULL;
return eina_hash_find(net->servers, server_name);
}
EXAPI Express_Server *
express_network_server_add(Express_Network *net, const char *server_name, int port)
{
Express_Server *srv;
if ((!net) || (!server_name)) return NULL;
/* try to allocate space for server structure */
if (!(srv = calloc(1, sizeof(Express_Server)))) return NULL;
srv->name = eina_stringshare_add(server_name);
srv->port = port;
srv->skip = EINA_FALSE;
/* add this server to the hash */
eina_hash_direct_add(net->servers, srv->name, srv);
return srv;
}
EXAPI void
express_network_server_del(Express_Network *net, const char *server_name)
{
if (!net) return;
eina_hash_del_by_key(net->servers, server_name);
}
EXAPI void
express_network_data_send(Express_Network *net, const char *data, int len)
{
if ((!net) || (!net->conn) || (!data)) return;
ecore_con_server_send(net->conn, data, len);
ecore_con_server_flush(net->conn);
}

View File

@ -49,23 +49,39 @@ extern int _exp_log_dom;
# endif
# define CRI(...) EINA_LOG_DOM_CRIT(_exp_log_dom, __VA_ARGS__)
struct _Express_Server
struct _Express_Network
{
const char *name, *nick;
const char *user, *pass;
int port;
Eina_Bool use_ssl : 1;
const char *name, *user;
const char *nick, *nick_pass;
const char *server_pass;
Eina_Bool autoconnect : 1;
Eina_Bool bypass_proxy : 1;
Eina_Bool use_ssl : 1;
Express_Callbacks callbacks;
Eina_Hash *servers;
Eina_Bool connecting : 1;
Eina_Bool connected : 1;
Ecore_Con_Server *conn;
unsigned int offset;
};
extern Eina_Hash *_servers;
struct _Express_Server
{
const char *name;
int port;
void _server_pass_send(Express_Server *server);
void _server_user_send(Express_Server *server);
void _server_nick_send(Express_Server *server);
Eina_Bool skip : 1;
};
extern Eina_Hash *_networks;
void _express_network_data_send(Express_Network *net, const char *data, int len);
void _express_network_data_process(Express_Network *net, const char *data, int offset);
#endif

View File

@ -35,12 +35,8 @@ _server_nick_send(Express_Server *server)
EXAPI Express_Server *
express_server_find(const char *name)
{
Express_Server *srv;
if (!name) return NULL;
if ((srv = eina_hash_find(_servers, name)))
return srv;
return NULL;
return eina_hash_find(_servers, name);
}
EXAPI Express_Server *
@ -48,8 +44,7 @@ express_server_create(const char *name, const char *nick, const char *user, cons
{
Express_Server *srv;
if (!(srv = calloc(1, sizeof(Express_Server))))
return NULL;
if (!(srv = calloc(1, sizeof(Express_Server)))) return NULL;
if (name) srv->name = eina_stringshare_add(name);
if (nick) srv->nick = eina_stringshare_add(nick);