commit
f4698fb41e
|
@ -0,0 +1,185 @@
|
|||
#include "e.h"
|
||||
|
||||
/* module setup */
|
||||
E_API E_Module_Api e_modapi =
|
||||
{
|
||||
E_MODULE_API_VERSION,
|
||||
"Presentator helper tool"
|
||||
};
|
||||
|
||||
static Evas_Object *notify, *bx;
|
||||
static Eina_Hash *string_hash;
|
||||
static int entry_counter = 0;
|
||||
|
||||
static Ecore_Exe *keylogger;
|
||||
|
||||
typedef struct {
|
||||
unsigned int ref;
|
||||
char *name;
|
||||
Evas_Object *vis;
|
||||
Ecore_Timer *timer;
|
||||
} Entry;
|
||||
|
||||
static void
|
||||
_del_key(const char *name)
|
||||
{
|
||||
Evas_Object *o;
|
||||
Eina_List *list;
|
||||
|
||||
Entry *e = eina_hash_find(string_hash, name);
|
||||
|
||||
//something fishy is going on sometimes, then we dont even have a entry
|
||||
if (!e)
|
||||
{
|
||||
ERR("What the fuck?!");
|
||||
return;
|
||||
}
|
||||
|
||||
//deref the entry
|
||||
e->ref --;
|
||||
//free if null
|
||||
if (e->ref == 0)
|
||||
{
|
||||
|
||||
//if ref is 0 nuke out that entry
|
||||
eina_hash_del_by_key(string_hash, name);
|
||||
entry_counter --;
|
||||
//we need to update the notify visuals depending on the state of the box
|
||||
if (entry_counter <= 0)
|
||||
evas_object_hide(notify);
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_timed_del(void *data)
|
||||
{
|
||||
Entry *e = data;
|
||||
_del_key(e->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_add_key(const char *name)
|
||||
{
|
||||
Eina_Strbuf *buf;
|
||||
Evas_Object *o;
|
||||
|
||||
Entry *e = eina_hash_find(string_hash, name);
|
||||
|
||||
//first if we have already displayed that string do not display it again
|
||||
if (e)
|
||||
{
|
||||
e->ref ++;
|
||||
ecore_timer_reset(e->timer);
|
||||
return;
|
||||
}
|
||||
|
||||
//find a considerable text to display
|
||||
buf = eina_strbuf_new();
|
||||
if (entry_counter == 0)
|
||||
eina_strbuf_append_printf(buf, "%s", name);
|
||||
else
|
||||
eina_strbuf_append_printf(buf, " + %s", name);
|
||||
|
||||
//create a label and attach to the box
|
||||
o = elm_label_add(bx);
|
||||
elm_object_text_set(o, eina_strbuf_string_get(buf));
|
||||
evas_object_show(o);
|
||||
elm_box_pack_end(bx, o);
|
||||
evas_object_show(notify);
|
||||
|
||||
//save as entry somewhere
|
||||
e = calloc(1, sizeof(Entry));
|
||||
e->ref = 2; //one for beeing used and one for the minimum time
|
||||
e->vis = o;
|
||||
e->name = strdup(name);
|
||||
entry_counter ++;
|
||||
eina_hash_add(string_hash, name, e);
|
||||
e->timer = ecore_timer_add(0.5, _timed_del, e);
|
||||
}
|
||||
|
||||
static void
|
||||
_entry_free(Entry *e)
|
||||
{
|
||||
evas_object_del(e->vis);
|
||||
free(e->name);
|
||||
free(e);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_msg_from_child_handler(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Exe_Event_Data *dataFromProcess = (Ecore_Exe_Event_Data *)event;
|
||||
|
||||
for (int i = 0; dataFromProcess->lines[i].line; ++i)
|
||||
{
|
||||
char first = dataFromProcess->lines[i].line[0];
|
||||
char *key = &dataFromProcess->lines[i].line[1];
|
||||
if (first == ',')
|
||||
{
|
||||
_del_key(key);
|
||||
}
|
||||
else if (first == '.')
|
||||
{
|
||||
_add_key(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("WHAT THE FUCK\n");
|
||||
}
|
||||
}
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_msg_from_child_handler_error(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
|
||||
printf("ERROR!!!!!!!\n");
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
E_API void *
|
||||
e_modapi_init(E_Module *m)
|
||||
{
|
||||
ecore_init();
|
||||
|
||||
string_hash = eina_hash_string_small_new(_entry_free);
|
||||
|
||||
notify = elm_notify_add(e_comp->elm);
|
||||
elm_notify_allow_events_set(notify, EINA_TRUE);
|
||||
evas_object_layer_set(notify, E_LAYER_POPUP);
|
||||
elm_notify_align_set(notify, 0.5, 1.0);
|
||||
|
||||
bx = elm_box_add(notify);
|
||||
elm_box_horizontal_set(bx, EINA_TRUE);
|
||||
elm_object_content_set(notify, bx);
|
||||
evas_object_show(bx);
|
||||
|
||||
{
|
||||
keylogger = ecore_exe_pipe_run("/usr/local/bin/keylogger", ECORE_EXE_PIPE_WRITE |
|
||||
ECORE_EXE_PIPE_READ_LINE_BUFFERED |
|
||||
ECORE_EXE_PIPE_READ, notify);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(keylogger, NULL);
|
||||
ecore_event_handler_add(ECORE_EXE_EVENT_DATA, _msg_from_child_handler, NULL);
|
||||
ecore_event_handler_add(ECORE_EXE_EVENT_ERROR, _msg_from_child_handler_error, NULL);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_modapi_shutdown(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
|
||||
ecore_shutdown();
|
||||
return 1;
|
||||
}
|
||||
|
||||
E_API int
|
||||
e_modapi_save(E_Module *m EINA_UNUSED)
|
||||
{
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/extensions/XInput.h>
|
||||
|
||||
#define INVALID_EVENT_TYPE -1
|
||||
|
||||
static int key_press_type = INVALID_EVENT_TYPE;
|
||||
static int key_release_type = INVALID_EVENT_TYPE;
|
||||
|
||||
static void
|
||||
_press(const char *symbol)
|
||||
{
|
||||
fprintf(stdout, ".%s\n", symbol);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
_release(const char *symbol)
|
||||
{
|
||||
fprintf(stdout, ",%s\n", symbol);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
int i;
|
||||
int number = 0;
|
||||
int run = 1;
|
||||
int default_screen;
|
||||
|
||||
Display * default_display;
|
||||
Window root_window;
|
||||
XEvent e;
|
||||
XDeviceKeyEvent * key;
|
||||
XInputClassInfo *ip;
|
||||
XEventClass event_list[20];
|
||||
|
||||
default_display = XOpenDisplay(getenv("DISPLAY"));
|
||||
default_screen = DefaultScreen(default_display);
|
||||
root_window = RootWindow(default_display, default_screen);
|
||||
|
||||
int num = 0;
|
||||
|
||||
XDeviceInfo *infos = XListInputDevices(default_display, &num);
|
||||
|
||||
//find all devices that are doing input
|
||||
for (int i = 0; i < num; ++i) {
|
||||
XDevice * device;
|
||||
|
||||
if (infos[i].id == IsXKeyboard) continue;
|
||||
if (infos[i].id == IsXPointer) continue;
|
||||
if (infos[i].id == IsXExtensionKeyboard) continue;
|
||||
if (infos[i].id == IsXExtensionPointer) continue;
|
||||
|
||||
|
||||
switch(infos[i].inputclassinfo->class) {
|
||||
case KeyClass:
|
||||
device = XOpenDevice(default_display, infos[i].id);
|
||||
|
||||
if(!device){
|
||||
fprintf(stderr, "unable to open device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DeviceKeyPress(device, key_press_type, event_list[number]); number++;
|
||||
DeviceKeyRelease(device, key_release_type, event_list[number]); number++;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* important */
|
||||
if(XSelectExtensionEvent(default_display, root_window, event_list, number)) {
|
||||
fprintf(stderr, "error selecting extended events\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(run) {
|
||||
XNextEvent(default_display, &e);
|
||||
key = (XDeviceKeyEvent *) &e;
|
||||
const char *symbol;
|
||||
|
||||
symbol = XKeysymToString(XKeycodeToKeysym(default_display, key->keycode, 0));
|
||||
|
||||
if (key->type == key_press_type)
|
||||
{
|
||||
_press(symbol);
|
||||
}
|
||||
else if (key->type == key_release_type)
|
||||
{
|
||||
_release(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the connection to the X server */
|
||||
XCloseDisplay(default_display);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue