callbacks.c 20.8 KB
Newer Older
Moritz Lipp's avatar
Moritz Lipp committed
1
/* See LICENSE file for license and copyright information */
Moritz Lipp's avatar
Moritz Lipp committed
2

3
4
5
#include <girara/statusbar.h>
#include <girara/session.h>
#include <girara/settings.h>
Sebastian Ramacher's avatar
Sebastian Ramacher committed
6
#include <girara/utils.h>
Moritz Lipp's avatar
Moritz Lipp committed
7
#include <stdlib.h>
8
#include <gtk/gtk.h>
Moritz Lipp's avatar
Moritz Lipp committed
9
#include <string.h>
10
#include <glib/gi18n.h>
11
#include <math.h>
Moritz Lipp's avatar
Moritz Lipp committed
12

Sebastian Ramacher's avatar
Sebastian Ramacher committed
13
#include "callbacks.h"
Moritz Lipp's avatar
Moritz Lipp committed
14
#include "links.h"
Moritz Lipp's avatar
Moritz Lipp committed
15
#include "zathura.h"
Moritz Lipp's avatar
Moritz Lipp committed
16
#include "render.h"
17
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
18
#include "utils.h"
Sebastian Ramacher's avatar
Sebastian Ramacher committed
19
#include "shortcuts.h"
20
#include "page-widget.h"
Moritz Lipp's avatar
Moritz Lipp committed
21
#include "page.h"
22
#include "adjustment.h"
23
24
#include "synctex.h"
#include "dbus-interface.h"
Moritz Lipp's avatar
Moritz Lipp committed
25
26

gboolean
27
cb_destroy(GtkWidget* UNUSED(widget), zathura_t* zathura)
Moritz Lipp's avatar
Moritz Lipp committed
28
{
29
  if (zathura != NULL && zathura->document != NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
30
    document_close(zathura, false);
31
32
  }

33
  gtk_main_quit();
Moritz Lipp's avatar
Moritz Lipp committed
34
35
  return TRUE;
}
Moritz Lipp's avatar
Moritz Lipp committed
36
37

void
Moritz Lipp's avatar
Moritz Lipp committed
38
cb_buffer_changed(girara_session_t* session)
Moritz Lipp's avatar
Moritz Lipp committed
39
40
{
  g_return_if_fail(session != NULL);
Moritz Lipp's avatar
Moritz Lipp committed
41
42
43
  g_return_if_fail(session->global.data != NULL);

  zathura_t* zathura = session->global.data;
Moritz Lipp's avatar
Moritz Lipp committed
44
45

  char* buffer = girara_buffer_get(session);
Moritz Lipp's avatar
Moritz Lipp committed
46
  if (buffer != NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
47
    girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
Moritz Lipp's avatar
Moritz Lipp committed
48
    free(buffer);
Moritz Lipp's avatar
Moritz Lipp committed
49
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
50
    girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
51
  }
Moritz Lipp's avatar
Moritz Lipp committed
52
}
53

54
void
55
56
update_visible_pages(zathura_t* zathura)
{
57
  const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
58
59
60

  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
61
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
62
    ZathuraPage* zathura_page_widget = ZATHURA_PAGE(page_widget);
63

64
65
    if (page_is_visible(zathura->document, page_id) == true) {
      /* make page visible */
66
      if (zathura_page_get_visibility(page) == false) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
67
        zathura_page_set_visibility(page, true);
68
        zathura_page_widget_update_view_time(zathura_page_widget);
69
        zathura_renderer_page_cache_add(zathura->sync.render_thread, zathura_page_get_index(page));
70
      }
71

72
    } else {
73
      /* make page invisible */
74
75
76
77
      if (zathura_page_get_visibility(page) == true) {
        zathura_page_set_visibility(page, false);
        /* If a page becomes invisible, abort the render request. */
        zathura_page_widget_abort_render_request(zathura_page_widget);
78
      }
Marwan Tanager's avatar
Marwan Tanager committed
79

80
      /* reset current search result */
Marwan Tanager's avatar
Marwan Tanager committed
81
      girara_list_t* results = NULL;
Sebastian Ramacher's avatar
Sebastian Ramacher committed
82
83
      GObject* obj_page_widget = G_OBJECT(page_widget);
      g_object_get(obj_page_widget, "search-results", &results, NULL);
Marwan Tanager's avatar
Marwan Tanager committed
84
      if (results != NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
85
        g_object_set(obj_page_widget, "search-current", 0, NULL);
Marwan Tanager's avatar
Marwan Tanager committed
86
      }
87
88
    }
  }
89
90
91
92
93
94
95
96
97
98
}

void
cb_view_hadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL) {
    return;
  }

99
100
101
102
103
  /* Do nothing in index mode */
  if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
    return;
  }

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  update_visible_pages(zathura);

  double position_x = zathura_adjustment_get_ratio(adjustment);
  double position_y = zathura_document_get_position_y(zathura->document);
  unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);

  zathura_document_set_position_x(zathura->document, position_x);
  zathura_document_set_position_y(zathura->document, position_y);
  zathura_document_set_current_page_number(zathura->document, page_id);

  statusbar_page_number_update(zathura);
}

void
cb_view_vadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL) {
    return;
  }

125
126
127
128
129
  /* Do nothing in index mode */
  if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
    return;
  }

130
131
132
133
134
135
136
137
138
  update_visible_pages(zathura);

  double position_x = zathura_document_get_position_x(zathura->document);
  double position_y = zathura_adjustment_get_ratio(adjustment);
  unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);

  zathura_document_set_position_x(zathura->document, position_x);
  zathura_document_set_position_y(zathura->document, position_y);
  zathura_document_set_current_page_number(zathura->document, page_id);
139
140

  statusbar_page_number_update(zathura);
141
}
142

Sebastian Ramacher's avatar
Sebastian Ramacher committed
143
144
145
static void
cb_view_adjustment_changed(GtkAdjustment* adjustment, zathura_t* zathura,
    bool width)
146
{
147
148
149
150
151
  /* Do nothing in index mode */
  if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
    return;
  }

Sebastian Ramacher's avatar
Sebastian Ramacher committed
152
153
154
155
  const zathura_adjust_mode_t adjust_mode =
    zathura_document_get_adjust_mode(zathura->document);

  /* Don't scroll, we're focusing the inputbar. */
156
157
  if (adjust_mode == ZATHURA_ADJUST_INPUTBAR) {
    return;
158
  }
159

Sebastian Ramacher's avatar
Sebastian Ramacher committed
160
161
162
163
164
165
166
  /* Save the viewport size */
  unsigned int size = (unsigned int)floor(gtk_adjustment_get_page_size(adjustment));
  if (width == true) {
    zathura_document_set_viewport_width(zathura->document, size);
  } else {
    zathura_document_set_viewport_height(zathura->document, size);
  }
167
168

  /* reset the adjustment, in case bounds have changed */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
169
170
  const double ratio = width == true ?
    zathura_document_get_position_x(zathura->document) :
Sebastian Ramacher's avatar
Sebastian Ramacher committed
171
    zathura_document_get_position_y(zathura->document);
172
  zathura_adjustment_set_value_from_ratio(adjustment, ratio);
173
174
175
}

void
Sebastian Ramacher's avatar
Sebastian Ramacher committed
176
cb_view_hadjustment_changed(GtkAdjustment* adjustment, gpointer data)
177
178
179
180
{
  zathura_t* zathura = data;
  g_return_if_fail(zathura != NULL);

Sebastian Ramacher's avatar
Sebastian Ramacher committed
181
182
  cb_view_adjustment_changed(adjustment, zathura, true);
}
183

Sebastian Ramacher's avatar
Sebastian Ramacher committed
184
185
186
187
188
void
cb_view_vadjustment_changed(GtkAdjustment* adjustment, gpointer data)
{
  zathura_t* zathura = data;
  g_return_if_fail(zathura != NULL);
189

Sebastian Ramacher's avatar
Sebastian Ramacher committed
190
  cb_view_adjustment_changed(adjustment, zathura, false);
191
192
}

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
void
cb_refresh_view(GtkWidget* GIRARA_UNUSED(view), gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL) {
    return;
  }

  unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
  zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
  if (page == NULL) {
    return;
  }

  GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
  GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));

  double position_x = zathura_document_get_position_x(zathura->document);
  double position_y = zathura_document_get_position_y(zathura->document);

  zathura_adjustment_set_value_from_ratio(vadj, position_y);
  zathura_adjustment_set_value_from_ratio(hadj, position_x);

  statusbar_page_number_update(zathura);
}

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
void
cb_monitors_changed(GdkScreen* screen, gpointer data)
{
  girara_debug("signal received");

  zathura_t* zathura = data;
  if (screen == NULL || zathura == NULL) {
    return;
  }

  zathura_update_view_dpi(zathura);
}

void
cb_widget_screen_changed(GtkWidget* widget, GdkScreen* UNUSED(previous_screen), gpointer data)
{
  girara_debug("signal received");

  zathura_t* zathura = data;
  if (widget == NULL || zathura == NULL) {
    return;
  }

  if (gtk_widget_has_screen(widget)) {
    GdkScreen* screen = gtk_widget_get_screen(widget);

    /* disconnect signal on previous screen */
    g_signal_handlers_disconnect_matched(screen, G_SIGNAL_MATCH_FUNC, 0, 0,
        NULL, (gpointer) cb_monitors_changed, zathura);

    /* connect to new screen */
    g_signal_connect(G_OBJECT(screen),
        "monitors-changed", G_CALLBACK(cb_monitors_changed), zathura);
  }

  zathura_update_view_dpi(zathura);
}

257
void
258
cb_scale_factor(GObject* object, GParamSpec* UNUSED(pspec), gpointer data)
259
{
260
261
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL) {
262
    return;
263
264
  }

265
  int new_factor = gtk_widget_get_scale_factor(GTK_WIDGET(object));
266
267
268
269
  if (new_factor == 0) {
    girara_debug("Ignoring new device scale factor = 0");
    return;
  }
270

271
272
273
274
275
  zathura_device_factors_t current = zathura_document_get_device_factors(zathura->document);
  if (fabs(new_factor - current.x) >= DBL_EPSILON ||
      fabs(new_factor - current.y) >= DBL_EPSILON) {
    zathura_document_set_device_factors(zathura->document, new_factor, new_factor);
    girara_debug("New device scale factor: %d", new_factor);
276
    zathura_update_view_dpi(zathura);
277
278
279
280
    render_all(zathura);
  }
}

281
void
Moritz Lipp's avatar
Moritz Lipp committed
282
cb_page_layout_value_changed(girara_session_t* session, const char* name, girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
283
{
284
  g_return_if_fail(value != NULL);
285
286
287
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  zathura_t* zathura = session->global.data;
288

Moritz Lipp's avatar
Moritz Lipp committed
289
290
291
292
293
294
  /* pages-per-row must not be 0 */
  if (g_strcmp0(name, "pages-per-row") == 0) {
    unsigned int pages_per_row = *((unsigned int*) value);
    if (pages_per_row == 0) {
      pages_per_row = 1;
      girara_setting_set(session, name, &pages_per_row);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
295
      girara_notify(session, GIRARA_WARNING, _("'%s' must not be 0. Set to 1."), name);
Moritz Lipp's avatar
Moritz Lipp committed
296
297
298
299
      return;
    }
  }

300
301
302
303
  if (zathura->document == NULL) {
    /* no document has been openend yet */
    return;
  }
304

305
306
  unsigned int pages_per_row = 1;
  girara_setting_get(session, "pages-per-row", &pages_per_row);
307

308
309
310
311
312
313
314
  /* get list of first_page_column settings */
  char* first_page_column_list = NULL;
  girara_setting_get(session, "first-page-column", &first_page_column_list);

  /* find value for first_page_column */
  unsigned int first_page_column = find_first_page_column(first_page_column_list, pages_per_row);
  g_free(first_page_column_list);
315

316
  unsigned int page_padding = 1;
317
  girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
318
319
320

  page_widget_set_mode(zathura, page_padding, pages_per_row, first_page_column);
  zathura_document_set_page_layout(zathura->document, page_padding, pages_per_row, first_page_column);
321
}
322
323

void
Moritz Lipp's avatar
Moritz Lipp committed
324
cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
Moritz Lipp's avatar
Moritz Lipp committed
325
                       GtkTreeViewColumn* UNUSED(column), void* data)
326
{
Sebastian Ramacher's avatar
Sebastian Ramacher committed
327
  zathura_t* zathura = data;
328
329
330
331
332
333
334
  if (tree_view == NULL || zathura == NULL || zathura->ui.session == NULL) {
    return;
  }

  GtkTreeModel  *model;
  GtkTreeIter   iter;

Sebastian Ramacher's avatar
Sebastian Ramacher committed
335
  g_object_get(G_OBJECT(tree_view), "model", &model, NULL);
336

Moritz Lipp's avatar
Moritz Lipp committed
337
  if(gtk_tree_model_get_iter(model, &iter, path)) {
338
    zathura_index_element_t* index_element;
Sebastian Ramacher's avatar
Sebastian Ramacher committed
339
    gtk_tree_model_get(model, &iter, 2, &index_element, -1);
340
341
342
343
344

    if (index_element == NULL) {
      return;
    }

Moritz Lipp's avatar
Moritz Lipp committed
345
    sc_toggle_index(zathura->ui.session, NULL, NULL, 0);
346
    zathura_link_evaluate(zathura, index_element->link);
347
348
349
350
  }

  g_object_unref(model);
}
Moritz Lipp's avatar
Moritz Lipp committed
351

352
353
354
355
356
357
358
359
360
typedef enum zathura_link_action_e
{
  ZATHURA_LINK_ACTION_FOLLOW,
  ZATHURA_LINK_ACTION_DISPLAY
} zathura_link_action_t;

static bool
handle_link(GtkEntry* entry, girara_session_t* session,
            zathura_link_action_t action)
Moritz Lipp's avatar
Moritz Lipp committed
361
362
363
364
365
{
  g_return_val_if_fail(session != NULL, FALSE);
  g_return_val_if_fail(session->global.data != NULL, FALSE);

  zathura_t* zathura = session->global.data;
Moritz Lipp's avatar
Moritz Lipp committed
366
  bool eval = true;
Moritz Lipp's avatar
Moritz Lipp committed
367
368

  char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
Moritz Lipp's avatar
Moritz Lipp committed
369
370
  if (input == NULL || strlen(input) == 0) {
    eval = false;
Moritz Lipp's avatar
Moritz Lipp committed
371
372
  }

Moritz Lipp's avatar
Moritz Lipp committed
373
374
375
376
  int index = 0;
  if (eval == true) {
    index = atoi(input);
    if (index == 0 && g_strcmp0(input, "0") != 0) {
377
      girara_notify(session, GIRARA_WARNING, _("Invalid input '%s' given."), input);
Moritz Lipp's avatar
Moritz Lipp committed
378
379
380
      eval = false;
    }
    index = index - 1;
Moritz Lipp's avatar
Moritz Lipp committed
381
382
383
384
  }

  /* set pages to draw links */
  bool invalid_index = true;
385
386
387
  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
Moritz Lipp's avatar
Moritz Lipp committed
388
    if (page == NULL || zathura_page_get_visibility(page) == false) {
Moritz Lipp's avatar
Moritz Lipp committed
389
390
391
      continue;
    }

392
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
393
    g_object_set(G_OBJECT(page_widget), "draw-links", FALSE, NULL);
394

Moritz Lipp's avatar
Moritz Lipp committed
395
    if (eval == true) {
Moritz Lipp's avatar
Moritz Lipp committed
396
      zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index);
397

Moritz Lipp's avatar
Moritz Lipp committed
398
399
      if (link != NULL) {
        invalid_index = false;
400
401
402
403
404
405
406
407
        switch (action) {
          case ZATHURA_LINK_ACTION_FOLLOW:
            zathura_link_evaluate(zathura, link);
            break;
          case ZATHURA_LINK_ACTION_DISPLAY:
            zathura_link_display(zathura, link);
            break;
        }
Moritz Lipp's avatar
Moritz Lipp committed
408
409
410
411
      }
    }
  }

Moritz Lipp's avatar
Moritz Lipp committed
412
  if (eval == true && invalid_index == true) {
413
    girara_notify(session, GIRARA_WARNING, _("Invalid index '%s' given."), input);
Moritz Lipp's avatar
Moritz Lipp committed
414
415
416
417
  }

  g_free(input);

Moritz Lipp's avatar
Moritz Lipp committed
418
  return (eval == TRUE) ? TRUE : FALSE;
Moritz Lipp's avatar
Moritz Lipp committed
419
}
Moritz Lipp's avatar
Moritz Lipp committed
420

421
gboolean
422
cb_sc_follow(GtkEntry* entry, void* data)
423
{
424
  girara_session_t* session = data;
425
426
427
  return handle_link(entry, session, ZATHURA_LINK_ACTION_FOLLOW);
}

428
gboolean
429
cb_sc_display_link(GtkEntry* entry, void* data)
430
{
431
  girara_session_t* session = data;
432
433
434
  return handle_link(entry, session, ZATHURA_LINK_ACTION_DISPLAY);
}

435
436
437
438
439
440
441
static gboolean
file_monitor_reload(void* data)
{
  sc_reload((girara_session_t*) data, NULL, NULL, 0);
  return FALSE;
}

Moritz Lipp's avatar
Moritz Lipp committed
442
void
443
cb_file_monitor(ZathuraFileMonitor* monitor, girara_session_t* session)
Moritz Lipp's avatar
Moritz Lipp committed
444
445
446
447
{
  g_return_if_fail(monitor  != NULL);
  g_return_if_fail(session  != NULL);

448
  g_main_context_invoke(NULL, file_monitor_reload, session);
Moritz Lipp's avatar
Moritz Lipp committed
449
}
450

451
452
453
454
static gboolean
password_dialog(gpointer data)
{
  zathura_password_dialog_info_t* dialog = data;
Moritz Lipp's avatar
Moritz Lipp committed
455

456
  if (dialog != NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
457
    girara_dialog(
Moritz Lipp's avatar
Moritz Lipp committed
458
459
460
461
      dialog->zathura->ui.session,
      "Incorrect password. Enter password:",
      true,
      NULL,
462
      cb_password_dialog,
Moritz Lipp's avatar
Moritz Lipp committed
463
464
      dialog
    );
465
  }
Moritz Lipp's avatar
Moritz Lipp committed
466

467
468
469
  return FALSE;
}

470
gboolean
471
cb_password_dialog(GtkEntry* entry, void* data)
472
{
473
  if (entry == NULL || data == NULL) {
474
475
476
    goto error_ret;
  }

477
478
  zathura_password_dialog_info_t* dialog = data;

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
  if (dialog->path == NULL) {
    free(dialog);
    goto error_ret;
  }

  if (dialog->zathura == NULL) {
    goto error_free;
  }

  char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);

  /* no or empty password: ask again */
  if (input == NULL || strlen(input) == 0) {
    if (input != NULL) {
      g_free(input);
    }

496
    gdk_threads_add_idle(password_dialog, dialog);
497
498
499
500
    return false;
  }

  /* try to open document again */
Lukas K.'s avatar
Lukas K. committed
501
  if (document_open(dialog->zathura, dialog->path, dialog->uri, input,
502
                    ZATHURA_PAGE_NUMBER_UNSPECIFIED) == false) {
503
    gdk_threads_add_idle(password_dialog, dialog);
504
505
  } else {
    g_free(dialog->path);
Lukas K.'s avatar
Lukas K. committed
506
    g_free(dialog->uri);
507
508
    free(dialog);
  }
509
510
511
512
513
514
515

  g_free(input);

  return true;

error_free:

Moritz Lipp's avatar
Moritz Lipp committed
516
517
  g_free(dialog->path);
  free(dialog);
518
519
520
521
522

error_ret:

  return false;
}
523

524
gboolean
525
cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* UNUSED(allocation), zathura_t* zathura)
526
527
528
529
530
{
  if (zathura == NULL || zathura->document == NULL) {
    return false;
  }

531
532
  /* adjust the scale according to settings. If nothing needs to be resized,
     it does not trigger the resize event.
533

534
535
536
537
     The right viewport size is already in the document object, due to a
     previous call to adjustment_changed. We don't want to use the allocation in
     here, because we would have to subtract scrollbars, etc. */
  adjust_view(zathura);
538
539

  return false;
540
}
Moritz Lipp's avatar
Moritz Lipp committed
541
542
543

void
cb_setting_recolor_change(girara_session_t* session, const char* name,
Moritz Lipp's avatar
Moritz Lipp committed
544
                          girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
Moritz Lipp's avatar
Moritz Lipp committed
545
546
547
548
549
550
551
{
  g_return_if_fail(value != NULL);
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  g_return_if_fail(name != NULL);
  zathura_t* zathura = session->global.data;

552
  const bool bool_value = *((bool*) value);
Moritz Lipp's avatar
Moritz Lipp committed
553

554
555
556
  if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_enabled(zathura->sync.render_thread) != bool_value) {
     zathura_renderer_enable_recolor(zathura->sync.render_thread, bool_value);
     render_all(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
557
558
  }
}
Moritz Lipp's avatar
Moritz Lipp committed
559

560
561
void
cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
Moritz Lipp's avatar
Moritz Lipp committed
562
                                   girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
563
564
565
566
567
568
569
{
  g_return_if_fail(value != NULL);
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  g_return_if_fail(name != NULL);
  zathura_t* zathura = session->global.data;

570
  const bool bool_value = *((bool*) value);
571

572
573
574
  if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_hue_enabled(zathura->sync.render_thread) != bool_value) {
     zathura_renderer_enable_recolor_hue(zathura->sync.render_thread, bool_value);
     render_all(zathura);
575
576
577
  }
}

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
void
cb_setting_recolor_keep_reverse_video_change(girara_session_t* session, const char* name,
                                   girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
{
  g_return_if_fail(value != NULL);
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  g_return_if_fail(name != NULL);
  zathura_t* zathura = session->global.data;

  const bool bool_value = *((bool*) value);

  if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_reverse_video_enabled(zathura->sync.render_thread) != bool_value) {
     zathura_renderer_enable_recolor_reverse_video(zathura->sync.render_thread, bool_value);
     render_all(zathura);
  }
}
595

Moritz Lipp's avatar
Moritz Lipp committed
596
597
598
599
600
601
602
603
604
605
606
607
608
609
bool
cb_unknown_command(girara_session_t* session, const char* input)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  g_return_val_if_fail(input != NULL, false);

  zathura_t* zathura = session->global.data;

  if (zathura->document == NULL) {
    return false;
  }

  /* check for number */
610
611
  const size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
Moritz Lipp's avatar
Moritz Lipp committed
612
613
614
615
616
    if (g_ascii_isdigit(input[i]) == FALSE) {
      return false;
    }
  }

617
  zathura_jumplist_add(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
618
  page_set(zathura, atoi(input) - 1);
619
  zathura_jumplist_add(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
620
621
622

  return true;
}
623
624
625
626
627
628
629
630
631

void
cb_page_widget_text_selected(ZathuraPage* page, const char* text, void* data)
{
  g_return_if_fail(page != NULL);
  g_return_if_fail(text != NULL);
  g_return_if_fail(data != NULL);

  zathura_t* zathura = data;
632
633
634
635
636
  girara_mode_t mode = girara_mode_get(zathura->ui.session);
  if (mode != zathura->modes.normal && mode != zathura->modes.fullscreen) {
    return;
  }

637
638
639
640
641
642
  GdkAtom* selection = get_selection(zathura);

  /* copy to clipboard */
  if (selection != NULL) {
    gtk_clipboard_set_text(gtk_clipboard_get(*selection), text, -1);

643
644
    bool notification = true;
    girara_setting_get(zathura->ui.session, "selection-notification", &notification);
645

646
    if (notification == true) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
647
648
649
      char* target = NULL;
      girara_setting_get(zathura->ui.session, "selection-clipboard", &target);

650
651
      char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' ');
      char* escaped_text = g_markup_printf_escaped(
Sebastian Ramacher's avatar
Sebastian Ramacher committed
652
653
          _("Copied selected text to selection %s: %s"), target, stripped_text);
      g_free(target);
654
655
656
657
658
      g_free(stripped_text);

      girara_notify(zathura->ui.session, GIRARA_INFO, "%s", escaped_text);
      g_free(escaped_text);
    }
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
  }

  g_free(selection);
}

void
cb_page_widget_image_selected(ZathuraPage* page, GdkPixbuf* pixbuf, void* data)
{
  g_return_if_fail(page != NULL);
  g_return_if_fail(pixbuf != NULL);
  g_return_if_fail(data != NULL);

  zathura_t* zathura = data;
  GdkAtom* selection = get_selection(zathura);

  if (selection != NULL) {
    gtk_clipboard_set_image(gtk_clipboard_get(*selection), pixbuf);

677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    bool notification = true;
    girara_setting_get(zathura->ui.session, "selection-notification", &notification);

    if (notification == true) {
      char* target = NULL;
      girara_setting_get(zathura->ui.session, "selection-clipboard", &target);

      char* escaped_text = g_markup_printf_escaped(
          _("Copied selected image to selection %s"), target);
      g_free(target);

      girara_notify(zathura->ui.session, GIRARA_INFO, "%s", escaped_text);
    }

    g_free(selection);
  }
693
}
694
695
696
697
698
699
700
701
702

void
cb_page_widget_link(ZathuraPage* page, void* data)
{
  g_return_if_fail(page != NULL);

  bool enter = (bool) data;

  GdkWindow* window = gtk_widget_get_parent_window(GTK_WIDGET(page));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
703
704
  GdkDisplay* display = gtk_widget_get_display(GTK_WIDGET(page));
  GdkCursor* cursor = gdk_cursor_new_for_display(display, enter == true ? GDK_HAND1 : GDK_LEFT_PTR);
705
706
707
  gdk_window_set_cursor(window, cursor);
  g_object_unref(cursor);
}
708
709
710
711
712

void
cb_page_widget_scaled_button_release(ZathuraPage* page_widget, GdkEventButton* event,
    void* data)
{
713
714
715
716
717
  zathura_t* zathura = data;

  zathura_page_t* page = zathura_page_widget_get_page(page_widget);

  /* set page number (but don't scroll there. it was clicked on, so it's visible) */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
718
  if (event->button == GDK_BUTTON_PRIMARY) {
719
720
721
722
    zathura_document_set_current_page_number(zathura->document, zathura_page_get_index(page));
    refresh_view(zathura);
  }

723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
  if (event->button != 1 || !(event->state & GDK_CONTROL_MASK)) {
    return;
  }

  bool synctex = false;
  girara_setting_get(zathura->ui.session, "synctex", &synctex);

  if (synctex == false) {
    return;
  }

  if (zathura->dbus != NULL) {
    zathura_dbus_edit(zathura->dbus, zathura_page_get_index(page), event->x, event->y);
  }

  char* editor = NULL;
  girara_setting_get(zathura->ui.session, "synctex-editor-command", &editor);
  if (editor == NULL || *editor == '\0') {
    g_free(editor);
    return;
  }

  synctex_edit(editor, page, event->x, event->y);
  g_free(editor);
}