diff --git a/README b/README
index 4d277185..dae13894 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Terminology 0.2.0
+Terminology 0.3.0
******************************************************************************
@@ -10,16 +10,20 @@ Terminology 0.2.0
Requirements:
-------------
- * elementary 1.1 (1.0.99 SVN latest)
- * eina
- * eet
- * evas 1.3 (1.2.99 SVN latest)
- * ecore
- * edje
- * emotion
- * ecore-imf
- * ecore-imf-evas
- * ecore-input 1.3 (1.2.99 SVN latest)
+ * elementary (>= 1.7.0)
+ * eina (>= 1.7.0)
+ * eet (>= 1.7.0)
+ * evas (>= 1.7.0)
+ * ecore (>= 1.7.0)
+ * edje (>= 1.7.0)
+ * emotion (>= 1.7.0)
+ * ecore-imf (>= 1.7.0)
+ * ecore-imf-evas (>= 1.7.0)
+ * ecore-input (>= 1.7.0)
+ * ethumb (>= 1.7.0)
+
+Please note that some features may not quite function correction or
+completely on EFL 1.7, and 1.8 or newer would be better.
Please see http://www.enlightenment.org for information on these.
@@ -59,6 +63,9 @@ Ctrl+Shift+Home = bring up "tab" switcher
Ctrl+Shift+PgUp = split terminal horizontally (1 term above the other)
Ctrl+Shift+PgDn = split terminal vertically (1 term to the left of the other)
Alt+Home = Enter command mode (enter commands to control terminology itself)
+Alt+Return = paste primary selection
+Ctrl+Shift+c = copy current selection to clipboard
+Ctrl+Shift+v = paste current clipboard selection
Command mode commands currently understood:
diff --git a/TODO b/TODO
index 1391b30d..2cb2aacb 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,8 @@
here's a short list of things i think we can do in the short to medium term to
make it a first-class terminal:
+[ ] better info in tyls -m
+[ ] tyls -b needs doing
[ ] blink and blink2 attributes need to be supported
[ ] general input mode handling improvements (keypad, other key
input, etc.)
@@ -24,32 +26,18 @@ make it a first-class terminal:
[ ] dnd of file to term offer to paste path, with escapes or paste file
content (if text) with or without escaping
[ ] helpers when executed need to escape path/uri in command buffer
-[ ] media - improve position slider to track ucr position as u play
+[ ] media - improve position slider to track position as u play
[ ] improve look of meida controls (youtube like better with mouse move show)
-[ ] media controls for music files need to be compact for music
[ ] make media controls an api where controls are provided by the media
object owner so they can be custom placed/swallowed/handled better
[ ] media controls need to have zoom controls for all formats
[ ] media controls need next/prev page controls for paged media (ps/pdf)
[ ] add better handling of music files (with just playbar+vol, no image)
[ ] display queue of media visually
-[ ] add escapes for displaying media
[ ] add option for cjk double width mode
[ ] apparently there are problems with mutt, screen and tmux? vim
mousewheel scroll suport doesnt work
[ ] possible evas font problem with proggy fonts: http://www.proggyfonts.com/
-[ ] alt+return doesn't copy current selection to input line.
-[ ] ctrl+shift+c and ctrl+shift+v should do copy & paste
-[ ] tab sel needs decent edje styling with spacing and shadows around items
-[ ] tab sel needs to display term title and track changes
-[ ] tab sel needs to display alert/bell state and display it
-[ ] termio needs a bg mode for invisible tabs (until sel view is up)
-[ ] termio needs a visible but not selected mode (for media volume?)
-[ ] tab sel needs to use temio bg/visible modes
-[ ] main term needs to track title in its struct and win title needs
- to show it when we switch focus to that term
-[ ] need an edje bg/overlay/swallow around sel that is put in the pane or
- terminology main swallow for styling and bg.
[ ] need mouse control for sel object (autoscroll based on position)
[ ] need mouseover top of term to go into sel mode
[ ] need to track bell on bg terms and indicate a bg term wants attention
diff --git a/configure.ac b/configure.ac
index 188ed0ee..4d0611fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ dnl Process this file with autoconf to produce a configure script.
# get rid of that stupid cache mechanism
rm -f config.cache
-AC_INIT([terminology], [0.2.0], [enlightenment-devel@lists.sourceforge.net])
+AC_INIT([terminology], [0.3.0], [enlightenment-devel@lists.sourceforge.net])
AC_PREREQ([2.60])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_MACRO_DIR([m4])
diff --git a/data/themes/default.edc b/data/themes/default.edc
index cba8427b..f6e8c278 100644
--- a/data/themes/default.edc
+++ b/data/themes/default.edc
@@ -2261,8 +2261,16 @@ target: "4.bottom"
images {
image: "pm_overlay.png" COMP;
image: "pm_fill.png" COMP;
+ image: "bg_shadow.png" COMP;
}
parts {
+ part { name: "shadow";
+ mouse_events: 0;
+ description { state: "default" 0.0;
+ image.normal: "bg_shadow.png";
+ fill.smooth: 0;
+ }
+ }
part { name: "fill";
mouse_events: 0;
description { state: "default" 0.0;
@@ -2393,7 +2401,24 @@ target: "4.bottom"
rel2.to: "terminology.content";
}
}
-
+ part { name: "terminology.background"; type: SWALLOW;
+ description { state: "default" 0.0;
+ rel1.to: "terminology.content";
+ rel2.to: "terminology.content";
+ }
+ description { state: "image" 0.0;
+ inherit: "default" 0.0;
+ }
+ description { state: "scale" 0.0;
+ inherit: "default" 0.0;
+ }
+ description { state: "edje" 0.0;
+ inherit: "default" 0.0;
+ }
+ description { state: "movie" 0.0;
+ inherit: "default" 0.0;
+ }
+ }
part { name: "terminology.content"; type: SWALLOW;
clip_to: "clip";
description { state: "default" 0.0;
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index e8734a08..ea63e6c7 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -1,6 +1,6 @@
MAINTAINERCLEANFILES = Makefile.in
-bin_PROGRAMS = terminology tycat tyls
+bin_PROGRAMS = terminology tybg tyalpha typop tyq tycat tyls
terminology_CPPFLAGS = -I. \
-DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \
@@ -41,6 +41,42 @@ win.c win.h \
utils.c utils.h \
extns.h
+tybg_SOURCES = \
+tybg.c
+
+tybg_CPPFLAGS = -I. \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(pkgdatadir)\"
+
+tybg_LDADD =
+
+tyalpha_SOURCES = \
+tyalpha.c
+
+tyalpha_CPPFLAGS = -I. \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(pkgdatadir)\"
+
+tyalpha_LDADD =
+
+typop_SOURCES = \
+typop.c
+
+typop_CPPFLAGS = -I. \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(pkgdatadir)\"
+
+typop_LDADD =
+
+tyq_SOURCES = \
+tyq.c
+
+tyq_CPPFLAGS = -I. \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(pkgdatadir)\"
+
+tyq_LDADD =
+
tycat_SOURCES = \
tycat.c \
extns.h
diff --git a/src/bin/about.c b/src/bin/about.c
index 17fe2ffe..6f11d3bb 100644
--- a/src/bin/about.c
+++ b/src/bin/about.c
@@ -56,7 +56,7 @@ about_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
"and otherwise push the boundaries of what a modern terminal "
"emulator should be. We hope you enjoy it.
"
"
"
- "Copyright © 2012 by:
"
+ "Copyright © 2012-2013 by:
"
"
"
"Carsten Haitzler
"
"Anisse Astier
"
@@ -74,6 +74,7 @@ about_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term)
"Samuel F. Baggen
"
"Rafael Antognolli
"
"Jerome Pinot
"
+ "Panagiotis Galatsanos
"
"
"
"
"
"Distributed under the 2-clause BSD license detailed below:
"
diff --git a/src/bin/main.c b/src/bin/main.c
index 95622de5..441c46c1 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -90,6 +90,7 @@ static void main_term_free(Term *term);
static void main_term_bg_redo(Term *term);
static Term *main_term_new(Win *wn, Config *config, const char *cmd, Eina_Bool login_shell, const char *cd, int size_w, int size_h, Eina_Bool hold);
static void _term_focus(Term *term);
+static void _sel_restore(Split *sp);
static void
_split_free(Split *sp)
@@ -485,6 +486,7 @@ main_close(Evas_Object *win, Evas_Object *term)
if (!sp) return;
if (!sp->term) return;
+ if (sp->sel) _sel_restore(sp);
spp = sp->parent;
if ((sp->term->focused) && (spp)) termfoc = _term_next_get(sp->term);
sp->wn->terms = eina_list_remove(sp->wn->terms, sp->term);
@@ -996,7 +998,10 @@ _cb_command(void *data, Evas_Object *obj __UNUSED__, void *event)
if (config)
{
config->temporary = EINA_TRUE;
- eina_stringshare_replace(&(config->background), cmd + 2);
+ if (cmd[2])
+ eina_stringshare_replace(&(config->background), cmd + 2);
+ else
+ eina_stringshare_replace(&(config->background), NULL);
main_media_update(config);
}
}
@@ -1007,8 +1012,12 @@ _cb_command(void *data, Evas_Object *obj __UNUSED__, void *event)
if (config)
{
config->temporary = EINA_FALSE;
- eina_stringshare_replace(&(config->background), cmd + 2);
+ if (cmd[2])
+ eina_stringshare_replace(&(config->background), cmd + 2);
+ else
+ eina_stringshare_replace(&(config->background), NULL);
main_media_update(config);
+ config_save(config, NULL);
}
}
}
@@ -1025,7 +1034,7 @@ _cb_command(void *data, Evas_Object *obj __UNUSED__, void *event)
(!strcasecmp(cmd + 2, "on")) ||
(!strcasecmp(cmd + 2, "true")) ||
(!strcasecmp(cmd + 2, "yes")))
- config->translucent = EINA_FALSE;
+ config->translucent = EINA_TRUE;
else
config->translucent = EINA_FALSE;
main_trans_update(config);
@@ -1042,10 +1051,11 @@ _cb_command(void *data, Evas_Object *obj __UNUSED__, void *event)
(!strcasecmp(cmd + 2, "on")) ||
(!strcasecmp(cmd + 2, "true")) ||
(!strcasecmp(cmd + 2, "yes")))
- config->translucent = EINA_FALSE;
+ config->translucent = EINA_TRUE;
else
config->translucent = EINA_FALSE;
main_trans_update(config);
+ config_save(config, NULL);
}
}
}
@@ -1134,7 +1144,7 @@ _sel_go(Split *sp, Term *term)
{
edje_object_part_unswallow(tm->bg, tm->term);
evas_object_lower(tm->term);
- evas_object_move(tm->term, 0, 0);
+ evas_object_move(tm->term, -9999, -9999);
evas_object_show(tm->term);
evas_object_clip_unset(tm->term);
#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
@@ -1756,6 +1766,11 @@ main_term_bg_redo(Term *term)
evas_object_size_hint_fill_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
theme_apply(o, term->config, "terminology/background");
+ if (term->config->translucent)
+ edje_object_signal_emit(term->bg, "translucent,on", "terminology");
+ else
+ edje_object_signal_emit(term->bg, "translucent,off", "terminology");
+
theme_auto_reload_enable(o);
evas_object_show(o);
@@ -1827,6 +1842,11 @@ main_term_new(Win *wn, Config *config, const char *cmd,
return NULL;
}
+ if (term->config->translucent)
+ edje_object_signal_emit(term->bg, "translucent,on", "terminology");
+ else
+ edje_object_signal_emit(term->bg, "translucent,off", "terminology");
+
theme_auto_reload_enable(o);
evas_object_show(o);
diff --git a/src/bin/sel.c b/src/bin/sel.c
index 79934064..2bd80c73 100644
--- a/src/bin/sel.c
+++ b/src/bin/sel.c
@@ -6,6 +6,8 @@
#include "sel.h"
#include "config.h"
#include "utils.h"
+#include "termio.h"
+#include "media.h"
typedef struct _Sel Sel;
typedef struct _Entry Entry;
@@ -37,7 +39,7 @@ struct _Sel
struct _Entry
{
- Evas_Object *obj, *bg;
+ Evas_Object *obj, *bg, *media, *termio;
Eina_Bool selected : 1;
Eina_Bool selected_before : 1;
Eina_Bool selected_orig : 1;
@@ -316,6 +318,68 @@ _transit(Evas_Object *obj, double tim)
if (!sd->anim) sd->anim = ecore_animator_add(_anim_cb, obj);
}
+static void
+_label_redo(Entry *en)
+{
+ const char *s;
+
+ if (!en->obj) return;
+ if (!en->termio) return;
+ s = termio_title_get(en->termio);
+ if (!s) s = termio_icon_name_get(en->termio);
+ if (s) edje_object_part_text_set(en->bg, "terminology.label", s);
+}
+
+static void
+_title_cb(void *data, Evas_Object *obj __UNUSED__, void *info __UNUSED__)
+{
+ _label_redo(data);
+}
+
+static void
+_icon_cb(void *data, Evas_Object *obj __UNUSED__, void *info __UNUSED__)
+{
+ _label_redo(data);
+}
+
+static void
+_bell_cb(void *data, Evas_Object *obj __UNUSED__, void *info __UNUSED__)
+{
+ Entry *en = data;
+ edje_object_signal_emit(en->bg, "bell", "terminology");
+}
+
+static void
+_media_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *info __UNUSED__)
+{
+ Entry *en = data;
+ en->media = NULL;
+}
+
+static void
+_entry_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *info __UNUSED__)
+{
+ Entry *en = data;
+ en->obj = NULL;
+ if (en->termio)
+ {
+ evas_object_smart_callback_del_full(en->termio, "title,change",
+ _title_cb, en);
+ evas_object_smart_callback_del_full(en->termio, "icon,change",
+ _icon_cb, en);
+ evas_object_smart_callback_del_full(en->termio, "bell",
+ _bell_cb, en);
+ en->termio = NULL;
+ }
+}
+
+static void
+_entry_termio_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *info __UNUSED__)
+{
+ Entry *en = data;
+ en->termio = NULL;
+}
+
static void
_smart_add(Evas_Object *obj)
{
@@ -346,7 +410,17 @@ _smart_del(Evas_Object *obj)
if (sd->autozoom_timeout) ecore_timer_del(sd->autozoom_timeout);
EINA_LIST_FREE(sd->items, en)
{
- evas_object_del(en->obj);
+ if (en->termio)
+ {
+ evas_object_smart_callback_del_full(en->termio, "title,change",
+ _title_cb, en);
+ evas_object_smart_callback_del_full(en->termio, "icon,change",
+ _icon_cb, en);
+ evas_object_smart_callback_del_full(en->termio, "bell",
+ _bell_cb, en);
+ }
+ if (en->obj) evas_object_del(en->obj);
+ if (en->media) evas_object_del(en->media);
evas_object_del(en->bg);
free(en);
}
@@ -441,7 +515,6 @@ void
sel_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Config *config)
{
Sel *sd = evas_object_smart_data_get(obj);
- Evas_Object *o;
Entry *en = calloc(1, sizeof(Entry));
if (!en) return;
sd->items = eina_list_append(sd->items, en);
@@ -455,20 +528,48 @@ sel_entry_add(Evas_Object *obj, Evas_Object *entry, Eina_Bool selected, Config *
evas_object_clip_set(en->bg, sd->clip);
edje_object_part_swallow(en->bg, "terminology.content", en->obj);
evas_object_show(en->obj);
+
+ if (config->background)
+ {
+ Evas_Object *o;
+ int type = 0;
+
+ en->media = o = media_add(obj,
+ config->background, config,
+ MEDIA_BG, &type);
+ evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
+ _media_del_cb, en);
+ edje_object_part_swallow(en->bg, "terminology.background", o);
+ evas_object_show(o);
+ if (type == TYPE_IMG)
+ edje_object_signal_emit(en->bg, "media,image", "terminology");
+ else if (type == TYPE_SCALE)
+ edje_object_signal_emit(en->bg, "media,scale", "terminology");
+ else if (type == TYPE_EDJE)
+ edje_object_signal_emit(en->bg, "media,edje", "terminology");
+ else if (type == TYPE_MOV)
+ edje_object_signal_emit(en->bg, "media,movie", "terminology");
+ }
+
evas_object_stack_below(en->bg, sd->o_event);
if (en->selected)
edje_object_signal_emit(en->bg, "selected,start", "terminology");
sd->interp = 1.0;
-
- o = evas_object_data_get(en->obj, "termio");
- if (o)
+ en->termio = evas_object_data_get(en->obj, "termio");
+ if (en->termio)
{
- const char *s;
-
- s = termio_title_get(o);
- if (!s) s = termio_icon_name_get(o);
- if (s) edje_object_part_text_set(en->bg, "terminology.label", s);
+ evas_object_smart_callback_add(en->termio, "title,change",
+ _title_cb, en);
+ evas_object_smart_callback_add(en->termio, "icon,change",
+ _icon_cb, en);
+ evas_object_smart_callback_add(en->termio, "bell",
+ _bell_cb, en);
+ _label_redo(en);
+ evas_object_event_callback_add(en->termio, EVAS_CALLBACK_DEL,
+ _entry_termio_del_cb, en);
}
+ evas_object_event_callback_add(en->obj, EVAS_CALLBACK_DEL,
+ _entry_del_cb, en);
}
void
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 4d012e9e..4c0f005c 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -1359,33 +1359,57 @@ _smart_cb_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
{
if (!strcmp(ev->keyname, "Prior"))
{
+ _compose_seq_reset(sd);
evas_object_smart_callback_call(data, "split,h", NULL);
goto end;
}
else if (!strcmp(ev->keyname, "Next"))
{
+ _compose_seq_reset(sd);
evas_object_smart_callback_call(data, "split,v", NULL);
goto end;
}
else if (!strcmp(ev->keyname, "t"))
{
+ _compose_seq_reset(sd);
evas_object_smart_callback_call(data, "new", NULL);
goto end;
}
else if (!strcmp(ev->keyname, "Home"))
{
+ _compose_seq_reset(sd);
evas_object_smart_callback_call(data, "select", NULL);
goto end;
}
+ else if (!strcmp(ev->keyname, "c"))
+ {
+ _compose_seq_reset(sd);
+ _take_selection(data, ELM_SEL_TYPE_CLIPBOARD);
+ goto end;
+ }
+ else if (!strcmp(ev->keyname, "v"))
+ {
+ _compose_seq_reset(sd);
+ _paste_selection(data, ELM_SEL_TYPE_CLIPBOARD);
+ goto end;
+ }
}
if ((evas_key_modifier_is_set(ev->modifiers, "Alt")) &&
(!evas_key_modifier_is_set(ev->modifiers, "Shift")) &&
- (!evas_key_modifier_is_set(ev->modifiers, "Control")) &&
- (!strcmp(ev->keyname, "Home")))
+ (!evas_key_modifier_is_set(ev->modifiers, "Control")))
{
- _compose_seq_reset(sd);
- evas_object_smart_callback_call(data, "cmdbox", NULL);
- goto end;
+ if (!strcmp(ev->keyname, "Home"))
+ {
+ _compose_seq_reset(sd);
+ evas_object_smart_callback_call(data, "cmdbox", NULL);
+ goto end;
+ }
+ else if (!strcmp(ev->keyname, "Return"))
+ {
+ _compose_seq_reset(sd);
+ _paste_selection(data, ELM_SEL_TYPE_PRIMARY);
+ goto end;
+ }
}
if ((evas_key_modifier_is_set(ev->modifiers, "Alt")) &&
(evas_key_modifier_is_set(ev->modifiers, "Control")) &&
diff --git a/src/bin/tyalpha.c b/src/bin/tyalpha.c
new file mode 100644
index 00000000..d8e5f343
--- /dev/null
+++ b/src/bin/tyalpha.c
@@ -0,0 +1,42 @@
+#include
+#include
+#include
+#include
+#include
+
+int
+main(int argc, char **argv)
+{
+ int i, perm = 0;
+
+ if (!getenv("TERMINOLOGY")) return 0;
+ if (argc <= 1)
+ {
+ printf("Usage: %s [-p] on|off\n"
+ " Change the terminal transparency on or off\n"
+ " -p Make change permanent (stored in config)\n"
+ "\n",
+ argv[0]);
+ return 0;
+ }
+ for (i = 1; i < argc; i++)
+ {
+ char tbuf[PATH_MAX];
+
+ if (!strcmp(argv[i], "-p"))
+ {
+ perm = 1;
+ i++;
+ if (i >= argc) break;
+ }
+ if (perm)
+ snprintf(tbuf, sizeof(tbuf), "%c}ap%s", 0x1b, argv[i]);
+ else
+ snprintf(tbuf, sizeof(tbuf), "%c}at%s", 0x1b, argv[i]);
+ if (write(0, tbuf, strlen(tbuf)) < 1) perror("write");
+ tbuf[0] = 0;
+ if (write(0, tbuf, 1) < 1) perror("write");
+ }
+ exit(0);
+ return 0;
+}
diff --git a/src/bin/tybg.c b/src/bin/tybg.c
new file mode 100644
index 00000000..9fd74b17
--- /dev/null
+++ b/src/bin/tybg.c
@@ -0,0 +1,44 @@
+#include
+#include
+#include
+#include
+#include
+
+int
+main(int argc, char **argv)
+{
+ int i, perm = 0;
+
+ if (!getenv("TERMINOLOGY")) return 0;
+ if (argc <= 1)
+ {
+ printf("Usage: %s [-p] FILE1 [FILE2 ...]\n"
+ " Change the terminal background to the given file/uri\n"
+ " -p Make change permanent (stored in config)\n"
+ "\n",
+ argv[0]);
+ return 0;
+ }
+ for (i = 1; i < argc; i++)
+ {
+ char *path, buf[PATH_MAX * 2], tbuf[PATH_MAX * 3];
+
+ if (!strcmp(argv[i], "-p"))
+ {
+ perm = 1;
+ i++;
+ if (i >= argc) break;
+ }
+ path = argv[i];
+ if (realpath(path, buf)) path = buf;
+ if (perm)
+ snprintf(tbuf, sizeof(tbuf), "%c}bp%s", 0x1b, path);
+ else
+ snprintf(tbuf, sizeof(tbuf), "%c}bt%s", 0x1b, path);
+ if (write(0, tbuf, strlen(tbuf)) < 1) perror("write");
+ tbuf[0] = 0;
+ if (write(0, tbuf, 1) < 1) perror("write");
+ }
+ exit(0);
+ return 0;
+}
diff --git a/src/bin/typop.c b/src/bin/typop.c
new file mode 100644
index 00000000..2686ed97
--- /dev/null
+++ b/src/bin/typop.c
@@ -0,0 +1,34 @@
+#include
+#include
+#include
+#include
+#include
+
+int
+main(int argc, char **argv)
+{
+ int i;
+
+ if (!getenv("TERMINOLOGY")) return 0;
+ if (argc <= 1)
+ {
+ printf("Usage: %s FILE1 [FILE2 ...]\n"
+ " Pop up a given media file/uri right now\n"
+ "\n",
+ argv[0]);
+ return 0;
+ }
+ for (i = 1; i < argc; i++)
+ {
+ char *path, buf[PATH_MAX * 2], tbuf[PATH_MAX * 3];
+
+ path = argv[i];
+ if (realpath(path, buf)) path = buf;
+ snprintf(tbuf, sizeof(tbuf), "%c}pn%s", 0x1b, path);
+ if (write(0, tbuf, strlen(tbuf)) < 1) perror("write");
+ tbuf[0] = 0;
+ if (write(0, tbuf, 1) < 1) perror("write");
+ }
+ exit(0);
+ return 0;
+}
diff --git a/src/bin/tyq.c b/src/bin/tyq.c
new file mode 100644
index 00000000..7e45d785
--- /dev/null
+++ b/src/bin/tyq.c
@@ -0,0 +1,34 @@
+#include
+#include
+#include
+#include
+#include
+
+int
+main(int argc, char **argv)
+{
+ int i;
+
+ if (!getenv("TERMINOLOGY")) return 0;
+ if (argc <= 1)
+ {
+ printf("Usage: %s FILE1 [FILE2 ...]\n"
+ " Queue a given media file/uri to the popped up\n"
+ "\n",
+ argv[0]);
+ return 0;
+ }
+ for (i = 1; i < argc; i++)
+ {
+ char *path, buf[PATH_MAX * 2], tbuf[PATH_MAX * 3];
+
+ path = argv[i];
+ if (realpath(path, buf)) path = buf;
+ snprintf(tbuf, sizeof(tbuf), "%c}pq%s", 0x1b, path);
+ if (write(0, tbuf, strlen(tbuf)) < 1) perror("write");
+ tbuf[0] = 0;
+ if (write(0, tbuf, 1) < 1) perror("write");
+ }
+ exit(0);
+ return 0;
+}