zathura.c 5.99 KB
Newer Older
1
2
/* See LICENSE file for license and copyright information */

Moritz Lipp's avatar
Moritz Lipp committed
3
4
#include <stdlib.h>

5
6
#include <girara.h>

Moritz Lipp's avatar
Moritz Lipp committed
7
8
#include "callbacks.h"
#include "config.h"
9
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
10
#include "shortcuts.h"
Moritz Lipp's avatar
Moritz Lipp committed
11
#include "zathura.h"
Moritz Lipp's avatar
Moritz Lipp committed
12
#include "utils.h"
Moritz Lipp's avatar
Moritz Lipp committed
13

Moritz Lipp's avatar
Moritz Lipp committed
14
15
16
/* function implementation */
bool
init_zathura()
17
{
18
  /* UI */
Moritz Lipp's avatar
Moritz Lipp committed
19
  if (!(Zathura.UI.session = girara_session_create())) {
Moritz Lipp's avatar
Moritz Lipp committed
20
    goto error_out;
Moritz Lipp's avatar
Moritz Lipp committed
21
  }
22

Moritz Lipp's avatar
Moritz Lipp committed
23
  if (!girara_session_init(Zathura.UI.session)) {
Moritz Lipp's avatar
Moritz Lipp committed
24
    goto error_out;
Moritz Lipp's avatar
Moritz Lipp committed
25
  }
26

Moritz Lipp's avatar
Moritz Lipp committed
27
28
29
  Zathura.UI.statusbar.file        = NULL;
  Zathura.UI.statusbar.buffer      = NULL;
  Zathura.UI.statusbar.page_number = NULL;
30
  Zathura.UI.page_view             = NULL;
31
  Zathura.UI.index                 = NULL;
32
33
34

  /* page view */
  Zathura.UI.page_view = gtk_vbox_new(FALSE, 0);
Moritz Lipp's avatar
Moritz Lipp committed
35
  if (!Zathura.UI.page_view) {
36
37
38
39
40
    goto error_free;
  }

  gtk_widget_show(Zathura.UI.page_view);
  gtk_box_set_spacing(GTK_BOX(Zathura.UI.page_view), 0);
Moritz Lipp's avatar
Moritz Lipp committed
41

42
  /* statusbar */
Moritz Lipp's avatar
Moritz Lipp committed
43
  Zathura.UI.statusbar.file = girara_statusbar_item_add(Zathura.UI.session, TRUE, TRUE, TRUE, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
44
  if (!Zathura.UI.statusbar.file) {
Moritz Lipp's avatar
Moritz Lipp committed
45
    goto error_free;
Moritz Lipp's avatar
Moritz Lipp committed
46
47
  }

Moritz Lipp's avatar
Moritz Lipp committed
48
  Zathura.UI.statusbar.buffer = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
49
  if (!Zathura.UI.statusbar.buffer) {
Moritz Lipp's avatar
Moritz Lipp committed
50
    goto error_free;
Moritz Lipp's avatar
Moritz Lipp committed
51
52
53
  }

  Zathura.UI.statusbar.page_number = girara_statusbar_item_add(Zathura.UI.session, FALSE, FALSE, FALSE, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
54
  if (!Zathura.UI.statusbar.page_number) {
Moritz Lipp's avatar
Moritz Lipp committed
55
    goto error_free;
Moritz Lipp's avatar
Moritz Lipp committed
56
57
58
59
  }

  girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.file, "[No Name]");

Moritz Lipp's avatar
Moritz Lipp committed
60
61
62
  /* signals */
  g_signal_connect(G_OBJECT(Zathura.UI.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), NULL);

63
64
65
  GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
  g_signal_connect(G_OBJECT(view_vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), NULL);

Moritz Lipp's avatar
Moritz Lipp committed
66
67
68
  /* girara events */
  Zathura.UI.session->events.buffer_changed = buffer_changed;

Moritz Lipp's avatar
Moritz Lipp committed
69
70
71
  /* load plugins */
  zathura_document_plugins_load();

Moritz Lipp's avatar
Moritz Lipp committed
72
73
74
  /* configuration */
  config_load_default();

Moritz Lipp's avatar
Moritz Lipp committed
75
  return true;
Moritz Lipp's avatar
Moritz Lipp committed
76
77
78

error_free:

Moritz Lipp's avatar
Moritz Lipp committed
79
  if (Zathura.UI.page_view) {
80
81
82
    g_object_unref(Zathura.UI.page_view);
  }

Moritz Lipp's avatar
Moritz Lipp committed
83
84
85
86
87
  girara_session_destroy(Zathura.UI.session);

error_out:

  return false;
88
89
}

Moritz Lipp's avatar
Moritz Lipp committed
90
91
92
bool
document_open(const char* path, const char* password)
{
Moritz Lipp's avatar
Moritz Lipp committed
93
  if (!path) {
94
    goto error_out;
Moritz Lipp's avatar
Moritz Lipp committed
95
96
97
98
  }

  zathura_document_t* document = zathura_document_open(path, password);

Moritz Lipp's avatar
Moritz Lipp committed
99
  if (!document) {
100
    goto error_out;
Moritz Lipp's avatar
Moritz Lipp committed
101
102
103
104
  }

  Zathura.document = document;

105
  /* init view */
106
107
108
  if (create_blank_pages() == false) {
    return false;
  }
Moritz Lipp's avatar
Moritz Lipp committed
109

110
111
112
113
114
  /* view mode */
  int* value = girara_setting_get(Zathura.UI.session, "pages-per-row");
  int pages_per_row = (value) ? *value : 1;
  free(value);
  page_view_set_mode(pages_per_row);
Moritz Lipp's avatar
Moritz Lipp committed
115

116
  girara_set_view(Zathura.UI.session, Zathura.UI.page_view);
Moritz Lipp's avatar
Moritz Lipp committed
117

Moritz Lipp's avatar
Moritz Lipp committed
118
119
120
  /* threads */
  Zathura.Sync.render_thread = render_init();

Moritz Lipp's avatar
Moritz Lipp committed
121
  if (!Zathura.Sync.render_thread) {
Moritz Lipp's avatar
Moritz Lipp committed
122
123
124
    goto error_free;
  }

125
  /* first page */
Moritz Lipp's avatar
Moritz Lipp committed
126
  if (!page_set(0)) {
127
128
    goto error_free;
  }
Moritz Lipp's avatar
Moritz Lipp committed
129
130

  return true;
131
132
133
134
135
136
137
138

error_free:

  zathura_document_free(document);

error_out:

  return false;
Moritz Lipp's avatar
Moritz Lipp committed
139
140
141
142
143
}

bool
document_close()
{
Moritz Lipp's avatar
Moritz Lipp committed
144
  if (!Zathura.document) {
Moritz Lipp's avatar
Moritz Lipp committed
145
146
147
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
148
  if (Zathura.Sync.render_thread) {
Moritz Lipp's avatar
Moritz Lipp committed
149
150
151
    render_free(Zathura.Sync.render_thread);
  }

Moritz Lipp's avatar
Moritz Lipp committed
152
153
154
155
156
157
158
159
  zathura_document_free(Zathura.document);

  return true;
}

bool
page_set(unsigned int page_id)
{
Moritz Lipp's avatar
Moritz Lipp committed
160
  if (!Zathura.document || !Zathura.document->pages) {
Moritz Lipp's avatar
Moritz Lipp committed
161
    goto error_out;
Moritz Lipp's avatar
Moritz Lipp committed
162
163
  }

Moritz Lipp's avatar
Moritz Lipp committed
164
  if (page_id >= Zathura.document->number_of_pages) {
Moritz Lipp's avatar
Moritz Lipp committed
165
    goto error_out;
Moritz Lipp's avatar
Moritz Lipp committed
166
167
  }

168
  /* render page */
169
  zathura_page_t* page = Zathura.document->pages[page_id];
Moritz Lipp's avatar
Moritz Lipp committed
170

Moritz Lipp's avatar
Moritz Lipp committed
171
  if (!page) {
172
173
174
    goto error_out;
  }

175
  GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(Zathura.UI.session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
176
  cb_view_vadjustment_value_changed(view_vadjustment, NULL);
177
178

  /* update page number */
Moritz Lipp's avatar
Moritz Lipp committed
179
180
181
182
183
184
185
  Zathura.document->current_page_number = page_id;

  char* page_number = g_strdup_printf("[%d/%d]", page_id + 1, Zathura.document->number_of_pages);
  girara_statusbar_item_set_text(Zathura.UI.session, Zathura.UI.statusbar.page_number, page_number);
  g_free(page_number);

  return true;
Moritz Lipp's avatar
Moritz Lipp committed
186
187
188
189

error_out:

  return false;
Moritz Lipp's avatar
Moritz Lipp committed
190
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
219
220
221
void
page_view_set_mode(unsigned int pages_per_row)
{
  /* empty page view */
  GList* container = gtk_container_get_children(GTK_CONTAINER(Zathura.UI.page_view));
  for (GList* child = container; child; child = g_list_next(child)) {
    gtk_container_remove(GTK_CONTAINER(Zathura.UI.page_view), child->data);
  }

  GtkWidget* row = NULL;

  /* create blank pages */
  for (unsigned int i = 0; i < Zathura.document->number_of_pages; i++)
  {
    if (i % pages_per_row == 0) {
      row = gtk_hbox_new(FALSE, 0);
    }

    /* pack row */
    gtk_box_pack_start(GTK_BOX(row), Zathura.document->pages[i]->event_box, FALSE, FALSE, 1);

    /* pack row to page view */
    if ((i + 1) % pages_per_row == 0) {
      gtk_box_pack_start(GTK_BOX(Zathura.UI.page_view), row, FALSE,  FALSE, 1);
    }
  }

  gtk_widget_show_all(Zathura.UI.page_view);
}

222
bool
223
224
225
226
227
228
229
230
create_blank_pages()
{
  /* create blank pages */
  for (unsigned int i = 0; i < Zathura.document->number_of_pages; i++)
  {
    zathura_page_t* page = Zathura.document->pages[i];
    g_static_mutex_lock(&(page->lock));

Moritz Lipp's avatar
Moritz Lipp committed
231
    cairo_t* cairo = gdk_cairo_create(page->drawing_area->window);
232
233
234
235
236
237
238

    if (cairo == NULL) {
      girara_error("Could not create blank page");
      g_static_mutex_unlock(&(page->lock));
      return false;
    }

Moritz Lipp's avatar
Moritz Lipp committed
239
240
241
242
    cairo_set_source_rgb(cairo, 1, 1, 1);
    cairo_rectangle(cairo, 0, 0, page->width, page->height);
    cairo_fill(cairo);
    cairo_destroy(cairo);
243
244
245

    g_static_mutex_unlock(&(page->lock));
  }
246
247

  return true;
248
249
}

Moritz Lipp's avatar
Moritz Lipp committed
250
/* main function */
251
int main(int argc, char* argv[])
Moritz Lipp's avatar
Moritz Lipp committed
252
{
253
254
  g_thread_init(NULL);
  gdk_threads_init();
Moritz Lipp's avatar
Moritz Lipp committed
255
256
  gtk_init(&argc, &argv);

Moritz Lipp's avatar
Moritz Lipp committed
257
  if (!init_zathura()) {
Moritz Lipp's avatar
Moritz Lipp committed
258
259
260
    printf("error: coult not initialize zathura\n");
    return -1;
  }
Moritz Lipp's avatar
Moritz Lipp committed
261

Moritz Lipp's avatar
Moritz Lipp committed
262
263
  if (argc > 1) {
    if (!document_open(argv[1], NULL)) {
Moritz Lipp's avatar
Moritz Lipp committed
264
      printf("error: could not open document\n");
Moritz Lipp's avatar
Moritz Lipp committed
265
266
      return -1;
    }
267
  }
Moritz Lipp's avatar
Moritz Lipp committed
268

Moritz Lipp's avatar
Moritz Lipp committed
269
270
271
  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();
272

Moritz Lipp's avatar
Moritz Lipp committed
273
274
  return 0;
}