2010-11-18 02:35:33 +01:00
|
|
|
/* See LICENSE file for license and copyright information */
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2011-03-05 21:00:41 +01:00
|
|
|
#include <stdarg.h>
|
2010-11-18 03:15:32 +01:00
|
|
|
#include <string.h>
|
2010-11-29 14:58:56 +01:00
|
|
|
#include <stdio.h>
|
2010-11-18 02:35:33 +01:00
|
|
|
#include <unistd.h>
|
2010-11-29 14:58:56 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/wait.h>
|
2010-11-18 02:35:33 +01:00
|
|
|
|
|
|
|
#include "utils.h"
|
2011-02-10 04:33:28 +01:00
|
|
|
#include "zathura.h"
|
2010-11-18 02:35:33 +01:00
|
|
|
|
2010-11-29 14:58:56 +01:00
|
|
|
#define BLOCK_SIZE 64
|
|
|
|
|
2010-11-18 02:35:33 +01:00
|
|
|
bool
|
|
|
|
file_exists(const char* path)
|
|
|
|
{
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!access(path, F_OK)) {
|
2010-11-18 02:35:33 +01:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char*
|
|
|
|
file_get_extension(const char* path)
|
|
|
|
{
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!path) {
|
2010-11-18 03:15:32 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int i = strlen(path);
|
2011-02-09 12:29:09 +01:00
|
|
|
for (; i > 0; i--)
|
2010-11-18 03:15:32 +01:00
|
|
|
{
|
2011-02-09 12:29:09 +01:00
|
|
|
if (*(path + i) != '.') {
|
2010-11-18 03:15:32 +01:00
|
|
|
continue;
|
2010-12-26 01:12:20 +01:00
|
|
|
} else {
|
2010-11-18 03:15:32 +01:00
|
|
|
break;
|
2010-12-26 01:12:20 +01:00
|
|
|
}
|
2010-11-18 03:15:32 +01:00
|
|
|
}
|
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!i) {
|
2010-11-18 03:15:32 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return path + i + 1;
|
2010-11-18 02:35:33 +01:00
|
|
|
}
|
2010-11-29 14:58:56 +01:00
|
|
|
|
|
|
|
bool
|
|
|
|
execute_command(char* const argv[], char** output)
|
|
|
|
{
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!output) {
|
2010-11-29 14:58:56 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int p[2];
|
2011-02-09 12:29:09 +01:00
|
|
|
if (pipe(p)) {
|
2010-11-29 14:58:56 +01:00
|
|
|
return -1;
|
2010-12-26 01:12:20 +01:00
|
|
|
}
|
2010-11-29 14:58:56 +01:00
|
|
|
|
|
|
|
pid_t pid = fork();
|
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (pid == -1) { // failure
|
2010-11-29 14:58:56 +01:00
|
|
|
return false;
|
2011-02-09 12:29:09 +01:00
|
|
|
} else if (pid == 0) { // child
|
2010-11-29 14:58:56 +01:00
|
|
|
dup2(p[1], 1);
|
|
|
|
close(p[0]);
|
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (execvp(argv[0], argv) == -1) {
|
2010-11-29 14:58:56 +01:00
|
|
|
return false;
|
|
|
|
}
|
2010-12-26 01:12:20 +01:00
|
|
|
} else { // parent
|
2010-11-29 14:58:56 +01:00
|
|
|
dup2(p[0], 0);
|
|
|
|
close(p[1]);
|
|
|
|
|
|
|
|
/* read output */
|
|
|
|
unsigned int bc = BLOCK_SIZE;
|
|
|
|
unsigned int i = 0;
|
|
|
|
char* buffer = malloc(sizeof(char) * bc);
|
|
|
|
*output = NULL;
|
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!buffer) {
|
2010-11-29 14:58:56 +01:00
|
|
|
close(p[0]);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char c;
|
2011-02-09 12:29:09 +01:00
|
|
|
while (1 == read(p[0], &c, 1)) {
|
2010-11-29 14:58:56 +01:00
|
|
|
buffer[i++] = c;
|
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (i == bc) {
|
2010-11-29 14:58:56 +01:00
|
|
|
bc += BLOCK_SIZE;
|
|
|
|
char* tmp = realloc(buffer, sizeof(char) * bc);
|
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!tmp) {
|
2010-11-29 14:58:56 +01:00
|
|
|
free(buffer);
|
|
|
|
close(p[0]);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char* tmp = realloc(buffer, sizeof(char) * (bc + 1));
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!tmp) {
|
2010-11-29 14:58:56 +01:00
|
|
|
free(buffer);
|
|
|
|
close(p[0]);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer = tmp;
|
|
|
|
buffer[i] = '\0';
|
|
|
|
|
|
|
|
*output = buffer;
|
|
|
|
|
|
|
|
/* wait for child to terminate */
|
|
|
|
waitpid(pid, NULL, 0);
|
|
|
|
close(p[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2010-12-28 09:47:09 +01:00
|
|
|
|
2010-12-29 11:46:13 +01:00
|
|
|
GtkWidget*
|
2010-12-28 09:47:09 +01:00
|
|
|
page_blank(unsigned int width, unsigned int height)
|
|
|
|
{
|
2011-02-09 12:29:09 +01:00
|
|
|
if ((width == 0) || (height == 0)) {
|
2010-12-28 09:47:09 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
guchar* buffer = malloc(sizeof(guchar) * (width * height * 1));
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!buffer) {
|
2010-12-28 09:47:09 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw white */
|
2011-02-09 12:29:09 +01:00
|
|
|
for (unsigned int i = 0; i < width * height; i++) {
|
2010-12-28 09:47:09 +01:00
|
|
|
buffer[i] = 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(buffer, GDK_COLORSPACE_RGB, FALSE, 8,
|
|
|
|
width, height, 1, NULL, NULL);
|
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!pixbuf) {
|
2010-12-28 09:47:09 +01:00
|
|
|
free(buffer);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-12-29 11:46:13 +01:00
|
|
|
/* convert to image */
|
|
|
|
GtkWidget* image = gtk_image_new();
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!image) {
|
2010-12-29 11:46:13 +01:00
|
|
|
free(buffer);
|
|
|
|
g_object_unref(pixbuf);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
|
|
|
|
gtk_widget_show(image);
|
|
|
|
|
2011-02-10 04:33:28 +01:00
|
|
|
/*free(buffer);*/ // XXX: Read documentation
|
2011-01-06 11:54:31 +01:00
|
|
|
g_object_unref(pixbuf);
|
|
|
|
|
2010-12-29 11:46:13 +01:00
|
|
|
return image;
|
2010-12-28 09:47:09 +01:00
|
|
|
}
|
2011-02-10 04:33:28 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_node_t* tree)
|
|
|
|
{
|
|
|
|
girara_list_t* list = girara_node_get_children(tree);
|
|
|
|
girara_list_iterator_t* it = girara_list_iterator(list);
|
|
|
|
|
|
|
|
do {
|
|
|
|
zathura_index_element_t* index_element = (zathura_index_element_t*) girara_list_iterator_data(it);
|
|
|
|
printf("%s\n", index_element->title);
|
|
|
|
} while ((it = girara_list_iterator_next(it)));
|
|
|
|
}
|
2011-03-05 21:00:41 +01:00
|
|
|
|
|
|
|
char* string_concat(const char* string1, ...)
|
|
|
|
{
|
|
|
|
if(!string1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_list args;
|
|
|
|
char* s;
|
|
|
|
int l = strlen(string1) + 1;
|
|
|
|
|
|
|
|
/* calculate length */
|
|
|
|
va_start(args, string1);
|
|
|
|
|
|
|
|
s = va_arg(args, char*);
|
|
|
|
|
|
|
|
while(s) {
|
|
|
|
l += strlen(s);
|
|
|
|
s = va_arg(args, char*);
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
/* prepare */
|
|
|
|
char* c = malloc(sizeof(char) * l);
|
|
|
|
char* p = c;
|
|
|
|
|
|
|
|
/* copy */
|
|
|
|
char* d = p;
|
|
|
|
char* x = (char*) string1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
*d++ = *x;
|
|
|
|
} while (*x++ != '\0');
|
|
|
|
|
|
|
|
p = d - 1;
|
|
|
|
|
|
|
|
va_start(args, string1);
|
|
|
|
|
|
|
|
s = va_arg(args, char*);
|
|
|
|
|
|
|
|
while(s) {
|
|
|
|
d = p;
|
|
|
|
x = s;
|
|
|
|
|
|
|
|
do {
|
|
|
|
*d++ = *x;
|
|
|
|
} while (*x++ != '\0');
|
|
|
|
|
|
|
|
p = d - 1;
|
|
|
|
s = va_arg(args, char*);
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|