Ejemplo n.º 1
0
} END_TEST

START_TEST(test_datastructures_sorted_list) {
  girara_list_t* list = girara_sorted_list_new2((girara_compare_function_t) g_strcmp0,
      (girara_free_function_t) g_free);
  fail_unless((list != NULL), NULL);
  girara_list_t* unsorted_list = girara_list_new2((girara_free_function_t) g_free);
  fail_unless((unsorted_list != NULL), NULL);

  static const char* test_strings[] = {
    "A",
    "C",
    "Baa",
    "Za",
    "Bba",
    "Bab",
    NULL
  };
  static const char* test_strings_sorted[] = {
    "A",
    "Baa",
    "Bab",
    "Bba",
    "C",
    "Za",
    NULL
  };

  // append
  for (const char** p = test_strings; *p != NULL; ++p) {
    girara_list_append(list, (void*)g_strdup(*p));
    girara_list_append(unsorted_list, (void*)g_strdup(*p));
  }

  fail_unless((girara_list_size(list) == sizeof(test_strings) / sizeof(char*) - 1), NULL);
  fail_unless((girara_list_size(unsorted_list) == sizeof(test_strings) / sizeof(char*) - 1), NULL);

  // check sorting
  const char** p = test_strings_sorted;
  GIRARA_LIST_FOREACH(list, const char*, iter, value)
    fail_unless((g_strcmp0(value, *p) == 0), NULL);
    ++p;
  GIRARA_LIST_FOREACH_END(list, const char*, iter, value);

  girara_list_sort(unsorted_list, (girara_compare_function_t) g_strcmp0);
  p = test_strings_sorted;
  GIRARA_LIST_FOREACH(unsorted_list, const char*, iter, value)
    fail_unless((g_strcmp0(value, *p) == 0), NULL);
    ++p;
  GIRARA_LIST_FOREACH_END(unsorted_list, const char*, iter, value);

  girara_list_free(list);
  girara_list_free(unsorted_list);
} END_TEST
Ejemplo n.º 2
0
girara_list_t*
pdf_document_attachments_get(zathura_document_t* document, void* data, zathura_error_t* error)
{
  if (document == NULL || data == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    return NULL;
  }

  PopplerDocument* poppler_document = data;
  if (poppler_document_has_attachments(poppler_document) == FALSE) {
    girara_warning("PDF file has no attachments");
    if (error != NULL) {
      *error = ZATHURA_ERROR_UNKNOWN;
    }
    return NULL;
  }

  girara_list_t* res = girara_sorted_list_new2((girara_compare_function_t) g_strcmp0, g_free);
  if (res == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_OUT_OF_MEMORY;
    }
    return NULL;
  }

  GList* attachment_list = poppler_document_get_attachments(poppler_document);
  for (GList* attachments = attachment_list; attachments != NULL; attachments = g_list_next(attachments)) {
    PopplerAttachment* attachment = (PopplerAttachment*) attachments->data;
    girara_list_append(res, g_strdup(attachment->name));
  }

  return res;
}
Ejemplo n.º 3
0
static bool
register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plugin)
{
  if (plugin == NULL
      || plugin->content_types == NULL
      || plugin->register_function == NULL
      || plugin_manager == NULL
      || plugin_manager->plugins == NULL) {
    girara_error("plugin: could not register\n");
    return false;
  }

  bool at_least_one = false;
  GIRARA_LIST_FOREACH(plugin->content_types, gchar*, iter, type)
  if (plugin_mapping_new(plugin_manager, type, plugin) == false) {
    girara_error("plugin: already registered for filetype %s\n", type);
  } else {
    at_least_one = true;
  }
  GIRARA_LIST_FOREACH_END(plugin->content_types, gchar*, iter, type);

  if (at_least_one == true) {
    girara_list_append(plugin_manager->plugins, plugin);
  }

  return at_least_one;
}
Ejemplo n.º 4
0
static bool
plugin_mapping_new(zathura_plugin_manager_t* plugin_manager, const gchar* type, zathura_plugin_t* plugin)
{
  g_return_val_if_fail(plugin_manager != NULL, false);
  g_return_val_if_fail(type           != NULL, false);
  g_return_val_if_fail(plugin         != NULL, false);

  GIRARA_LIST_FOREACH(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping)
  if (g_content_type_equals(type, mapping->type)) {
    girara_list_iterator_free(iter);
    return false;
  }
  GIRARA_LIST_FOREACH_END(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping);

  zathura_type_plugin_mapping_t* mapping = g_try_malloc0(sizeof(zathura_type_plugin_mapping_t));
  if (mapping == NULL) {
    return false;
  }

  mapping->type   = g_strdup(type);
  mapping->plugin = plugin;
  girara_list_append(plugin_manager->type_plugin_mapping, mapping);

  return true;
}
Ejemplo n.º 5
0
bool
girara_setting_add(girara_session_t* session, const char* name, void* value, girara_setting_type_t type, bool init_only, const char* description, girara_setting_callback_t callback, void* data)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(name != NULL, false);
  g_return_val_if_fail(type != UNKNOWN, false);
  if (type != STRING && value == NULL) {
    return false;
  }

  /* search for existing setting */
  if (girara_setting_find(session, name) != NULL) {
    return false;
  }

  /* add new setting */
  girara_setting_t* setting = g_slice_new0(girara_setting_t);

  setting->name        = g_strdup(name);
  setting->type        = type;
  setting->init_only   = init_only;
  setting->description = description ? g_strdup(description) : NULL;
  setting->callback    = callback;
  setting->data        = data;
  girara_setting_set_value(NULL, setting, value);

  girara_list_append(session->private_data->settings, setting);

  return true;
}
Ejemplo n.º 6
0
girara_list_t*
jumanji_db_history_find(jumanji_database_t* database, const char* input)
{
  if (database == NULL || database->session == NULL || input == NULL) {
    return NULL;
  }

  /* prepare statement */
  static const char SQL_HISTORY_FIND[] =
    "SELECT * FROM history WHERE "
    "url LIKE (SELECT '%' || ? || '%') OR "
    "title LIKE (SELECT '%' || ? || '%');";

  sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session,
      SQL_HISTORY_FIND);

  if (statement == NULL) {
    return NULL;
  }

  /* bind values */
  if (sqlite3_bind_text(statement, 1, input, -1, NULL) != SQLITE_OK ||
      sqlite3_bind_text(statement, 2, input, -1, NULL) != SQLITE_OK
      ) {
    girara_error("Could not bind query parameters");
    sqlite3_finalize(statement);
    return NULL;
  }

  girara_list_t* results = girara_list_new();

  if (results == NULL) {
    sqlite3_finalize(statement);
    return NULL;
  }

  girara_list_set_free_function(results, jumanji_db_free_result_link);

  while(sqlite3_step(statement) == SQLITE_ROW) {
    jumanji_db_result_link_t* link = malloc(sizeof(jumanji_db_result_link_t));
    if (link == NULL) {
      sqlite3_finalize(statement);
      return NULL;
    }

    char* url   = (char*) sqlite3_column_text(statement, 0);
    char* title = (char*) sqlite3_column_text(statement, 1);

    link->url     = g_strdup(url);
    link->title   = g_strdup(title);
    link->visited = sqlite3_column_int(statement, 2);

    girara_list_append(results, link);
  }

  sqlite3_finalize(statement);

  return results;
}
Ejemplo n.º 7
0
void
zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type)
{
  if (plugin == NULL || mime_type == NULL) {
    return;
  }

  girara_list_append(plugin->content_types, g_content_type_from_mime_type(mime_type));
}
Ejemplo n.º 8
0
void
zathura_plugin_manager_add_dir(zathura_plugin_manager_t* plugin_manager, const char* dir)
{
  if (plugin_manager == NULL || plugin_manager->path == NULL) {
    return;
  }

  girara_list_append(plugin_manager->path, g_strdup(dir));
}
Ejemplo n.º 9
0
} END_TEST

START_TEST(test_datastructures_list_free_free_function) {
  // free function
  girara_list_t* list = girara_list_new();
  list_free_called = 0;
  fail_unless((list != NULL), NULL);
  girara_list_set_free_function(list, list_free);
  girara_list_append(list, (void*) 0xDEAD);
  girara_list_free(list);
  fail_unless((list_free_called == 1), NULL);
} END_TEST
Ejemplo n.º 10
0
} END_TEST

START_TEST(test_datastructures_list_free_already_cleared) {
  // free cleared list
  girara_list_t* list = girara_list_new();
  fail_unless((list != NULL), NULL);
  girara_list_append(list, (void*) 0xDEAD);
  fail_unless((girara_list_size(list) == 1), NULL);
  girara_list_clear(list);
  fail_unless((girara_list_size(list) == 0), NULL);
  girara_list_free(list);
} END_TEST
Ejemplo n.º 11
0
} END_TEST

START_TEST(test_datastructures_list_free_free_function_remove) {
  // remove with free function
  list_free_called = 0;
  girara_list_t* list = girara_list_new2(list_free);
  fail_unless((list != NULL), NULL);
  girara_list_append(list, (void*)0xDEAD);
  girara_list_remove(list, (void*)0xDEAD);
  fail_unless((girara_list_size(list) == 0), NULL);
  girara_list_free(list);
  fail_unless((list_free_called == 1), NULL);
} END_TEST
Ejemplo n.º 12
0
} END_TEST

START_TEST(test_datastructures_list_merge) {
  girara_list_t* list1 = girara_list_new();
  girara_list_t* list2 = girara_list_new();
  fail_unless((list1 != NULL), NULL);
  fail_unless((list2 != NULL), NULL);

  fail_unless((girara_list_merge(NULL, NULL) == NULL), NULL);
  fail_unless((girara_list_merge(list1, NULL) == list1), NULL);
  fail_unless((girara_list_merge(NULL, list2) == NULL), NULL);

  girara_list_append(list1, (void*)0);
  girara_list_append(list2, (void*)1);

  girara_list_t* list3 = girara_list_merge(list1, list2);
  fail_unless((list3 == list1), NULL);
  fail_unless((girara_list_nth(list3, 0) == (void*)0), NULL);
  fail_unless((girara_list_nth(list3, 1) == (void*)1), NULL);
  girara_list_free(list1);
  girara_list_free(list2);
} END_TEST
Ejemplo n.º 13
0
bool
cmd_search_engine(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  jumanji_t* jumanji = (jumanji_t*) session->global.data;

  if (jumanji->global.search_engines == NULL) {
    return false;
  }

  if (girara_list_size(argument_list) < 2) {
    return false;
  }

  char* identifier = (char*) girara_list_nth(argument_list, 0);
  char* url        = (char*) girara_list_nth(argument_list, 1);

  /* search for existing search engine */
  if (girara_list_size(jumanji->global.search_engines) > 0) {
    girara_list_iterator_t* iter = girara_list_iterator(jumanji->global.search_engines);

    do {
      jumanji_search_engine_t* search_engine = (jumanji_search_engine_t*) girara_list_iterator_data(iter);
      if (search_engine == NULL) {
        continue;
      }

      if (!g_strcmp0(search_engine->identifier, identifier)) {
        g_free(search_engine->url);
        search_engine->url = g_strdup(url);
        return true;
      }
    } while (girara_list_iterator_next(iter));

    girara_list_iterator_free(iter);
  }

  /* create new entry */
  jumanji_search_engine_t* search_engine = malloc(sizeof(jumanji_search_engine_t));
  if (search_engine == NULL) {
    return false;
  }

  search_engine->url        = g_strdup(url);
  search_engine->identifier = g_strdup(identifier);

  girara_list_append(jumanji->global.search_engines, search_engine);

  return true;
}
Ejemplo n.º 14
0
zathura_bookmark_t*
zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page)
{
  g_return_val_if_fail(zathura && zathura->document && zathura->bookmarks.bookmarks, NULL);
  g_return_val_if_fail(id, NULL);

  double position_x = zathura_document_get_position_x(zathura->document);
  double position_y = zathura_document_get_position_y(zathura->document);
  zathura_bookmark_t* old = zathura_bookmark_get(zathura, id);

  if (old != NULL) {
    old->page = page;
    old->x = position_x;
    old->y = position_y;

    if (zathura->database != NULL) {
      const char* path = zathura_document_get_path(zathura->document);
      if (zathura_db_remove_bookmark(zathura->database, path, old->id) == false) {
        girara_warning("Failed to remove old bookmark from database.");
      }

      if (zathura_db_add_bookmark(zathura->database, path, old) == false) {
        girara_warning("Failed to add new bookmark to database.");
      }
    }

    return old;
  }

  zathura_bookmark_t* bookmark = g_try_malloc0(sizeof(zathura_bookmark_t));
  if (bookmark == NULL) {
    return NULL;
  }

  bookmark->id = g_strdup(id);
  bookmark->page = page;
  bookmark->x = position_x;
  bookmark->y = position_y;
  girara_list_append(zathura->bookmarks.bookmarks, bookmark);

  if (zathura->database != NULL) {
    const char* path = zathura_document_get_path(zathura->document);
    if (zathura_db_add_bookmark(zathura->database, path, bookmark) == false) {
      girara_warning("Failed to add bookmark to database.");
    }
  }

  return bookmark;
}
Ejemplo n.º 15
0
girara_list_t*
girara_split_path_array(const char* patharray)
{
  if (patharray == NULL || !g_strcmp0(patharray, "")) {
    return NULL;
  }

  girara_list_t* res = girara_list_new2(g_free);
  char** paths = g_strsplit(patharray, ":", 0);
  for (size_t i = 0; paths[i] != NULL; ++i) {
    girara_list_append(res, g_strdup(paths[i]));
  }
  g_strfreev(paths);

  return res;
}
Ejemplo n.º 16
0
bool
synctex_view(zathura_t* zathura, const char* input_file,
             unsigned int line, unsigned int column)
{
  if (zathura == NULL || input_file == NULL) {
    return false;
  }

  const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);

  unsigned int page = 0;
  girara_list_t* secondary_rects = NULL;
  girara_list_t* rectangles = synctex_rectangles_from_position(
    zathura_document_get_path(zathura->document), input_file, line,
    column, &page, &secondary_rects);

  if (rectangles == NULL) {
    return false;
  }

  girara_list_t** all_rectangles = g_try_malloc0(number_of_pages * sizeof(girara_list_t*));
  if (all_rectangles == NULL) {
    girara_list_free(rectangles);
    return false;
  }

  for (unsigned int p = 0; p != number_of_pages; ++p) {
    if (p == page) {
      all_rectangles[p] = rectangles;
    } else {
      all_rectangles[p] = girara_list_new2(g_free);
    }
  }

  if (secondary_rects != NULL) {
    GIRARA_LIST_FOREACH(secondary_rects, synctex_page_rect_t*, iter, rect)
      zathura_rectangle_t* newrect = g_try_malloc0(sizeof(zathura_rectangle_t));
      if (newrect != NULL) {
        *newrect = rect->rect;
        girara_list_append(all_rectangles[rect->page], newrect);
      }
    GIRARA_LIST_FOREACH_END(secondary_rects, synctex_page_rect_t*, iter, rect);
  }
Ejemplo n.º 17
0
static girara_list_t*
read_pwd_info(void)
{
  girara_list_t* list = girara_list_new();
  girara_list_set_free_function(list, &free_pwd_info);

  struct passwd* pw;
  errno = 0;
  while ((pw = getpwent()) != NULL) {
    pwd_info_t* pwdinfo = g_malloc0(sizeof(pwd_info_t));
    pwdinfo->name = g_strdup(pw->pw_name);
    pwdinfo->dir = g_strdup(pw->pw_dir);
    girara_list_append(list, pwdinfo);
    errno = 0;
  }
  fail_unless(errno == 0, "Non-zero errno :%d", errno, NULL);
  endpwent();

  return list;
}
Ejemplo n.º 18
0
void
mark_add(zathura_t* zathura, int key)
{
  if (zathura == NULL || zathura->document == NULL || zathura->global.marks == NULL) {
    return;
  }

  GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view);
  GtkAdjustment* v_adjustment = gtk_scrolled_window_get_vadjustment(window);
  GtkAdjustment* h_adjustment = gtk_scrolled_window_get_hadjustment(window);

  if (v_adjustment == NULL || h_adjustment == NULL) {
    return;
  }

  double position_x = gtk_adjustment_get_value(h_adjustment);
  double position_y = gtk_adjustment_get_value(v_adjustment);
  float scale       = zathura_document_get_scale(zathura->document);

  /* search for existing mark */
  GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark)
    if (mark->key == key) {
      mark->position_x = position_x;
      mark->position_y = position_y;
      mark->scale      = scale;
      return;
    }
  GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark);

  /* add new mark */
  zathura_mark_t* mark = g_malloc0(sizeof(zathura_mark_t));

  mark->key        = key;
  mark->position_x = position_x;
  mark->position_y = position_y;
  mark->scale      = scale;

  girara_list_append(zathura->global.marks, mark);
}
Ejemplo n.º 19
0
girara_list_t*
synctex_rectangles_from_position(const char* filename, const char* input_file,
                                 int line, int column, unsigned int* page,
                                 girara_list_t** secondary_rects)
{
  if (filename == NULL || input_file == NULL || page == NULL) {
    return NULL;
  }

  synctex_scanner_t scanner = synctex_scanner_new_with_output_file(filename, NULL, 1);
  if (scanner == NULL) {
    girara_debug("Failed to create synctex scanner.");
    return NULL;
  }

  synctex_scanner_t temp = synctex_scanner_parse(scanner);
  if (temp == NULL) {
    girara_debug("Failed to parse synctex file.");
    synctex_scanner_free(scanner);
    return NULL;
  }

  girara_list_t* hitlist     = girara_list_new2(g_free);
  girara_list_t* other_rects = girara_list_new2(g_free);

  if (synctex_display_query(scanner, input_file, line, column) > 0) {
    synctex_node_t node        = NULL;
    bool got_page              = false;

    while ((node = synctex_next_result (scanner)) != NULL) {
      const unsigned int current_page = synctex_node_page(node) - 1;
      if (got_page == false) {
        got_page = true;
        *page = current_page;
      }

      zathura_rectangle_t rect = { 0, 0, 0, 0 };
      rect.x1 = synctex_node_box_visible_h(node);
      rect.y1 = synctex_node_box_visible_v(node) - synctex_node_box_visible_height(node);
      rect.x2 = rect.x1 + synctex_node_box_visible_width(node);
      rect.y2 = synctex_node_box_visible_depth(node) + synctex_node_box_visible_height (node) + rect.y1;

      if (*page == current_page) {
        zathura_rectangle_t* real_rect = g_try_malloc(sizeof(zathura_rectangle_t));
        if (real_rect == NULL) {
          continue;
        }

        *real_rect = rect;
        girara_list_append(hitlist, real_rect);
      } else {
        synctex_page_rect_t* page_rect = g_try_malloc(sizeof(synctex_page_rect_t));
        if (page_rect == NULL) {
          continue;
        }

        page_rect->page = current_page;
        page_rect->rect = rect;

        girara_list_append(other_rects, page_rect);
      }
    }
  }

  synctex_scanner_free(scanner);

  if (secondary_rects != NULL) {
    *secondary_rects = other_rects;
  } else {
    girara_list_free(other_rects);
  }

  return hitlist;
}
Ejemplo n.º 20
0
girara_list_t*
pdf_page_images_get(zathura_page_t* page, void* data, zathura_error_t* error)
{
  mupdf_page_t* mupdf_page = data;

  if (page == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  girara_list_t* list = NULL;
  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    goto error_ret;
  }

  mupdf_document_t* mupdf_document = zathura_document_get_data(document);

  /* Setup image list */
  list = girara_list_new();
  if (list == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_OUT_OF_MEMORY;
    }
    goto error_free;
  }

  girara_list_set_free_function(list, (girara_free_function_t) pdf_zathura_image_free);

  /* Extract images */
  mupdf_page_extract_text(mupdf_document, mupdf_page);

  fz_stext_block* block;
  for (block = mupdf_page->text->first_block; block; block = block->next) {
    if (block->type == FZ_STEXT_BLOCK_IMAGE) {
      zathura_image_t* zathura_image = g_malloc(sizeof(zathura_image_t));

      zathura_image->position.x1 = block->bbox.x0;
      zathura_image->position.y1 = block->bbox.y0;
      zathura_image->position.x2 = block->bbox.x1;
      zathura_image->position.y2 = block->bbox.y1;
      zathura_image->data        = block->u.i.image;

      girara_list_append(list, zathura_image);
    }
  }

  return list;

error_free:

  if (error != NULL && *error == ZATHURA_ERROR_OK) {
    *error = ZATHURA_ERROR_UNKNOWN;
  }

  if (list != NULL) {
    girara_list_free(list);
  }

error_ret:

  return NULL;
}
Ejemplo n.º 21
0
static girara_list_t*
list_files(zathura_t* zathura, const char* current_path, const char* current_file,
    unsigned int current_file_length, bool is_dir, bool check_file_ext)
{
  if (zathura == NULL || zathura->ui.session == NULL || current_path == NULL) {
    return NULL;
  }

  /* read directory */
  GDir* dir = g_dir_open(current_path, 0, NULL);
  if (dir == NULL) {
    return NULL;
  }

  girara_list_t* res = girara_sorted_list_new2((girara_compare_function_t)compare_case_insensitive,
      (girara_free_function_t)g_free);

  bool show_hidden = false;
  girara_setting_get(zathura->ui.session, "show-hidden", &show_hidden);
  bool show_directories = true;
  girara_setting_get(zathura->ui.session, "show-directories", &show_directories);

  /* read files */
  char* name = NULL;
  while ((name = (char*) g_dir_read_name(dir)) != NULL) {
    char* e_name   = g_filename_display_name(name);
    if (e_name == NULL) {
      goto error_free;
    }

    size_t e_length = strlen(e_name);

    if (show_hidden == false && e_name[0] == '.') {
      g_free(e_name);
      continue;
    }

    if ((current_file_length > e_length) || strncmp(current_file, e_name, current_file_length)) {
      g_free(e_name);
      continue;
    }

    char* tmp = "/";
    if (is_dir == true || g_strcmp0(current_path, "/") == 0) {
      tmp = "";
    };

    char* full_path = g_strdup_printf("%s%s%s", current_path, tmp, e_name);

    if (g_file_test(full_path, G_FILE_TEST_IS_DIR) == true) {
      if (show_directories == false) {
        g_free(e_name);
        g_free(full_path);
        continue;
      }
      girara_list_append(res, full_path);
    } else if (check_file_ext == false || file_valid_extension(zathura, full_path) == true) {
      girara_list_append(res, full_path);
    } else {
      g_free(full_path);
    }
    g_free(e_name);
  }

  g_dir_close(dir);

  if (girara_list_size(res) == 1) {
    char* path = girara_list_nth(res, 0);
    if (g_file_test(path, G_FILE_TEST_IS_DIR) == true) {
      char* newpath = g_strdup_printf("%s/", path);
      girara_list_clear(res);
      girara_list_append(res, newpath);
    }
  }

  return res;

error_free:
  girara_list_free(res);
  return NULL;
}
Ejemplo n.º 22
0
girara_list_t*
djvu_page_links_get(zathura_page_t* page, void* UNUSED(data), zathura_error_t* error)
{
  if (page == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    goto error_ret;
  }

  girara_list_t* list = girara_list_new2((girara_free_function_t) zathura_link_free);
  if (list == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_OUT_OF_MEMORY;
    }
    goto error_ret;
  }

  djvu_document_t* djvu_document = zathura_document_get_data(document);

  miniexp_t annotations = miniexp_nil;
  while ((annotations = ddjvu_document_get_pageanno(djvu_document->document,
          zathura_page_get_index(page))) == miniexp_dummy) {
    handle_messages(djvu_document, true);
  }

  if (annotations == miniexp_nil) {
    goto error_free;
  }

  miniexp_t* hyperlinks = ddjvu_anno_get_hyperlinks(annotations);
  for (miniexp_t* iter = hyperlinks; *iter != NULL; iter++) {
    if (miniexp_car(*iter) != miniexp_symbol("maparea")) {
      continue;
    }

    miniexp_t inner = miniexp_cdr(*iter);

    /* extract url information */
    const char* target_string = NULL;

    if (miniexp_caar(inner) == miniexp_symbol("url")) {
      if (exp_to_str(miniexp_caddr(miniexp_car(inner)), &target_string) == false) {
        continue;
      }
    } else {
      if (exp_to_str(miniexp_car(inner), &target_string) == false) {
        continue;
      }
    }

    /* skip comment */
    inner = miniexp_cdr(inner);

    /* extract link area */
    inner = miniexp_cdr(inner);

    zathura_rectangle_t rect = { 0, 0, 0, 0 };
    if (exp_to_rect(miniexp_car(inner), &rect) == false) {
      continue;
    }

    /* update rect */
    unsigned int page_height = zathura_page_get_height(page) / ZATHURA_DJVU_SCALE;
    rect.x1 = rect.x1 * ZATHURA_DJVU_SCALE;
    rect.x2 = rect.x2 * ZATHURA_DJVU_SCALE;
    double tmp = rect.y1;
    rect.y1 = (page_height - rect.y2) * ZATHURA_DJVU_SCALE;
    rect.y2 = (page_height - tmp)     * ZATHURA_DJVU_SCALE;

    /* create zathura link */
    zathura_link_type_t type = ZATHURA_LINK_INVALID;
    zathura_link_target_t target = { ZATHURA_LINK_DESTINATION_UNKNOWN, NULL, 0, -1, -1, -1, -1, 0 };;

    /* goto page */
    if (target_string[0] == '#' && target_string[1] == 'p') {
      type = ZATHURA_LINK_GOTO_DEST;
      target.page_number = atoi(target_string + 2) - 1;
    /* url or other? */
    } else if (strstr(target_string, "//") != NULL) {
      type = ZATHURA_LINK_URI;
      target.value = (char*) target_string;
    /* TODO: Parse all different links */
    } else {
      continue;
    }

    zathura_link_t* link = zathura_link_new(type, rect, target);
    if (link != NULL) {
      girara_list_append(list, link);
    }
  }

  return list;

error_free:

  if (list != NULL) {
    girara_list_free(list);
  }

error_ret:

  return NULL;
}
Ejemplo n.º 23
0
bool
cmd_proxy(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  jumanji_t* jumanji = (jumanji_t*) session->global.data;

  if (jumanji->global.proxies == NULL) {
    return false;
  }

  unsigned int number_of_arguments = girara_list_size(argument_list);
  if (number_of_arguments < 1) {
    return false;
  }

  char* url         = (char*) girara_list_nth(argument_list, 0);
  char* description = (number_of_arguments > 1) ? (char*) girara_list_nth(argument_list, 1) : NULL;

  if (url == NULL) {
    return false;
  }

  url = (strstr(url, "://") != NULL) ? g_strdup(url) : g_strconcat("http://", url, NULL);

  /* search for existing proxy */
  if (girara_list_size(jumanji->global.proxies) > 0) {
    girara_list_iterator_t* iter = girara_list_iterator(jumanji->global.proxies);

    do {
      jumanji_proxy_t* proxy = (jumanji_proxy_t*) girara_list_iterator_data(iter);
      if (proxy == NULL) {
        continue;
      }

      if (!g_strcmp0(proxy->url, url)) {
        g_free(proxy->url);
        g_free(proxy->description);
        proxy->url         = g_strdup(url);
        proxy->description = description ? g_strdup(description) : NULL;
        g_free(url);
        girara_list_iterator_free(iter);
        return true;
      }
    } while (girara_list_iterator_next(iter));

    girara_list_iterator_free(iter);
  }

  /* create new entry */
  jumanji_proxy_t* proxy = malloc(sizeof(jumanji_proxy_t));
  if (proxy == NULL) {
    g_free(url);
    return false;
  }

  proxy->url         = url;
  proxy->description = description != NULL ? g_strdup(description) : NULL;

  girara_list_append(jumanji->global.proxies, proxy);

  return true;
}