summaryrefslogtreecommitdiff
path: root/src/imlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/imlib.c')
-rw-r--r--src/imlib.c2243
1 files changed, 1058 insertions, 1185 deletions
diff --git a/src/imlib.c b/src/imlib.c
index 6abd88a..d419539 100644
--- a/src/imlib.c
+++ b/src/imlib.c
@@ -51,265 +51,233 @@ Window root = 0;
XineramaScreenInfo *xinerama_screens = NULL;
int xinerama_screen;
int num_xinerama_screens;
-#endif /* HAVE_LIBXINERAMA */
+#endif /* HAVE_LIBXINERAMA */
#ifdef HAVE_LIBXINERAMA
-void
-init_xinerama(void)
+void init_xinerama(void)
{
- if (opt.xinerama && XineramaIsActive(disp)) {
- int major, minor;
- xinerama_screen = 0;
- XineramaQueryVersion(disp, &major, &minor);
- xinerama_screens = XineramaQueryScreens(disp, &num_xinerama_screens);
- }
+ if (opt.xinerama && XineramaIsActive(disp)) {
+ int major, minor;
+ xinerama_screen = 0;
+ XineramaQueryVersion(disp, &major, &minor);
+ xinerama_screens = XineramaQueryScreens(disp, &num_xinerama_screens);
+ }
}
-#endif /* HAVE_LIBXINERAMA */
+#endif /* HAVE_LIBXINERAMA */
-void
-init_imlib_fonts(void)
+void init_imlib_fonts(void)
{
- D_ENTER(4);
+ D_ENTER(4);
- /* Set up the font stuff */
- imlib_add_path_to_font_path(".");
- imlib_add_path_to_font_path(PREFIX "/share/feh/fonts");
- imlib_add_path_to_font_path("./ttfonts");
+ /* Set up the font stuff */
+ imlib_add_path_to_font_path(".");
+ imlib_add_path_to_font_path(PREFIX "/share/feh/fonts");
+ imlib_add_path_to_font_path("./ttfonts");
- D_RETURN_(4);
+ D_RETURN_(4);
}
-void
-init_x_and_imlib(void)
+void init_x_and_imlib(void)
{
- D_ENTER(4);
-
- disp = XOpenDisplay(NULL);
- if (!disp)
- eprintf("Can't open X display. It *is* running, yeah?");
- vis = DefaultVisual(disp, DefaultScreen(disp));
- depth = DefaultDepth(disp, DefaultScreen(disp));
- cm = DefaultColormap(disp, DefaultScreen(disp));
- root = RootWindow(disp, DefaultScreen(disp));
- scr = ScreenOfDisplay(disp, DefaultScreen(disp));
- xid_context = XUniqueContext();
+ D_ENTER(4);
+
+ disp = XOpenDisplay(NULL);
+ if (!disp)
+ eprintf("Can't open X display. It *is* running, yeah?");
+ vis = DefaultVisual(disp, DefaultScreen(disp));
+ depth = DefaultDepth(disp, DefaultScreen(disp));
+ cm = DefaultColormap(disp, DefaultScreen(disp));
+ root = RootWindow(disp, DefaultScreen(disp));
+ scr = ScreenOfDisplay(disp, DefaultScreen(disp));
+ xid_context = XUniqueContext();
#ifdef HAVE_LIBXINERAMA
- init_xinerama();
-#endif /* HAVE_LIBXINERAMA */
+ init_xinerama();
+#endif /* HAVE_LIBXINERAMA */
- imlib_context_set_display(disp);
- imlib_context_set_visual(vis);
- imlib_context_set_colormap(cm);
- imlib_context_set_color_modifier(NULL);
- imlib_context_set_progress_function(NULL);
- imlib_context_set_operation(IMLIB_OP_COPY);
- wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False);
+ imlib_context_set_display(disp);
+ imlib_context_set_visual(vis);
+ imlib_context_set_colormap(cm);
+ imlib_context_set_color_modifier(NULL);
+ imlib_context_set_progress_function(NULL);
+ imlib_context_set_operation(IMLIB_OP_COPY);
+ wmDeleteWindow = XInternAtom(disp, "WM_DELETE_WINDOW", False);
- /* Initialise random numbers */
- srand(getpid() * time(NULL) % ((unsigned int) -1));
+ /* Initialise random numbers */
+ srand(getpid() * time(NULL) % ((unsigned int) -1));
- D_RETURN_(4);
+ D_RETURN_(4);
}
-int
-feh_load_image_char(Imlib_Image * im, char *filename)
+int feh_load_image_char(Imlib_Image * im, char *filename)
{
- feh_file *file;
- int i;
-
- D_ENTER(4);
- file = feh_file_new(filename);
- i = feh_load_image(im, file);
- feh_file_free(file);
- D_RETURN(4, i);
+ feh_file *file;
+ int i;
+
+ D_ENTER(4);
+ file = feh_file_new(filename);
+ i = feh_load_image(im, file);
+ feh_file_free(file);
+ D_RETURN(4, i);
}
-int
-feh_load_image(Imlib_Image * im, feh_file * file)
+int feh_load_image(Imlib_Image * im, feh_file * file)
{
- Imlib_Load_Error err;
-
- D_ENTER(4);
- D(3, ("filename is %s, image is %p\n", file->filename, im));
-
- if (!file || !file->filename)
- D_RETURN(4, 0);
-
- /* Handle URLs */
- if ((!strncmp(file->filename, "http://", 7)) ||
- (!strncmp(file->filename, "https://", 8)) ||
- (!strncmp(file->filename, "ftp://", 6)))
- {
- char *tmpname = NULL;
- char *tempcpy;
-
- tmpname = feh_http_load_image(file->filename);
- if (tmpname == NULL)
- D_RETURN(4, 0);
- *im = imlib_load_image_with_error_return(tmpname, &err);
- if (im)
- {
- /* load the info now, in case it's needed after we delete the
- temporary image file */
- tempcpy = file->filename;
- file->filename = tmpname;
- feh_file_info_load(file, *im);
- file->filename = tempcpy;
- }
- if ((opt.slideshow) && (opt.reload == 0))
- {
- /* Http, no reload, slideshow. Let's keep this image on hand... */
- free(file->filename);
- file->filename = estrdup(tmpname);
- }
- else
- {
- /* Don't cache the image if we're doing reload + http (webcams etc) */
- if (!opt.keep_http)
- unlink(tmpname);
- }
- if (!opt.keep_http)
- add_file_to_rm_filelist(tmpname);
- free(tmpname);
- }
- else
- {
- *im = imlib_load_image_with_error_return(file->filename, &err);
- }
-
- if ((err) || (!im))
- {
- if (opt.verbose && !opt.quiet)
- {
- fprintf(stdout, "\n");
- reset_output = 1;
- }
- /* Check error code */
- switch (err)
- {
- case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST:
- if (!opt.quiet)
- weprintf("%s - File does not exist", file->filename);
- break;
- case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY:
- if (!opt.quiet)
- weprintf("%s - Directory specified for image filename",
- file->filename);
- break;
- case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ:
- if (!opt.quiet)
- weprintf("%s - No read access to directory", file->filename);
- break;
- case IMLIB_LOAD_ERROR_UNKNOWN:
- case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT:
- if (!opt.quiet)
- weprintf("%s - No Imlib2 loader for that file format",
- file->filename);
- break;
- case IMLIB_LOAD_ERROR_PATH_TOO_LONG:
- if (!opt.quiet)
- weprintf("%s - Path specified is too long", file->filename);
- break;
- case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT:
- if (!opt.quiet)
- weprintf("%s - Path component does not exist", file->filename);
- break;
- case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY:
- if (!opt.quiet)
- weprintf("%s - Path component is not a directory",
- file->filename);
- break;
- case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE:
- if (!opt.quiet)
- weprintf("%s - Path points outside address space",
- file->filename);
- break;
- case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS:
- if (!opt.quiet)
- weprintf("%s - Too many levels of symbolic links",
- file->filename);
- break;
- case IMLIB_LOAD_ERROR_OUT_OF_MEMORY:
- if (!opt.quiet)
- weprintf("While loading %s - Out of memory", file->filename);
- break;
- case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS:
- eprintf("While loading %s - Out of file descriptors",
- file->filename);
- break;
- case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE:
- if (!opt.quiet)
- weprintf("%s - Cannot write to directory", file->filename);
- break;
- case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE:
- if (!opt.quiet)
- weprintf("%s - Cannot write - out of disk space",
- file->filename);
- break;
- default:
- if (!opt.quiet)
- weprintf
- ("While loading %s - Unknown error (%d). Attempting to continue",
- file->filename, err);
- break;
- }
- D(3, ("Load *failed*\n"));
- D_RETURN(4, 0);
- }
-
- D(3, ("Loaded ok\n"));
- D_RETURN(4, 1);
+ Imlib_Load_Error err;
+
+ D_ENTER(4);
+ D(3, ("filename is %s, image is %p\n", file->filename, im));
+
+ if (!file || !file->filename)
+ D_RETURN(4, 0);
+
+ /* Handle URLs */
+ if ((!strncmp(file->filename, "http://", 7)) || (!strncmp(file->filename, "https://", 8))
+ || (!strncmp(file->filename, "ftp://", 6))) {
+ char *tmpname = NULL;
+ char *tempcpy;
+
+ tmpname = feh_http_load_image(file->filename);
+ if (tmpname == NULL)
+ D_RETURN(4, 0);
+ *im = imlib_load_image_with_error_return(tmpname, &err);
+ if (im) {
+ /* load the info now, in case it's needed after we delete the
+ temporary image file */
+ tempcpy = file->filename;
+ file->filename = tmpname;
+ feh_file_info_load(file, *im);
+ file->filename = tempcpy;
+ }
+ if ((opt.slideshow) && (opt.reload == 0)) {
+ /* Http, no reload, slideshow. Let's keep this image on hand... */
+ free(file->filename);
+ file->filename = estrdup(tmpname);
+ } else {
+ /* Don't cache the image if we're doing reload + http (webcams etc) */
+ if (!opt.keep_http)
+ unlink(tmpname);
+ }
+ if (!opt.keep_http)
+ add_file_to_rm_filelist(tmpname);
+ free(tmpname);
+ } else {
+ *im = imlib_load_image_with_error_return(file->filename, &err);
+ }
+
+ if ((err) || (!im)) {
+ if (opt.verbose && !opt.quiet) {
+ fprintf(stdout, "\n");
+ reset_output = 1;
+ }
+ /* Check error code */
+ switch (err) {
+ case IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST:
+ if (!opt.quiet)
+ weprintf("%s - File does not exist", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY:
+ if (!opt.quiet)
+ weprintf("%s - Directory specified for image filename", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ:
+ if (!opt.quiet)
+ weprintf("%s - No read access to directory", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_UNKNOWN:
+ case IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT:
+ if (!opt.quiet)
+ weprintf("%s - No Imlib2 loader for that file format", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_TOO_LONG:
+ if (!opt.quiet)
+ weprintf("%s - Path specified is too long", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT:
+ if (!opt.quiet)
+ weprintf("%s - Path component does not exist", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY:
+ if (!opt.quiet)
+ weprintf("%s - Path component is not a directory", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE:
+ if (!opt.quiet)
+ weprintf("%s - Path points outside address space", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS:
+ if (!opt.quiet)
+ weprintf("%s - Too many levels of symbolic links", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_OUT_OF_MEMORY:
+ if (!opt.quiet)
+ weprintf("While loading %s - Out of memory", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS:
+ eprintf("While loading %s - Out of file descriptors", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE:
+ if (!opt.quiet)
+ weprintf("%s - Cannot write to directory", file->filename);
+ break;
+ case IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE:
+ if (!opt.quiet)
+ weprintf("%s - Cannot write - out of disk space", file->filename);
+ break;
+ default:
+ if (!opt.quiet)
+ weprintf("While loading %s - Unknown error (%d). Attempting to continue",
+ file->filename, err);
+ break;
+ }
+ D(3, ("Load *failed*\n"));
+ D_RETURN(4, 0);
+ }
+
+ D(3, ("Loaded ok\n"));
+ D_RETURN(4, 1);
}
-char *
-feh_http_load_image(char *url)
+char *feh_http_load_image(char *url)
{
- char *tmpname;
- char *tmpname_timestamper = NULL;
- char *basename;
- char *newurl = NULL;
- char randnum[20];
- int rnum;
- char *path = NULL;
-
- D_ENTER(4);
-
- if (opt.keep_http)
- {
- if (opt.output_dir)
- path = opt.output_dir;
- else
- path = "";
- }
- else
- path = "/tmp/";
-
- basename = strrchr(url, '/') + 1;
- tmpname = feh_unique_filename(path, basename);
-
- if (opt.wget_timestamp)
- {
- char cppid[10];
- pid_t ppid;
-
- ppid = getpid();
- snprintf(cppid, sizeof(cppid), "%06ld", (long)ppid);
- tmpname_timestamper =
- estrjoin("", "/tmp/feh_", cppid, "_", basename, NULL);
- newurl = estrdup(url);
- }
- else
- {
- rnum = rand();
- snprintf(randnum, sizeof(randnum), "%d", rnum);
- newurl = estrjoin("?", url, randnum, NULL);
- }
- D(3, ("newurl: %s\n", newurl));
-
- if (opt.builtin_http)
- {
- /* state for HTTP header parser */
+ char *tmpname;
+ char *tmpname_timestamper = NULL;
+ char *basename;
+ char *newurl = NULL;
+ char randnum[20];
+ int rnum;
+ char *path = NULL;
+
+ D_ENTER(4);
+
+ if (opt.keep_http) {
+ if (opt.output_dir)
+ path = opt.output_dir;
+ else
+ path = "";
+ } else
+ path = "/tmp/";
+
+ basename = strrchr(url, '/') + 1;
+ tmpname = feh_unique_filename(path, basename);
+
+ if (opt.wget_timestamp) {
+ char cppid[10];
+ pid_t ppid;
+
+ ppid = getpid();
+ snprintf(cppid, sizeof(cppid), "%06ld", (long) ppid);
+ tmpname_timestamper = estrjoin("", "/tmp/feh_", cppid, "_", basename, NULL);
+ newurl = estrdup(url);
+ } else {
+ rnum = rand();
+ snprintf(randnum, sizeof(randnum), "%d", rnum);
+ newurl = estrjoin("?", url, randnum, NULL);
+ }
+ D(3, ("newurl: %s\n", newurl));
+
+ if (opt.builtin_http) {
+ /* state for HTTP header parser */
#define SAW_NONE 1
#define SAW_ONE_CM 2
#define SAW_ONE_CJ 3
@@ -319,996 +287,901 @@ feh_http_load_image(char *url)
#define OUR_BUF_SIZE 1024
#define EOL "\015\012"
- int sockno = 0;
- int size;
- int body = SAW_NONE;
- struct sockaddr_in addr;
- struct hostent *hptr;
- char *hostname;
- char *get_string;
- char *host_string;
- char *query_string;
- char *get_url;
- static char buf[OUR_BUF_SIZE];
- char ua_string[] = "User-Agent: feh image viewer";
- char accept_string[] = "Accept: image/*";
- FILE *fp;
-
- D(4, ("using builtin http collection\n"));
- fp = fopen(tmpname, "w");
- if (!fp)
- {
- weprintf("couldn't write to file %s:", tmpname);
- free(tmpname);
- D_RETURN(4, NULL);
- }
-
- hostname = feh_strip_hostname(newurl);
- if (!hostname)
- {
- weprintf("couldn't work out hostname from %s:", newurl);
- free(tmpname);
- free(newurl);
- D_RETURN(4, NULL);
- }
-
- D(4, ("trying hostname %s\n", hostname));
-
- if (!(hptr = feh_gethostbyname(hostname)))
- {
- weprintf("error resolving host %s:", hostname);
- free(hostname);
- free(tmpname);
- free(newurl);
- D_RETURN(4, NULL);
- }
-
- /* Copy the address of the host to socket description. */
- memcpy(&addr.sin_addr, hptr->h_addr, hptr->h_length);
-
- /* Set port and protocol */
- addr.sin_family = AF_INET;
- addr.sin_port = htons(80);
-
- if ((sockno = socket(PF_INET, SOCK_STREAM, 0)) == -1)
- {
- weprintf("error opening socket:");
- free(tmpname);
- free(hostname);
- free(newurl);
- D_RETURN(4, NULL);
- }
- if (connect(sockno, (struct sockaddr *) &addr, sizeof(addr)) == -1)
- {
- weprintf("error connecting socket:");
- free(tmpname);
- free(hostname);
- free(newurl);
- D_RETURN(4, NULL);
- }
-
- get_url = strchr(newurl, '/') + 2;
- get_url = strchr(get_url, '/');
-
- get_string = estrjoin(" ", "GET", get_url, "HTTP/1.0", NULL);
- host_string = estrjoin(" ", "Host:", hostname, NULL);
- query_string =
- estrjoin(EOL, get_string, host_string, accept_string, ua_string, "",
- "", NULL);
- /* At this point query_string looks something like
- **
- ** GET /dir/foo.jpg?123456 HTTP/1.0^M^J
- ** Host: www.example.com^M^J
- ** Accept: image/ *^M^J
- ** User-Agent: feh image viewer^M^J
- ** ^M^J
- **
- ** Host: is required by HTTP/1.1 and very important for some sites,
- ** even with HTTP/1.0
- **
- ** -- BEG
- */
- if ((send(sockno, query_string, strlen(query_string), 0)) == -1)
- {
- free(get_string);
- free(host_string);
- free(query_string);
- free(tmpname);
- free(hostname);
- free(newurl);
- weprintf("error sending over socket:");
- D_RETURN(4, NULL);
- }
- free(get_string);
- free(host_string);
- free(query_string);
- free(hostname);
- free(newurl);
-
- while ((size = read(sockno, &buf, OUR_BUF_SIZE)))
- {
- if (body == IN_BODY)
- {
- fwrite(buf, 1, size, fp);
- }
- else
- {
- int i;
-
- for (i = 0; i < size; i++)
- {
- /* We are looking for ^M^J^M^J, but will accept
- ** ^J^J from broken servers. Stray ^Ms will be
- ** ignored.
- **
- ** TODO:
- ** Checking the headers for a
- ** Content-Type: image/ *
- ** header would help detect problems with results.
- ** Maybe look at the response code too? But there is
- ** no fundamental reason why a 4xx or 5xx response
- ** could not return an image, it is just the 3xx
- ** series we need to worry about.
- **
- ** Also, grabbing the size from the Content-Length
- ** header and killing the connection after that
- ** many bytes where read would speed up closing the
- ** socket.
- ** -- BEG
- */
-
- switch (body)
- {
-
- case IN_BODY:
- fwrite(buf + i, 1, size - i, fp);
- i = size;
- break;
-
- case SAW_ONE_CM:
- if (buf[i] == '\012')
- {
- body = SAW_ONE_CJ;
- }
- else
- {
- body = SAW_NONE;
- }
- break;
-
- case SAW_ONE_CJ:
- if (buf[i] == '\015')
- {
- body = SAW_TWO_CM;
- }
- else
- {
- if (buf[i] == '\012')
- {
- body = IN_BODY;
- }
- else
- {
- body = SAW_NONE;
- }
- }
- break;
-
- case SAW_TWO_CM:
- if (buf[i] == '\012')
- {
- body = IN_BODY;
- }
- else
- {
- body = SAW_NONE;
- }
- break;
-
- case SAW_NONE:
- if (buf[i] == '\015')
- {
- body = SAW_ONE_CM;
- }
- else
- {
- if (buf[i] == '\012')
- {
- body = SAW_ONE_CJ;
- }
- }
- break;
-
- } /* switch */
- } /* for i */
- }
- } /* while read */
- close(sockno);
- fclose(fp);
- }
- else
- {
- int pid;
- int status;
-
- if ((pid = fork()) < 0)
- {
- weprintf("open url: fork failed:");
- free(tmpname);
- free(newurl);
- D_RETURN(4, NULL);
- }
- else if (pid == 0)
- {
- char *quiet = NULL;
-
- if (!opt.verbose)
- quiet = estrdup("-q");
-
- if (opt.wget_timestamp)
- {
- execlp("wget", "wget", "-N", "-O", tmpname_timestamper, newurl,
- quiet, (char*) NULL);
- }
- else
- {
- execlp("wget", "wget", "--cache=off", "-O", tmpname, newurl,
- quiet, NULL);
- }
- eprintf("url: exec failed: wget:");
- }
- else
- {
- waitpid(pid, &status, 0);
-
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
- {
- weprintf("url: wget failed to load URL %s\n", url);
- free(newurl);
- free(tmpname);
- D_RETURN(4, NULL);
- }
- if (opt.wget_timestamp)
- {
- char cmd[2048];
-
- snprintf(cmd, sizeof(cmd), "/bin/cp %s %s", tmpname_timestamper,
- tmpname);
- system(cmd);
- }
- free(newurl);
- }
- }
-
- D_RETURN(4, tmpname);
+ int sockno = 0;
+ int size;
+ int body = SAW_NONE;
+ struct sockaddr_in addr;
+ struct hostent *hptr;
+ char *hostname;
+ char *get_string;
+ char *host_string;
+ char *query_string;
+ char *get_url;
+ static char buf[OUR_BUF_SIZE];
+ char ua_string[] = "User-Agent: feh image viewer";
+ char accept_string[] = "Accept: image/*";
+ FILE *fp;
+
+ D(4, ("using builtin http collection\n"));
+ fp = fopen(tmpname, "w");
+ if (!fp) {
+ weprintf("couldn't write to file %s:", tmpname);
+ free(tmpname);
+ D_RETURN(4, NULL);
+ }
+
+ hostname = feh_strip_hostname(newurl);
+ if (!hostname) {
+ weprintf("couldn't work out hostname from %s:", newurl);
+ free(tmpname);
+ free(newurl);
+ D_RETURN(4, NULL);
+ }
+
+ D(4, ("trying hostname %s\n", hostname));
+
+ if (!(hptr = feh_gethostbyname(hostname))) {
+ weprintf("error resolving host %s:", hostname);
+ free(hostname);
+ free(tmpname);
+ free(newurl);
+ D_RETURN(4, NULL);
+ }
+
+ /* Copy the address of the host to socket description. */
+ memcpy(&addr.sin_addr, hptr->h_addr, hptr->h_length);
+
+ /* Set port and protocol */
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(80);
+
+ if ((sockno = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+ weprintf("error opening socket:");
+ free(tmpname);
+ free(hostname);
+ free(newurl);
+ D_RETURN(4, NULL);
+ }
+ if (connect(sockno, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
+ weprintf("error connecting socket:");
+ free(tmpname);
+ free(hostname);
+ free(newurl);
+ D_RETURN(4, NULL);
+ }
+
+ get_url = strchr(newurl, '/') + 2;
+ get_url = strchr(get_url, '/');
+
+ get_string = estrjoin(" ", "GET", get_url, "HTTP/1.0", NULL);
+ host_string = estrjoin(" ", "Host:", hostname, NULL);
+ query_string = estrjoin(EOL, get_string, host_string, accept_string, ua_string, "", "", NULL);
+ /* At this point query_string looks something like
+ **
+ ** GET /dir/foo.jpg?123456 HTTP/1.0^M^J
+ ** Host: www.example.com^M^J
+ ** Accept: image/ *^M^J
+ ** User-Agent: feh image viewer^M^J
+ ** ^M^J
+ **
+ ** Host: is required by HTTP/1.1 and very important for some sites,
+ ** even with HTTP/1.0
+ **
+ ** -- BEG
+ */
+ if ((send(sockno, query_string, strlen(query_string), 0)) == -1) {
+ free(get_string);
+ free(host_string);
+ free(query_string);
+ free(tmpname);
+ free(hostname);
+ free(newurl);
+ weprintf("error sending over socket:");
+ D_RETURN(4, NULL);
+ }
+ free(get_string);
+ free(host_string);
+ free(query_string);
+ free(hostname);
+ free(newurl);
+
+ while ((size = read(sockno, &buf, OUR_BUF_SIZE))) {
+ if (body == IN_BODY) {
+ fwrite(buf, 1, size, fp);
+ } else {
+ int i;
+
+ for (i = 0; i < size; i++) {
+ /* We are looking for ^M^J^M^J, but will accept
+ ** ^J^J from broken servers. Stray ^Ms will be
+ ** ignored.
+ **
+ ** TODO:
+ ** Checking the headers for a
+ ** Content-Type: image/ *
+ ** header would help detect problems with results.
+ ** Maybe look at the response code too? But there is
+ ** no fundamental reason why a 4xx or 5xx response
+ ** could not return an image, it is just the 3xx
+ ** series we need to worry about.
+ **
+ ** Also, grabbing the size from the Content-Length
+ ** header and killing the connection after that
+ ** many bytes where read would speed up closing the
+ ** socket.
+ ** -- BEG
+ */
+
+ switch (body) {
+
+ case IN_BODY:
+ fwrite(buf + i, 1, size - i, fp);
+ i = size;
+ break;
+
+ case SAW_ONE_CM:
+ if (buf[i] == '\012') {
+ body = SAW_ONE_CJ;
+ } else {
+ body = SAW_NONE;
+ }
+ break;
+
+ case SAW_ONE_CJ:
+ if (buf[i] == '\015') {
+ body = SAW_TWO_CM;
+ } else {
+ if (buf[i] == '\012') {
+ body = IN_BODY;
+ } else {
+ body = SAW_NONE;
+ }
+ }
+ break;
+
+ case SAW_TWO_CM:
+ if (buf[i] == '\012') {
+ body = IN_BODY;
+ } else {
+ body = SAW_NONE;
+ }
+ break;
+
+ case SAW_NONE:
+ if (buf[i] == '\015') {
+ body = SAW_ONE_CM;
+ } else {
+ if (buf[i] == '\012') {
+ body = SAW_ONE_CJ;
+ }
+ }
+ break;
+
+ } /* switch */
+ } /* for i */
+ }
+ } /* while read */
+ close(sockno);
+ fclose(fp);
+ } else {
+ int pid;
+ int status;
+
+ if ((pid = fork()) < 0) {
+ weprintf("open url: fork failed:");
+ free(tmpname);
+ free(newurl);
+ D_RETURN(4, NULL);
+ } else if (pid == 0) {
+ char *quiet = NULL;
+
+ if (!opt.verbose)
+ quiet = estrdup("-q");
+
+ if (opt.wget_timestamp) {
+ execlp("wget", "wget", "-N", "-O", tmpname_timestamper, newurl, quiet, (char *) NULL);
+ } else {
+ execlp("wget", "wget", "--cache=off", "-O", tmpname, newurl, quiet, NULL);
+ }
+ eprintf("url: exec failed: wget:");
+ } else {
+ waitpid(pid, &status, 0);
+
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ weprintf("url: wget failed to load URL %s\n", url);
+ free(newurl);
+ free(tmpname);
+ D_RETURN(4, NULL);
+ }
+ if (opt.wget_timestamp) {
+ char cmd[2048];
+
+ snprintf(cmd, sizeof(cmd), "/bin/cp %s %s", tmpname_timestamper, tmpname);
+ system(cmd);
+ }
+ free(newurl);
+ }
+ }
+
+ D_RETURN(4, tmpname);
}
-struct hostent *
-feh_gethostbyname(const char *name)
+struct hostent *feh_gethostbyname(const char *name)
{
- struct hostent *hp;
- unsigned long addr;
-
- D_ENTER(3);
- addr = (unsigned long) inet_addr(name);
- if ((int) addr != -1)
- hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
- else
- hp = gethostbyname(name);
- D_RETURN(3, hp);
+ struct hostent *hp;
+ unsigned long addr;
+
+ D_ENTER(3);
+ addr = (unsigned long) inet_addr(name);
+ if ((int) addr != -1)
+ hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
+ else
+ hp = gethostbyname(name);
+ D_RETURN(3, hp);
}
-char *
-feh_strip_hostname(char *url)
+char *feh_strip_hostname(char *url)
{
- char *ret;
- char *start;
- char *finish;
- int len;
+ char *ret;
+ char *start;
+ char *finish;
+ int len;
- D_ENTER(3);
+ D_ENTER(3);
- start = strchr(url, '/');
- if (!start)
- D_RETURN(3, NULL);
+ start = strchr(url, '/');
+ if (!start)
+ D_RETURN(3, NULL);
- start += 2;
+ start += 2;
- finish = strchr(start, '/');
- if (!finish)
- D_RETURN(3, NULL);
+ finish = strchr(start, '/');
+ if (!finish)
+ D_RETURN(3, NULL);
- len = finish - start;
+ len = finish - start;
- ret = emalloc(len + 1);
- strncpy(ret, start, len);
- ret[len] = '\0';
- D_RETURN(3, ret);
+ ret = emalloc(len + 1);
+ strncpy(ret, start, len);
+ ret[len] = '\0';
+ D_RETURN(3, ret);
}
-void
-feh_draw_zoom(winwidget w)
+void feh_draw_zoom(winwidget w)
{
- static Imlib_Font fn = NULL;
- int tw = 0, th = 0;
- Imlib_Image im = NULL;
- char buf[100];
- static DATA8 atab[256];
-
- D_ENTER(4);
-
- if (!w->im)
- D_RETURN_(4);
-
- if (!fn) {
- fn = gib_imlib_load_font(DEFAULT_FONT);
- memset(atab, 0, sizeof(atab));
- }
-
- if (!fn)
- {
- weprintf("Couldn't load font for zoom printing");
- D_RETURN_(4);
- }
-
- snprintf(buf, sizeof(buf), "%.0f%%, %dx%d", w->zoom * 100,
- (int) (w->im_w * w->zoom), (int) (w->im_h * w->zoom));
-
- /* Work out how high the font is */
- gib_imlib_get_text_size(fn, buf, NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT);
-
- tw += 3;
- th += 3;
- im = imlib_create_image(tw, th);
- if (!im)
- eprintf("Couldn't create image. Out of memory?");
-
- gib_imlib_image_set_has_alpha(im, 1);
- gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, th,
- NULL, NULL, NULL, atab);
- gib_imlib_image_fill_rectangle(im, 0, 0, tw, th, 0, 0, 0, 0);
-
- gib_imlib_text_draw(im, fn, NULL, 2, 2, buf, IMLIB_TEXT_TO_RIGHT,
- 0, 0, 0, 255);
- gib_imlib_text_draw(im, fn, NULL, 1, 1, buf, IMLIB_TEXT_TO_RIGHT,
- 255, 255, 255, 255);
- gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0, w->h - th, 1, 1, 0);
- gib_imlib_free_image_and_decache(im);
- D_RETURN_(4);
+ static Imlib_Font fn = NULL;
+ int tw = 0, th = 0;
+ Imlib_Image im = NULL;
+ char buf[100];
+ static DATA8 atab[256];
+
+ D_ENTER(4);
+
+ if (!w->im)
+ D_RETURN_(4);
+
+ if (!fn) {
+ fn = gib_imlib_load_font(DEFAULT_FONT);
+ memset(atab, 0, sizeof(atab));
+ }
+
+ if (!fn) {
+ weprintf("Couldn't load font for zoom printing");
+ D_RETURN_(4);
+ }
+
+ snprintf(buf, sizeof(buf), "%.0f%%, %dx%d", w->zoom * 100,
+ (int) (w->im_w * w->zoom), (int) (w->im_h * w->zoom));
+
+ /* Work out how high the font is */
+ gib_imlib_get_text_size(fn, buf, NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT);
+
+ tw += 3;
+ th += 3;
+ im = imlib_create_image(tw, th);
+ if (!im)
+ eprintf("Couldn't create image. Out of memory?");
+
+ gib_imlib_image_set_has_alpha(im, 1);
+ gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, th, NULL, NULL, NULL, atab);
+ gib_imlib_image_fill_rectangle(im, 0, 0, tw, th, 0, 0, 0, 0);
+
+ gib_imlib_text_draw(im, fn, NULL, 2, 2, buf, IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
+ gib_imlib_text_draw(im, fn, NULL, 1, 1, buf, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
+ gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0, w->h - th, 1, 1, 0);
+ gib_imlib_free_image_and_decache(im);
+ D_RETURN_(4);
}
-void
-feh_draw_filename(winwidget w)
+void feh_draw_filename(winwidget w)
{
- static Imlib_Font fn = NULL;
- int tw = 0, th = 0;
- Imlib_Image im = NULL;
- static DATA8 atab[256];
- char *s = NULL;
- int len = 0;
-
- D_ENTER(4);
-
- if ((!w->file) || (!FEH_FILE(w->file->data))
- || (!FEH_FILE(w->file->data)->filename))
- D_RETURN_(4);
-
- if (!fn)
- {
- memset(atab, 0, sizeof(atab));
- if (w->full_screen)
- fn = gib_imlib_load_font(DEFAULT_FONT_BIG);
- else
- fn = gib_imlib_load_font(DEFAULT_FONT);
- }
-
- if (!fn)
- {
- weprintf("Couldn't load font for filename printing");
- D_RETURN_(4);
- }
-
- /* Work out how high the font is */
- gib_imlib_get_text_size(fn, FEH_FILE(w->file->data)->filename, NULL, &tw, &th,
- IMLIB_TEXT_TO_RIGHT);
-
- /* tw is no longer correct, if the filename is shorter than
- * the string "%d of %d" used below in fullscreen mode */
- tw += 3;
- th += 3;
- im = imlib_create_image(tw, 2*th);
- if (!im)
- eprintf("Couldn't create image. Out of memory?");
-
- gib_imlib_image_set_has_alpha(im, 1);
- gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, 2*th,
- NULL, NULL, NULL, atab);
- gib_imlib_image_fill_rectangle(im, 0, 0, tw, 2*th, 0, 0, 0, 0);
-
- gib_imlib_text_draw(im, fn, NULL, 2, 2, FEH_FILE(w->file->data)->filename,
- IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
- gib_imlib_text_draw(im, fn, NULL, 1, 1, FEH_FILE(w->file->data)->filename,
- IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
- /* Print the position in the filelist, if we are in fullscreen and the
- * list has more than one element */
- if (w->full_screen && (gib_list_length(filelist)-1))
- {
- /* sic! */
- len = snprintf(NULL, 0, "%d of %d", gib_list_length(filelist), gib_list_length(filelist))+1;
- s = emalloc(len);
- snprintf(s, len, "%d of %d",
- gib_list_num(filelist, current_file) + 1,
- gib_list_length(filelist));
- /* This should somehow be right-aligned */
- gib_imlib_text_draw(im, fn, NULL, 2, th+1, s, IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
- gib_imlib_text_draw(im, fn, NULL, 1, th, s, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
- free(s);
- }
-
- gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0, 0, 1, 1, 0);
-
- gib_imlib_free_image_and_decache(im);
- D_RETURN_(4);
+ static Imlib_Font fn = NULL;
+ int tw = 0, th = 0;
+ Imlib_Image im = NULL;
+ static DATA8 atab[256];
+ char *s = NULL;
+ int len = 0;
+
+ D_ENTER(4);
+
+ if ((!w->file) || (!FEH_FILE(w->file->data))
+ || (!FEH_FILE(w->file->data)->filename))
+ D_RETURN_(4);
+
+ if (!fn) {
+ memset(atab, 0, sizeof(atab));
+ if (w->full_screen)
+ fn = gib_imlib_load_font(DEFAULT_FONT_BIG);
+ else
+ fn = gib_imlib_load_font(DEFAULT_FONT);
+ }
+
+ if (!fn) {
+ weprintf("Couldn't load font for filename printing");
+ D_RETURN_(4);
+ }
+
+ /* Work out how high the font is */
+ gib_imlib_get_text_size(fn, FEH_FILE(w->file->data)->filename, NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT);
+
+ /* tw is no longer correct, if the filename is shorter than
+ * the string "%d of %d" used below in fullscreen mode */
+ tw += 3;
+ th += 3;
+ im = imlib_create_image(tw, 2 * th);
+ if (!im)
+ eprintf("Couldn't create image. Out of memory?");
+
+ gib_imlib_image_set_has_alpha(im, 1);
+ gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, 2 * th, NULL, NULL, NULL, atab);
+ gib_imlib_image_fill_rectangle(im, 0, 0, tw, 2 * th, 0, 0, 0, 0);
+
+ gib_imlib_text_draw(im, fn, NULL, 2, 2, FEH_FILE(w->file->data)->filename,
+ IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
+ gib_imlib_text_draw(im, fn, NULL, 1, 1, FEH_FILE(w->file->data)->filename,
+ IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
+ /* Print the position in the filelist, if we are in fullscreen and the
+ * list has more than one element */
+ if (w->full_screen && (gib_list_length(filelist) - 1)) {
+ /* sic! */
+ len = snprintf(NULL, 0, "%d of %d", gib_list_length(filelist), gib_list_length(filelist)) + 1;
+ s = emalloc(len);
+ snprintf(s, len, "%d of %d", gib_list_num(filelist, current_file) + 1, gib_list_length(filelist));
+ /* This should somehow be right-aligned */
+ gib_imlib_text_draw(im, fn, NULL, 2, th + 1, s, IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
+ gib_imlib_text_draw(im, fn, NULL, 1, th, s, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
+ free(s);
+ }
+
+ gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0, 0, 1, 1, 0);
+
+ gib_imlib_free_image_and_decache(im);
+ D_RETURN_(4);
}
-char *build_caption_filename(feh_file *file) {
- char *caption_filename;
- char *s, *dir;
- s = strrchr(file->filename, '/');
- if (s) {
- dir = estrdup(file->filename);
- s = strrchr(dir, '/');
- *s = '\0';
- } else {
- dir = estrdup(".");
- }
- caption_filename = estrjoin("",
- dir,
- "/",
- opt.caption_path,
- "/",
- file->name,
- ".txt",
- NULL);
- free(dir);
- return caption_filename;
+char *build_caption_filename(feh_file * file)
+{
+ char *caption_filename;
+ char *s, *dir;
+ s = strrchr(file->filename, '/');
+ if (s) {
+ dir = estrdup(file->filename);
+ s = strrchr(dir, '/');
+ *s = '\0';
+ } else {
+ dir = estrdup(".");
+ }
+ caption_filename = estrjoin("", dir, "/", opt.caption_path, "/", file->name, ".txt", NULL);
+ free(dir);
+ return caption_filename;
}
-void
-feh_draw_caption(winwidget w)
+void feh_draw_caption(winwidget w)
{
- static Imlib_Font fn = NULL;
- int tw = 0, th = 0, ww, hh;
- int x, y;
- Imlib_Image im = NULL;
- static DATA8 atab[256];
- char *p;
- gib_list *lines, *l;
- static gib_style *caption_style = NULL;
- feh_file *file;
-
- D_ENTER(4);
-
- if (!w->file) {
- D_RETURN_(4);
- }
- file = FEH_FILE(w->file->data);
- if (!file->filename) {
- D_RETURN_(4);
- }
-
- if (!file->caption) {
- char *caption_filename;
- caption_filename = build_caption_filename(file);
- /* read caption from file */
- file->caption = ereadfile(caption_filename);
- free(caption_filename);
- }
-
- if (file->caption == NULL) {
- /* caption file is not there, we want to cache that, otherwise we'll stat
- * the damn file every time we render the image. Reloading an image will
- * always cause the caption to be reread though so we're safe to do so.
- * (Before this bit was added, when zooming a captionless image with
- * captions enabled, the captions file would be stat()d like 30 times a
- * second) - don't forget this function is called from
- * winwidget_render_image().
- */
- file->caption = estrdup("");
- D_RETURN_(4);
- }
-
- if (file->caption == '\0') {
- D_RETURN_(4);
- }
-
- if (!caption_style) {
- caption_style = gib_style_new("caption");
- caption_style->bits = gib_list_add_front(caption_style->bits,
- gib_style_bit_new(0,0,0,0,0,0));
- caption_style->bits = gib_list_add_front(caption_style->bits,
- gib_style_bit_new(1,1,0,0,0,255));
- }
-
- if (!fn)
- {
- memset(atab, 0, sizeof(atab));
- if (w->full_screen)
- fn = gib_imlib_load_font(DEFAULT_FONT_BIG);
- else
- fn = gib_imlib_load_font(DEFAULT_FONT);
- }
-
- if (!fn)
- {
- weprintf("Couldn't load font for caption printing");
- D_RETURN_(4);
- }
-
- lines = feh_wrap_string(file->caption, w->w, w->h, fn, NULL);
- if (!lines)
- D_RETURN_(4);
-
- /* Work out how high/wide the caption is */
- l = lines;
- while (l) {
- p = (char *) l->data;
- gib_imlib_get_text_size(fn, p, caption_style, &ww, &hh, IMLIB_TEXT_TO_RIGHT);
- if (ww > tw)
- tw = ww;
- th += hh;
- if (l->next)
- th += 1; /* line spacing */
- l = l->next;
- }
-
- /* we don't want the caption overlay larger than our window */
- if (th > w->h)
- th = w->h;
- if (tw > w->w)
- tw = w->w;
-
- im = imlib_create_image(tw, th);
- if (!im)
- eprintf("Couldn't create image. Out of memory?");
-
- gib_imlib_image_set_has_alpha(im, 1);
- gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, th,
- NULL, NULL, NULL, atab);
- gib_imlib_image_fill_rectangle(im, 0, 0, tw, th, 0, 0, 0, 0);
-
- l = lines;
- x = 0;
- y = 0;
- while (l) {
- p = (char *) l->data;
- gib_imlib_get_text_size(fn, p, caption_style, &ww, &hh, IMLIB_TEXT_TO_RIGHT);
- x = (tw - ww) / 2;
- if (w->caption_entry) {
- gib_imlib_text_draw(im, fn, caption_style, x, y, p, IMLIB_TEXT_TO_RIGHT,
- 255, 255, 0, 255);
- } else {
- gib_imlib_text_draw(im, fn, caption_style, x, y, p, IMLIB_TEXT_TO_RIGHT,
- 255, 255, 255, 255);
- }
-
- y += hh + 1; /* line spacing */
- l = l->next;
- }
-
- gib_imlib_render_image_on_drawable(w->bg_pmap, im, (w->w - tw) / 2, w->h - th, 1, 1, 0);
- gib_imlib_free_image_and_decache(im);
- gib_list_free_and_data(lines);
- D_RETURN_(4);
+ static Imlib_Font fn = NULL;
+ int tw = 0, th = 0, ww, hh;
+ int x, y;
+ Imlib_Image im = NULL;
+ static DATA8 atab[256];
+ char *p;
+ gib_list *lines, *l;
+ static gib_style *caption_style = NULL;
+ feh_file *file;
+
+ D_ENTER(4);
+
+ if (!w->file) {
+ D_RETURN_(4);
+ }
+ file = FEH_FILE(w->file->data);
+ if (!file->filename) {
+ D_RETURN_(4);
+ }
+
+ if (!file->caption) {
+ char *caption_filename;
+ caption_filename = build_caption_filename(file);
+ /* read caption from file */
+ file->caption = ereadfile(caption_filename);
+ free(caption_filename);
+ }
+
+ if (file->caption == NULL) {
+ /* caption file is not there, we want to cache that, otherwise we'll stat
+ * the damn file every time we render the image. Reloading an image will
+ * always cause the caption to be reread though so we're safe to do so.
+ * (Before this bit was added, when zooming a captionless image with
+ * captions enabled, the captions file would be stat()d like 30 times a
+ * second) - don't forget this function is called from
+ * winwidget_render_image().
+ */
+ file->caption = estrdup("");
+ D_RETURN_(4);
+ }
+
+ if (file->caption == '\0') {
+ D_RETURN_(4);
+ }
+
+ if (!caption_style) {
+ caption_style = gib_style_new("caption");
+ caption_style->bits = gib_list_add_front(caption_style->bits, gib_style_bit_new(0, 0, 0, 0, 0, 0));
+ caption_style->bits = gib_list_add_front(caption_style->bits, gib_style_bit_new(1, 1, 0, 0, 0, 255));
+ }
+
+ if (!fn) {
+ memset(atab, 0, sizeof(atab));
+ if (w->full_screen)
+ fn = gib_imlib_load_font(DEFAULT_FONT_BIG);
+ else
+ fn = gib_imlib_load_font(DEFAULT_FONT);
+ }
+
+ if (!fn) {
+ weprintf("Couldn't load font for caption printing");
+ D_RETURN_(4);
+ }
+
+ lines = feh_wrap_string(file->caption, w->w, w->h, fn, NULL);
+ if (!lines)
+ D_RETURN_(4);
+
+ /* Work out how high/wide the caption is */
+ l = lines;
+ while (l) {
+ p = (char *) l->data;
+ gib_imlib_get_text_size(fn, p, caption_style, &ww, &hh, IMLIB_TEXT_TO_RIGHT);
+ if (ww > tw)
+ tw = ww;
+ th += hh;
+ if (l->next)
+ th += 1; /* line spacing */
+ l = l->next;
+ }
+
+ /* we don't want the caption overlay larger than our window */
+ if (th > w->h)
+ th = w->h;
+ if (tw > w->w)
+ tw = w->w;
+
+ im = imlib_create_image(tw, th);
+ if (!im)
+ eprintf("Couldn't create image. Out of memory?");
+
+ gib_imlib_image_set_has_alpha(im, 1);
+ gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, th, NULL, NULL, NULL, atab);
+ gib_imlib_image_fill_rectangle(im, 0, 0, tw, th, 0, 0, 0, 0);
+
+ l = lines;
+ x = 0;
+ y = 0;
+ while (l) {
+ p = (char *) l->data;
+ gib_imlib_get_text_size(fn, p, caption_style, &ww, &hh, IMLIB_TEXT_TO_RIGHT);
+ x = (tw - ww) / 2;
+ if (w->caption_entry) {
+ gib_imlib_text_draw(im, fn, caption_style, x, y, p, IMLIB_TEXT_TO_RIGHT, 255, 255, 0, 255);
+ } else {
+ gib_imlib_text_draw(im, fn, caption_style, x, y, p, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
+ }
+
+ y += hh + 1; /* line spacing */
+ l = l->next;
+ }
+
+ gib_imlib_render_image_on_drawable(w->bg_pmap, im, (w->w - tw) / 2, w->h - th, 1, 1, 0);
+ gib_imlib_free_image_and_decache(im);
+ gib_list_free_and_data(lines);
+ D_RETURN_(4);
}
-
unsigned char reset_output = 0;
-void
-feh_display_status(char stat)
+void feh_display_status(char stat)
{
- static int i = 0;
- static int init_len = 0;
- int j = 0;
-
- D_ENTER(5);
-
- D(5, ("filelist %p, filelist->next %p\n", filelist, filelist->next));
-
- if (!init_len)
- init_len = gib_list_length(filelist);
-
- if (i)
- {
- if (reset_output)
- {
- /* There's just been an error message. Unfortunate ;) */
- for (j = 0; j < (((i % 50) + ((i % 50) / 10)) + 7); j++)
- fprintf(stdout, " ");
- }
-
- if (!(i % 50))
- {
- int len;
- char buf[50];
-
- len = gib_list_length(filelist);
- snprintf(buf, sizeof(buf), " %5d/%d (%d)\n[%3d%%] ", i, init_len,
- len, ((int) ((float) i / init_len * 100)));
- fprintf(stdout, buf);
- }
- else if ((!(i % 10)) && (!reset_output))
- fprintf(stdout, " ");
-
- reset_output = 0;
- }
- else
- fprintf(stdout, "[ 0%%] ");
-
- fprintf(stdout, "%c", stat);
- fflush(stdout);
- i++;
- D_RETURN_(5);
+ static int i = 0;
+ static int init_len = 0;
+ int j = 0;
+
+ D_ENTER(5);
+
+ D(5, ("filelist %p, filelist->next %p\n", filelist, filelist->next));
+
+ if (!init_len)
+ init_len = gib_list_length(filelist);
+
+ if (i) {
+ if (reset_output) {
+ /* There's just been an error message. Unfortunate ;) */
+ for (j = 0; j < (((i % 50) + ((i % 50) / 10)) + 7); j++)
+ fprintf(stdout, " ");
+ }
+
+ if (!(i % 50)) {
+ int len;
+ char buf[50];
+
+ len = gib_list_length(filelist);
+ snprintf(buf, sizeof(buf),
+ " %5d/%d (%d)\n[%3d%%] ", i, init_len, len, ((int) ((float) i / init_len * 100)));
+ fprintf(stdout, buf);
+ } else if ((!(i % 10)) && (!reset_output))
+ fprintf(stdout, " ");
+
+ reset_output = 0;
+ } else
+ fprintf(stdout, "[ 0%%] ");
+
+ fprintf(stdout, "%c", stat);
+ fflush(stdout);
+ i++;
+ D_RETURN_(5);
}
-void feh_edit_inplace_orient(winwidget w, int orientation) {
- int ret;
- Imlib_Image old;
- D_ENTER(4);
- if(!w->file
- || !w->file->data
- || !FEH_FILE(w->file->data)->filename)
- D_RETURN_(4);
-
- if (!strcmp(gib_imlib_image_format(w->im), "jpeg")) {
- feh_edit_inplace_lossless_rotate(w, orientation);
- feh_reload_image(w, 1, 1);
- D_RETURN_(4);
- }
-
- ret = feh_load_image(&old, FEH_FILE(w->file->data));
- if(ret) {
- gib_imlib_image_orientate(old, orientation);
- gib_imlib_save_image(old, FEH_FILE(w->file->data)->filename);
- gib_imlib_free_image(old);
- feh_reload_image(w, 1, 1);
- } else {
- weprintf("failed to load image from disk to edit it in place\n");
- }
-
- D_RETURN_(4);
+void feh_edit_inplace_orient(winwidget w, int orientation)
+{
+ int ret;
+ Imlib_Image old;
+ D_ENTER(4);
+ if (!w->file || !w->file->data || !FEH_FILE(w->file->data)->filename)
+ D_RETURN_(4);
+
+ if (!strcmp(gib_imlib_image_format(w->im), "jpeg")) {
+ feh_edit_inplace_lossless_rotate(w, orientation);
+ feh_reload_image(w, 1, 1);
+ D_RETURN_(4);
+ }
+
+ ret = feh_load_image(&old, FEH_FILE(w->file->data));
+ if (ret) {
+ gib_imlib_image_orientate(old, orientation);
+ gib_imlib_save_image(old, FEH_FILE(w->file->data)->filename);
+ gib_imlib_free_image(old);
+ feh_reload_image(w, 1, 1);
+ } else {
+ weprintf("failed to load image from disk to edit it in place\n");
+ }
+
+ D_RETURN_(4);
}
-
/* TODO max_height is ignored... Could use a function which generates a
* transparent text overlay image, with wrapping and all. Would be useful */
-gib_list *
-feh_wrap_string(char *text, int wrap_width, int max_height, Imlib_Font fn, gib_style * style)
+gib_list *feh_wrap_string(char *text, int wrap_width, int max_height, Imlib_Font fn, gib_style * style)
{
- gib_list *ll, *lines = NULL, *list = NULL, *words;
- gib_list *l = NULL;
- char delim[2] = { '\n', '\0' };
- int w, line_width;
- int tw, th;
- char *p, *pp;
- char *line = NULL;
- char *temp;
- int space_width = 0, m_width = 0, t_width = 0, new_width = 0;
-
- lines = gib_string_split(text, delim);
-
- if (wrap_width)
- {
- gib_imlib_get_text_size(fn, "M M", style, &t_width, NULL,
- IMLIB_TEXT_TO_RIGHT);
- gib_imlib_get_text_size(fn, "M", style, &m_width, NULL,
- IMLIB_TEXT_TO_RIGHT);
- space_width = t_width - (2 * m_width);
- w = wrap_width;
- l = lines;
- while (l)
- {
- line_width = 0;
- p = (char *) l->data;
- /* quick check to see if whole line fits okay */
- gib_imlib_get_text_size(fn, p, style, &tw, &th, IMLIB_TEXT_TO_RIGHT);
- if (tw <= w) {
- list = gib_list_add_end(list, estrdup(p));
- } else if (strlen(p) == 0) {
- list = gib_list_add_end(list, estrdup(""));
- } else if (!strcmp(p, " ")) {
- list = gib_list_add_end(list, estrdup(" "));
- } else {
- words = gib_string_split(p, " ");
- if (words) {
- ll = words;
- while (ll) {
- pp = (char *) ll->data;
- if (strcmp(pp, " ")) {
- gib_imlib_get_text_size(fn, pp, style, &tw, &th,
- IMLIB_TEXT_TO_RIGHT);
- if (line_width == 0)
- new_width = tw;
- else
- new_width = line_width + space_width + tw;
- if (new_width <= w) {
- /* add word to line */
- if (line) {
- int len;
-
- len = strlen(line) + strlen(pp) + 2;
- temp = emalloc(len);
- snprintf(temp, len, "%s %s", line, pp);
- free(line);
- line = temp;
- } else {
- line = estrdup(pp);
- }
- line_width = new_width;
- } else if (line_width == 0) {
- /* can't fit single word in :/
- increase width limit to width of word
- and jam the bastard in anyhow */
- w = tw;
- line = estrdup(pp);
- line_width = new_width;
- } else {
- /* finish this line, start next and add word there */
- if (line) {
- list = gib_list_add_end(list, estrdup(line));
- free(line);
- line = NULL;
- }
- line = estrdup(pp);
- line_width = tw;
- }
- }
- ll = ll->next;
- }
- if (line) {
- /* finish last line */
- list = gib_list_add_end(list, estrdup(line));
- free(line);
- line = NULL;
- line_width = 0;
- }
- gib_list_free_and_data(words);
- }
- }
- l = l->next;
- }
- gib_list_free_and_data(lines);
- lines = list;
- }
- return lines;
+ gib_list *ll, *lines = NULL, *list = NULL, *words;
+ gib_list *l = NULL;
+ char delim[2] = { '\n', '\0' };
+ int w, line_width;
+ int tw, th;
+ char *p, *pp;
+ char *line = NULL;
+ char *temp;
+ int space_width = 0, m_width = 0, t_width = 0, new_width = 0;
+
+ lines = gib_string_split(text, delim);
+
+ if (wrap_width) {
+ gib_imlib_get_text_size(fn, "M M", style, &t_width, NULL, IMLIB_TEXT_TO_RIGHT);
+ gib_imlib_get_text_size(fn, "M", style, &m_width, NULL, IMLIB_TEXT_TO_RIGHT);
+ space_width = t_width - (2 * m_width);
+ w = wrap_width;
+ l = lines;
+ while (l) {
+ line_width = 0;
+ p = (char *) l->data;
+ /* quick check to see if whole line fits okay */
+ gib_imlib_get_text_size(fn, p, style, &tw, &th, IMLIB_TEXT_TO_RIGHT);
+ if (tw <= w) {
+ list = gib_list_add_end(list, estrdup(p));
+ } else if (strlen(p) == 0) {
+ list = gib_list_add_end(list, estrdup(""));
+ } else if (!strcmp(p, " ")) {
+ list = gib_list_add_end(list, estrdup(" "));
+ } else {
+ words = gib_string_split(p, " ");
+ if (words) {
+ ll = words;
+ while (ll) {
+ pp = (char *) ll->data;
+ if (strcmp(pp, " ")) {
+ gib_imlib_get_text_size
+ (fn, pp, style, &tw, &th, IMLIB_TEXT_TO_RIGHT);
+ if (line_width == 0)
+ new_width = tw;
+ else
+ new_width = line_width + space_width + tw;
+ if (new_width <= w) {
+ /* add word to line */
+ if (line) {
+ int len;
+
+ len = strlen(line)
+ + strlen(pp)
+ + 2;
+ temp = emalloc(len);
+ snprintf(temp, len, "%s %s", line, pp);
+ free(line);
+ line = temp;
+ } else {
+ line = estrdup(pp);
+ }
+ line_width = new_width;
+ } else if (line_width == 0) {
+ /* can't fit single word in :/
+ increase width limit to width of word
+ and jam the bastard in anyhow */
+ w = tw;
+ line = estrdup(pp);
+ line_width = new_width;
+ } else {
+ /* finish this line, start next and add word there */
+ if (line) {
+ list = gib_list_add_end(list, estrdup(line));
+ free(line);
+ line = NULL;
+ }
+ line = estrdup(pp);
+ line_width = tw;
+ }
+ }
+ ll = ll->next;
+ }
+ if (line) {
+ /* finish last line */
+ list = gib_list_add_end(list, estrdup(line));
+ free(line);
+ line = NULL;
+ line_width = 0;
+ }
+ gib_list_free_and_data(words);
+ }
+ }
+ l = l->next;
+ }
+ gib_list_free_and_data(lines);
+ lines = list;
+ }
+ return lines;
}
-void feh_edit_inplace_lossless_rotate(winwidget w, int orientation) {
- FILE *input_file;
- FILE *output_file;
- struct jpeg_decompress_struct srcinfo;
- struct jpeg_compress_struct dstinfo;
- struct jpeg_error_mgr jsrcerr, jdsterr;
- jvirt_barray_ptr * src_coef_arrays;
- jvirt_barray_ptr * dst_coef_arrays;
- JCOPY_OPTION copyoption;
- jpeg_transform_info transformoption;
- int len;
- char *outfilename;
- char *infilename = FEH_FILE(w->file->data)->filename;
-
- copyoption = JCOPYOPT_ALL;
- transformoption.transform = JXFORM_NONE;
- transformoption.trim = FALSE;
- transformoption.force_grayscale = FALSE;
-
- if (orientation == 1) {
- transformoption.transform = JXFORM_ROT_90;
- } else if (orientation == 2) {
- transformoption.transform = JXFORM_ROT_180;
- } else {
- transformoption.transform = JXFORM_ROT_270;
- }
-
- if ((input_file = fopen(infilename, "rb")) == NULL) {
- weprintf("couldn't open file for reading: %s\n", infilename);
- D_RETURN_(4);
- }
- len = strlen(infilename) + sizeof(".tmp") + 1;
- outfilename = emalloc(len);
- snprintf(outfilename, len, "%s.tmp", infilename);
-
- if ((output_file = fopen(outfilename, "wb")) == NULL) {
- weprintf("couldn't open file for writing: %s\n", outfilename);
- free(outfilename);
- fclose(input_file);
- D_RETURN_(4);
- }
-
- /* Initialize the JPEG decompression object with default error handling. */
- srcinfo.err = jpeg_std_error(&jsrcerr);
- jpeg_create_decompress(&srcinfo);
-
- /* Initialize the JPEG compression object with default error handling. */
- dstinfo.err = jpeg_std_error(&jdsterr);
- jpeg_create_compress(&dstinfo);
- jsrcerr.trace_level = jdsterr.trace_level;
-
- /* Specify data source for decompression */
- jpeg_stdio_src(&srcinfo, input_file);
-
- /* Enable saving of extra markers that we want to copy */
- jcopy_markers_setup(&srcinfo, copyoption);
-
- /* Read file header */
- (void) jpeg_read_header(&srcinfo, TRUE);
-
- /* Any space needed by a transform option must be requested before
- * jpeg_read_coefficients so that memory allocation will be done right.
- */
- jtransform_request_workspace(&srcinfo, &transformoption);
-
- /* Read source file as DCT coefficients */
- src_coef_arrays = jpeg_read_coefficients(&srcinfo);
-
- /* Initialize destination compression parameters from source values */
- jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
-
- /* Adjust destination parameters if required by transform options;
- * also find out which set of coefficient arrays will hold the output.
- */
- dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
- src_coef_arrays,
- &transformoption);
-
- /* Specify data destination for compression */
- jpeg_stdio_dest(&dstinfo, output_file);
-
- /* Start compressor (note no image data is actually written here) */
- jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
-
- /* Copy to the output file any extra markers that we want to preserve */
- jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
-
- /* Execute image transformation */
- jtransform_execute_transformation(&srcinfo, &dstinfo,
- src_coef_arrays,
- &transformoption);
-
- /* Finish compression and release memory */
- jpeg_finish_compress(&dstinfo);
- jpeg_destroy_compress(&dstinfo);
-
- (void) jpeg_finish_decompress(&srcinfo);
- jpeg_destroy_decompress(&srcinfo);
-
- fclose(input_file);
- fclose(output_file);
-
- /* TODO fix EXIF tags (orientation, width, height) */
-
- /* rename outfilename to infilename.. if it worked */
- if (jsrcerr.num_warnings > 0) {
- weprintf("got errors from libjpeg (%d), not replacing file\n", jsrcerr.num_warnings);
- } else {
- if (rename(outfilename, infilename)) {
- weprintf("failed to replace file %s with %s\n", infilename, outfilename);
- }
- }
- free(outfilename);
+void feh_edit_inplace_lossless_rotate(winwidget w, int orientation)
+{
+ FILE *input_file;
+ FILE *output_file;
+ struct jpeg_decompress_struct srcinfo;
+ struct jpeg_compress_struct dstinfo;
+ struct jpeg_error_mgr jsrcerr, jdsterr;
+ jvirt_barray_ptr *src_coef_arrays;
+ jvirt_barray_ptr *dst_coef_arrays;
+ JCOPY_OPTION copyoption;
+ jpeg_transform_info transformoption;
+ int len;
+ char *outfilename;
+ char *infilename = FEH_FILE(w->file->data)->filename;
+
+ copyoption = JCOPYOPT_ALL;
+ transformoption.transform = JXFORM_NONE;
+ transformoption.trim = FALSE;
+ transformoption.force_grayscale = FALSE;
+
+ if (orientation == 1) {
+ transformoption.transform = JXFORM_ROT_90;
+ } else if (orientation == 2) {
+ transformoption.transform = JXFORM_ROT_180;
+ } else {
+ transformoption.transform = JXFORM_ROT_270;
+ }
+
+ if ((input_file = fopen(infilename, "rb")) == NULL) {
+ weprintf("couldn't open file for reading: %s\n", infilename);
+ D_RETURN_(4);
+ }
+ len = strlen(infilename) + sizeof(".tmp") + 1;
+ outfilename = emalloc(len);
+ snprintf(outfilename, len, "%s.tmp", infilename);
+
+ if ((output_file = fopen(outfilename, "wb")) == NULL) {
+ weprintf("couldn't open file for writing: %s\n", outfilename);
+ free(outfilename);
+ fclose(input_file);
+ D_RETURN_(4);
+ }
+
+ /* Initialize the JPEG decompression object with default error handling. */
+ srcinfo.err = jpeg_std_error(&jsrcerr);
+ jpeg_create_decompress(&srcinfo);
+
+ /* Initialize the JPEG compression object with default error handling. */
+ dstinfo.err = jpeg_std_error(&jdsterr);
+ jpeg_create_compress(&dstinfo);
+ jsrcerr.trace_level = jdsterr.trace_level;
+
+ /* Specify data source for decompression */
+ jpeg_stdio_src(&srcinfo, input_file);
+
+ /* Enable saving of extra markers that we want to copy */
+ jcopy_markers_setup(&srcinfo, copyoption);
+
+ /* Read file header */
+ (void) jpeg_read_header(&srcinfo, TRUE);
+
+ /* Any space needed by a transform option must be requested before
+ * jpeg_read_coefficients so that memory allocation will be done right.
+ */
+ jtransform_request_workspace(&srcinfo, &transformoption);
+
+ /* Read source file as DCT coefficients */
+ src_coef_arrays = jpeg_read_coefficients(&srcinfo);
+
+ /* Initialize destination compression parameters from source values */
+ jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
+
+ /* Adjust destination parameters if required by transform options;
+ * also find out which set of coefficient arrays will hold the output.
+ */
+ dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo, src_coef_arrays, &transformoption);
+
+ /* Specify data destination for compression */
+ jpeg_stdio_dest(&dstinfo, output_file);
+
+ /* Start compressor (note no image data is actually written here) */
+ jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
+
+ /* Copy to the output file any extra markers that we want to preserve */
+ jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
+
+ /* Execute image transformation */
+ jtransform_execute_transformation(&srcinfo, &dstinfo, src_coef_arrays, &transformoption);
+
+ /* Finish compression and release memory */
+ jpeg_finish_compress(&dstinfo);
+ jpeg_destroy_compress(&dstinfo);
+
+ (void) jpeg_finish_decompress(&srcinfo);
+ jpeg_destroy_decompress(&srcinfo);
+
+ fclose(input_file);
+ fclose(output_file);
+
+ /* TODO fix EXIF tags (orientation, width, height) */
+
+ /* rename outfilename to infilename.. if it worked */
+ if (jsrcerr.num_warnings > 0) {
+ weprintf("got errors from libjpeg (%d), not replacing file\n", jsrcerr.num_warnings);
+ } else {
+ if (rename(outfilename, infilename)) {
+ weprintf("failed to replace file %s with %s\n", infilename, outfilename);
+ }
+ }
+ free(outfilename);
}
-void
-feh_draw_actions(winwidget w)
+void feh_draw_actions(winwidget w)
{
- static Imlib_Font fn = NULL;
- int tw = 0, th = 0;
- int th_offset = 0;
- int max_tw = 0;
- int line_th = 0;
- Imlib_Image im = NULL;
- static DATA8 atab[256];
- int i = 0;
- int num_actions = 0;
- int cur_action = 0;
- char index[1];
- char *line;
-
- D_ENTER(4);
-
- /* Count number of defined actions. This method sucks a bit since it needs
- * to be changed if the number of actions changes, but at least it doesn't
- * miss actions 2 to 9 if action1 isn't defined
- */
- for (i = 0; i < 10; i++) {
- if (opt.actions[i])
- num_actions++;
- }
-
- if (num_actions == 0)
- return;
-
- if ((!w->file) || (!FEH_FILE(w->file->data))
- || (!FEH_FILE(w->file->data)->filename))
- D_RETURN_(4);
-
- if (!fn)
- {
- memset(atab, 0, sizeof(atab));
- if (w->full_screen)
- fn = gib_imlib_load_font(DEFAULT_FONT_BIG);
- else
- fn = gib_imlib_load_font(DEFAULT_FONT);
- }
-
- if (!fn)
- {
- weprintf("Couldn't load font for actions printing");
- D_RETURN_(4);
- }
-
- gib_imlib_get_text_size(fn, "defined actions:", NULL, &tw, &th,
- IMLIB_TEXT_TO_RIGHT);
+ static Imlib_Font fn = NULL;
+ int tw = 0, th = 0;
+ int th_offset = 0;
+ int max_tw = 0;
+ int line_th = 0;
+ Imlib_Image im = NULL;
+ static DATA8 atab[256];
+ int i = 0;
+ int num_actions = 0;
+ int cur_action = 0;
+ char index[1];
+ char *line;
+
+ D_ENTER(4);
+
+ /* Count number of defined actions. This method sucks a bit since it needs
+ * to be changed if the number of actions changes, but at least it doesn't
+ * miss actions 2 to 9 if action1 isn't defined
+ */
+ for (i = 0; i < 10; i++) {
+ if (opt.actions[i])
+ num_actions++;
+ }
+
+ if (num_actions == 0)
+ return;
+
+ if ((!w->file) || (!FEH_FILE(w->file->data))
+ || (!FEH_FILE(w->file->data)->filename))
+ D_RETURN_(4);
+
+ if (!fn) {
+ memset(atab, 0, sizeof(atab));
+ if (w->full_screen)
+ fn = gib_imlib_load_font(DEFAULT_FONT_BIG);
+ else
+ fn = gib_imlib_load_font(DEFAULT_FONT);
+ }
+
+ if (!fn) {
+ weprintf("Couldn't load font for actions printing");
+ D_RETURN_(4);
+ }
+
+ gib_imlib_get_text_size(fn, "defined actions:", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT);
// Check for the widest line
- max_tw = tw;
-
- for (i = 0; i < 10; i++) {
- if (opt.actions[i]) {
- gib_imlib_get_text_size(fn, opt.actions[i], NULL, &tw, &th,
- IMLIB_TEXT_TO_RIGHT);
- if (tw > max_tw)
- max_tw = tw;
- }
- }
-
- tw = max_tw;
- tw += 3;
- th += 3;
- line_th = th;
- th = (th*num_actions)+line_th;
-
- /* This depends on feh_draw_filename internals...
- * should be fixed some time
- */
- if (opt.draw_filename && w->full_screen)
- th_offset = line_th * 2;
- else if (opt.draw_filename)
- th_offset = line_th;
-
- im = imlib_create_image(tw, th);
- if (!im)
- eprintf("Couldn't create image. Out of memory?");
-
- gib_imlib_image_set_has_alpha(im, 1);
- gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, th,
- NULL, NULL, NULL, atab);
- gib_imlib_image_fill_rectangle(im, 0, 0, tw, th, 0, 0, 0, 0);
-
- gib_imlib_text_draw(im, fn, NULL, 2, 2, "defined actions:",
- IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
- gib_imlib_text_draw(im, fn, NULL, 1, 1, "defined actions:",
- IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
-
- for (i = 0; i < 10; i++) {
- if (opt.actions[i]) {
- cur_action++;
- line = emalloc(strlen(opt.actions[i])+5);
- sprintf(index, "%d", i);
- strcpy(line, index);
- strcat(line, ": ");
- strcat(line, opt.actions[i]);
-
- gib_imlib_text_draw(im, fn, NULL, 2, (cur_action*line_th)+2, line,
- IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
- gib_imlib_text_draw(im, fn, NULL, 1, (cur_action*line_th)+1, line,
- IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
- free(line);
- }
- }
-
- gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0, 0 + th_offset, 1, 1, 0);
-
- gib_imlib_free_image_and_decache(im);
- D_RETURN_(4);
+ max_tw = tw;
+
+ for (i = 0; i < 10; i++) {
+ if (opt.actions[i]) {
+ gib_imlib_get_text_size(fn, opt.actions[i], NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT);
+ if (tw > max_tw)
+ max_tw = tw;
+ }
+ }
+
+ tw = max_tw;
+ tw += 3;
+ th += 3;
+ line_th = th;
+ th = (th * num_actions) + line_th;
+
+ /* This depends on feh_draw_filename internals...
+ * should be fixed some time
+ */
+ if (opt.draw_filename && w->full_screen)
+ th_offset = line_th * 2;
+ else if (opt.draw_filename)
+ th_offset = line_th;
+
+ im = imlib_create_image(tw, th);
+ if (!im)
+ eprintf("Couldn't create image. Out of memory?");
+
+ gib_imlib_image_set_has_alpha(im, 1);
+ gib_imlib_apply_color_modifier_to_rectangle(im, 0, 0, tw, th, NULL, NULL, NULL, atab);
+ gib_imlib_image_fill_rectangle(im, 0, 0, tw, th, 0, 0, 0, 0);
+
+ gib_imlib_text_draw(im, fn, NULL, 2, 2, "defined actions:", IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
+ gib_imlib_text_draw(im, fn, NULL, 1, 1, "defined actions:", IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
+
+ for (i = 0; i < 10; i++) {
+ if (opt.actions[i]) {
+ cur_action++;
+ line = emalloc(strlen(opt.actions[i]) + 5);
+ sprintf(index, "%d", i);
+ strcpy(line, index);
+ strcat(line, ": ");
+ strcat(line, opt.actions[i]);
+
+ gib_imlib_text_draw(im, fn, NULL, 2,
+ (cur_action * line_th) + 2, line,
+ IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255);
+ gib_imlib_text_draw(im, fn, NULL, 1,
+ (cur_action * line_th) + 1, line,
+ IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255);
+ free(line);
+ }
+ }
+
+ gib_imlib_render_image_on_drawable(w->bg_pmap, im, 0, 0 + th_offset, 1, 1, 0);
+
+ gib_imlib_free_image_and_decache(im);
+ D_RETURN_(4);
}