aboutsummaryrefslogtreecommitdiff
path: root/vito.c
diff options
context:
space:
mode:
Diffstat (limited to 'vito.c')
-rw-r--r--vito.c337
1 files changed, 0 insertions, 337 deletions
diff --git a/vito.c b/vito.c
deleted file mode 100644
index effba9e..0000000
--- a/vito.c
+++ /dev/null
@@ -1,337 +0,0 @@
-#include <gtk/gtk.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk/gdkenums.h>
-
-/* Time in milliseconds it takes to write a character, i.e. if you hold down
- * the mouse button for this many ms it will write the character and move on to
- * the next character (or emoji).
- *
- * Initially had this set to 500 ms (half a second), but that was a bit short,
- * so I've updated it to one second. */
-#define CLICK_TIME 1000
-
-#define LEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
-
-/* Returns the current time in seconds and milliseconds since the epoch.
- * Mostly useful for calculating time intervals. */
-static void aeGetTime(long *seconds, long *milliseconds)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- *seconds = tv.tv_sec;
- *milliseconds = tv.tv_usec/1000;
-}
-
-GtkWidget *text_widget;
-GtkTextTag *tag;
-
-/* List of emojis. */
-#define STOP "\xf0\x9f\x9b\x91"
-#define THANK_YOU "\xf0\x9f\x99\x8f"
-#define UNAMUSED "\xf0\x9f\x98\x92"
-#define SLEEPING "\xf0\x9f\x98\xb4"
-#define BED "\xf0\x9f\x9b\x8f"
-#define CHAIR "\xf0\x9f\xaa\x91"
-#define NURSE "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9a\x95\xef\xb8\x8f"
-#define ROLLING_EYES "\xf0\x9f\x99\x84"
-#define OVERHEATED "\xf0\x9f\xa5\xb5"
-#define FREEZING "\xf0\x9f\xa5\xb6"
-#define NAUSEOUS "\xf0\x9f\xa4\xa2"
-#define THINKING "\xf0\x9f\xa4\x94"
-#define THUMBS_UP "\xf0\x9f\x91\x8d"
-#define THUMBS_DOWN "\xf0\x9f\x91\x8e"
-#define LEFT_ARROW "\xe2\x86\x90"
-#define CLEAR_SCREEN "\xe2\x8e\x9a"
-#define SOUND "\xf0\x9f\x94\x8a"
-#define DROPLET "\xf0\x9f\x92\xa7"
-#define FOOD "\xf0\x9f\x8d\xb2"
-#define TIRED "\xf0\x9f\x98\xab"
-#define HAPPY "\xf0\x9f\x98\x80"
-#define LAUGHING "\xf0\x9f\x98\x84"
-#define NEWLINE "\xe2\x86\xb5"
-
-typedef struct chars
-{
- const char **characters;
- int len;
-} chars;
-
-const char *emoji_array[] = {
- THINKING,
- THUMBS_UP,
- THUMBS_DOWN,
- STOP,
- HAPPY,
- LAUGHING,
- TIRED,
- FREEZING,
- OVERHEATED,
- NAUSEOUS,
- ROLLING_EYES,
- SLEEPING,
- UNAMUSED,
- THANK_YOU,
- NURSE,
- DROPLET,
- CHAIR,
- BED,
- //FOOD,
- LEFT_ARROW,
- CLEAR_SCREEN,
-};
-
-const char *alphabet_array[] = {
- "a",
- "b",
- "c",
- "d",
- "e",
- "f",
- "g",
- "h",
- "i",
- "j",
- "k",
- "l",
- "m",
- "n",
- "o",
- "p",
- "q",
- "r",
- "s",
- "t",
- "u",
- "v",
- "w",
- "x",
- "y",
- "z",
- LEFT_ARROW,
- CLEAR_SCREEN,
- SOUND,
- "_",
- NEWLINE,
- "!",
- "?",
- "."
-};
-
-chars emoji = { emoji_array, LEN(emoji_array)};
-chars alphabet = {alphabet_array, LEN(alphabet_array)};
-chars *current_chars = &emoji;
-
-char buf[100000];
-
-/* The current alphabetical letter. */
-int current_letter = 0;
-/* The current position in the buffer.
- *
- * FIXME: What to do if we run out of buffer space?. */
-int current_position = 0;
-
-/* Time the mouse was clicked (seconds) */
-long pressed_time_sec = 0;
-/* Time the mouse was clicked (milliseconds) */
-long pressed_time_msec = 0;
-/* Time the mouse was released (seconds) */
-long released_time_sec = 0;
-/* Time the mouse was released (milliseconds) */
-long released_time_msec = 0;
-
-void backspace(void)
-{
- GtkTextBuffer *text_buffer;
- GtkTextIter start, end;
-
- if (current_position > 0) {
- text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_widget));
- gtk_text_buffer_set_text(text_buffer, buf, -1);
-
- gtk_text_buffer_get_iter_at_offset(text_buffer, &start, 0);
- gtk_text_buffer_get_iter_at_offset(text_buffer, &end, g_utf8_strlen(buf,-1)-2);
- current_position = strlen(gtk_text_buffer_get_slice(text_buffer,&start,&end,TRUE));
- }
-}
-
-static void write_buf(void)
-{
- GtkTextBuffer *text_buffer;
- GtkTextIter start, end;
-
- text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_widget));
- sprintf(buf+current_position,"%s",current_chars->characters[current_letter % current_chars->len]);
-
- gtk_text_buffer_set_text(text_buffer, buf, -1);
-
- gtk_text_buffer_get_iter_at_offset(text_buffer, &start, g_utf8_strlen(buf,-1)-1);
- gtk_text_buffer_get_iter_at_offset(text_buffer, &end, -1);
- gtk_text_buffer_apply_tag(text_buffer, tag, &start, &end);
-}
-
-static int right_click_pressed(GtkWidget *widget, gpointer data)
-{
- backspace();
- write_buf();
- return TRUE;
-}
-
-static int right_click_released(GtkWidget *widget, gpointer data)
-{
- return TRUE;
-}
-
-static int pressed(GtkWidget *widget, gpointer data)
-{
- aeGetTime(&pressed_time_sec,&pressed_time_msec);
- return TRUE;
-}
-
-static int released(GtkWidget *widget, gpointer data)
-{
- const char *current_char;
-
- aeGetTime(&released_time_sec,&released_time_msec);
- long long diff = (released_time_sec - pressed_time_sec)*1000 + (released_time_msec - pressed_time_msec);
-
- if (diff > 10000) {
- current_position = 0;
- current_letter = 0;
- } else if (diff > CLICK_TIME) {
- current_char = current_chars->characters[current_letter % current_chars->len];
- if (!strcmp(current_char,LEFT_ARROW)) {
- backspace();
- } else if (!strcmp(current_char,CLEAR_SCREEN)) {
- current_position = 0;
- current_letter = 0;
- } else if (!strcmp(current_char,SOUND)) {
- char cmd[1000000];
- buf[current_position] = '\0';
- sprintf(cmd, "gtts-cli \"%s\" --output vito.mp3", buf);
- if (!system(cmd)) {
- system("mpg123 vito.mp3");
- system("rm vito.mp3");
- }
- } else if (!strcmp(current_char,"_")) {
- sprintf(buf+current_position," ");
- current_position += strlen(current_char);
- } else if (!strcmp(current_char,NEWLINE)) {
- sprintf(buf+current_position,"\n");
- current_position += 1;
- } else {
- sprintf(buf+current_position,"%s",current_char);
- current_position += strlen(current_char);
- }
- if (current_position > LEN(buf) - 1) {
- /* FIXME: better way to do this? */
- current_position = 0;
- }
- /* Uncomment the next line to start over at the beginning of the
- * alphabet after a new letter is entered. But, I think it's better
- * to keep the current letter. The reason is that you might want to
- * delete a whole word and so when you navigate to the backspace you
- * just have to keep entering the same letter. */
- current_letter = 0;
- } else {
- current_letter += 1;
- }
-
- write_buf();
-
- return TRUE;
-}
-
-gboolean on_key_press(GtkEventControllerKey *, guint keyval, guint keycode, GdkModifierType mod, gpointer user_data)
-{
- switch (keyval)
- {
- case GDK_KEY_space:
- if (current_chars == &emoji)
- current_chars = &alphabet;
- else if (current_chars == &alphabet)
- current_chars = &emoji;
- current_letter = 0;
- write_buf();
- break;
- case GDK_KEY_BackSpace:
- backspace();
- write_buf();
- break;
- default:
- return FALSE;
- }
- return FALSE;
-}
-
-static void activate(GtkApplication *app, gpointer user_data)
-{
- GtkWidget *window;
- GtkTextBuffer *text_buffer;
- GtkCssProvider *provider;
- GtkStyleContext *context;
- GtkGesture *gesture, *right_click_gesture;
- GtkEventController *event_controller;
-
- window = gtk_application_window_new(app);
- gtk_window_set_title(GTK_WINDOW(window), "Window");
- gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);
-
- event_controller = gtk_event_controller_key_new();
- g_signal_connect(event_controller, "key-pressed", G_CALLBACK(on_key_press), NULL);
- gtk_widget_add_controller(window, event_controller);
-
- right_click_gesture = gtk_gesture_click_new();
- gtk_gesture_single_set_button(GTK_GESTURE_SINGLE (right_click_gesture), 3);
- g_signal_connect(right_click_gesture, "pressed", G_CALLBACK(right_click_pressed), NULL);
- g_signal_connect(right_click_gesture, "released", G_CALLBACK(right_click_released), NULL);
- gtk_widget_add_controller(window, GTK_EVENT_CONTROLLER(right_click_gesture));
-
- gesture = gtk_gesture_click_new();
- g_signal_connect(gesture, "pressed", G_CALLBACK(pressed), NULL);
- g_signal_connect(gesture, "released", G_CALLBACK(released), NULL);
- gtk_widget_add_controller(window, GTK_EVENT_CONTROLLER(gesture));
-
- text_widget = gtk_text_view_new();
- gtk_text_view_set_editable((GtkTextView *) text_widget, FALSE);
- gtk_text_view_set_cursor_visible((GtkTextView *) text_widget, TRUE);
- gtk_text_view_set_wrap_mode((GtkTextView *) text_widget, GTK_WRAP_CHAR);
- gtk_widget_set_can_focus(text_widget, FALSE);
- gtk_widget_set_can_target(text_widget, FALSE);
- text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_widget));
-
- /* Change default font and color throughout the widget */
- provider = gtk_css_provider_new();
- gtk_css_provider_load_from_data(provider,
- "textview {"
- " font: 144pt monospace;"
- " color: black;"
- "}",
- -1);
- context = gtk_widget_get_style_context(text_widget);
- gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
- /* Use a tag to change the color for just one part of the widget */
- tag = gtk_text_buffer_create_tag(text_buffer, "red_foreground", "foreground", "red", NULL);
- write_buf();
- gtk_window_set_child(GTK_WINDOW(window), text_widget);
-
- gtk_window_fullscreen(GTK_WINDOW(window));
-
- gtk_window_present(GTK_WINDOW(window));
-}
-
-int main(int argc, char **argv)
-{
- GtkApplication *app;
- int status;
-
- app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE);
- g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
- status = g_application_run(G_APPLICATION(app), argc, argv);
- g_object_unref(app);
-
- return status;
-}