示例#1
0
/* @brief Processes an entered key by:
 * 
 * 1) Adding the key to the query buffer (backspace will remove a character).
 * 2) Drawing the updated query to the screen if necessary.
 * 3) Writing the updated query to the child process if necessary.
 * 
 * @param query_buffer The string of the current query (what is typed).
 * @param query_index A reference to the current length of the query.
 * @param query_cursor_index A reference to the current index of the cursor
          in the query.
 * @param key The key enetered.
 * @param connection A connection to the Xorg server.
 * @param cairo_context A cairo context for drawing to the screen.
 * @param cairo_surface A cairo surface for drawing to the screen.
 * @param to_write A descriptor to write to the child process.
 * @return 0 on success and 1 on failure.
 */
static inline int32_t process_key_stroke(char *query_buffer, uint32_t *query_index, uint32_t *query_cursor_index, xcb_keysym_t key, xcb_connection_t *connection, cairo_t *cairo_context, cairo_surface_t *cairo_surface, FILE *to_write) {
  pthread_mutex_lock(&global.result_mutex);

  /* Check when we should update. */
  int32_t redraw = 0;
  int32_t resend = 0;

  debug("key: %u\n", key);

  switch (key) {
    case 65293: /* Enter. */
      if (global.results && global.result_highlight < global.result_count && global.result_highlight >= 0) {
        printf("%s", global.results[global.result_highlight].action);
        goto cleanup;
      }
      break;
    case 65361: /* Left. */
      if (*query_cursor_index > 0) {
        (*query_cursor_index)--;
        redraw = 1;
      }
      break;
    case 65363: /* Right. */
      if (*query_cursor_index < *query_index) {
        (*query_cursor_index)++;
        redraw = 1;
      }
      break;
    case 65362: /* Up. */
      if (global.result_highlight > 0) {
        global.result_highlight--;
        draw_response_text(connection, 0, cairo_context, cairo_surface, global.results, global.result_count);
      }
      break;
    case 65364: /* Down. */
      if (global.result_count && global.result_highlight < global.result_count - 1) {
        global.result_highlight++;
        draw_response_text(connection, 0, cairo_context, cairo_surface, global.results, global.result_count);
      }
      break;
    case 65289: /* Tab. */
      if (global.result_count && global.result_highlight < global.result_count - 1) {
        global.result_highlight++;
        draw_response_text(connection, 0, cairo_context, cairo_surface, global.results, global.result_count);
      } else if(global.result_count && global.result_highlight == global.result_count - 1) {
        global.result_highlight = 0;
        draw_response_text(connection, 0, cairo_context, cairo_surface, global.results, global.result_count);
      }
      break;
    case 65056: /* Shift Tab */
      if (global.result_count && global.result_highlight > 0) {
        global.result_highlight--;
        draw_response_text(connection, 0, cairo_context, cairo_surface, global.results, global.result_count);
      } else if(global.result_count && global.result_highlight == 0) {
        global.result_highlight = global.result_count - 1;
        draw_response_text(connection, 0, cairo_context, cairo_surface, global.results, global.result_count);
      }
      break;
    case 65307: /* Escape. */
      goto cleanup;
    case 65288: /* Backspace. */
      if (*query_index > 0 && *query_cursor_index > 0) {
        memmove(&query_buffer[(*query_cursor_index) - 1], &query_buffer[*query_cursor_index], *query_index - *query_cursor_index + 1);
        (*query_cursor_index)--;
        (*query_index)--;
        query_buffer[(*query_index)] = 0;
        redraw = 1;
        resend = 1;
      } else if (*query_index == 0 && settings.backspace_exit) { /* Backspace with nothing? */
        goto cleanup;
      }
      break;
    default:
      if (isprint((char)key) && *query_index < MAX_QUERY) {
        memmove(&query_buffer[(*query_cursor_index) + 1], &query_buffer[*query_cursor_index], *query_index - *query_cursor_index + 1);
        query_buffer[(*query_cursor_index)++] = key;
        (*query_index)++;
        redraw = 1;
        resend = 1;
      }
      break;
  }

  if (redraw) {
    draw_query_text(cairo_context, cairo_surface, query_buffer, *query_cursor_index);
    xcb_flush(connection);
  }

  if (resend) {
    if (write_to_remote(to_write, "%s\n", query_buffer)) {
      fprintf(stderr, "Failed to write.\n");
    }
  }

  pthread_mutex_unlock(&global.result_mutex);
  return 1;

cleanup:
  pthread_mutex_unlock(&global.result_mutex);
  return 0;
}
示例#2
0
/* @brief Processes an entered key by:
 *
 * 1) Adding the key to the query buffer (backspace will remove a character).
 * 2) Drawing the updated query to the screen if necessary.
 * 3) Writing the updated query to the child process if necessary.
 *
 * @param query_buffer The string of the current query (what is typed).
 * @param query_index A reference to the current length of the query.
 * @param query_cursor_index A reference to the current index of the cursor
          in the query.
 * @param key The key enetered.
 * @param connection A connection to the Xorg server.
 * @param cairo_context A cairo context for drawing to the screen.
 * @param cairo_surface A cairo surface for drawing to the screen.
 * @param to_write A descriptor to write to the child process.
 * @return 0 on success and 1 on failure.
 */
static inline int32_t process_key_stroke(xcb_window_t window, char *query_buffer, uint32_t *query_index, uint32_t *query_cursor_index, xcb_keysym_t key, uint16_t modifier_mask, xcb_connection_t *connection, cairo_t *cairo_context, cairo_surface_t *cairo_surface, FILE *to_write) {
  pthread_mutex_lock(&global.result_mutex);

  /* Check when we should update. */
  int32_t redraw = 0;
  int32_t resend = 0;

  uint8_t mod_key = get_modifiers(modifier_mask);

  debug("key: %u, modifier: %u\n", key, mod_key);

  uint32_t highlight = global.result_highlight;
  uint32_t old_pos;
  if (global.result_count && key == 100 && mod_key == 3) {
    /* CTRL-D
     * GO down to the next title
     */
    next_title(&highlight);
    draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
  } else if (global.result_count && key == 117 && mod_key == 3) {
    /* CTRL-U
     * GO up to the next title
     */
    previous_title(&highlight);
    draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
  } else {
  switch (key) {
    case 65293: /* Enter. */
      if (global.results && global.result_highlight < global.result_count) {
		char *title = global.results[global.result_highlight].text;
		char *action = global.results[global.result_highlight].action;

		char command[255] = "echo '";
		strcat(command, query_buffer);
		strcat(command, " {");
		char titleParsed[255];
		str_replace(strcpy(titleParsed, title), "'", "'\\''");
		strcat(command, titleParsed);
		strcat(command, " | ");
		char actionParsed[255];
		str_replace(strcpy(actionParsed, action), "'", "'\\''");
		strcat(command, actionParsed);
		strcat(command, "}");
		strcat(command, "' >> /home/olli/.local/share/lighthouse_queries && ");
        printf("%s", command);

        printf("%s", action);
        goto cleanup;
      }
      break;
    case 65471: /* F2 */
      next_title(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65472: /* F3 */
      previous_title(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65361: /* Left. */
      if (*query_cursor_index > 0) {
        (*query_cursor_index)--;
        redraw = 1;
      }
      break;
    case 65363: /* Right. */
      if (*query_cursor_index < *query_index) {
        (*query_cursor_index)++;
        redraw = 1;
      }
      break;
    case 65362: /* Up. */
      if (!global.result_count)
          break;
      if (highlight) { /* Avoid segfault when highlight on the top. */
        old_pos = highlight;
        get_previous_non_title(&highlight);
        if (!global.results[highlight].action) {
            /* If it's a title it mean the get_previous_non_title function
            * found nothing and hit the top.
            */
            highlight = old_pos; /* To not let the highlight point on a title. */
            if (global.result_offset)
                global.result_offset--;
        }
        global.result_highlight = highlight;
        draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      }
      break;
    case 65364: /* Down. */
      if (!global.result_count)
          break;
      if (highlight < global.result_count - 1) {
       old_pos = highlight;
       get_next_non_title(&highlight);
       if (highlight == global.result_count) {
           /* If no other result with an action can be found, it just inc the
            * the offset so it can show the hidden title and make the highlight to the
            * previous non_title.
            * NB: If the offset limit is exceed, it's handled by the draw_result_text function.
            */
            highlight = old_pos;
            global.result_offset++;
       }
       global.result_highlight = highlight;
       draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      }
      break;
    case 65289: /* Tab. */
      if (!global.result_count)
          break;
      get_next_line(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65056: /* Shift Tab */
      if (!global.result_count)
          break;
      get_previous_line(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65307: /* Escape. */
      goto cleanup;
    case 65288: /* Backspace. */
      if (*query_index > 0 && *query_cursor_index > 0) {
          memmove(&query_buffer[(*query_cursor_index) - 1], &query_buffer[*query_cursor_index], *query_index - *query_cursor_index + 1);
          (*query_cursor_index)--;
          (*query_index)--;
          query_buffer[(*query_index)] = 0;
          redraw = 1;
          resend = 1;
      } else if (*query_index == 0 && settings.backspace_exit) { /* Backspace with nothing */
          goto cleanup;
      }
      break;
    default:
      if (isprint((char)key) && *query_index < MAX_QUERY) {
          memmove(&query_buffer[(*query_cursor_index) + 1], &query_buffer[*query_cursor_index], *query_index - *query_cursor_index + 1);
          query_buffer[(*query_cursor_index)++] = key;
          (*query_index)++;
          redraw = 1;
          resend = 1;
      }
      break;
  }
  }

  if (redraw) {
    draw_query_text(cairo_context, cairo_surface, query_buffer, *query_cursor_index);
    xcb_flush(connection);
  }

  if (resend) {
    if (write_to_remote(to_write, "%s\n", query_buffer)) {
      fprintf(stderr, "Failed to write.\n");
    }
  }

  pthread_mutex_unlock(&global.result_mutex);
  return 1;

cleanup:
  pthread_mutex_unlock(&global.result_mutex);
  return 0;
}