terminology can do multi instance now (in a single process). that

means 2 or 3 or more windows == same terminology process. there is a
checkbox to turn it on.

in theory it CAN do multipe terms within 1 windows, except there's
incomplete sizing logic code for hansling step sizing and min size
with multielp terms in the same window (imagine u laid them out in a
table grid... all we need is a table and pack n terms in and presto..
but the sizing will be "bizarre" at the moment)... if they are packed
on top of eachother like a notebook... sure - but no notebook widget
and no way to sensibly display and switch... but the code infra now
all supports it in theory. this is more about testing and making that
infra work. first will probably be a grid layout of some sort because
frankly... it's easier.

but for now... lets get this multi-instance fun on the table.



SVN revision: 81740
This commit is contained in:
Carsten Haitzler 2012-12-27 11:20:32 +00:00
parent a91fa68c1d
commit e401e87660
11 changed files with 904 additions and 265 deletions

View File

@ -29,6 +29,7 @@ requirements="\
ecore-input >= 1.7.0 \
ecore-imf >= 1.7.0 \
ecore-imf-evas >= 1.7.0 \
ecore-ipc >= 1.7.0 \
efreet >= 1.7.0
"

View File

@ -14,6 +14,7 @@ about.c about.h \
col.c col.h \
config.c config.h \
controls.c controls.h \
ipc.c ipc.h \
keyin.c keyin.h \
main.c main.h \
media.c media.h \

View File

@ -78,6 +78,8 @@ config_init(void)
(edd_base, Config, "mute", mute, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC
(edd_base, Config, "urg_bell", urg_bell, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC
(edd_base, Config, "multi_instance", multi_instance, EET_T_UCHAR);
}
void
@ -369,6 +371,7 @@ config_load(const char *key)
config->vidmod = 0;
config->mute = EINA_FALSE;
config->urg_bell = EINA_TRUE;
config->multi_instance = EINA_FALSE;
}
}

View File

@ -38,6 +38,7 @@ struct _Config
Eina_Bool translucent;
Eina_Bool mute;
Eina_Bool urg_bell;
Eina_Bool multi_instance;
Eina_Bool temporary; /* not in EET */
const char *config_key; /* not in EET, the key that config was loaded */

188
src/bin/ipc.c Normal file
View File

@ -0,0 +1,188 @@
#include "private.h"
#include <Ecore.h>
#include <Ecore_Ipc.h>
#include <Eet.h>
#include "ipc.h"
static Ecore_Ipc_Server *ipc = NULL;
static Ecore_Event_Handler *hnd_data = NULL;
static void (*func_new_inst) (Ipc_Instance *inst) = NULL;
static Eet_Data_Descriptor *new_inst_edd = NULL;
static Eina_Bool
_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event)
{
Ecore_Ipc_Event_Client_Data *e = event;
if (ecore_ipc_client_server_get(e->client) != ipc)
return ECORE_CALLBACK_PASS_ON;
if ((e->major == 3) && (e->minor == 7) && (e->data) && (e->size > 0))
{
Ipc_Instance *inst;
inst = eet_data_descriptor_decode(new_inst_edd, e->data, e->size);
if (inst)
{
if (func_new_inst) func_new_inst(inst);
// NOTE strings in inst are part of the inst alloc blob and
// dont need separate frees.
free(inst);
}
}
return ECORE_CALLBACK_PASS_ON;
}
static char *
_ipc_hash_get(void)
{
char buf[1024], hash[128];
const char *disp, *session;
char *s, i;
unsigned char c1, c2;
/* sumb stoopid hash - i'm feeling lazy */
disp = getenv("DISPLAY");
if (!disp) disp = "-unknown-";
session = getenv("DBUS_SESSION_BUS_ADDRESS");
if (!session) session = ":unknown:";
snprintf(buf, sizeof(buf), "%s/%s", disp, session);
memset(hash, 0, sizeof(hash));
memset(hash, 'x', 32);
for (i = 0, s = buf; *s; s++)
{
c1 = (((unsigned char)*s) >> 4) & 0xf;;
c2 = ((unsigned char)*s) & 0x0f;
hash[i % 32] = (((hash[i % 32] - 'a') ^ c1) % 26) + 'a';
i++;
hash[i % 32] = (((hash[i % 32] - 'a') ^ c2) % 26) + 'a';
i++;
}
return strdup(hash);
}
void
ipc_init(void)
{
Eet_Data_Descriptor_Class eddc;
ecore_ipc_init();
eet_init();
eet_eina_stream_data_descriptor_class_set(&eddc, sizeof(eddc),
"inst", sizeof(Ipc_Instance));
new_inst_edd = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"cmd", cmd, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"cd", cd, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"background", background, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"name", name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"role", role, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"title", title, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"icon_name", icon_name, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"font", font, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"startup_id", startup_id, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"x", x, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"y", y, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"w", w, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"h", h, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"pos", pos, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"login_shell", login_shell, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"fullscreen", fullscreen, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"iconic", iconic, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"borderless", borderless, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"override", override, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"maximized", maximized, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"hold", hold, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(new_inst_edd, Ipc_Instance,
"nowm", nowm, EET_T_INT);
}
void
ipc_serve(void)
{
char *hash = _ipc_hash_get();
if (!hash) return;
ipc = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, hash, 0, NULL);
free(hash);
if (!ipc) return;
hnd_data = ecore_event_handler_add
(ECORE_IPC_EVENT_CLIENT_DATA, _ipc_cb_client_data, NULL);
}
void
ipc_shutdown(void)
{
if (ipc)
{
ecore_ipc_server_del(ipc);
ipc = NULL;
}
if (new_inst_edd)
{
eet_data_descriptor_free(new_inst_edd);
new_inst_edd = NULL;
}
eet_shutdown();
ecore_ipc_shutdown();
if (hnd_data)
{
ecore_event_handler_del(hnd_data);
hnd_data = NULL;
}
}
void
ipc_instance_new_func_set(void (*func) (Ipc_Instance *inst))
{
func_new_inst = func;
}
Eina_Bool
ipc_instance_add(Ipc_Instance *inst)
{
int size = 0;
void *data;
char *hash = _ipc_hash_get();
Ecore_Ipc_Server *ipcsrv;
if (!hash) return EINA_FALSE;
data = eet_data_descriptor_encode(new_inst_edd, inst, &size);
if (!data)
{
free(hash);
return EINA_FALSE;
}
ipcsrv = ecore_ipc_server_connect(ECORE_IPC_LOCAL_USER, hash, 0, NULL);
if (ipcsrv)
{
ecore_ipc_server_send(ipcsrv, 3, 7, 0, 0, 0, data, size);
ecore_ipc_server_flush(ipcsrv);
free(data);
free(hash);
ecore_ipc_server_del(ipcsrv);
return EINA_TRUE;
}
free(data);
free(hash);
return EINA_FALSE;
}

37
src/bin/ipc.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef _IPC_H__
#define _IPC_H__ 1
#include "config.h"
typedef struct _Ipc_Instance Ipc_Instance;
struct _Ipc_Instance
{
const char *cmd;
const char *cd;
const char *background;
const char *name;
const char *role;
const char *title;
const char *icon_name;
const char *font;
const char *startup_id;
int x, y, w, h;
int pos;
int login_shell;
int fullscreen;
int iconic;
int borderless;
int override;
int maximized;
int hold;
int nowm;
};
void ipc_init(void);
void ipc_shutdown(void);
void ipc_serve(void);
void ipc_instance_new_func_set(void (*func) (Ipc_Instance *inst));
Eina_Bool ipc_instance_add(Ipc_Instance *inst);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -67,6 +67,15 @@ _cb_op_behavior_urg_bell_chg(void *data, Evas_Object *obj, void *event __UNUSED_
config_save(config, NULL);
}
static void
_cb_op_behavior_multi_instance_chg(void *data, Evas_Object *obj, void *event __UNUSED__)
{
Evas_Object *term = data;
Config *config = termio_config_get(term);
config->multi_instance = elm_check_state_get(obj);
config_save(config, NULL);
}
static void
_cb_op_behavior_wsep_chg(void *data, Evas_Object *obj, void *event __UNUSED__)
{
@ -187,6 +196,16 @@ options_behavior(Evas_Object *opbox, Evas_Object *term)
evas_object_smart_callback_add(o, "changed",
_cb_op_behavior_urg_bell_chg, term);
o = elm_check_add(bx);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);
elm_object_text_set(o, "Multiple instances, one process");
elm_check_state_set(o, config->multi_instance);
elm_box_pack_end(bx, o);
evas_object_show(o);
evas_object_smart_callback_add(o, "changed",
_cb_op_behavior_multi_instance_chg, term);
o = elm_separator_add(bx);
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, 0.5);

View File

@ -84,8 +84,19 @@ static void
_cb_op_font_preview_del(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event __UNUSED__)
{
Evas_Object *o;
Ecore_Timer *timer = evas_object_data_get(obj, "delay");
if (timer)
{
ecore_timer_del(timer);
evas_object_data_del(obj, "delay");
}
o = edje_object_part_swallow_get(obj, "terminology.text.preview");
if (o) evas_object_del(o);
if (o)
{
evas_object_del(o);
}
}
static Eina_Bool

View File

@ -2310,6 +2310,7 @@ _smart_del(Evas_Object *obj)
_parent_sc.del(obj);
evas_object_smart_data_set(obj, NULL);
free(sd);
}
static void

View File

@ -151,7 +151,6 @@ _cb_exe_exit(void *data, int type __UNUSED__, void *event)
if (ev->pid != ty->pid) return ECORE_CALLBACK_PASS_ON;
ty->exit_code = ev->exit_code;
if (ty->cb.exited.func) ty->cb.exited.func(ty->cb.exited.data);
ty->pid = -1;
@ -164,6 +163,8 @@ _cb_exe_exit(void *data, int type __UNUSED__, void *event)
if (ty->slavefd >= 0) close(ty->slavefd);
ty->slavefd = -1;
if (ty->cb.exited.func) ty->cb.exited.func(ty->cb.exited.data);
return ECORE_CALLBACK_PASS_ON;
}
@ -322,14 +323,16 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd, int w, int h
{
if (i != ty->slavefd) close(i);
}
ty->fd = ty->slavefd;
setsid();
dup2(ty->fd, 0);
dup2(ty->fd, 1);
dup2(ty->fd, 2);
dup2(ty->slavefd, 0);
dup2(ty->slavefd, 1);
dup2(ty->slavefd, 2);
if (ioctl(ty->fd, TIOCSCTTY, NULL) < 0) exit(1);
if (ioctl(ty->slavefd, TIOCSCTTY, NULL) < 0) exit(1);
close(ty->fd);
close(ty->slavefd);
/* TODO: should we reset signals here? */
@ -356,6 +359,7 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd, int w, int h
_cb_fd_read, ty,
NULL, NULL);
close(ty->slavefd);
ty->slavefd = -1;
_pty_size(ty);
return ty;
err: