Beispiel #1
0
void
gui_nicklist_send_signal (const char *signal, struct t_gui_buffer *buffer,
                          const char *arguments)
{
    char *str_args;
    int length;

    if (buffer)
    {
        length = 128 + ((arguments) ? strlen (arguments) : 0) + 1 + 1;
        str_args = malloc (length);
        if (str_args)
        {
            snprintf (str_args, length,
                      "0x%lx,%s",
                      (long unsigned int)(buffer),
                      (arguments) ? arguments : "");
            (void) hook_signal_send (signal,
                                     WEECHAT_HOOK_SIGNAL_STRING, str_args);
            free (str_args);
        }
    }
    else
    {
        (void) hook_signal_send (signal,
                                 WEECHAT_HOOK_SIGNAL_STRING, (char *)arguments);
    }
}
Beispiel #2
0
void
gui_filter_free (struct t_gui_filter *filter)
{
    int i;

    (void) hook_signal_send ("filter_removing",
                             WEECHAT_HOOK_SIGNAL_POINTER, filter);

    /* free data */
    if (filter->name)
        free (filter->name);
    if (filter->buffer_name)
        free (filter->buffer_name);
    if (filter->buffers)
        string_free_split (filter->buffers);
    if (filter->tags)
        free (filter->tags);
    if (filter->tags_array)
    {
        for (i = 0; i < filter->tags_count; i++)
        {
            string_free_split (filter->tags_array[i]);
        }
        free (filter->tags_array);
    }
    if (filter->regex)
        free (filter->regex);
    if (filter->regex_prefix)
    {
        regfree (filter->regex_prefix);
        free (filter->regex_prefix);
    }
    if (filter->regex_message)
    {
        regfree (filter->regex_message);
        free (filter->regex_message);
    }

    /* remove filter from filters list */
    if (filter->prev_filter)
        (filter->prev_filter)->next_filter = filter->next_filter;
    if (filter->next_filter)
        (filter->next_filter)->prev_filter = filter->prev_filter;
    if (gui_filters == filter)
        gui_filters = filter->next_filter;
    if (last_gui_filter == filter)
        last_gui_filter = filter->prev_filter;

    free (filter);

    (void) hook_signal_send ("filter_removed", WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #3
0
void
gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer)
{
    char str_buffer[128], *new_input;
    
    /* send modifier, and change input if needed */
    snprintf (str_buffer, sizeof (str_buffer),
              "0x%lx", (long unsigned int)buffer);
    new_input = hook_modifier_exec (NULL,
                                    "input_text_content",
                                    str_buffer,
                                    (buffer->input_buffer) ?
                                    buffer->input_buffer : "");
    if (new_input)
    {
        if (strcmp (new_input, buffer->input_buffer) != 0)
        {
            /* input has been changed by modifier, use it */
            gui_input_replace_input (buffer, new_input);
        }
        free (new_input);
    }
    
    /* send signal */
    hook_signal_send ("input_text_changed", WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #4
0
void
upgrade_weechat_end ()
{
    struct timeval tv_now;
    long long time_diff;

    /* remove .upgrade files */
    util_exec_on_files (weechat_home,
                        0,
                        NULL,
                        &upgrade_weechat_remove_file_cb);

    /* display message for end of /upgrade with duration */
    gettimeofday (&tv_now, NULL);
    time_diff = util_timeval_diff (&weechat_current_start_timeval, &tv_now);
    gui_chat_printf (NULL,
                     /* TRANSLATORS: %.02fs is a float number + "s" ("seconds") */
                     _("Upgrade done (%.02fs)"),
                     ((float)time_diff) / 1000000);

    /* upgrading ended */
    weechat_upgrading = 0;

    /* send signal for end of /upgrade */
    (void) hook_signal_send ("upgrade_ended", WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #5
0
void
weechat_sigterm ()
{
    log_printf (_("Signal %s received, exiting WeeChat..."), "SIGTERM");
    (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
    weechat_quit = 1;
}
Beispiel #6
0
void
gui_main_signal_sigquit ()
{
    log_printf (_("Signal %s received, exiting WeeChat..."),
                "SIGQUIT");
    (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
    weechat_quit = 1;
}
Beispiel #7
0
void
gui_mouse_enable ()
{
    gui_mouse_enabled = 1;
    fprintf (stderr, "\033[?1005h\033[?1000h\033[?1002h");
    fflush (stderr);

    (void) hook_signal_send ("mouse_enabled",
                             WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #8
0
void
gui_filter_global_disable ()
{
    if (gui_filters_enabled)
    {
        gui_filters_enabled = 0;
        gui_filter_all_buffers ();
        hook_signal_send ("filters_disabled",
                          WEECHAT_HOOK_SIGNAL_STRING, NULL);
    }
}
Beispiel #9
0
void
gui_filter_global_enable ()
{
    if (!gui_filters_enabled)
    {
        gui_filters_enabled = 1;
        gui_filter_all_buffers ();
        (void) hook_signal_send ("filters_enabled",
                                 DOGECHAT_HOOK_SIGNAL_STRING, NULL);
    }
}
Beispiel #10
0
void
gui_main_signal_sighup ()
{
    /*
     * SIGHUP signal is received when terminal is closed (exit of WeeChat
     * without using /quit command), that's why we set only flag to reload
     * configuration files later (when terminal is closed, config files are NOT
     * reloaded, but they are if signal SIGHUP is sent to WeeChat by user)
     */
    gui_reload_config = 1;

    (void) hook_signal_send ("signal_sighup", WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #11
0
void
gui_main_loop ()
{
    struct t_hook *hook_fd_keyboard;

    /* catch SIGWINCH signal: redraw screen */
    util_catch_signal (SIGWINCH, &gui_main_signal_sigwinch);

    /* hook stdin (read keyboard) */
    hook_fd_keyboard = hook_fd (NULL, STDIN_FILENO, 1, 0, 0,
                                &gui_key_read_cb, NULL);

    gui_window_ask_refresh (1);

    while (!dogechat_quit)
    {
        /* execute timer hooks */
        hook_timer_exec ();

        /* auto reset of color pairs */
        if (gui_color_pairs_auto_reset)
        {
            gui_color_reset_pairs ();
            gui_color_pairs_auto_reset_last = time (NULL);
            gui_color_pairs_auto_reset = 0;
            gui_color_pairs_auto_reset_pending = 1;
        }

        gui_main_refreshs ();
        if (gui_window_refresh_needed && !gui_window_bare_display)
            gui_main_refreshs ();

        if (gui_signal_sigwinch_received)
        {
            (void) hook_signal_send ("signal_sigwinch",
                                     DOGECHAT_HOOK_SIGNAL_STRING, NULL);
            gui_signal_sigwinch_received = 0;
        }

        gui_color_pairs_auto_reset_pending = 0;

        /* execute fd hooks */
        hook_fd_exec ();
    }

    /* remove keyboard hook */
    unhook (hook_fd_keyboard);
}
Beispiel #12
0
void
gui_completion_stop (struct t_gui_completion *completion)
{
    if (!completion)
        return;

    completion->context = GUI_COMPLETION_NULL;
    completion->position = -1;

    if (completion->partial_list->size > 0)
    {
        arraylist_clear (completion->partial_list);
        (void) hook_signal_send ("partial_completion",
                                 WEECHAT_HOOK_SIGNAL_STRING, NULL);
    }
}
Beispiel #13
0
void
gui_completion_stop (struct t_gui_completion *completion)
{
    if (!completion)
        return;

    completion->context = GUI_COMPLETION_NULL;
    completion->position = -1;

    if (completion->partial_completion_list)
    {
        gui_completion_partial_list_free_all (completion);
        hook_signal_send ("partial_completion",
                          WEECHAT_HOOK_SIGNAL_STRING, NULL);
    }
}
Beispiel #14
0
void
gui_window_switch (struct t_gui_window *window)
{
    if (gui_current_window == window)
        return;

    /* remove unused bars from current window */
    /* ... */

    gui_current_window = window;

    gui_window_switch_to_buffer (gui_current_window, gui_current_window->buffer, 1);

    gui_window_redraw_buffer (gui_current_window->buffer);

    hook_signal_send ("window_switch",
                      WEECHAT_HOOK_SIGNAL_POINTER, window);
}
Beispiel #15
0
void
gui_keyboard_flush ()
{
    int i, key, insert_ok;
    char key_str[32], *key_utf, *input_old;
    
    /* if there's no paste pending, then we use buffer and do actions
       according to keys */
    if (!gui_keyboard_paste_pending)
    {
        if (gui_keyboard_buffer_size > 0)
            gui_keyboard_last_activity_time = time (NULL);
        
        for (i = 0; i < gui_keyboard_buffer_size; i++)
        {
            key = gui_keyboard_buffer[i];
            
            insert_ok = 1;
            
            if (key < 32)
            {
                insert_ok = 0;
                key_str[0] = '^';
                key_str[1] = (char) key + '@';
                key_str[2] = '\0';
            }
            else if (key == 127)
            {
                key_str[0] = '^';
                key_str[1] = '?';
                key_str[2] = '\0';
            }
            else
            {
                if (local_utf8)
                {
                    /* 1 char: 0vvvvvvv */
                    if (key < 0x80)
                    {
                        key_str[0] = (char) key;
                        key_str[1] = '\0';
                    }
                    /* 2 chars: 110vvvvv 10vvvvvv */
                    else if ((key & 0xE0) == 0xC0)
                    {
                        key_str[0] = (char) key;
                        if (i < gui_keyboard_buffer_size - 1)
                        {
                            key_str[1] = (char) (gui_keyboard_buffer[++i]);
                            key_str[2] = '\0';
                        }
                        else
                            key_str[1] = '\0';
                    }
                    /* 3 chars: 1110vvvv 10vvvvvv 10vvvvvv */
                    else if ((key & 0xF0) == 0xE0)
                    {
                        key_str[0] = (char) key;
                        if (i < gui_keyboard_buffer_size - 1)
                        {
                            key_str[1] = (char) (gui_keyboard_buffer[++i]);
                            if (i < gui_keyboard_buffer_size - 1)
                            {
                                key_str[2] = (char) (gui_keyboard_buffer[++i]);
                                key_str[3] = '\0';
                            }
                            else
                                key_str[2] = '\0';
                        }
                        else
                            key_str[1] = '\0';
                    }
                    /* 4 chars: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */
                    else if ((key & 0xF8) == 0xF0)
                    {
                        key_str[0] = (char) key;
                        if (i < gui_keyboard_buffer_size - 1)
                        {
                            key_str[1] = (char) (gui_keyboard_buffer[++i]);
                            if (i < gui_keyboard_buffer_size - 1)
                            {
                                key_str[2] = (char) (gui_keyboard_buffer[++i]);
                                if (i < gui_keyboard_buffer_size - 1)
                                {
                                    key_str[3] = (char) (gui_keyboard_buffer[++i]);
                                    key_str[4] = '\0';
                                }
                                else
                                    key_str[3] = '\0';
                            }
                            else
                                key_str[2] = '\0';
                        }
                        else
                            key_str[1] = '\0';
                    }
                }
                else
                {
                    key_str[0] = (char) key;
                    key_str[1] = '\0';
                    
                    /* convert input to UTF-8 is user is not using UTF-8 as locale */
                    if (!local_utf8)
                    {
                        key_utf = string_iconv_to_internal (NULL, key_str);
                        strncpy (key_str, key_utf, sizeof (key_str));
                        key_str[sizeof (key_str) - 1] = '\0';
                    }
                }
            }
            
            if (strcmp (key_str, "^") == 0)
            {
                key_str[1] = '^';
                key_str[2] = '\0';
            }
            
            /*gui_printf (gui_current_window->buffer,
                          "gui_input_read: key = %s (%d)\n", key_str, key);*/
            
            hook_signal_send ("key_pressed",
                              WEECHAT_HOOK_SIGNAL_STRING, key_str);
            
            if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
                input_old = (gui_current_window->buffer->input_buffer) ?
                    strdup (gui_current_window->buffer->input_buffer) : strdup ("");
            else
                input_old = NULL;
            
            if ((gui_keyboard_pressed (key_str) != 0) && (insert_ok))
            {
                if (strcmp (key_str, "^^") == 0)
                    key_str[1] = '\0';
                
                gui_input_insert_string (gui_current_window->buffer,
                                         key_str, -1);
                if (gui_current_window->buffer->completion)
                    gui_completion_stop (gui_current_window->buffer->completion, 0);
                gui_input_text_changed_modifier_and_signal (gui_current_window->buffer);
            }
            
            /* incremental text search in buffer */
            if ((gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
                && ((input_old == NULL) || (gui_current_window->buffer->input_buffer == NULL)
                    || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0)))
            {
                gui_window_search_restart (gui_current_window);
            }
            
            if (input_old)
                free (input_old);
        }
        
        if (gui_key_grab && (gui_key_grab_count > 0))
            gui_keyboard_grab_end ();
        
        gui_keyboard_buffer_reset ();
    }
}
Beispiel #16
0
void
gui_hotlist_changed_signal ()
{
    (void) hook_signal_send ("hotlist_changed",
                             WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #17
0
int
gui_keyboard_read_cb (void *data, int fd)
{
    int ret, i, accept_paste, cancel_paste, text_added_to_buffer, paste_lines;
    unsigned char buffer[4096];
    
    /* make C compiler happy */
    (void) data;
    (void) fd;
    
    accept_paste = 0;
    cancel_paste = 0;
    text_added_to_buffer = 0;

    if (gui_keyboard_paste_pending)
    {
        ret = read (STDIN_FILENO, buffer, 1);
        if (ret == 0)
        {
            /* no data on stdin, terminal lost */
            log_printf (_("Terminal lost, exiting WeeChat..."));
            hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
            weechat_quit = 1;
            return WEECHAT_RC_OK;
        }
        if (ret <= 0)
            return WEECHAT_RC_OK;
        
        /* ctrl-Y: accept paste */
        if (buffer[0] == 25)
            accept_paste = 1;
        
        /* ctrl-N: cancel paste */
        if (buffer[0] == 14)
            cancel_paste = 1;
    }
    else
    {
        ret = read (STDIN_FILENO, buffer, sizeof (buffer));
        if (ret == 0)
        {
            /* no data on stdin, terminal lost */
            log_printf (_("Terminal lost, exiting WeeChat..."));
            hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
            weechat_quit = 1;
            return WEECHAT_RC_OK;
        }
        if (ret < 0)
            return WEECHAT_RC_OK;
        
        for (i = 0; i < ret; i++)
        {
            gui_keyboard_buffer_add (buffer[i]);
        }
        
        text_added_to_buffer = 1;
    }
    
    if (gui_keyboard_paste_pending)
    {
        /* user is ok for pasting text, let's paste! */
        if (accept_paste)
            gui_keyboard_paste_accept ();
        /* user doesn't want to paste text: clear whole buffer! */
        else if (cancel_paste)
            gui_keyboard_paste_cancel ();
        else if (text_added_to_buffer)
            gui_input_text_changed_modifier_and_signal (gui_current_window->buffer);
    }
    else
    {
        /* detect user paste or large amount of text
           if so, ask user what to do */
        if (CONFIG_INTEGER(config_look_paste_max_lines) > 0)
        {
            paste_lines = gui_keyboard_get_paste_lines ();
            if (paste_lines > CONFIG_INTEGER(config_look_paste_max_lines))
            {
                gui_keyboard_paste_pending = 1;
                gui_input_paste_pending_signal ();
            }
        }
    }
    
    gui_keyboard_flush ();
    
    return WEECHAT_RC_OK;
}
Beispiel #18
0
void
gui_main_loop ()
{
    struct t_hook *hook_fd_keyboard;
    struct timeval tv_timeout;
    fd_set read_fds, write_fds, except_fds;
    int max_fd;
    int ready;

    /* catch SIGTERM signal: quit program */
    util_catch_signal (SIGTERM, &gui_main_signal_sigterm);
    util_catch_signal (SIGQUIT, &gui_main_signal_sigquit);

    /* catch SIGHUP signal: reload configuration */
    util_catch_signal (SIGHUP, &gui_main_signal_sighup);

    /* catch SIGWINCH signal: redraw screen */
    util_catch_signal (SIGWINCH, &gui_main_signal_sigwinch);

    /* hook stdin (read keyboard) */
    hook_fd_keyboard = hook_fd (NULL, STDIN_FILENO, 1, 0, 0,
                                &gui_key_read_cb, NULL);

    gui_window_ask_refresh (1);

    while (!weechat_quit)
    {
        /* reload config, if SIGHUP received */
        if (gui_reload_config)
        {
            gui_reload_config = 0;
            log_printf (_("Signal SIGHUP received, reloading configuration "
                          "files"));
            command_reload (NULL, NULL, 0, NULL, NULL);
        }

        /* execute hook timers */
        hook_timer_exec ();

        /* auto reset of color pairs */
        if (gui_color_pairs_auto_reset)
        {
            gui_color_reset_pairs ();
            gui_color_pairs_auto_reset_last = time (NULL);
            gui_color_pairs_auto_reset = 0;
            gui_color_pairs_auto_reset_pending = 1;
        }

        gui_main_refreshs ();
        if (gui_window_refresh_needed && !gui_window_bare_display)
            gui_main_refreshs ();

        if (gui_signal_sigwinch_received)
        {
            (void) hook_signal_send ("signal_sigwinch",
                                     WEECHAT_HOOK_SIGNAL_STRING, NULL);
            gui_signal_sigwinch_received = 0;
        }

        gui_color_pairs_auto_reset_pending = 0;

        /* wait for keyboard or network activity */
        FD_ZERO (&read_fds);
        FD_ZERO (&write_fds);
        FD_ZERO (&except_fds);
        max_fd = hook_fd_set (&read_fds, &write_fds, &except_fds);
        hook_timer_time_to_next (&tv_timeout);
        ready = select (max_fd + 1, &read_fds, &write_fds, &except_fds,
                        &tv_timeout);
        if (ready > 0)
        {
            hook_fd_exec (&read_fds, &write_fds, &except_fds);
        }
    }

    /* remove keyboard hook */
    unhook (hook_fd_keyboard);
}
Beispiel #19
0
int
gui_key_read_cb (const void *pointer, void *data, int fd)
{
    int ret, i, accept_paste, cancel_paste, text_added_to_buffer, pos;
    unsigned char buffer[4096];

    /* make C compiler happy */
    (void) pointer;
    (void) data;
    (void) fd;

    accept_paste = 0;
    cancel_paste = 0;
    text_added_to_buffer = 0;

    ret = read (STDIN_FILENO, buffer, sizeof (buffer));
    if (ret == 0)
    {
        /* no data on stdin, terminal lost */
        if (!weechat_quit)
        {
            log_printf (_("Terminal lost, exiting WeeChat..."));
            (void) hook_signal_send ("quit", WEECHAT_HOOK_SIGNAL_STRING, NULL);
            weechat_quit = 1;
        }
        return WEECHAT_RC_OK;
    }
    if (ret < 0)
        return WEECHAT_RC_OK;

    for (i = 0; i < ret; i++)
    {
        /*
         * add all chars, but ignore a newline ('\r' or '\n') after
         * another one)
         */
        if ((i == 0)
            || ((buffer[i] != '\r') && (buffer[i] != '\n'))
            || ((buffer[i - 1] != '\r') && (buffer[i - 1] != '\n')))
        {
            if (gui_key_paste_pending && (buffer[i] == 25))
            {
                /* ctrl-Y: accept paste */
                accept_paste = 1;
            }
            else if (gui_key_paste_pending && (buffer[i] == 14))
            {
                /* ctrl-N: cancel paste */
                cancel_paste = 1;
            }
            else
            {
                gui_key_buffer_add (buffer[i]);
                text_added_to_buffer = 1;
            }
        }
    }

    if (gui_key_paste_pending)
    {
        if (accept_paste)
        {
            /* user is OK for pasting text, let's paste! */
            gui_key_paste_accept ();
        }
        else if (cancel_paste)
        {
            /* user doesn't want to paste text: clear whole buffer! */
            gui_key_paste_cancel ();
        }
        else if (text_added_to_buffer)
        {
            /* new text received while asking for paste, update message */
            gui_input_paste_pending_signal ();
        }
    }
    else
    {
        if (!gui_key_paste_bracketed)
        {
            pos = gui_key_buffer_search (0, -1, GUI_KEY_BRACKETED_PASTE_START);
            if (pos >= 0)
            {
                gui_key_buffer_remove (pos, GUI_KEY_BRACKETED_PASTE_LENGTH);
                gui_key_paste_bracketed_start ();
            }
        }

        if (!gui_key_paste_bracketed)
            gui_key_paste_check (0);
    }

    gui_key_flush ((accept_paste) ? 1 : 0);

    if (gui_key_paste_bracketed)
    {
        pos = gui_key_buffer_search (0, -1, GUI_KEY_BRACKETED_PASTE_END);
        if (pos >= 0)
        {
            /* remove the code for end of bracketed paste (ESC[201~) */
            gui_key_buffer_remove (pos, GUI_KEY_BRACKETED_PASTE_LENGTH);

            /* remove final newline (if needed) */
            gui_key_paste_remove_newline ();

            /* replace tabs by spaces */
            gui_key_paste_replace_tabs ();

            /* stop bracketed mode */
            gui_key_paste_bracketed_timer_remove ();
            gui_key_paste_bracketed_stop ();

            /* if paste confirmation not displayed, flush buffer now */
            if (!gui_key_paste_pending)
                gui_key_flush (1);
        }
    }

    return WEECHAT_RC_OK;
}
Beispiel #20
0
void
gui_key_flush (int paste)
{
    int i, key, last_key_used, insert_ok, undo_done;
    static char key_str[64] = { '\0' };
    static int length_key_str = 0;
    char key_temp[2], *key_utf, *input_old, *ptr_char, *next_char, *ptr_error;
    char utf_partial_char[16];
    struct t_gui_buffer *old_buffer;

    /* if paste pending or bracketed paste detected, just return */
    if (gui_key_paste_pending || gui_key_paste_bracketed)
        return;

    /* if buffer is empty, just return */
    if (gui_key_buffer_size == 0)
        return;

    /*
     * if there's no paste pending, then we use buffer and do actions
     * according to keys
     */
    gui_key_last_activity_time = time (NULL);
    last_key_used = -1;
    undo_done = 0;
    old_buffer = NULL;
    for (i = 0; i < gui_key_buffer_size; i++)
    {
        key = gui_key_buffer[i];
        insert_ok = 1;
        utf_partial_char[0] = '\0';

        if (gui_mouse_event_pending || (key < 32) || (key == 127))
        {
            if (gui_mouse_event_pending)
            {
                insert_ok = 0;
                key_str[0] = (char)key;
                key_str[1] = '\0';
                length_key_str = 1;
            }
            else if (key < 32)
            {
                insert_ok = 0;
                key_str[0] = '\x01';
                key_str[1] = (char)key + '@';
                key_str[2] = '\0';
                length_key_str = 2;
            }
            else if (key == 127)
            {
                key_str[0] = '\x01';
                key_str[1] = '?';
                key_str[2] = '\0';
                length_key_str = 2;
            }
        }
        else
        {
            if (local_utf8)
            {
                key_str[length_key_str] = (char)key;
                key_str[length_key_str + 1] = '\0';
                length_key_str++;

                /*
                 * replace invalid chars by "?", but NOT last char of
                 * string, if it is incomplete UTF-8 char (another char
                 * will be added to the string on next iteration)
                 */
                ptr_char = key_str;
                while (ptr_char && ptr_char[0])
                {
                    (void) utf8_is_valid (ptr_char, -1, &ptr_error);
                    if (!ptr_error)
                        break;
                    next_char = (char *)utf8_next_char (ptr_error);
                    if (next_char && next_char[0])
                    {
                        ptr_char = ptr_error;
                        while (ptr_char < next_char)
                        {
                            ptr_char[0] = '?';
                            ptr_char++;
                        }
                    }
                    else
                    {
                        strcpy (utf_partial_char, ptr_char);
                        ptr_char[0] = '\0';
                        break;
                    }
                    ptr_char = next_char;
                }
            }
            else
            {
                /* convert input to UTF-8 */
                key_temp[0] = (char)key;
                key_temp[1] = '\0';
                key_utf = string_iconv_to_internal (NULL, key_temp);
                strcat (key_str, key_utf);
            }
        }

        if (key_str[0])
        {
            (void) hook_signal_send ("key_pressed",
                                     WEECHAT_HOOK_SIGNAL_STRING, key_str);

            if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
                input_old = (gui_current_window->buffer->input_buffer) ?
                    strdup (gui_current_window->buffer->input_buffer) : strdup ("");
            else
                input_old = NULL;
            old_buffer = gui_current_window->buffer;

            if ((gui_key_pressed (key_str) != 0) && (insert_ok)
                && (!gui_cursor_mode))
            {
                if (!paste || !undo_done)
                    gui_buffer_undo_snap (gui_current_window->buffer);
                gui_input_insert_string (gui_current_window->buffer,
                                         key_str, -1);
                gui_input_text_changed_modifier_and_signal (gui_current_window->buffer,
                                                            (!paste || !undo_done) ? 1 : 0,
                                                            1); /* stop completion */
                undo_done = 1;
            }

            /* incremental text search in buffer */
            if ((old_buffer == gui_current_window->buffer)
                && (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED)
                && ((input_old == NULL)
                    || (gui_current_window->buffer->input_buffer == NULL)
                    || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0)))
            {
                /*
                 * if following conditions are all true, then do not search
                 * again (search will not find any result and can take some time
                 * on a buffer with many lines):
                 * - old search was not successful
                 * - searching a string (not a regex)
                 * - current input is longer than old input
                 * - beginning of current input is exactly equal to old input.
                 */
                if (!gui_current_window->buffer->text_search_found
                    && !gui_current_window->buffer->text_search_regex
                    && (input_old != NULL)
                    && (input_old[0])
                    && (gui_current_window->buffer->input_buffer != NULL)
                    && (gui_current_window->buffer->input_buffer[0])
                    && (strlen (gui_current_window->buffer->input_buffer) > strlen (input_old))
                    && (strncmp (gui_current_window->buffer->input_buffer, input_old,
                                 strlen (input_old)) == 0))
                {
                    /*
                     * do not search text in buffer, just alert about text not
                     * found
                     */
                    if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert))
                    {
                        fprintf (stderr, "\a");
                        fflush (stderr);
                    }
                }
                else
                {
                    gui_window_search_restart (gui_current_window);
                }
            }

            if (input_old)
                free (input_old);
        }

        /* prepare incomplete UTF-8 char for next iteration */
        if (utf_partial_char[0])
            strcpy (key_str, utf_partial_char);
        else
            key_str[0] = '\0';
        length_key_str = strlen (key_str);

        /* set last key used in buffer if combo buffer is empty */
        if (gui_key_grab || gui_mouse_event_pending || !gui_key_combo_buffer[0])
            last_key_used = i;
    }

    if (last_key_used == gui_key_buffer_size - 1)
        gui_key_buffer_reset ();
    else if (last_key_used >= 0)
        gui_key_buffer_remove (0, last_key_used + 1);

    if (!gui_key_grab && !gui_mouse_event_pending)
        gui_key_combo_buffer[0] = '\0';
}
Beispiel #21
0
struct t_gui_filter *
gui_filter_new (int enabled, const char *name, const char *buffer_name,
                const char *tags, const char *regex)
{
    struct t_gui_filter *new_filter;
    regex_t *regex1, *regex2;
    char *pos_tab, *regex_prefix, **tags_array, buf[512], str_error[512];
    const char *ptr_start_regex, *pos_regex_message;
    int i, rc;

    if (!name || !buffer_name || !tags || !regex)
    {
        gui_filter_new_error (name, _("not enough arguments"));
        return NULL;
    }

    if (gui_filter_search_by_name (name))
    {
        gui_filter_new_error (name,
                              _("a filter with same name already exists"));
        return NULL;
    }

    ptr_start_regex = regex;
    if ((ptr_start_regex[0] == '!')
        || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!')))
    {
        ptr_start_regex++;
    }

    regex1 = NULL;
    regex2 = NULL;

    if (strcmp (ptr_start_regex, "*") != 0)
    {
        pos_tab = strstr (ptr_start_regex, "\\t");
        if (pos_tab)
        {
            regex_prefix = string_strndup (ptr_start_regex,
                                           pos_tab - ptr_start_regex);
            pos_regex_message = pos_tab + 2;
        }
        else
        {
            regex_prefix = NULL;
            pos_regex_message = ptr_start_regex;
        }

        if (regex_prefix && regex_prefix[0])
        {
            regex1 = malloc (sizeof (*regex1));
            if (regex1)
            {
                rc = string_regcomp (regex1, regex_prefix,
                                     REG_EXTENDED | REG_ICASE | REG_NOSUB);
                if (rc != 0)
                {
                    regerror (rc, regex1, buf, sizeof (buf));
                    snprintf (str_error, sizeof (str_error),
                              /* TRANSLATORS: %s is the error returned by regerror */
                              _("invalid regular expression (%s)"),
                              buf);
                    gui_filter_new_error (name, str_error);
                    free (regex_prefix);
                    free (regex1);
                    return NULL;
                }
            }
        }

        if (pos_regex_message && pos_regex_message[0])
        {
            regex2 = malloc (sizeof (*regex2));
            if (regex2)
            {
                rc = string_regcomp (regex2, pos_regex_message,
                                     REG_EXTENDED | REG_ICASE | REG_NOSUB);
                if (rc != 0)
                {
                    regerror (rc, regex2, buf, sizeof (buf));
                    snprintf (str_error, sizeof (str_error),
                              /* TRANSLATORS: %s is the error returned by regerror */
                              _("invalid regular expression (%s)"),
                              buf);
                    gui_filter_new_error (name, str_error);
                    if (regex_prefix)
                        free (regex_prefix);
                    if (regex1)
                    {
                        regfree (regex1);
                        free (regex1);
                    }
                    free (regex2);
                    return NULL;
                }
            }
        }

        if (regex_prefix)
            free (regex_prefix);
    }

    /* create new filter */
    new_filter = malloc (sizeof (*new_filter));
    if (new_filter)
    {
        /* init filter */
        new_filter->enabled = enabled;
        new_filter->name = strdup (name);
        new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*");
        new_filter->buffers = string_split (new_filter->buffer_name,
                                            ",", 0, 0,
                                            &new_filter->num_buffers);
        new_filter->tags = (tags) ? strdup (tags) : NULL;
        new_filter->tags_count = 0;
        new_filter->tags_array = NULL;
        if (new_filter->tags)
        {
            tags_array = string_split (new_filter->tags, ",", 0, 0,
                                       &new_filter->tags_count);
            if (tags_array)
            {
                new_filter->tags_array = malloc (new_filter->tags_count *
                                                 sizeof (*new_filter->tags_array));
                if (new_filter->tags_array)
                {
                    for (i = 0; i < new_filter->tags_count; i++)
                    {
                        new_filter->tags_array[i] = string_split (tags_array[i],
                                                                  "+", 0, 0,
                                                                  NULL);
                    }
                }
                string_free_split (tags_array);
            }
        }
        new_filter->regex = strdup (regex);
        new_filter->regex_prefix = regex1;
        new_filter->regex_message = regex2;

        /* add filter to filters list */
        new_filter->prev_filter = last_gui_filter;
        if (gui_filters)
            last_gui_filter->next_filter = new_filter;
        else
            gui_filters = new_filter;
        last_gui_filter = new_filter;
        new_filter->next_filter = NULL;

        (void) hook_signal_send ("filter_added",
                                 WEECHAT_HOOK_SIGNAL_POINTER, new_filter);
    }
    else
    {
        gui_filter_new_error (name, _("not enough memory"));
    }

    return new_filter;
}
Beispiel #22
0
struct t_gui_filter *
gui_filter_new (int enabled, const char *name, const char *buffer_name,
                const char *tags, const char *regex)
{
    struct t_gui_filter *new_filter;
    regex_t *regex1, *regex2;
    char *pos_tab, *regex_prefix;
    const char *ptr_start_regex, *pos_regex_message;

    if (!name || !buffer_name || !tags || !regex)
        return NULL;

    if (gui_filter_search_by_name (name))
        return NULL;

    ptr_start_regex = regex;
    if ((ptr_start_regex[0] == '!')
        || ((ptr_start_regex[0] == '\\') && (ptr_start_regex[1] == '!')))
    {
        ptr_start_regex++;
    }

    regex1 = NULL;
    regex2 = NULL;
    if (strcmp (ptr_start_regex, "*") != 0)
    {
        pos_tab = strstr (ptr_start_regex, "\\t");
        if (pos_tab)
        {
            regex_prefix = string_strndup (ptr_start_regex,
                                           pos_tab - ptr_start_regex);
            pos_regex_message = pos_tab + 2;
        }
        else
        {
            regex_prefix = NULL;
            pos_regex_message = ptr_start_regex;
        }

        if (regex_prefix)
        {
            regex1 = malloc (sizeof (*regex1));
            if (regex1)
            {
                if (string_regcomp (regex1, regex_prefix,
                                    REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
                {
                    free (regex_prefix);
                    free (regex1);
                    return NULL;
                }
            }
        }

        regex2 = malloc (sizeof (*regex2));
        if (regex2)
        {
            if (string_regcomp (regex2, pos_regex_message,
                                REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
            {
                if (regex_prefix)
                    free (regex_prefix);
                if (regex1)
                    free (regex1);
                free (regex2);
                return NULL;
            }
        }

        if (regex_prefix)
            free (regex_prefix);
    }

    /* create new filter */
    new_filter = malloc (sizeof (*new_filter));
    if (new_filter)
    {
        /* init filter */
        new_filter->enabled = enabled;
        new_filter->name = strdup (name);
        new_filter->buffer_name = strdup ((buffer_name) ? buffer_name : "*");
        new_filter->buffers = string_split (new_filter->buffer_name,
                                            ",", 0, 0,
                                            &new_filter->num_buffers);
        if (tags)
        {
            new_filter->tags = (tags) ? strdup (tags) : NULL;
            new_filter->tags_array = string_split (tags, ",", 0, 0,
                                                   &new_filter->tags_count);
        }
        else
        {
            new_filter->tags = NULL;
            new_filter->tags_count = 0;
            new_filter->tags_array = NULL;
        }
        new_filter->regex = strdup (regex);
        new_filter->regex_prefix = regex1;
        new_filter->regex_message = regex2;

        /* add filter to filters list */
        new_filter->prev_filter = last_gui_filter;
        if (gui_filters)
            last_gui_filter->next_filter = new_filter;
        else
            gui_filters = new_filter;
        last_gui_filter = new_filter;
        new_filter->next_filter = NULL;

        hook_signal_send ("filter_added",
                          WEECHAT_HOOK_SIGNAL_POINTER, new_filter);
    }

    return new_filter;
}
Beispiel #23
0
void
gui_input_paste_pending_signal ()
{
    hook_signal_send ("input_paste_pending", WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #24
0
void
gui_filter_buffer (struct t_gui_buffer *buffer,
                   struct t_gui_line_data *line_data)
{
    struct t_gui_line *ptr_line;
    struct t_gui_line_data *ptr_line_data;
    struct t_gui_window *ptr_window;
    int lines_changed, line_displayed, lines_hidden;

    lines_changed = 0;
    lines_hidden = buffer->lines->lines_hidden;

    if (!line_data)
        buffer->lines->prefix_max_length = CONFIG_INTEGER(config_look_prefix_align_min);

    ptr_line = buffer->lines->first_line;
    while (ptr_line || line_data)
    {
        ptr_line_data = (line_data) ? line_data : ptr_line->data;

        line_displayed = gui_filter_check_line (ptr_line_data);

        if (line_displayed
            && (ptr_line_data->prefix_length > buffer->lines->prefix_max_length))
        {
            buffer->lines->prefix_max_length = ptr_line_data->prefix_length;
        }

        if (ptr_line_data->displayed != line_displayed)
        {
            lines_changed = 1;
            lines_hidden += (line_displayed) ? -1 : 1;
        }

        ptr_line_data->displayed = line_displayed;

        if (line_data)
            break;

        ptr_line = ptr_line->next_line;
    }

    if (line_data)
        line_data->buffer->lines->prefix_max_length_refresh = 1;

    if (buffer->lines->lines_hidden != lines_hidden)
    {
        buffer->lines->lines_hidden = lines_hidden;
        hook_signal_send ("buffer_lines_hidden",
                          WEECHAT_HOOK_SIGNAL_POINTER, buffer);
    }

    if (lines_changed)
    {
        /* force a full refresh of buffer */
        gui_buffer_ask_chat_refresh (buffer, 2);

        /*
         * check that a scroll in a window displaying this buffer is not on a
         * hidden line (if this happens, use the previous displayed line as
         * scroll)
         */
        for (ptr_window = gui_windows; ptr_window;
             ptr_window = ptr_window->next_window)
        {
            if ((ptr_window->buffer == buffer)
                && ptr_window->scroll->start_line
                && !ptr_window->scroll->start_line->data->displayed)
            {
                ptr_window->scroll->start_line =
                    gui_line_get_prev_displayed (ptr_window->scroll->start_line);
                ptr_window->scroll->start_line_pos = 0;
            }
        }
    }
}
Beispiel #25
0
void
gui_input_text_cursor_moved_signal ()
{
    hook_signal_send ("input_text_cursor_moved", WEECHAT_HOOK_SIGNAL_STRING, NULL);
}
Beispiel #26
0
void
gui_line_add_y (struct t_gui_buffer *buffer, int y, const char *message)
{
    struct t_gui_line *ptr_line, *new_line;
    struct t_gui_line_data *new_line_data;
    struct t_gui_window *ptr_win;

    /* search if line exists for "y" */
    for (ptr_line = buffer->own_lines->first_line; ptr_line;
         ptr_line = ptr_line->next_line)
    {
        if (ptr_line->data->y >= y)
            break;
    }

    if (!ptr_line || (ptr_line->data->y > y))
    {
        new_line = malloc (sizeof (*new_line));
        if (!new_line)
        {
            log_printf (_("Not enough memory for new line"));
            return;
        }

        new_line_data = malloc (sizeof (*(new_line->data)));
        if (!new_line_data)
        {
            free (new_line);
            log_printf (_("Not enough memory for new line"));
            return;
        }
        new_line->data = new_line_data;

        buffer->own_lines->lines_count++;

        /* fill data in new line */
        new_line->data->buffer = buffer;
        new_line->data->y = y;
        new_line->data->date = 0;
        new_line->data->date_printed = 0;
        new_line->data->str_time = NULL;
        new_line->data->tags_count = 0;
        new_line->data->tags_array = NULL;
        new_line->data->refresh_needed = 1;
        new_line->data->prefix = NULL;
        new_line->data->prefix_length = 0;
        new_line->data->message = NULL;
        new_line->data->highlight = 0;

        /* add line to lines list */
        if (ptr_line)
        {
            /* add before line found */
            new_line->prev_line = ptr_line->prev_line;
            new_line->next_line = ptr_line;
            if (ptr_line->prev_line)
                (ptr_line->prev_line)->next_line = new_line;
            else
                buffer->own_lines->first_line = new_line;
            ptr_line->prev_line = new_line;
        }
        else
        {
            /* add at end of list */
            new_line->prev_line = buffer->own_lines->last_line;
            if (buffer->own_lines->first_line)
                buffer->own_lines->last_line->next_line = new_line;
            else
                buffer->own_lines->first_line = new_line;
            buffer->own_lines->last_line = new_line;
            new_line->next_line = NULL;
        }

        ptr_line = new_line;
    }

    /* set message for line */
    if (ptr_line->data->message)
    {
        /* remove line from coords if the content is changing */
        for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
        {
            gui_window_coords_remove_line (ptr_win, ptr_line);
        }

        /* free message in line */
        free (ptr_line->data->message);
    }
    ptr_line->data->message = (message) ? strdup (message) : strdup ("");

    /* check if line is filtered or not */
    ptr_line->data->displayed = gui_filter_check_line (ptr_line->data);
    if (!ptr_line->data->displayed)
    {
        buffer->own_lines->lines_hidden++;
        hook_signal_send ("buffer_lines_hidden",
                          WEECHAT_HOOK_SIGNAL_POINTER, buffer);
    }

    ptr_line->data->refresh_needed = 1;
}
Beispiel #27
0
struct t_gui_line *
gui_line_add (struct t_gui_buffer *buffer, time_t date,
              time_t date_printed, const char *tags,
              const char *prefix, const char *message)
{
    struct t_gui_line *new_line;
    struct t_gui_line_data *new_line_data;
    struct t_gui_window *ptr_win;
    char *message_for_signal;
    const char *nick;
    int notify_level, *max_notify_level, lines_removed;
    time_t current_time;

    /*
     * remove line(s) if necessary, according to history options:
     *   max_lines:   if > 0, keep only N lines in buffer
     *   max_minutes: if > 0, keep only lines from last N minutes
     */
    lines_removed = 0;
    current_time = time (NULL);
    while (buffer->own_lines->first_line
           && (((CONFIG_INTEGER(config_history_max_buffer_lines_number) > 0)
                && (buffer->own_lines->lines_count + 1 >
                    CONFIG_INTEGER(config_history_max_buffer_lines_number)))
               || ((CONFIG_INTEGER(config_history_max_buffer_lines_minutes) > 0)
                   && (current_time - buffer->own_lines->first_line->data->date_printed >
                       CONFIG_INTEGER(config_history_max_buffer_lines_minutes) * 60))))
    {
        gui_line_free (buffer, buffer->own_lines->first_line);
        lines_removed++;
    }

    /* create new line */
    new_line = malloc (sizeof (*new_line));
    if (!new_line)
    {
        log_printf (_("Not enough memory for new line"));
        return NULL;
    }

    /* create data for line */
    new_line_data = malloc (sizeof (*(new_line->data)));
    if (!new_line_data)
    {
        free (new_line);
        log_printf (_("Not enough memory for new line"));
        return NULL;
    }
    new_line->data = new_line_data;

    /* fill data in new line */
    new_line->data->buffer = buffer;
    new_line->data->y = -1;
    new_line->data->date = date;
    new_line->data->date_printed = date_printed;
    new_line->data->str_time = gui_chat_get_time_string (date);
    gui_line_tags_alloc (new_line->data, tags);
    new_line->data->refresh_needed = 0;
    new_line->data->prefix = (prefix) ?
        (char *)string_shared_get (prefix) : ((date != 0) ? (char *)string_shared_get ("") : NULL);
    new_line->data->prefix_length = (prefix) ?
        gui_chat_strlen_screen (prefix) : 0;
    new_line->data->message = (message) ? strdup (message) : strdup ("");

    /* get notify level and max notify level for nick in buffer */
    notify_level = gui_line_get_notify_level (new_line);
    max_notify_level = NULL;
    nick = gui_line_get_nick_tag (new_line);
    if (nick)
        max_notify_level = hashtable_get (buffer->hotlist_max_level_nicks, nick);
    if (max_notify_level
        && (*max_notify_level < notify_level))
        notify_level = *max_notify_level;

    if (notify_level == GUI_HOTLIST_HIGHLIGHT)
        new_line->data->highlight = 1;
    else if (max_notify_level && (*max_notify_level < GUI_HOTLIST_HIGHLIGHT))
        new_line->data->highlight = 0;
    else
        new_line->data->highlight = gui_line_has_highlight (new_line);

    /* check if line is filtered or not */
    new_line->data->displayed = gui_filter_check_line (new_line->data);

    /* add line to lines list */
    gui_line_add_to_list (buffer->own_lines, new_line);

    /* update hotlist and/or send signals for line */
    if (new_line->data->displayed)
    {
        if (new_line->data->highlight)
        {
            (void) gui_hotlist_add (buffer, GUI_HOTLIST_HIGHLIGHT, NULL);
            if (!weechat_upgrading)
            {
                message_for_signal = gui_chat_build_string_prefix_message (new_line);
                if (message_for_signal)
                {
                    hook_signal_send ("weechat_highlight",
                                      WEECHAT_HOOK_SIGNAL_STRING,
                                      message_for_signal);
                    free (message_for_signal);
                }
            }
        }
        else
        {
            if (!weechat_upgrading && (notify_level == GUI_HOTLIST_PRIVATE))
            {
                message_for_signal = gui_chat_build_string_prefix_message (new_line);
                if (message_for_signal)
                {
                    hook_signal_send ("weechat_pv",
                                      WEECHAT_HOOK_SIGNAL_STRING,
                                      message_for_signal);
                    free (message_for_signal);
                }
            }
            if (notify_level >= GUI_HOTLIST_MIN)
                (void) gui_hotlist_add (buffer, notify_level, NULL);
        }
    }
    else
    {
        buffer->own_lines->lines_hidden++;
        if (buffer->mixed_lines)
            buffer->mixed_lines->lines_hidden++;
        hook_signal_send ("buffer_lines_hidden",
                          WEECHAT_HOOK_SIGNAL_POINTER, buffer);
    }

    /* add mixed line, if buffer is attached to at least one other buffer */
    if (buffer->mixed_lines)
    {
        gui_line_mixed_add (buffer->mixed_lines, new_line->data);
    }

    /*
     * if some lines were removed, force a full refresh if at least one window
     * is displaying buffer and that number of lines in buffer is lower than
     * window height
     */
    if (lines_removed > 0)
    {
        for (ptr_win = gui_windows; ptr_win; ptr_win = ptr_win->next_window)
        {
            if ((ptr_win->buffer == buffer)
                && (buffer->own_lines->lines_count < ptr_win->win_chat_height))
            {
                gui_buffer_ask_chat_refresh (buffer, 2);
                break;
            }
        }
    }

    hook_signal_send ("buffer_line_added",
                      WEECHAT_HOOK_SIGNAL_POINTER, new_line);

    return new_line;
}
Beispiel #28
0
void
gui_hotlist_changed_signal (struct t_gui_buffer *buffer)
{
    (void) hook_signal_send ("hotlist_changed",
                             WEECHAT_HOOK_SIGNAL_POINTER, buffer);
}
Beispiel #29
0
void
gui_input_search_signal ()
{
    hook_signal_send ("input_search", WEECHAT_HOOK_SIGNAL_STRING, NULL);
}