diff options
author | Daniel Friesel <derf@derf.homelinux.org> | 2010-02-13 19:55:53 +0100 |
---|---|---|
committer | Daniel Friesel <derf@derf.homelinux.org> | 2010-02-13 19:55:53 +0100 |
commit | 8ded860d0b73bf90203bf5e0297ba82837340fd1 (patch) | |
tree | 6ba3f3ac576e3df65186849d112f5b160268c6d7 | |
parent | 2fb795cf66d74df690263c438a7d2212eb74b3f6 (diff) |
Change source code indentation (indent -kr -i8 -hnl, mainly)
-rw-r--r-- | src/collage.c | 388 | ||||
-rw-r--r-- | src/events.c | 1126 | ||||
-rw-r--r-- | src/feh.h | 31 | ||||
-rw-r--r-- | src/feh_png.c | 51 | ||||
-rw-r--r-- | src/feh_png.h | 4 | ||||
-rw-r--r-- | src/filelist.c | 923 | ||||
-rw-r--r-- | src/filelist.h | 44 | ||||
-rw-r--r-- | src/getopt.c | 1254 | ||||
-rw-r--r-- | src/getopt.h | 72 | ||||
-rw-r--r-- | src/getopt1.c | 200 | ||||
-rw-r--r-- | src/imlib.c | 2243 | ||||
-rw-r--r-- | src/index.c | 1049 | ||||
-rw-r--r-- | src/ipc.c | 84 | ||||
-rw-r--r-- | src/ipc.h | 32 | ||||
-rw-r--r-- | src/jpegint.h | 364 | ||||
-rw-r--r-- | src/keyevents.c | 783 | ||||
-rw-r--r-- | src/list.c | 140 | ||||
-rw-r--r-- | src/main.c | 310 | ||||
-rw-r--r-- | src/md5.c | 427 | ||||
-rw-r--r-- | src/md5.h | 30 | ||||
-rw-r--r-- | src/menu.c | 3648 | ||||
-rw-r--r-- | src/menu.h | 121 | ||||
-rw-r--r-- | src/multiwindow.c | 71 | ||||
-rw-r--r-- | src/options.c | 2271 | ||||
-rw-r--r-- | src/options.h | 205 | ||||
-rw-r--r-- | src/slideshow.c | 974 | ||||
-rw-r--r-- | src/support.c | 1081 | ||||
-rw-r--r-- | src/support.h | 9 | ||||
-rw-r--r-- | src/thumbnail.c | 1414 | ||||
-rw-r--r-- | src/thumbnail.h | 55 | ||||
-rw-r--r-- | src/timers.c | 239 | ||||
-rw-r--r-- | src/timers.h | 19 | ||||
-rw-r--r-- | src/transupp.c | 2027 | ||||
-rw-r--r-- | src/transupp.h | 44 | ||||
-rw-r--r-- | src/utils.c | 327 | ||||
-rw-r--r-- | src/utils.h | 3 | ||||
-rw-r--r-- | src/winwidget.c | 1802 | ||||
-rw-r--r-- | src/winwidget.h | 109 |
38 files changed, 11291 insertions, 12683 deletions
diff --git a/src/collage.c b/src/collage.c index fee6ed9..e76f8ae 100644 --- a/src/collage.c +++ b/src/collage.c @@ -28,213 +28,185 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "filelist.h" #include "options.h" -void -init_collage_mode(void) +void init_collage_mode(void) { - Imlib_Image im_main; - Imlib_Image im_temp; - int ww, hh, www, hhh, xxx, yyy; - int w = 800, h = 600; - int bg_w = 0, bg_h = 0; - winwidget winwid = NULL; - Imlib_Image bg_im = NULL, im_thumb = NULL; - feh_file *file = NULL; - unsigned char trans_bg = 0; - gib_list *l, *last = NULL; - char *s; - - D_ENTER(4); - - mode = "collage"; - - /* Use bg image dimensions for default size */ - if (opt.bg && opt.bg_file) - { - if (!strcmp(opt.bg_file, "trans")) - trans_bg = 1; - else - { - - D(4,("Time to apply a background to blend onto\n")); - if (feh_load_image_char(&bg_im, opt.bg_file) != 0) - { - bg_w = gib_imlib_image_get_width(bg_im); - bg_h = gib_imlib_image_get_height(bg_im); - } - } - } - - if (!opt.limit_w || !opt.limit_h) - { - if (bg_im) - { - if (opt.verbose) - fprintf(stdout, - PACKAGE " - No size restriction specified for collage.\n" - " You did specify a background however, so the\n" - " collage size has defaulted to the size of the image\n"); - opt.limit_w = bg_w; - opt.limit_h = bg_h; - } - else - { - if (opt.verbose) - fprintf(stdout, - PACKAGE " - No size restriction specified for collage.\n" - " - For collage mode, you need to specify width and height.\n" - " Using defaults (width 800, height 600)\n"); - opt.limit_w = 800; - opt.limit_h = 600; - } - } - - w = opt.limit_w; - h = opt.limit_h; - D(4,("Limiting width to %d and height to %d\n", w, h)); - - im_main = imlib_create_image(w, h); - - if (!im_main) - eprintf("Imlib error creating image"); - - if (bg_im) - gib_imlib_blend_image_onto_image(im_main, bg_im, - gib_imlib_image_has_alpha(bg_im), 0, 0, - bg_w, bg_h, 0, 0, w, h, 1, 0, 0); - else if (trans_bg) - { - gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 0); - gib_imlib_image_set_has_alpha(im_main, 1); - } - else - { - /* Colour the background */ - gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 255); - } - - /* Create the title string */ - - if (!opt.title) - s = estrdup(PACKAGE " [collage mode]"); - else - s = estrdup(feh_printf(opt.title, NULL)); - - if (opt.display) - { - winwid = - winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE); - winwidget_show(winwid); - } - - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - if (last) - { - filelist = feh_file_remove_from_list(filelist, last); - filelist_len--; - last = NULL; - } - D(3,("About to load image %s\n", file->filename)); - if (feh_load_image(&im_temp, file) != 0) - { - D(3,("Successfully loaded %s\n", file->filename)); - if (opt.verbose) - feh_display_status('.'); - www = opt.thumb_w; - hhh = opt.thumb_h; - ww = gib_imlib_image_get_width(im_temp); - hh = gib_imlib_image_get_height(im_temp); - - if (opt.aspect) - { - double ratio = 0.0; - - /* Keep the aspect ratio for the thumbnail */ - ratio = ((double) ww / hh) / ((double) www / hhh); - - if (ratio > 1.0) - hhh = opt.thumb_h / ratio; - else if (ratio != 1.0) - www = opt.thumb_w * ratio; - } - - if ((!opt.stretch) && ((www > ww) || (hhh > hh))) - { - /* Don't make the image larger unless stretch is specified */ - www = ww; - hhh = hh; - } - - /* pick random coords for thumbnail */ - xxx = ((w - www) * ((double) rand() / RAND_MAX)); - yyy = ((h - hhh) * ((double) rand() / RAND_MAX)); - D(5,("image going on at x=%d, y=%d\n", xxx, yyy)); - - im_thumb = - gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, - hhh, 1); - gib_imlib_free_image_and_decache(im_temp); - - if (opt.alpha) - { - DATA8 atab[256]; - - D(4,("Applying alpha options\n")); - gib_imlib_image_set_has_alpha(im_thumb, 1); - memset(atab, opt.alpha_level, sizeof(atab)); - gib_imlib_apply_color_modifier_to_rectangle(im_thumb, 0, 0, www, - hhh, NULL, NULL, NULL, - atab); - } - gib_imlib_blend_image_onto_image(im_main, im_thumb, - gib_imlib_image_has_alpha(im_thumb), - 0, 0, www, hhh, xxx, yyy, www, hhh, - 1, - gib_imlib_image_has_alpha(im_thumb), - 0); - gib_imlib_free_image_and_decache(im_thumb); - } - else - { - last = l; - if (opt.verbose) - feh_display_status('x'); - } - if (opt.display) - { - winwidget_render_image(winwid, 0, 0); - if (!feh_main_iteration(0)) - exit(0); - } - } - if (opt.verbose) - fprintf(stdout, "\n"); - - if (opt.output && opt.output_file) - { - char output_buf[1024]; - if (opt.output_dir) - snprintf(output_buf,1024,"%s/%s", opt.output_dir, opt.output_file); - else - strncpy(output_buf,opt.output_file, 1024); - gib_imlib_save_image(im_main, output_buf); - if (opt.verbose) - { - int tw, th; - - tw = gib_imlib_image_get_width(im_main); - th = gib_imlib_image_get_height(im_main); - fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf); - fprintf(stdout, - " - Image is %dx%d pixels and contains %d thumbnails\n", - tw, th, (tw / opt.thumb_w) * (th / opt.thumb_h)); - } - } - - if (!opt.display) - gib_imlib_free_image_and_decache(im_main); - free(s); - D_RETURN_(4); + Imlib_Image im_main; + Imlib_Image im_temp; + int ww, hh, www, hhh, xxx, yyy; + int w = 800, h = 600; + int bg_w = 0, bg_h = 0; + winwidget winwid = NULL; + Imlib_Image bg_im = NULL, im_thumb = NULL; + feh_file *file = NULL; + unsigned char trans_bg = 0; + gib_list *l, *last = NULL; + char *s; + + D_ENTER(4); + + mode = "collage"; + + /* Use bg image dimensions for default size */ + if (opt.bg && opt.bg_file) { + if (!strcmp(opt.bg_file, "trans")) + trans_bg = 1; + else { + + D(4, ("Time to apply a background to blend onto\n")); + if (feh_load_image_char(&bg_im, opt.bg_file) != 0) { + bg_w = gib_imlib_image_get_width(bg_im); + bg_h = gib_imlib_image_get_height(bg_im); + } + } + } + + if (!opt.limit_w || !opt.limit_h) { + if (bg_im) { + if (opt.verbose) + fprintf(stdout, + PACKAGE + " - No size restriction specified for collage.\n" + " You did specify a background however, so the\n" + " collage size has defaulted to the size of the image\n"); + opt.limit_w = bg_w; + opt.limit_h = bg_h; + } else { + if (opt.verbose) + fprintf(stdout, + PACKAGE + " - No size restriction specified for collage.\n" + " - For collage mode, you need to specify width and height.\n" + " Using defaults (width 800, height 600)\n"); + opt.limit_w = 800; + opt.limit_h = 600; + } + } + + w = opt.limit_w; + h = opt.limit_h; + D(4, ("Limiting width to %d and height to %d\n", w, h)); + + im_main = imlib_create_image(w, h); + + if (!im_main) + eprintf("Imlib error creating image"); + + if (bg_im) + gib_imlib_blend_image_onto_image(im_main, bg_im, + gib_imlib_image_has_alpha(bg_im), 0, 0, + bg_w, bg_h, 0, 0, w, h, 1, 0, 0); + else if (trans_bg) { + gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 0); + gib_imlib_image_set_has_alpha(im_main, 1); + } else { + /* Colour the background */ + gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h, 0, 0, 0, 255); + } + + /* Create the title string */ + + if (!opt.title) + s = estrdup(PACKAGE " [collage mode]"); + else + s = estrdup(feh_printf(opt.title, NULL)); + + if (opt.display) { + winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE); + winwidget_show(winwid); + } + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + if (last) { + filelist = feh_file_remove_from_list(filelist, last); + filelist_len--; + last = NULL; + } + D(3, ("About to load image %s\n", file->filename)); + if (feh_load_image(&im_temp, file) != 0) { + D(3, ("Successfully loaded %s\n", file->filename)); + if (opt.verbose) + feh_display_status('.'); + www = opt.thumb_w; + hhh = opt.thumb_h; + ww = gib_imlib_image_get_width(im_temp); + hh = gib_imlib_image_get_height(im_temp); + + if (opt.aspect) { + double ratio = 0.0; + + /* Keep the aspect ratio for the thumbnail */ + ratio = ((double) ww / hh) / ((double) www / hhh); + + if (ratio > 1.0) + hhh = opt.thumb_h / ratio; + else if (ratio != 1.0) + www = opt.thumb_w * ratio; + } + + if ((!opt.stretch) && ((www > ww) || (hhh > hh))) { + /* Don't make the image larger unless stretch is specified */ + www = ww; + hhh = hh; + } + + /* pick random coords for thumbnail */ + xxx = ((w - www) * ((double) rand() / RAND_MAX)); + yyy = ((h - hhh) * ((double) rand() / RAND_MAX)); + D(5, ("image going on at x=%d, y=%d\n", xxx, yyy)); + + im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, + 0, 0, ww, hh, www, hhh, 1); + gib_imlib_free_image_and_decache(im_temp); + + if (opt.alpha) { + DATA8 atab[256]; + + D(4, ("Applying alpha options\n")); + gib_imlib_image_set_has_alpha(im_thumb, 1); + memset(atab, opt.alpha_level, sizeof(atab)); + gib_imlib_apply_color_modifier_to_rectangle(im_thumb, + 0, 0, www, hhh, NULL, NULL, NULL, atab); + } + gib_imlib_blend_image_onto_image(im_main, im_thumb, + gib_imlib_image_has_alpha(im_thumb), 0, 0, www, hhh, xxx, + yyy,www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0); + gib_imlib_free_image_and_decache(im_thumb); + } else { + last = l; + if (opt.verbose) + feh_display_status('x'); + } + if (opt.display) { + winwidget_render_image(winwid, 0, 0); + if (!feh_main_iteration(0)) + exit(0); + } + } + if (opt.verbose) + fprintf(stdout, "\n"); + + if (opt.output && opt.output_file) { + char output_buf[1024]; + if (opt.output_dir) + snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file); + else + strncpy(output_buf, opt.output_file, 1024); + gib_imlib_save_image(im_main, output_buf); + if (opt.verbose) { + int tw, th; + + tw = gib_imlib_image_get_width(im_main); + th = gib_imlib_image_get_height(im_main); + fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf); + fprintf(stdout, + " - Image is %dx%d pixels and contains %d thumbnails\n", + tw, th, (tw / opt.thumb_w) * (th / opt.thumb_h)); + } + } + + if (!opt.display) + gib_imlib_free_image_and_decache(im_main); + free(s); + D_RETURN_(4); } diff --git a/src/events.c b/src/events.c index 610178c..7db319d 100644 --- a/src/events.c +++ b/src/events.c @@ -41,648 +41,542 @@ static void feh_event_handle_LeaveNotify(XEvent * ev); static void feh_event_handle_MotionNotify(XEvent * ev); static void feh_event_handle_ClientMessage(XEvent * ev); -void -feh_event_init(void) +void feh_event_init(void) { - int i; - - D_ENTER(4); - for (i = 0; i < LASTEvent; i++) - ev_handler[i] = NULL; - - ev_handler[KeyPress] = feh_event_handle_keypress; - ev_handler[ButtonPress] = feh_event_handle_ButtonPress; - ev_handler[ButtonRelease] = feh_event_handle_ButtonRelease; - ev_handler[ConfigureNotify] = feh_event_handle_ConfigureNotify; - ev_handler[EnterNotify] = feh_event_handle_EnterNotify; - ev_handler[LeaveNotify] = feh_event_handle_LeaveNotify; - ev_handler[MotionNotify] = feh_event_handle_MotionNotify; - ev_handler[ClientMessage] = feh_event_handle_ClientMessage; - - D_RETURN_(4); + int i; + + D_ENTER(4); + for (i = 0; i < LASTEvent; i++) + ev_handler[i] = NULL; + + ev_handler[KeyPress] = feh_event_handle_keypress; + ev_handler[ButtonPress] = feh_event_handle_ButtonPress; + ev_handler[ButtonRelease] = feh_event_handle_ButtonRelease; + ev_handler[ConfigureNotify] = feh_event_handle_ConfigureNotify; + ev_handler[EnterNotify] = feh_event_handle_EnterNotify; + ev_handler[LeaveNotify] = feh_event_handle_LeaveNotify; + ev_handler[MotionNotify] = feh_event_handle_MotionNotify; + ev_handler[ClientMessage] = feh_event_handle_ClientMessage; + + D_RETURN_(4); } -static void -feh_event_handle_ButtonPress(XEvent * ev) +static void feh_event_handle_ButtonPress(XEvent * ev) { - winwidget winwid = NULL; - int scr_width, scr_height; + winwidget winwid = NULL; + int scr_width, scr_height; - D_ENTER(4); + D_ENTER(4); - /* get the heck out if it's a mouse-click on the - cover, we'll hide the menus on release */ - if (ev->xbutton.window == menu_cover) { - D_RETURN_(4); - } + /* get the heck out if it's a mouse-click on the + cover, we'll hide the menus on release */ + if (ev->xbutton.window == menu_cover) { + D_RETURN_(4); + } - scr_width = scr->width; - scr_height = scr->height; + scr_width = scr->width; + scr_height = scr->height; #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - scr_width = xinerama_screens[xinerama_screen].width; - scr_height = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - - winwid = winwidget_get_from_window(ev->xbutton.window); - if (winwid && winwid->caption_entry) { - D_RETURN_(4); - } - - if (!opt.no_menus && EV_IS_MENU_BUTTON(ev)) { - D(3, ("Menu Button Press event\n")); - if (winwid != NULL) { - winwidget_show_menu(winwid); - } - } - else if ((ev->xbutton.button == opt.rotate_button) - && ((opt.no_rotate_ctrl_mask) - || (ev->xbutton.state & ControlMask))) - { - if (winwid != NULL) - { - opt.mode = MODE_ROTATE; - winwid->mode = MODE_ROTATE; - D(3, ("rotate starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } - } - else if ((ev->xbutton.button == opt.blur_button) - && ((opt.no_blur_ctrl_mask) || (ev->xbutton.state & ControlMask))) - { - if (winwid != NULL) - { - opt.mode = MODE_BLUR; - winwid->mode = MODE_BLUR; - D(3, ("blur starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); - } - } - else if (ev->xbutton.button == opt.pan_button) - { - D(3, ("Pan Button Press event\n")); - if (winwid != NULL) - { - D(3, ("Next button, but could be pan mode\n")); - opt.mode = MODE_NEXT; - winwid->mode = MODE_NEXT; - D(3, ("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); - winwid->click_offset_x = ev->xbutton.x - winwid->im_x; - winwid->click_offset_y = ev->xbutton.y - winwid->im_y; - } - } - else if (ev->xbutton.button == opt.zoom_button) - { - D(3, ("Zoom Button Press event\n")); - if (winwid != NULL) - { - D(3, ("Zoom mode baby!\n")); - opt.mode = MODE_ZOOM; - winwid->mode = MODE_ZOOM; - D(3, ("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); - winwid->click_offset_x = ev->xbutton.x - winwid->im_x; - winwid->click_offset_y = ev->xbutton.y - winwid->im_y; - winwid->im_click_offset_x = winwid->click_offset_x / winwid->zoom; - winwid->im_click_offset_y = winwid->click_offset_y / winwid->zoom; - winwid->zoom = 1.0; - if (winwid->full_screen) - { - winwid->im_x = (scr_width - winwid->im_w) >> 1; - winwid->im_y = (scr_height - winwid->im_h) >> 1; - } - else - { - if (opt.geom_flags & WidthValue) { - winwid->im_x = (opt.geom_w - winwid->im_w) >> 1; - } else { - winwid->im_x = 0; - } - if (opt.geom_flags & HeightValue) { - winwid->im_y = (opt.geom_h - winwid->im_h) >> 1; - } else { - winwid->im_y = 0; - } - } - if (winwid->im_click_offset_x < 30) - winwid->im_click_offset_x = 30; - if (winwid->im_click_offset_y < 0) - winwid->im_click_offset_y = 0; - if (winwid->im_click_offset_x > winwid->im_w) - winwid->im_click_offset_x = winwid->im_w; - if (winwid->im_click_offset_y > winwid->im_h) - winwid->im_click_offset_y = winwid->im_h; - - if (winwid->click_offset_x < 30) - winwid->click_offset_x = 30; - if (winwid->click_offset_y < 0) - winwid->click_offset_y = 0; - if (winwid->click_offset_x > winwid->w) - winwid->click_offset_x = winwid->w; - if (winwid->click_offset_y > winwid->h) - winwid->click_offset_y = winwid->h; - - winwidget_render_image(winwid, 0, 0); - } - } - else if (ev->xbutton.button == opt.reload_button) - { - D(3, ("Reload Button Press event\n")); - if (winwid != NULL) - feh_reload_image(winwid, 0, 0); - } - else if (ev->xbutton.button == opt.prev_button ) - { - D(3, ("Prev Button Press event\n")); - if ((winwid != NULL) && (winwid->type == WIN_TYPE_SLIDESHOW)) - slideshow_change_image(winwid, SLIDE_PREV); - } - else if (ev->xbutton.button == opt.next_button ) - { - D(3, ("Next Button 5 Press event\n")); - if ((winwid != NULL) && (winwid->type == WIN_TYPE_SLIDESHOW)) - slideshow_change_image(winwid, SLIDE_NEXT); - } - else - { - D(3, ("Received other ButtonPress event\n")); - } - D_RETURN_(4); + if (opt.xinerama && xinerama_screens) { + scr_width = xinerama_screens[xinerama_screen].width; + scr_height = xinerama_screens[xinerama_screen].height; + } +#endif /* HAVE_LIBXINERAMA */ + + winwid = winwidget_get_from_window(ev->xbutton.window); + if (winwid && winwid->caption_entry) { + D_RETURN_(4); + } + + if (!opt.no_menus && EV_IS_MENU_BUTTON(ev)) { + D(3, ("Menu Button Press event\n")); + if (winwid != NULL) { + winwidget_show_menu(winwid); + } + } else if ((ev->xbutton.button == opt.rotate_button) + && ((opt.no_rotate_ctrl_mask) + || (ev->xbutton.state & ControlMask))) { + if (winwid != NULL) { + opt.mode = MODE_ROTATE; + winwid->mode = MODE_ROTATE; + D(3, ("rotate starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); + } + } else if ((ev->xbutton.button == opt.blur_button) + && ((opt.no_blur_ctrl_mask) + || (ev->xbutton.state & ControlMask))) { + if (winwid != NULL) { + opt.mode = MODE_BLUR; + winwid->mode = MODE_BLUR; + D(3, ("blur starting at %d, %d\n", ev->xbutton.x, ev->xbutton.y)); + } + } else if (ev->xbutton.button == opt.pan_button) { + D(3, ("Pan Button Press event\n")); + if (winwid != NULL) { + D(3, ("Next button, but could be pan mode\n")); + opt.mode = MODE_NEXT; + winwid->mode = MODE_NEXT; + D(3, ("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); + winwid->click_offset_x = ev->xbutton.x - winwid->im_x; + winwid->click_offset_y = ev->xbutton.y - winwid->im_y; + } + } else if (ev->xbutton.button == opt.zoom_button) { + D(3, ("Zoom Button Press event\n")); + if (winwid != NULL) { + D(3, ("Zoom mode baby!\n")); + opt.mode = MODE_ZOOM; + winwid->mode = MODE_ZOOM; + D(3, ("click offset is %d,%d\n", ev->xbutton.x, ev->xbutton.y)); + winwid->click_offset_x = ev->xbutton.x - winwid->im_x; + winwid->click_offset_y = ev->xbutton.y - winwid->im_y; + winwid->im_click_offset_x = winwid->click_offset_x / winwid->zoom; + winwid->im_click_offset_y = winwid->click_offset_y / winwid->zoom; + winwid->zoom = 1.0; + if (winwid->full_screen) { + winwid->im_x = (scr_width - winwid->im_w) >> 1; + winwid->im_y = (scr_height - winwid->im_h) >> 1; + } else { + if (opt.geom_flags & WidthValue) { + winwid->im_x = (opt.geom_w - winwid->im_w) >> 1; + } else { + winwid->im_x = 0; + } + if (opt.geom_flags & HeightValue) { + winwid->im_y = (opt.geom_h - winwid->im_h) >> 1; + } else { + winwid->im_y = 0; + } + } + if (winwid->im_click_offset_x < 30) + winwid->im_click_offset_x = 30; + if (winwid->im_click_offset_y < 0) + winwid->im_click_offset_y = 0; + if (winwid->im_click_offset_x > winwid->im_w) + winwid->im_click_offset_x = winwid->im_w; + if (winwid->im_click_offset_y > winwid->im_h) + winwid->im_click_offset_y = winwid->im_h; + + if (winwid->click_offset_x < 30) + winwid->click_offset_x = 30; + if (winwid->click_offset_y < 0) + winwid->click_offset_y = 0; + if (winwid->click_offset_x > winwid->w) + winwid->click_offset_x = winwid->w; + if (winwid->click_offset_y > winwid->h) + winwid->click_offset_y = winwid->h; + + winwidget_render_image(winwid, 0, 0); + } + } else if (ev->xbutton.button == opt.reload_button) { + D(3, ("Reload Button Press event\n")); + if (winwid != NULL) + feh_reload_image(winwid, 0, 0); + } else if (ev->xbutton.button == opt.prev_button) { + D(3, ("Prev Button Press event\n")); + if ((winwid != NULL) + && (winwid->type == WIN_TYPE_SLIDESHOW)) + slideshow_change_image(winwid, SLIDE_PREV); + } else if (ev->xbutton.button == opt.next_button) { + D(3, ("Next Button 5 Press event\n")); + if ((winwid != NULL) + && (winwid->type == WIN_TYPE_SLIDESHOW)) + slideshow_change_image(winwid, SLIDE_NEXT); + } else { + D(3, ("Received other ButtonPress event\n")); + } + D_RETURN_(4); } -static void -feh_event_handle_ButtonRelease(XEvent * ev) +static void feh_event_handle_ButtonRelease(XEvent * ev) { - winwidget winwid = NULL; - - D_ENTER(4); - if (menu_root) - { - /* if menus are open, close them, and execute action if needed */ - - if (ev->xbutton.window == menu_cover) { - feh_menu_hide(menu_root, True); - } else if (menu_root) { - feh_menu *m; - - if ((m = feh_menu_get_from_window(ev->xbutton.window))) - { - feh_menu_item *i = NULL; - - i = feh_menu_find_selected(m); - feh_menu_item_activate(m, i); - } - } - D_RETURN_(4); - } - - winwid = winwidget_get_from_window(ev->xbutton.window); - if (winwid && winwid->caption_entry) { - D_RETURN_(4); - } - - if ((ev->xbutton.button == opt.menu_button) - && - (((!opt.menu_ctrl_mask) - && ((!(ev->xbutton.state & ControlMask)) - || ((ev->xbutton.state & ControlMask) && (opt.menu_ctrl_mask))))) - && (opt.no_menus)) - winwidget_destroy_all(); - else if (ev->xbutton.button == opt.pan_button) - { - if (opt.mode == MODE_PAN) - { - if (winwid != NULL) - { - D(3, ("Disabling pan mode\n")); - opt.mode = MODE_NORMAL; - winwid->mode = MODE_NORMAL; - winwidget_sanitise_offsets(winwid); - winwidget_render_image(winwid, 0, 1); - } - } - else - { - opt.mode = MODE_NORMAL; - if(winwid != NULL) - winwid->mode = MODE_NORMAL; - if ((winwid != NULL) && (winwid->type == WIN_TYPE_SLIDESHOW)) - { - slideshow_change_image(winwid, SLIDE_NEXT); - } - else if ((winwid != NULL) && (winwid->type == WIN_TYPE_THUMBNAIL)) - { - feh_file *thumbfile; - winwidget thumbwin = NULL; - int x, y; - char *s; - - x = ev->xbutton.x; - y = ev->xbutton.y; - x -= winwid->im_x; - y -= winwid->im_y; - x /= winwid->zoom; - y /= winwid->zoom; - thumbfile = feh_thumbnail_get_file_from_coords(x, y); - if (thumbfile) - { - if (!opt.thumb_title) - s = thumbfile->name; - else - s = feh_printf(opt.thumb_title, thumbfile); - thumbwin = - winwidget_get_first_window_of_type - (WIN_TYPE_THUMBNAIL_VIEWER); - if (!thumbwin) - { - thumbwin = - winwidget_create_from_file(gib_list_add_front - (NULL, thumbfile), s, - WIN_TYPE_THUMBNAIL_VIEWER); - winwidget_show(thumbwin); - } - else if (FEH_FILE(thumbwin->file->data) != thumbfile) - { - free(thumbwin->file); - thumbwin->file = gib_list_add_front(NULL, thumbfile); - winwidget_rename(thumbwin, s); - feh_reload_image(thumbwin, 1, 0); - } - } - } - } - } - else if ((ev->xbutton.button == opt.rotate_button) - || (ev->xbutton.button == opt.zoom_button)) - { - D(3, ("Mode-based Button Release event\n")); - if (winwid != NULL) - { - D(3, ("Disabling mode\n")); - opt.mode = MODE_NORMAL; - winwid->mode = MODE_NORMAL; - winwidget_sanitise_offsets(winwid); - winwidget_render_image(winwid, 0, 1); - } - } - else if ((ev->xbutton.button == opt.blur_button) - && ((opt.no_blur_ctrl_mask) || (ev->xbutton.state & ControlMask))) - { - D(3, ("Blur Button Release event\n")); - if (winwid != NULL) - { - D(3, ("Disabling Blur mode\n")); - opt.mode = MODE_NORMAL; - winwid->mode = MODE_NORMAL; - } - } - D_RETURN_(4); + winwidget winwid = NULL; + + D_ENTER(4); + if (menu_root) { + /* if menus are open, close them, and execute action if needed */ + + if (ev->xbutton.window == menu_cover) { + feh_menu_hide(menu_root, True); + } else if (menu_root) { + feh_menu *m; + + if ((m = feh_menu_get_from_window(ev->xbutton.window))) { + feh_menu_item *i = NULL; + + i = feh_menu_find_selected(m); + feh_menu_item_activate(m, i); + } + } + D_RETURN_(4); + } + + winwid = winwidget_get_from_window(ev->xbutton.window); + if (winwid && winwid->caption_entry) { + D_RETURN_(4); + } + + if ((ev->xbutton.button == opt.menu_button) + && (((!opt.menu_ctrl_mask) + && ((!(ev->xbutton.state & ControlMask)) + || ((ev->xbutton.state & ControlMask) + && (opt.menu_ctrl_mask))))) + && (opt.no_menus)) + winwidget_destroy_all(); + else if (ev->xbutton.button == opt.pan_button) { + if (opt.mode == MODE_PAN) { + if (winwid != NULL) { + D(3, ("Disabling pan mode\n")); + opt.mode = MODE_NORMAL; + winwid->mode = MODE_NORMAL; + winwidget_sanitise_offsets(winwid); + winwidget_render_image(winwid, 0, 1); + } + } else { + opt.mode = MODE_NORMAL; + if (winwid != NULL) + winwid->mode = MODE_NORMAL; + if ((winwid != NULL) + && (winwid->type == WIN_TYPE_SLIDESHOW)) { + slideshow_change_image(winwid, SLIDE_NEXT); + } else if ((winwid != NULL) + && (winwid->type == WIN_TYPE_THUMBNAIL)) { + feh_file *thumbfile; + winwidget thumbwin = NULL; + int x, y; + char *s; + + x = ev->xbutton.x; + y = ev->xbutton.y; + x -= winwid->im_x; + y -= winwid->im_y; + x /= winwid->zoom; + y /= winwid->zoom; + thumbfile = feh_thumbnail_get_file_from_coords(x, y); + if (thumbfile) { + if (!opt.thumb_title) + s = thumbfile->name; + else + s = feh_printf(opt.thumb_title, thumbfile); + thumbwin = winwidget_get_first_window_of_type(WIN_TYPE_THUMBNAIL_VIEWER); + if (!thumbwin) { + thumbwin = winwidget_create_from_file( + gib_list_add_front(NULL, thumbfile), + s, WIN_TYPE_THUMBNAIL_VIEWER); + winwidget_show(thumbwin); + } else if (FEH_FILE(thumbwin->file->data) != thumbfile) { + free(thumbwin->file); + thumbwin->file = gib_list_add_front(NULL, thumbfile); + winwidget_rename(thumbwin, s); + feh_reload_image(thumbwin, 1, 0); + } + } + } + } + } else if ((ev->xbutton.button == opt.rotate_button) + || (ev->xbutton.button == opt.zoom_button)) { + D(3, ("Mode-based Button Release event\n")); + if (winwid != NULL) { + D(3, ("Disabling mode\n")); + opt.mode = MODE_NORMAL; + winwid->mode = MODE_NORMAL; + winwidget_sanitise_offsets(winwid); + winwidget_render_image(winwid, 0, 1); + } + } else if ((ev->xbutton.button == opt.blur_button) + && ((opt.no_blur_ctrl_mask) + || (ev->xbutton.state & ControlMask))) { + D(3, ("Blur Button Release event\n")); + if (winwid != NULL) { + D(3, ("Disabling Blur mode\n")); + opt.mode = MODE_NORMAL; + winwid->mode = MODE_NORMAL; + } + } + D_RETURN_(4); } -static void -feh_event_handle_ConfigureNotify(XEvent * ev) +static void feh_event_handle_ConfigureNotify(XEvent * ev) { - D_ENTER(4); - while (XCheckTypedWindowEvent - (disp, ev->xconfigure.window, ConfigureNotify, ev)); - if (!menu_root) - { - winwidget w = winwidget_get_from_window(ev->xconfigure.window); - - if (w) - { - D(3, - ("configure size %dx%d\n", ev->xconfigure.width, - ev->xconfigure.height)); - if ((w->w != ev->xconfigure.width) - || (w->h != ev->xconfigure.height)) - { - D(3, ("assigning size and rerendering\n")); - w->w = ev->xconfigure.width; - w->h = ev->xconfigure.height; - w->had_resize = 1; - if (opt.geom_flags & WidthValue || opt.geom_flags & HeightValue) - { - opt.geom_w = w->w; - opt.geom_h = w->h; - } - winwidget_render_image(w, 0, 1); - } - } - } - - D_RETURN_(4); + D_ENTER(4); + while (XCheckTypedWindowEvent(disp, ev->xconfigure.window, ConfigureNotify, ev)); + if (!menu_root) { + winwidget w = winwidget_get_from_window(ev->xconfigure.window); + + if (w) { + D(3, ("configure size %dx%d\n", ev->xconfigure.width, ev->xconfigure.height)); + if ((w->w != ev->xconfigure.width) + || (w->h != ev->xconfigure.height)) { + D(3, ("assigning size and rerendering\n")); + w->w = ev->xconfigure.width; + w->h = ev->xconfigure.height; + w->had_resize = 1; + if (opt.geom_flags & WidthValue || opt.geom_flags & HeightValue) { + opt.geom_w = w->w; + opt.geom_h = w->h; + } + winwidget_render_image(w, 0, 1); + } + } + } + + D_RETURN_(4); } -static void -feh_event_handle_EnterNotify(XEvent * ev) +static void feh_event_handle_EnterNotify(XEvent * ev) { - D_ENTER(4); - D_RETURN_(4); - ev = NULL; + D_ENTER(4); + D_RETURN_(4); + ev = NULL; } -static void -feh_event_handle_LeaveNotify(XEvent * ev) +static void feh_event_handle_LeaveNotify(XEvent * ev) { - D_ENTER(4); - if ((menu_root) && (ev->xcrossing.window == menu_root->win)) - { - feh_menu_item *ii; - - D(4, ("It is for a menu\n")); - for (ii = menu_root->items; ii; ii = ii->next) - { - if (MENU_ITEM_IS_SELECTED(ii)) - { - D(4, ("Unselecting menu\n")); - MENU_ITEM_SET_NORMAL(ii); - menu_root->updates = - imlib_update_append_rect(menu_root->updates, ii->x, ii->y, - ii->w, ii->h); - menu_root->needs_redraw = 1; - } - } - feh_raise_all_menus(); - } - - D_RETURN_(4); + D_ENTER(4); + if ((menu_root) && (ev->xcrossing.window == menu_root->win)) { + feh_menu_item *ii; + + D(4, ("It is for a menu\n")); + for (ii = menu_root->items; ii; ii = ii->next) { + if (MENU_ITEM_IS_SELECTED(ii)) { + D(4, ("Unselecting menu\n")); + MENU_ITEM_SET_NORMAL(ii); + menu_root->updates = + imlib_update_append_rect(menu_root->updates, ii->x, ii->y, ii->w, ii->h); + menu_root->needs_redraw = 1; + } + } + feh_raise_all_menus(); + } + + D_RETURN_(4); } -static void -feh_event_handle_MotionNotify(XEvent * ev) +static void feh_event_handle_MotionNotify(XEvent * ev) { - winwidget winwid = NULL; - int dx, dy; - int scr_width, scr_height; + winwidget winwid = NULL; + int dx, dy; + int scr_width, scr_height; - scr_width = scr->width; - scr_height = scr->height; + scr_width = scr->width; + scr_height = scr->height; #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - scr_width = xinerama_screens[xinerama_screen].width; - scr_height = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - - D_ENTER(5); - if (menu_root) - { - feh_menu *m; - feh_menu_item *selected_item, *mouseover_item; - - D(3, ("motion notify with menus open\n")); - while (XCheckTypedWindowEvent - (disp, ev->xmotion.window, MotionNotify, ev)); - - if (ev->xmotion.window == menu_cover) - { - D_RETURN_(5); - } - else if ((m = feh_menu_get_from_window(ev->xmotion.window))) - { - selected_item = feh_menu_find_selected(m); - mouseover_item = - feh_menu_find_at_xy(m, ev->xmotion.x, ev->xmotion.y); - - if (selected_item != mouseover_item) - { - D(4, ("selecting a menu item\n")); - if (selected_item) - feh_menu_deselect_selected(m); - if ((mouseover_item) - && ((mouseover_item->func) || (mouseover_item->submenu) - || (mouseover_item->func_gen_sub))) - feh_menu_select(m, mouseover_item); - } - /* check if we are close to the right and/or the bottom edge of the - * screen. If so, and if the menu we are currently over is partially - * hidden, slide the menu to the left and/or up until it is - * fully visible */ - - /* FIXME: get this working nicely with xinerama screen edges -- - * at the moment it does really funky stuff with - * scr_{width,height} instead of scr->{width,height} -- pabs*/ - if (mouseover_item - && ((scr->width - (ev->xmotion.x + m->x)) < m->w - || (scr->height - (ev->xmotion.y + m->y)) < m->w)) - { - dx = scr_width - (m->x + m->w); - dy = scr_height - (m->y + m->h); - dx = dx < 0 ? dx : 0; - dy = dy < 0 ? dy : 0; - if (dx || dy) - feh_menu_slide_all_menus_relative(dx, dy); - } - /* if a submenu is open we want to see that also */ - if (mouseover_item && m->next - && ((scr->width - (ev->xmotion.x + m->next->x)) < m->next->w - || (scr->height - (ev->xmotion.y + m->next->y)) < m->next->w)) - { - dx = scr->width - (m->next->x + m->next->w); - dy = scr->height - (m->next->y + m->next->h); - dx = dx < 0 ? dx : 0; - dy = dy < 0 ? dy : 0; - if (dx || dy) - feh_menu_slide_all_menus_relative(dx, dy); - } - } - } - else if (opt.mode == MODE_ZOOM) - { - while (XCheckTypedWindowEvent - (disp, ev->xmotion.window, MotionNotify, ev)); - - winwid = winwidget_get_from_window(ev->xmotion.window); - if (winwid) - { - winwid->zoom = - ((double) ev->xmotion.x - (double) winwid->click_offset_x) / 64.0; - if (winwid->zoom < 0) - winwid->zoom = - 1.0 + - ((winwid->zoom * 64.0) / - ((double) (winwid->click_offset_x + 1))); - else - winwid->zoom += 1.0; - - if (winwid->zoom < 0.01) - winwid->zoom = 0.01; - - /* calculate change in zoom and move im_x and im_y respectively to - enable zooming to the clicked spot... */ - /* for now, center around im_click_offset_x and im_click_offset_y */ - winwid->im_x = - (winwid->w / 2) - (winwid->im_click_offset_x * winwid->zoom); - winwid->im_y = - (winwid->h / 2) - (winwid->im_click_offset_y * winwid->zoom); - - winwidget_render_image(winwid, 0, 0); - } - } - else if ((opt.mode == MODE_PAN) || (opt.mode == MODE_NEXT)) - { - int orig_x, orig_y; - - while (XCheckTypedWindowEvent - (disp, ev->xmotion.window, MotionNotify, ev)); - winwid = winwidget_get_from_window(ev->xmotion.window); - if (winwid) - { - if (opt.mode == MODE_NEXT) - { - opt.mode = MODE_PAN; - winwid->mode = MODE_PAN; - } - D(5, ("Panning\n")); - orig_x = winwid->im_x; - orig_y = winwid->im_y; - - winwid->im_x = ev->xmotion.x - winwid->click_offset_x; - winwid->im_y = ev->xmotion.y - winwid->click_offset_y; - - winwidget_sanitise_offsets(winwid); - - if ((winwid->im_x != orig_x) || (winwid->im_y != orig_y)) - winwidget_render_image(winwid, 0, 0); - } - } - else if (opt.mode == MODE_ROTATE) - { - while (XCheckTypedWindowEvent - (disp, ev->xmotion.window, MotionNotify, ev)); - winwid = winwidget_get_from_window(ev->xmotion.window); - if (winwid) - { - D(5, ("Rotating\n")); - if (!winwid->has_rotated) - { - Imlib_Image temp; - - temp = gib_imlib_create_rotated_image(winwid->im, 0.0); - winwid->im_w = gib_imlib_image_get_width(temp); - winwid->im_h = gib_imlib_image_get_height(temp); - gib_imlib_free_image_and_decache(temp); - if (!winwid->full_screen && !opt.geom_flags) - winwidget_resize(winwid, winwid->im_w, winwid->im_h); - winwid->has_rotated = 1; - } - winwid->im_angle = - (ev->xmotion.x - - winwid->w / 2) / ((double) winwid->w / 2) * 3.1415926535; - D(5, ("angle: %f\n", winwid->im_angle)); - winwidget_render_image(winwid, 0, 0); - } - } - else if (opt.mode == MODE_BLUR) - { - while (XCheckTypedWindowEvent - (disp, ev->xmotion.window, MotionNotify, ev)); - winwid = winwidget_get_from_window(ev->xmotion.window); - if (winwid) - { - Imlib_Image temp, ptr; - signed int blur_radius; - - D(5, ("Blurring\n")); - - temp = gib_imlib_clone_image(winwid->im); - blur_radius = (((double) ev->xmotion.x / winwid->w) * 20) - 10; - D(5, ("angle: %d\n", blur_radius)); - if (blur_radius > 0) - gib_imlib_image_sharpen(temp, blur_radius); - else - gib_imlib_image_blur(temp, 0 - blur_radius); - ptr = winwid->im; - winwid->im = temp; - winwidget_render_image(winwid, 0, 0); - gib_imlib_free_image_and_decache(winwid->im); - winwid->im = ptr; - } - } - else - { - while (XCheckTypedWindowEvent - (disp, ev->xmotion.window, MotionNotify, ev)); - winwid = winwidget_get_from_window(ev->xmotion.window); - if (winwid != NULL) - { - if (winwid->type == WIN_TYPE_ABOUT) - { - Imlib_Image orig_im; - int x, y; - - x = ev->xmotion.x - winwid->im_x; - y = ev->xmotion.y - winwid->im_y; - orig_im = winwid->im; - winwid->im = gib_imlib_clone_image(orig_im); - imlib_context_set_image(winwid->im); - imlib_apply_filter("bump_map_point(x=[],y=[],map=" PREFIX - "/share/feh/images/about.png);", &x, &y); - winwidget_render_image(winwid, 0, 1); - gib_imlib_free_image_and_decache(winwid->im); - winwid->im = orig_im; - } - else if (winwid->type == WIN_TYPE_THUMBNAIL) - { - static feh_thumbnail *last_thumb = NULL; - feh_thumbnail *thumbnail; - int x, y; - - x = (ev->xbutton.x - winwid->im_x) / winwid->zoom; - y = (ev->xbutton.y - winwid->im_y) / winwid->zoom; - thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y); - if (thumbnail != last_thumb) - { - if (thumbnail) - { - Imlib_Image origwin; - - origwin = winwid->im; - winwid->im = gib_imlib_clone_image(origwin); - gib_imlib_image_fill_rectangle(winwid->im, thumbnail->x, - thumbnail->y, thumbnail->w, - thumbnail->h, 50, 50, 255, - 100); - gib_imlib_image_draw_rectangle(winwid->im, thumbnail->x, - thumbnail->y, thumbnail->w, - thumbnail->h, 255, 255, 255, - 255); - gib_imlib_image_draw_rectangle(winwid->im, thumbnail->x + 1, - thumbnail->y + 1, - thumbnail->w - 2, - thumbnail->h - 2, 0, 0, 0, - 255); - gib_imlib_image_draw_rectangle(winwid->im, thumbnail->x + 2, - thumbnail->y + 2, - thumbnail->w - 4, - thumbnail->h - 4, 255, 255, - 255, 255); - winwidget_render_image(winwid, 0, 1); - gib_imlib_free_image_and_decache(winwid->im); - winwid->im = origwin; - } - else - winwidget_render_image(winwid, 0, 1); - } - last_thumb = thumbnail; - } - } - } - D_RETURN_(5); + if (opt.xinerama && xinerama_screens) { + scr_width = xinerama_screens[xinerama_screen].width; + scr_height = xinerama_screens[xinerama_screen].height; + } +#endif /* HAVE_LIBXINERAMA */ + + D_ENTER(5); + if (menu_root) { + feh_menu *m; + feh_menu_item *selected_item, *mouseover_item; + + D(3, ("motion notify with menus open\n")); + while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); + + if (ev->xmotion.window == menu_cover) { + D_RETURN_(5); + } else if ((m = feh_menu_get_from_window(ev->xmotion.window))) { + selected_item = feh_menu_find_selected(m); + mouseover_item = feh_menu_find_at_xy(m, ev->xmotion.x, ev->xmotion.y); + + if (selected_item != mouseover_item) { + D(4, ("selecting a menu item\n")); + if (selected_item) + feh_menu_deselect_selected(m); + if ((mouseover_item) + && ((mouseover_item->func) + || (mouseover_item->submenu) + || (mouseover_item->func_gen_sub))) + feh_menu_select(m, mouseover_item); + } + /* check if we are close to the right and/or the bottom edge of the + * screen. If so, and if the menu we are currently over is partially + * hidden, slide the menu to the left and/or up until it is + * fully visible */ + + /* FIXME: get this working nicely with xinerama screen edges -- + * at the moment it does really funky stuff with + * scr_{width,height} instead of scr->{width,height} -- pabs*/ + if (mouseover_item + && ((scr->width - (ev->xmotion.x + m->x)) < + m->w || (scr->height - (ev->xmotion.y + m->y)) < m->w)) { + dx = scr_width - (m->x + m->w); + dy = scr_height - (m->y + m->h); + dx = dx < 0 ? dx : 0; + dy = dy < 0 ? dy : 0; + if (dx || dy) + feh_menu_slide_all_menus_relative(dx, dy); + } + /* if a submenu is open we want to see that also */ + if (mouseover_item && m->next && ((scr->width - (ev->xmotion.x + m->next->x)) + < m->next->w + || (scr->height - + (ev->xmotion.y + m->next->y)) < m->next->w)) { + dx = scr->width - (m->next->x + m->next->w); + dy = scr->height - (m->next->y + m->next->h); + dx = dx < 0 ? dx : 0; + dy = dy < 0 ? dy : 0; + if (dx || dy) + feh_menu_slide_all_menus_relative(dx, dy); + } + } + } else if (opt.mode == MODE_ZOOM) { + while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); + + winwid = winwidget_get_from_window(ev->xmotion.window); + if (winwid) { + winwid->zoom = ((double) ev->xmotion.x - (double) winwid->click_offset_x) / 64.0; + if (winwid->zoom < 0) + winwid->zoom = 1.0 + ((winwid->zoom * 64.0) / ((double) + (winwid->click_offset_x + 1))); + else + winwid->zoom += 1.0; + + if (winwid->zoom < 0.01) + winwid->zoom = 0.01; + + /* calculate change in zoom and move im_x and im_y respectively to + enable zooming to the clicked spot... */ + /* for now, center around im_click_offset_x and im_click_offset_y */ + winwid->im_x = (winwid->w / 2) - (winwid->im_click_offset_x * winwid->zoom); + winwid->im_y = (winwid->h / 2) - (winwid->im_click_offset_y * winwid->zoom); + + winwidget_render_image(winwid, 0, 0); + } + } else if ((opt.mode == MODE_PAN) || (opt.mode == MODE_NEXT)) { + int orig_x, orig_y; + + while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); + winwid = winwidget_get_from_window(ev->xmotion.window); + if (winwid) { + if (opt.mode == MODE_NEXT) { + opt.mode = MODE_PAN; + winwid->mode = MODE_PAN; + } + D(5, ("Panning\n")); + orig_x = winwid->im_x; + orig_y = winwid->im_y; + + winwid->im_x = ev->xmotion.x - winwid->click_offset_x; + winwid->im_y = ev->xmotion.y - winwid->click_offset_y; + + winwidget_sanitise_offsets(winwid); + + if ((winwid->im_x != orig_x) + || (winwid->im_y != orig_y)) + winwidget_render_image(winwid, 0, 0); + } + } else if (opt.mode == MODE_ROTATE) { + while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); + winwid = winwidget_get_from_window(ev->xmotion.window); + if (winwid) { + D(5, ("Rotating\n")); + if (!winwid->has_rotated) { + Imlib_Image temp; + + temp = gib_imlib_create_rotated_image(winwid->im, 0.0); + winwid->im_w = gib_imlib_image_get_width(temp); + winwid->im_h = gib_imlib_image_get_height(temp); + gib_imlib_free_image_and_decache(temp); + if (!winwid->full_screen && !opt.geom_flags) + winwidget_resize(winwid, winwid->im_w, winwid->im_h); + winwid->has_rotated = 1; + } + winwid->im_angle = (ev->xmotion.x - winwid->w / 2) / ((double) winwid->w / 2) * 3.1415926535; + D(5, ("angle: %f\n", winwid->im_angle)); + winwidget_render_image(winwid, 0, 0); + } + } else if (opt.mode == MODE_BLUR) { + while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); + winwid = winwidget_get_from_window(ev->xmotion.window); + if (winwid) { + Imlib_Image temp, ptr; + signed int blur_radius; + + D(5, ("Blurring\n")); + + temp = gib_imlib_clone_image(winwid->im); + blur_radius = (((double) ev->xmotion.x / winwid->w) * 20) - 10; + D(5, ("angle: %d\n", blur_radius)); + if (blur_radius > 0) + gib_imlib_image_sharpen(temp, blur_radius); + else + gib_imlib_image_blur(temp, 0 - blur_radius); + ptr = winwid->im; + winwid->im = temp; + winwidget_render_image(winwid, 0, 0); + gib_imlib_free_image_and_decache(winwid->im); + winwid->im = ptr; + } + } else { + while (XCheckTypedWindowEvent(disp, ev->xmotion.window, MotionNotify, ev)); + winwid = winwidget_get_from_window(ev->xmotion.window); + if (winwid != NULL) { + if (winwid->type == WIN_TYPE_ABOUT) { + Imlib_Image orig_im; + int x, y; + + x = ev->xmotion.x - winwid->im_x; + y = ev->xmotion.y - winwid->im_y; + orig_im = winwid->im; + winwid->im = gib_imlib_clone_image(orig_im); + imlib_context_set_image(winwid->im); + imlib_apply_filter("bump_map_point(x=[],y=[],map=" + PREFIX "/share/feh/images/about.png);", &x, &y); + winwidget_render_image(winwid, 0, 1); + gib_imlib_free_image_and_decache(winwid->im); + winwid->im = orig_im; + } else if (winwid->type == WIN_TYPE_THUMBNAIL) { + static feh_thumbnail *last_thumb = NULL; + feh_thumbnail *thumbnail; + int x, y; + + x = (ev->xbutton.x - winwid->im_x) / winwid->zoom; + y = (ev->xbutton.y - winwid->im_y) / winwid->zoom; + thumbnail = feh_thumbnail_get_thumbnail_from_coords(x, y); + if (thumbnail != last_thumb) { + if (thumbnail) { + Imlib_Image origwin; + + origwin = winwid->im; + winwid->im = gib_imlib_clone_image(origwin); + gib_imlib_image_fill_rectangle(winwid->im, + thumbnail->x, thumbnail->y, thumbnail->w, + thumbnail->h, 50, 50, 255, 100); + gib_imlib_image_draw_rectangle(winwid->im, + thumbnail->x, thumbnail->y, thumbnail->w, + thumbnail->h, 255, 255, 255, 255); + gib_imlib_image_draw_rectangle(winwid->im, + thumbnail->x + 1, thumbnail->y + 1, + thumbnail->w - 2, thumbnail->h - 2, + 0, 0, 0, 255); + gib_imlib_image_draw_rectangle(winwid->im, + thumbnail->x + 2, thumbnail->y + 2, + thumbnail->w - 4, thumbnail->h - 4, + 255, 255, 255, 255); + winwidget_render_image(winwid, 0, 1); + gib_imlib_free_image_and_decache(winwid->im); + winwid->im = origwin; + } else + winwidget_render_image(winwid, 0, 1); + } + last_thumb = thumbnail; + } + } + } + D_RETURN_(5); } -static void -feh_event_handle_ClientMessage(XEvent * ev) +static void feh_event_handle_ClientMessage(XEvent * ev) { - winwidget winwid = NULL; - - D_ENTER(4); - if (ev->xclient.format == 32 - && ev->xclient.data.l[0] == (signed) wmDeleteWindow) - { - winwid = winwidget_get_from_window(ev->xclient.window); - if (winwid) - winwidget_destroy(winwid); - } - - D_RETURN_(4); + winwidget winwid = NULL; + + D_ENTER(4); + if (ev->xclient.format == 32 && ev->xclient.data.l[0] == (signed) wmDeleteWindow) { + winwid = winwidget_get_from_window(ev->xclient.window); + if (winwid) + winwidget_destroy(winwid); + } + + D_RETURN_(4); } @@ -37,7 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef HAVE_LIBXINERAMA #include <X11/extensions/Xinerama.h> #include <X11/X.h> -#endif /* HAVE_LIBXINERAMA */ +#endif /* HAVE_LIBXINERAMA */ #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -67,7 +67,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "utils.h" #include "getopt.h" - #include "debug.h" #define SLIDESHOW_RELOAD_MAX 4096 @@ -89,15 +88,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DEFAULT_FONT_BIG "yudit/12" #define DEFAULT_FONT_TITLE "yudit/14" -enum mode_type -{ MODE_NORMAL = 0, MODE_PAN, MODE_ZOOM, MODE_ROTATE, MODE_BLUR, MODE_NEXT }; +enum mode_type { MODE_NORMAL = 0, MODE_PAN, MODE_ZOOM, MODE_ROTATE, MODE_BLUR, MODE_NEXT +}; -enum bgmode_type -{ BG_MODE_NONE = 0, BG_MODE_TILE, BG_MODE_CENTER, BG_MODE_SEAMLESS, BG_MODE_SCALE }; +enum bgmode_type { BG_MODE_NONE = 0, BG_MODE_TILE, BG_MODE_CENTER, BG_MODE_SEAMLESS, + BG_MODE_SCALE +}; -enum slide_change -{ SLIDE_NEXT, SLIDE_PREV, SLIDE_FIRST, SLIDE_LAST, SLIDE_JUMP_FWD, - SLIDE_JUMP_BACK +enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_FIRST, SLIDE_LAST, + SLIDE_JUMP_FWD, + SLIDE_JUMP_BACK }; typedef void (*sighandler_t) (int); @@ -110,7 +110,7 @@ void init_imlib_fonts(void); void init_x_and_imlib(void); #ifdef HAVE_LIBXINERAMA void init_xinerama(void); -#endif /* HAVE_LIBXINERAMA */ +#endif /* HAVE_LIBXINERAMA */ void init_multiwindow_mode(void); void init_thumbnail_mode(void); void init_collage_mode(void); @@ -146,10 +146,9 @@ struct hostent *feh_gethostbyname(const char *name); void slideshow_save_image(winwidget win); void feh_edit_inplace_orient(winwidget w, int orientation); void feh_edit_inplace_lossless_rotate(winwidget w, int orientation); -gib_list * feh_wrap_string(char *text, int wrap_width, int max_height, Imlib_Font fn, gib_style * style); -char *build_caption_filename(feh_file *file); -gib_list * feh_list_jump(gib_list * root, gib_list * l, int direction, int num); - +gib_list *feh_wrap_string(char *text, int wrap_width, int max_height, Imlib_Font fn, gib_style * style); +char *build_caption_filename(feh_file * file); +gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num); /* Imlib stuff */ extern Display *disp; @@ -162,7 +161,7 @@ extern Atom wmDeleteWindow; extern int num_xinerama_screens; extern XineramaScreenInfo *xinerama_screens; extern int xinerama_screen; -#endif /* HAVE_LIBXINERAMA */ +#endif /* HAVE_LIBXINERAMA */ /* Thumbnail sizes */ extern int cmdargc; @@ -174,6 +173,6 @@ extern unsigned char reset_output; extern int call_level; extern feh_menu *menu_main; extern feh_menu *menu_close; -extern char *mode; /* label for the current mode */ +extern char *mode; /* label for the current mode */ #endif diff --git a/src/feh_png.c b/src/feh_png.c index 7654880..e2842f8 100644 --- a/src/feh_png.c +++ b/src/feh_png.c @@ -31,10 +31,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <stdarg.h> #define FEH_PNG_COMPRESSION 3 -#define FEH_PNG_NUM_COMMENTS 2 /* only Thumb::URI and Thumb::MTime for now */ +#define FEH_PNG_NUM_COMMENTS 2 /* only Thumb::URI and Thumb::MTime for now */ -gib_hash* -feh_png_read_comments(char *file) +gib_hash *feh_png_read_comments(char *file) { gib_hash *hash = NULL; @@ -44,8 +43,8 @@ feh_png_read_comments(char *file) png_structp png_ptr; png_infop info_ptr; png_textp text_ptr; - - if (!(fp = fopen(file, "rb"))) + + if (!(fp = fopen(file, "rb"))) return hash; if (!(sig_bytes = feh_png_file_is_png(fp))) { @@ -55,8 +54,7 @@ feh_png_read_comments(char *file) /* initialize data structures */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) - { + if (!png_ptr) { fclose(fp); return hash; } @@ -68,8 +66,7 @@ feh_png_read_comments(char *file) return hash; } - if (setjmp(png_ptr->jmpbuf)) - { + if (setjmp(png_ptr->jmpbuf)) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); return hash; @@ -88,7 +85,7 @@ feh_png_read_comments(char *file) for (i = 0; i < comments; i++) gib_hash_set(hash, text_ptr[i].key, estrdup(text_ptr[i].text)); } -#endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_TEXT_SUPPORTED */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); @@ -97,8 +94,7 @@ feh_png_read_comments(char *file) } /* grab image data from image and write info file with comments ... */ -int -feh_png_write_png(Imlib_Image image, char *file, ...) +int feh_png_write_png(Imlib_Image image, char *file, ...) { FILE *fp; int i, w, h; @@ -113,7 +109,7 @@ feh_png_write_png(Imlib_Image image, char *file, ...) va_list args; png_text text[FEH_PNG_NUM_COMMENTS]; char *pair_key, *pair_text; -#endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_TEXT_SUPPORTED */ if (!(fp = fopen(file, "wb"))) return 0; @@ -123,14 +119,12 @@ feh_png_write_png(Imlib_Image image, char *file, ...) return 0; info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) - { + if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); return 0; } - if (setjmp(png_ptr->jmpbuf)) - { + if (setjmp(png_ptr->jmpbuf)) { fclose(fp); png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_info_struct(png_ptr, &info_ptr); @@ -143,14 +137,13 @@ feh_png_write_png(Imlib_Image image, char *file, ...) png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB_ALPHA, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); #ifdef WORDS_BIGENDIAN png_set_swap_alpha(png_ptr); -#else /* !WORDS_BIGENDIAN */ +#else /* !WORDS_BIGENDIAN */ png_set_bgr(png_ptr); -#endif /* WORDS_BIGENDIAN */ +#endif /* WORDS_BIGENDIAN */ sig_bit.red = 8; sig_bit.green = 8; @@ -160,24 +153,21 @@ feh_png_write_png(Imlib_Image image, char *file, ...) #ifdef PNG_TEXT_SUPPORTED va_start(args, file); - for (i = 0; i < FEH_PNG_NUM_COMMENTS; i++) - { - if ((pair_key = va_arg(args, char *)) && - (pair_text = va_arg(args, char *))) - { + for (i = 0; i < FEH_PNG_NUM_COMMENTS; i++) { + if ((pair_key = va_arg(args, char *)) + && (pair_text = va_arg(args, char *))) { /* got a complete pair, add to info structure */ text[i].key = pair_key; text[i].text = pair_text; text[i].compression = PNG_TEXT_COMPRESSION_NONE; - } - else + } else break; } va_end(args); if (i > 0) png_set_text(png_ptr, info_ptr, text, i); -#endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_TEXT_SUPPORTED */ png_set_compression_level(png_ptr, FEH_PNG_COMPRESSION); png_write_info(png_ptr, info_ptr); @@ -200,8 +190,7 @@ feh_png_write_png(Imlib_Image image, char *file, ...) } /* check PNG signature */ -int -feh_png_file_is_png(FILE *fp) +int feh_png_file_is_png(FILE * fp) { unsigned char buf[8]; diff --git a/src/feh_png.h b/src/feh_png.h index 458f6c5..6502978 100644 --- a/src/feh_png.h +++ b/src/feh_png.h @@ -34,6 +34,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. gib_hash *feh_png_read_comments(char *file); int feh_png_write_png(Imlib_Image image, char *file, ...); -int feh_png_file_is_png(FILE *fp); +int feh_png_file_is_png(FILE * fp); -#endif /* FEH_PNG_H */ +#endif /* FEH_PNG_H */ diff --git a/src/filelist.c b/src/filelist.c index dcbab54..da17f15 100644 --- a/src/filelist.c +++ b/src/filelist.c @@ -28,584 +28,525 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "options.h" gib_list *filelist = NULL; -int filelist_len = 0; +int filelist_len = 0; gib_list *current_file = NULL; extern int errno; static gib_list *rm_filelist = NULL; -feh_file * -feh_file_new(char *filename) +feh_file *feh_file_new(char *filename) { - feh_file *newfile; - char *s; - - D_ENTER(4); - - newfile = (feh_file *) emalloc(sizeof(feh_file)); - newfile->caption = NULL; - newfile->filename = estrdup(filename); - s = strrchr(filename, '/'); - if (s) - newfile->name = estrdup(s + 1); - else - newfile->name = estrdup(filename); - newfile->info = NULL; - D_RETURN(4, newfile); + feh_file *newfile; + char *s; + + D_ENTER(4); + + newfile = (feh_file *) emalloc(sizeof(feh_file)); + newfile->caption = NULL; + newfile->filename = estrdup(filename); + s = strrchr(filename, '/'); + if (s) + newfile->name = estrdup(s + 1); + else + newfile->name = estrdup(filename); + newfile->info = NULL; + D_RETURN(4, newfile); } -void -feh_file_free(feh_file * file) +void feh_file_free(feh_file * file) { - D_ENTER(4); - if (!file) - D_RETURN_(4); - if (file->filename) - free(file->filename); - if (file->name) - free(file->name); - if (file->caption) - free(file->caption); - if (file->info) - feh_file_info_free(file->info); - free(file); - D_RETURN_(4); + D_ENTER(4); + if (!file) + D_RETURN_(4); + if (file->filename) + free(file->filename); + if (file->name) + free(file->name); + if (file->caption) + free(file->caption); + if (file->info) + feh_file_info_free(file->info); + free(file); + D_RETURN_(4); } -feh_file_info * -feh_file_info_new(void) +feh_file_info *feh_file_info_new(void) { - feh_file_info *info; + feh_file_info *info; - D_ENTER(4); + D_ENTER(4); - info = (feh_file_info *) emalloc(sizeof(feh_file_info)); + info = (feh_file_info *) emalloc(sizeof(feh_file_info)); - info->width = 0; - info->height = 0; - info->size = 0; - info->pixels = 0; - info->has_alpha = 0; - info->format = NULL; - info->extension = NULL; + info->width = 0; + info->height = 0; + info->size = 0; + info->pixels = 0; + info->has_alpha = 0; + info->format = NULL; + info->extension = NULL; - D_RETURN(4, info); + D_RETURN(4, info); } -void -feh_file_info_free(feh_file_info * info) +void feh_file_info_free(feh_file_info * info) { - D_ENTER(4); - if (!info) - D_RETURN_(4); - if (info->format) - free(info->format); - if (info->extension) - free(info->extension); - free(info); - D_RETURN_(4); + D_ENTER(4); + if (!info) + D_RETURN_(4); + if (info->format) + free(info->format); + if (info->extension) + free(info->extension); + free(info); + D_RETURN_(4); } -gib_list * -feh_file_rm_and_free(gib_list * list, gib_list * l) +gib_list *feh_file_rm_and_free(gib_list * list, gib_list * l) { - D_ENTER(4); - unlink(FEH_FILE(l->data)->filename); - D_RETURN(4, feh_file_remove_from_list(list, l)); + D_ENTER(4); + unlink(FEH_FILE(l->data)->filename); + D_RETURN(4, feh_file_remove_from_list(list, l)); } -gib_list * -feh_file_remove_from_list(gib_list * list, gib_list * l) +gib_list *feh_file_remove_from_list(gib_list * list, gib_list * l) { - D_ENTER(4); - feh_file_free(FEH_FILE(l->data)); - D_RETURN(4, gib_list_remove(list, l)); + D_ENTER(4); + feh_file_free(FEH_FILE(l->data)); + D_RETURN(4, gib_list_remove(list, l)); } /* Recursive */ -void -add_file_to_filelist_recursively(char *origpath, unsigned char level) +void add_file_to_filelist_recursively(char *origpath, unsigned char level) { - struct stat st; - char *path; - - D_ENTER(5); - if (!origpath) - D_RETURN_(5); - - path = estrdup(origpath); - D(4, ("file is %s\n", path)); - - if (level == FILELIST_FIRST) - { - /* First time through, sort out pathname */ - int len = 0; - - len = strlen(path); - if (path[len - 1] == '/') - path[len - 1] = '\0'; - - if ((!strncmp(path, "http://", 7)) || - (!strncmp(path, "https://", 8)) || - (!strncmp(path, "ftp://", 6))) - { - /* Its a url */ - D(3, ("Adding url %s to filelist\n", path)); - filelist = gib_list_add_front(filelist, feh_file_new(path)); - /* We'll download it later... */ - free(path); - D_RETURN_(5); - } - else if (opt.filelistfile) - { - char *newpath = feh_absolute_path(path); - - free(path); - path = newpath; - } - } - - errno = 0; - if (stat(path, &st)) - { - /* Display useful error message */ - switch (errno) - { - case ENOENT: - case ENOTDIR: - if (!opt.quiet) - weprintf("%s does not exist - skipping", path); - break; - case ELOOP: - if (!opt.quiet) - weprintf("%s - too many levels of symbolic links - skipping", - path); - break; - case EACCES: - if (!opt.quiet) - weprintf("you don't have permission to open %s - skipping", - path); - break; - default: - if (!opt.quiet) - weprintf("couldn't open %s", path); - break; - } - free(path); - D_RETURN_(5); - } - - if ((S_ISDIR(st.st_mode)) && (level != FILELIST_LAST)) - { - struct dirent *de; - DIR *dir; - - D(4, ("It is a directory\n")); - - if ((dir = opendir(path)) == NULL) - { - if (!opt.quiet) - weprintf("couldn't open directory %s:", path); - free(path); - D_RETURN_(5); - } - de = readdir(dir); - while (de != NULL) - { - if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) - { - char *newfile; - - newfile = estrjoin("", path, "/", de->d_name, NULL); - - /* This ensures we go down one level even if not fully recursive - - this way "feh some_dir" expands to some_dir's contents */ - if (opt.recursive) - add_file_to_filelist_recursively(newfile, FILELIST_CONTINUE); - else - add_file_to_filelist_recursively(newfile, FILELIST_LAST); - - free(newfile); - } - de = readdir(dir); - } - closedir(dir); - } - else if (S_ISREG(st.st_mode)) - { - D(5, ("Adding regular file %s to filelist\n", path)); - filelist = gib_list_add_front(filelist, feh_file_new(path)); - } - free(path); - D_RETURN_(5); + struct stat st; + char *path; + + D_ENTER(5); + if (!origpath) + D_RETURN_(5); + + path = estrdup(origpath); + D(4, ("file is %s\n", path)); + + if (level == FILELIST_FIRST) { + /* First time through, sort out pathname */ + int len = 0; + + len = strlen(path); + if (path[len - 1] == '/') + path[len - 1] = '\0'; + + if ((!strncmp(path, "http://", 7)) + || (!strncmp(path, "https://", 8)) + || (!strncmp(path, "ftp://", 6))) { + /* Its a url */ + D(3, ("Adding url %s to filelist\n", path)); + filelist = gib_list_add_front(filelist, feh_file_new(path)); + /* We'll download it later... */ + free(path); + D_RETURN_(5); + } else if (opt.filelistfile) { + char *newpath = feh_absolute_path(path); + + free(path); + path = newpath; + } + } + + errno = 0; + if (stat(path, &st)) { + /* Display useful error message */ + switch (errno) { + case ENOENT: + case ENOTDIR: + if (!opt.quiet) + weprintf("%s does not exist - skipping", path); + break; + case ELOOP: + if (!opt.quiet) + weprintf("%s - too many levels of symbolic links - skipping", path); + break; + case EACCES: + if (!opt.quiet) + weprintf("you don't have permission to open %s - skipping", path); + break; + default: + if (!opt.quiet) + weprintf("couldn't open %s", path); + break; + } + free(path); + D_RETURN_(5); + } + + if ((S_ISDIR(st.st_mode)) && (level != FILELIST_LAST)) { + struct dirent *de; + DIR *dir; + + D(4, ("It is a directory\n")); + + if ((dir = opendir(path)) == NULL) { + if (!opt.quiet) + weprintf("couldn't open directory %s:", path); + free(path); + D_RETURN_(5); + } + de = readdir(dir); + while (de != NULL) { + if (strcmp(de->d_name, ".") + && strcmp(de->d_name, "..")) { + char *newfile; + + newfile = estrjoin("", path, "/", de->d_name, NULL); + + /* This ensures we go down one level even if not fully recursive + - this way "feh some_dir" expands to some_dir's contents */ + if (opt.recursive) + add_file_to_filelist_recursively(newfile, FILELIST_CONTINUE); + else + add_file_to_filelist_recursively(newfile, FILELIST_LAST); + + free(newfile); + } + de = readdir(dir); + } + closedir(dir); + } else if (S_ISREG(st.st_mode)) { + D(5, ("Adding regular file %s to filelist\n", path)); + filelist = gib_list_add_front(filelist, feh_file_new(path)); + } + free(path); + D_RETURN_(5); } -void -add_file_to_rm_filelist(char *file) +void add_file_to_rm_filelist(char *file) { - D_ENTER(4); - rm_filelist = gib_list_add_front(rm_filelist, feh_file_new(file)); - D_RETURN_(4); + D_ENTER(4); + rm_filelist = gib_list_add_front(rm_filelist, feh_file_new(file)); + D_RETURN_(4); } -void -delete_rm_files(void) +void delete_rm_files(void) { - gib_list *l; + gib_list *l; - D_ENTER(4); - for (l = rm_filelist; l; l = l->next) - unlink(FEH_FILE(l->data)->filename); - D_RETURN_(4); + D_ENTER(4); + for (l = rm_filelist; l; l = l->next) + unlink(FEH_FILE(l->data)->filename); + D_RETURN_(4); } -gib_list * -feh_file_info_preload(gib_list * list) +gib_list *feh_file_info_preload(gib_list * list) { - gib_list *l; - feh_file *file = NULL; - gib_list *remove_list = NULL; - - D_ENTER(4); - if (opt.verbose) - fprintf(stdout, PACKAGE " - preloading...\n"); - - for (l = list; l; l = l->next) - { - file = FEH_FILE(l->data); - D(5, - ("file %p, file->next %p, file->name %s\n", l, l->next, file->name)); - if (feh_file_info_load(file, NULL)) - { - D(3, ("Failed to load file %p\n", file)); - remove_list = gib_list_add_front(remove_list, l); - if (opt.verbose) - feh_display_status('x'); - } - else if (opt.verbose) - feh_display_status('.'); - } - if (opt.verbose) - fprintf(stdout, "\n"); - - if (remove_list) - { - for (l = remove_list; l; l = l->next) - filelist = list = gib_list_remove(list, (gib_list *) l->data); - - gib_list_free(remove_list); - } - - D_RETURN(4, list); + gib_list *l; + feh_file *file = NULL; + gib_list *remove_list = NULL; + + D_ENTER(4); + if (opt.verbose) + fprintf(stdout, PACKAGE " - preloading...\n"); + + for (l = list; l; l = l->next) { + file = FEH_FILE(l->data); + D(5, ("file %p, file->next %p, file->name %s\n", l, l->next, file->name)); + if (feh_file_info_load(file, NULL)) { + D(3, ("Failed to load file %p\n", file)); + remove_list = gib_list_add_front(remove_list, l); + if (opt.verbose) + feh_display_status('x'); + } else if (opt.verbose) + feh_display_status('.'); + } + if (opt.verbose) + fprintf(stdout, "\n"); + + if (remove_list) { + for (l = remove_list; l; l = l->next) + filelist = list = gib_list_remove(list, (gib_list *) l->data); + + gib_list_free(remove_list); + } + + D_RETURN(4, list); } -int -feh_file_info_load(feh_file * file, Imlib_Image im) +int feh_file_info_load(feh_file * file, Imlib_Image im) { - struct stat st; - int need_free = 1; - Imlib_Image im1; - - D_ENTER(4); - - D(4, ("im is %p\n", im)); - - if (im) - need_free = 0; - - errno = 0; - if (stat(file->filename, &st)) - { - /* Display useful error message */ - switch (errno) - { - case ENOENT: - case ENOTDIR: - if (!opt.quiet) - weprintf("%s does not exist - skipping", file->filename); - break; - case ELOOP: - if (!opt.quiet) - weprintf("%s - too many levels of symbolic links - skipping", - file->filename); - break; - case EACCES: - if (!opt.quiet) - weprintf("you don't have permission to open %s - skipping", - file->filename); - break; - default: - if (!opt.quiet) - weprintf("couldn't open %s ", file->filename); - break; - } - D_RETURN(4, 1); - } - - if (im) - im1 = im; - else if (!feh_load_image(&im1, file)) - D_RETURN(4, 1); - - if (!im1) - D_RETURN(4, 1); - - file->info = feh_file_info_new(); - - file->info->width = gib_imlib_image_get_width(im1); - file->info->height = gib_imlib_image_get_height(im1); - - file->info->has_alpha = gib_imlib_image_has_alpha(im1); - - file->info->pixels = file->info->width * file->info->height; - - file->info->format = estrdup(gib_imlib_image_format(im1)); - - file->info->size = st.st_size; - - if (need_free && im1) - gib_imlib_free_image_and_decache(im1); - D_RETURN(4, 0); + struct stat st; + int need_free = 1; + Imlib_Image im1; + + D_ENTER(4); + + D(4, ("im is %p\n", im)); + + if (im) + need_free = 0; + + errno = 0; + if (stat(file->filename, &st)) { + /* Display useful error message */ + switch (errno) { + case ENOENT: + case ENOTDIR: + if (!opt.quiet) + weprintf("%s does not exist - skipping", file->filename); + break; + case ELOOP: + if (!opt.quiet) + weprintf("%s - too many levels of symbolic links - skipping", file->filename); + break; + case EACCES: + if (!opt.quiet) + weprintf("you don't have permission to open %s - skipping", file->filename); + break; + default: + if (!opt.quiet) + weprintf("couldn't open %s ", file->filename); + break; + } + D_RETURN(4, 1); + } + + if (im) + im1 = im; + else if (!feh_load_image(&im1, file)) + D_RETURN(4, 1); + + if (!im1) + D_RETURN(4, 1); + + file->info = feh_file_info_new(); + + file->info->width = gib_imlib_image_get_width(im1); + file->info->height = gib_imlib_image_get_height(im1); + + file->info->has_alpha = gib_imlib_image_has_alpha(im1); + + file->info->pixels = file->info->width * file->info->height; + + file->info->format = estrdup(gib_imlib_image_format(im1)); + + file->info->size = st.st_size; + + if (need_free && im1) + gib_imlib_free_image_and_decache(im1); + D_RETURN(4, 0); } -int -feh_cmp_filename(void *file1, void *file2) +int feh_cmp_filename(void *file1, void *file2) { - D_ENTER(4); - D_RETURN(4, strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); + D_ENTER(4); + D_RETURN(4, strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename)); } -int -feh_cmp_name(void *file1, void *file2) +int feh_cmp_name(void *file1, void *file2) { - D_ENTER(4); - D_RETURN(4, strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); + D_ENTER(4); + D_RETURN(4, strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name)); } -int -feh_cmp_width(void *file1, void *file2) +int feh_cmp_width(void *file1, void *file2) { - D_ENTER(4); - D_RETURN(4, (FEH_FILE(file1)->info->width - FEH_FILE(file2)->info->width)); + D_ENTER(4); + D_RETURN(4, (FEH_FILE(file1)->info->width - FEH_FILE(file2)->info->width)); } -int -feh_cmp_height(void *file1, void *file2) +int feh_cmp_height(void *file1, void *file2) { - D_ENTER(4); - D_RETURN(4, - (FEH_FILE(file1)->info->height - FEH_FILE(file2)->info->height)); + D_ENTER(4); + D_RETURN(4, (FEH_FILE(file1)->info->height - FEH_FILE(file2)->info->height)); } -int -feh_cmp_pixels(void *file1, void *file2) +int feh_cmp_pixels(void *file1, void *file2) { - D_ENTER(4); - D_RETURN(4, - (FEH_FILE(file1)->info->pixels - FEH_FILE(file2)->info->pixels)); + D_ENTER(4); + D_RETURN(4, (FEH_FILE(file1)->info->pixels - FEH_FILE(file2)->info->pixels)); } -int -feh_cmp_size(void *file1, void *file2) +int feh_cmp_size(void *file1, void *file2) { - D_ENTER(4); - D_RETURN(4, (FEH_FILE(file1)->info->size - FEH_FILE(file2)->info->size)); + D_ENTER(4); + D_RETURN(4, (FEH_FILE(file1)->info->size - FEH_FILE(file2)->info->size)); } -int -feh_cmp_format(void *file1, void *file2) +int feh_cmp_format(void *file1, void *file2) { - D_ENTER(4); - D_RETURN(4, - strcmp(FEH_FILE(file1)->info->format, - FEH_FILE(file2)->info->format)); + D_ENTER(4); + D_RETURN(4, strcmp(FEH_FILE(file1)->info->format, FEH_FILE(file2)->info->format)); } -void -feh_prepare_filelist(void) +void feh_prepare_filelist(void) { - D_ENTER(4); - if (opt.list || opt.customlist || (opt.sort > SORT_FILENAME) - || opt.preload) - { - /* For these sort options, we have to preload images */ - filelist = feh_file_info_preload(filelist); - if (!gib_list_length(filelist)) - show_mini_usage(); - } - - D(3, ("sort mode requested is: %d\n", opt.sort)); - switch (opt.sort) - { - case SORT_NONE: - if (opt.randomize) - { - /* Randomize the filename order */ - filelist = gib_list_randomize(filelist); - } - else if (!opt.reverse) - { - /* Let's reverse the list. Its back-to-front right now ;) */ - filelist = gib_list_reverse(filelist); - } - break; - case SORT_NAME: - filelist = gib_list_sort(filelist, feh_cmp_name); - break; - case SORT_FILENAME: - filelist = gib_list_sort(filelist, feh_cmp_filename); - break; - case SORT_WIDTH: - filelist = gib_list_sort(filelist, feh_cmp_width); - break; - case SORT_HEIGHT: - filelist = gib_list_sort(filelist, feh_cmp_height); - break; - case SORT_PIXELS: - filelist = gib_list_sort(filelist, feh_cmp_pixels); - break; - case SORT_SIZE: - filelist = gib_list_sort(filelist, feh_cmp_size); - break; - case SORT_FORMAT: - filelist = gib_list_sort(filelist, feh_cmp_format); - break; - default: - break; - } - - /* no point reversing a random list */ - if (opt.reverse && (opt.sort != SORT_NONE)) - { - D(3, ("Reversing filelist as requested\n")); - filelist = gib_list_reverse(filelist); - } - - D_RETURN_(4); + D_ENTER(4); + if (opt.list || opt.customlist || (opt.sort > SORT_FILENAME) + || opt.preload) { + /* For these sort options, we have to preload images */ + filelist = feh_file_info_preload(filelist); + if (!gib_list_length(filelist)) + show_mini_usage(); + } + + D(3, ("sort mode requested is: %d\n", opt.sort)); + switch (opt.sort) { + case SORT_NONE: + if (opt.randomize) { + /* Randomize the filename order */ + filelist = gib_list_randomize(filelist); + } else if (!opt.reverse) { + /* Let's reverse the list. Its back-to-front right now ;) */ + filelist = gib_list_reverse(filelist); + } + break; + case SORT_NAME: + filelist = gib_list_sort(filelist, feh_cmp_name); + break; + case SORT_FILENAME: + filelist = gib_list_sort(filelist, feh_cmp_filename); + break; + case SORT_WIDTH: + filelist = gib_list_sort(filelist, feh_cmp_width); + break; + case SORT_HEIGHT: + filelist = gib_list_sort(filelist, feh_cmp_height); + break; + case SORT_PIXELS: + filelist = gib_list_sort(filelist, feh_cmp_pixels); + break; + case SORT_SIZE: + filelist = gib_list_sort(filelist, feh_cmp_size); + break; + case SORT_FORMAT: + filelist = gib_list_sort(filelist, feh_cmp_format); + break; + default: + break; + } + + /* no point reversing a random list */ + if (opt.reverse && (opt.sort != SORT_NONE)) { + D(3, ("Reversing filelist as requested\n")); + filelist = gib_list_reverse(filelist); + } + + D_RETURN_(4); } -int -feh_write_filelist(gib_list * list, char *filename) +int feh_write_filelist(gib_list * list, char *filename) { - FILE *fp; - gib_list *l; + FILE *fp; + gib_list *l; - D_ENTER(4); + D_ENTER(4); - if (!list || !filename) - D_RETURN(4, 0); + if (!list || !filename) + D_RETURN(4, 0); - errno = 0; - if ((fp = fopen(filename, "w")) == NULL) - { - weprintf("can't write filelist %s:", filename); - D_RETURN(4, 0); - } + errno = 0; + if ((fp = fopen(filename, "w")) == NULL) { + weprintf("can't write filelist %s:", filename); + D_RETURN(4, 0); + } - for (l = list; l; l = l->next) - fprintf(fp, "%s\n", (FEH_FILE(l->data)->filename)); + for (l = list; l; l = l->next) + fprintf(fp, "%s\n", (FEH_FILE(l->data)->filename)); - fclose(fp); + fclose(fp); - D_RETURN(4, 1); + D_RETURN(4, 1); } -gib_list * -feh_read_filelist(char *filename) +gib_list *feh_read_filelist(char *filename) { - FILE *fp; - gib_list *list = NULL; - char s[1024], s1[1024]; - Imlib_Image im1; - - D_ENTER(4); - - if (!filename) - D_RETURN(4, NULL); - - /* try and load the given filelist as an image, cowardly refuse to - * overwrite an image with a filelist. (requested by user who did feh -df * - * when he meant feh -dF *, as it overwrote the first image with the - * filelist). - */ - if (feh_load_image_char(&im1, filename)) { - weprintf("The file you specified as a filelist to read - %s - appears to be an image. Ignoring it (this is a common mistake).\n", filename); - opt.filelistfile = NULL; - D_RETURN(4, NULL); - } - - errno = 0; - if ((fp = fopen(filename, "r")) == NULL) - { - /* return quietly, as it's okay to specify a filelist file that doesn't - exist. In that case we create it on exit. */ - D_RETURN(4, NULL); - } - - for (; fgets(s, sizeof(s), fp);) - { - D(5, ("Got line '%s'\n", s)); - s1[0] = '\0'; - sscanf(s, "%[^\n]", (char *) &s1); - if (!(*s1) || (*s1 == '\n')) - continue; - D(5, ("Got filename %s from filelist file\n", s1)); - /* Add it to the new list */ - list = gib_list_add_front(list, feh_file_new(s1)); - } - fclose(fp); - - D_RETURN(4, list); + FILE *fp; + gib_list *list = NULL; + char s[1024], s1[1024]; + Imlib_Image im1; + + D_ENTER(4); + + if (!filename) + D_RETURN(4, NULL); + + /* try and load the given filelist as an image, cowardly refuse to + * overwrite an image with a filelist. (requested by user who did feh -df * + * when he meant feh -dF *, as it overwrote the first image with the + * filelist). + */ + if (feh_load_image_char(&im1, filename)) { + weprintf( + "The file you specified as a filelist to read - %s - appears to be an image. Ignoring it (this is a common mistake).\n", + filename); + opt.filelistfile = NULL; + D_RETURN(4, NULL); + } + + errno = 0; + if ((fp = fopen(filename, "r")) == NULL) { + /* return quietly, as it's okay to specify a filelist file that doesn't + exist. In that case we create it on exit. */ + D_RETURN(4, NULL); + } + + for (; fgets(s, sizeof(s), fp);) { + D(5, ("Got line '%s'\n", s)); + s1[0] = '\0'; + sscanf(s, "%[^\n]", (char *) &s1); + if (!(*s1) || (*s1 == '\n')) + continue; + D(5, ("Got filename %s from filelist file\n", s1)); + /* Add it to the new list */ + list = gib_list_add_front(list, feh_file_new(s1)); + } + fclose(fp); + + D_RETURN(4, list); } -char * -feh_absolute_path(char *path) +char *feh_absolute_path(char *path) { - char cwd[PATH_MAX]; - char fullpath[PATH_MAX]; - char temp[PATH_MAX]; - char *ret; - - D_ENTER(4); - - if (!path) - D_RETURN(4, NULL); - if (path[0] == '/') - D_RETURN(4, estrdup(path)); - /* This path is not relative. We're gonna convert it, so that a - filelist file can be saved anywhere and feh will still find the - images */ - D(4, ("Need to convert %s to an absolute form\n", path)); - /* I SHOULD be able to just use a simple realpath() here, but dumb * - old Solaris's realpath doesn't return an absolute path if the - path you give it is relative. Linux and BSD get this right... */ - getcwd(cwd, sizeof(cwd)); - snprintf(temp, sizeof(temp), "%s/%s", cwd, path); - if (realpath(temp, fullpath) != NULL) - { - ret = estrdup(fullpath); - } - else - { - ret = estrdup(temp); - } - D(4, ("Converted path to %s\n", ret)); - D_RETURN(4, ret); + char cwd[PATH_MAX]; + char fullpath[PATH_MAX]; + char temp[PATH_MAX]; + char *ret; + + D_ENTER(4); + + if (!path) + D_RETURN(4, NULL); + if (path[0] == '/') + D_RETURN(4, estrdup(path)); + /* This path is not relative. We're gonna convert it, so that a + filelist file can be saved anywhere and feh will still find the + images */ + D(4, ("Need to convert %s to an absolute form\n", path)); + /* I SHOULD be able to just use a simple realpath() here, but dumb * + old Solaris's realpath doesn't return an absolute path if the + path you give it is relative. Linux and BSD get this right... */ + getcwd(cwd, sizeof(cwd)); + snprintf(temp, sizeof(temp), "%s/%s", cwd, path); + if (realpath(temp, fullpath) != NULL) { + ret = estrdup(fullpath); + } else { + ret = estrdup(temp); + } + D(4, ("Converted path to %s\n", ret)); + D_RETURN(4, ret); } void feh_save_filelist() { - char *tmpname; + char *tmpname; - D_ENTER(4); + D_ENTER(4); - tmpname = - feh_unique_filename("", "filelist"); + tmpname = feh_unique_filename("", "filelist"); - if(!opt.quiet) - printf("saving filelist to filename '%s'\n", tmpname); + if (!opt.quiet) + printf("saving filelist to filename '%s'\n", tmpname); - feh_write_filelist(filelist, tmpname); - free(tmpname); - D_RETURN_(4); + feh_write_filelist(filelist, tmpname); + free(tmpname); + D_RETURN_(4); } diff --git a/src/filelist.h b/src/filelist.h index a292bb4..842e3af 100644 --- a/src/filelist.h +++ b/src/filelist.h @@ -26,35 +26,33 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef FILELIST_H #define FILELIST_H -struct __feh_file -{ - char *filename; - char *caption; - char *name; - - /* info stuff */ - feh_file_info *info; /* only set when needed */ +struct __feh_file { + char *filename; + char *caption; + char *name; + + /* info stuff */ + feh_file_info *info; /* only set when needed */ }; -struct __feh_file_info -{ - int width; - int height; - int size; - int pixels; - unsigned char has_alpha; - char *format; - char *extension; +struct __feh_file_info { + int width; + int height; + int size; + int pixels; + unsigned char has_alpha; + char *format; + char *extension; }; #define FEH_FILE(l) ((feh_file *) l) -enum filelist_recurse -{ FILELIST_FIRST, FILELIST_CONTINUE, FILELIST_LAST }; +enum filelist_recurse { FILELIST_FIRST, FILELIST_CONTINUE, FILELIST_LAST }; -enum sort_type -{ SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_WIDTH, SORT_HEIGHT, SORT_PIXELS, - SORT_SIZE, SORT_FORMAT +enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_WIDTH, + SORT_HEIGHT, + SORT_PIXELS, + SORT_SIZE, SORT_FORMAT }; feh_file *feh_file_new(char *filename); @@ -83,7 +81,7 @@ int feh_cmp_size(void *file1, void *file2); int feh_cmp_format(void *file1, void *file2); extern gib_list *filelist; -extern int filelist_len; +extern int filelist_len; extern gib_list *current_file; #endif diff --git a/src/getopt.c b/src/getopt.c index 4503953..5a8bb6c 100644 --- a/src/getopt.c +++ b/src/getopt.c @@ -59,7 +59,6 @@ #ifndef ELIDE_CODE - /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ @@ -67,7 +66,7 @@ contain conflicting prototypes for getopt. */ #include <stdlib.h> #include <unistd.h> -#endif /* GNU C library. */ +#endif /* GNU C library. */ #ifdef VMS #include <unixlib.h> @@ -181,11 +180,9 @@ int optopt = '?'; of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} -ordering; +static enum { + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; @@ -204,18 +201,16 @@ static char *posixly_correct; char *getenv(); -static char * -my_index(str, chr) - const char *str; - int chr; +static char *my_index(str, chr) +const char *str; +int chr; { - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; + while (*str) { + if (*str == chr) + return (char *) str; + str++; + } + return 0; } /* If using GCC, we can safely declare strlen this way. @@ -227,10 +222,10 @@ my_index(str, chr) /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen(const char *); -#endif /* not __STDC__ */ -#endif /* __GNUC__ */ +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ -#endif /* not __GNU_LIBRARY__ */ +#endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ @@ -257,18 +252,18 @@ static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ -static void __attribute__ ((unused)) store_args_and_env(int argc, - char *const *argv) +static void + __attribute__ ((unused)) store_args_and_env(int argc, char *const *argv) { - /* XXX This is no good solution. We should rather copy the args so that - we can compare them later. But we must not use malloc(3). */ - original_argc = argc; - original_argv = argv; + /* XXX This is no good solution. We should rather copy the args so that + we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; } # ifdef text_set_element text_set_element(__libc_subinit, store_args_and_env); -# endif /* text_set_element */ +# endif /* text_set_element */ # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ @@ -277,9 +272,9 @@ text_set_element(__libc_subinit, store_args_and_env); __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } -#else /* !_LIBC */ +#else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -294,85 +289,76 @@ text_set_element(__libc_subinit, store_args_and_env); static void exchange(char **); #endif -static void -exchange(argv) - char **argv; +static void exchange(argv) +char **argv; { - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. It leaves the - longer segment in the right place overall, but it consists of two parts - that need to be swapped next. */ + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. It leaves the + longer segment in the right place overall, but it consists of two parts + that need to be swapped next. */ #ifdef _LIBC - /* First make sure the handling of the `__getopt_nonoption_flags' string - can work normally. Our top argument must be in the range of the - string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and presents - new arguments. */ - char *new_str = malloc(top + 1); - - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memset(__mempcpy - (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), - '\0', top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } + /* First make sure the handling of the `__getopt_nonoption_flags' string + can work normally. Our top argument must be in the range of the + string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { + /* We must extend the array. The user plays games with us and presents + new arguments. */ + char *new_str = malloc(top + 1); + + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else { + memset(__mempcpy + (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } #endif - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS(bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; + while (top > middle && middle > bottom) { + if (top - middle > middle - bottom) { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS(bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ @@ -380,71 +366,61 @@ exchange(argv) #if defined (__STDC__) && __STDC__ static const char *_getopt_initialize(int, char *const *, const char *); #endif -static const char * -_getopt_initialize(argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +static const char *_getopt_initialize(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; { - /* Start processing options with ARGV-element 1 (since ARGV-element 0 is - the program name); the sequence of previously skipped non-option - ARGV-elements is empty. */ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 is + the program name); the sequence of previously skipped non-option + ARGV-elements is empty. */ - first_nonopt = last_nonopt = optind; + first_nonopt = last_nonopt = optind; - nextchar = NULL; + nextchar = NULL; - posixly_correct = getenv("POSIXLY_CORRECT"); + posixly_correct = getenv("POSIXLY_CORRECT"); - /* Determine how to handle the ordering of options and nonoptions. */ + /* Determine how to handle the ordering of options and nonoptions. */ - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; + if (optstring[0] == '-') { + ordering = RETURN_IN_ORDER; + ++optstring; + } else if (optstring[0] == '+') { + ordering = REQUIRE_ORDER; + ++optstring; + } else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; #ifdef _LIBC - if (posixly_correct == NULL && argc == original_argc - && argv == original_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen(orig_str); - - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc(nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - memset(__mempcpy(__getopt_nonoption_flags, orig_str, len), - '\0', nonoption_flags_max_len - len); - } - } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; + if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { + if (nonoption_flags_max_len == 0) { + if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen(orig_str); + + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = (char *) + malloc(nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset(__mempcpy + (__getopt_nonoption_flags, + orig_str, len), '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } else + nonoption_flags_len = 0; #endif - return optstring; + return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters @@ -503,30 +479,28 @@ _getopt_initialize(argc, argv, optstring) If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ -int -_getopt_internal(argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; +int _getopt_internal(argc, argv, optstring, longopts, longind, long_only) +int argc; +char *const *argv; +const char *optstring; +const struct option *longopts; +int *longind; +int long_only; { - optarg = NULL; - - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the - program name. */ - optstring = _getopt_initialize(argc, argv, optstring); - __getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. Either it - does not have option syntax, or there is an environment flag from the - shell indicating it is not an option. The later information is only - used when the used in the GNU libc. */ + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the + program name. */ + optstring = _getopt_initialize(argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. Either it + does not have option syntax, or there is an environment flag from the + shell indicating it is not an option. The later information is only + used when the used in the GNU libc. */ #ifdef _LIBC #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ @@ -535,511 +509,445 @@ _getopt_internal(argc, argv, optstring, longopts, longind, long_only) #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some - non-options, exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options and extend the range of - non-options previously skipped. */ - - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. Skip - it like a null option, then exchange with previous non-options as if - it were an option, then skip everything else like a non-option. */ - - if (optind != argc && !strcmp(argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan and back over - any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options that we - previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, either stop - the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. Skip the initial - punctuation. */ - - nextchar = - (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is a valid - short option, don't consider it an abbreviated form of a long option - that starts with f. Otherwise there would be no way to give the -f - short option. - - On the other hand, if there's a long option "fubar" and the - ARGV-element is "-fu", do consider that an abbreviation of the long - option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only - && (argv[optind][2] - || !my_index(optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated matches. - */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == - (unsigned int) strlen(p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf(stderr, _("%s: option `%s' is ambiguous\n"), argv[0], - argv[optind]); - nextchar += strlen(nextchar); - optind++; - optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf(stderr, - _ - ("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf(stderr, - _ - ("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen(nextchar); - - optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf(stderr, _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen(nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen(nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, or - the option starts with '--' or is not a valid short option, then - it's an error. Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index(optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf(stderr, _("%s: unrecognized option `--%s'\n"), argv[0], - nextchar); - else - /* +option or -option */ - fprintf(stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], - argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index(optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c); - else - fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, we - must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; increment it again when - taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the table of longopts. - */ - - for (nextchar = nameend = optarg; *nameend && *nameend != '='; - nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match or abbreviated - matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp(p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen(p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (opterr) - fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen(nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - fprintf(stderr, _("\ + if (nextchar == NULL || *nextchar == '\0') { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) { + /* If we have just processed some options following some + non-options, exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options and extend the range of + non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. Skip + it like a null option, then exchange with previous non-options as if + it were an option, then skip everything else like a non-option. */ + + if (optind != argc && !strcmp(argv[optind], "--")) { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan and back over + any non-options that we skipped and permuted. */ + + if (optind == argc) { + /* Set the next-arg-index to point at the non-options that we + previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, either stop + the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. Skip the initial + punctuation. */ + + nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is a valid + short option, don't consider it an abbreviated form of a long option + that starts with f. Otherwise there would be no way to give the -f + short option. + + On the other hand, if there's a long option "fubar" and the + ARGV-element is "-fu", do consider that an abbreviation of the long + option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] + || !my_index(optstring, argv[optind] + [1]))))) { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match or abbreviated matches. + */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, nextchar, nameend - nextchar)) { + if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) { + if (opterr) + fprintf(stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); + nextchar += strlen(nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) { + option_index = indfound; + optind++; + if (*nameend) { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else { + if (opterr) { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf(stderr, + _ + ("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf(stderr, + _ + ("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + } + + nextchar += strlen(nextchar); + + optopt = pfound->val; + return '?'; + } + } else if (pfound->has_arg == 1) { + if (optind < argc) + optarg = argv[optind++]; + else { + if (opterr) + fprintf(stderr, + _ + ("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen(nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen(nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, or + the option starts with '--' or is not a valid short option, then + it's an error. Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' || my_index(optstring, *nextchar) == NULL) { + if (opterr) { + if (argv[optind][1] == '-') + /* --option */ + fprintf(stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); + else + /* +option or -option */ + fprintf(stderr, + _ + ("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index(optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') { + if (opterr) { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c); + else + fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, we + must advance to the next element now. */ + optind++; + } else if (optind == argc) { + if (opterr) { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } else + /* We already incremented `optind' once; increment it again when + taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the table of longopts. + */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match or abbreviated + matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp(p->name, nextchar, nameend - nextchar)) { + if ((unsigned int) (nameend - nextchar) == strlen(p->name)) { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } else if (pfound == NULL) { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) { + if (opterr) + fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); + nextchar += strlen(nextchar); + optind++; + return '?'; + } + if (pfound != NULL) { + option_index = indfound; + if (*nameend) { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else { + if (opterr) + fprintf(stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); - nextchar += strlen(nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf(stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen(nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen(nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. - */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf(stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; increment it again - when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } + nextchar += strlen(nextchar); + return '?'; + } + } else if (pfound->has_arg == 1) { + if (optind < argc) + optarg = argv[optind++]; + else { + if (opterr) + fprintf(stderr, + _ + ("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen(nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen(nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. + */ + } + if (temp[1] == ':') { + if (temp[2] == ':') { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') { + optarg = nextchar; + optind++; + } else + optarg = NULL; + nextchar = NULL; + } else { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } else if (optind == argc) { + if (opterr) { + /* 1003.2 specifies the format of this message. */ + fprintf(stderr, + _("%s: option requires an argument -- %c\n"), argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } else + /* We already incremented `optind' once; increment it again + when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } } -int -getopt(argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; +int getopt(argc, argv, optstring) +int argc; +char *const *argv; +const char *optstring; { - return _getopt_internal(argc, argv, optstring, (const struct option *) 0, - (int *) 0, 0); + return _getopt_internal(argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ -int -main(argc, argv) - int argc; - char **argv; +int main(argc, argv) +int argc; +char **argv; { - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt(argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf("option %c\n", c); - break; - - case 'a': - printf("option a\n"); - break; - - case 'b': - printf("option b\n"); - break; - - case 'c': - printf("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf("non-option ARGV-elements: "); - while (optind < argc) - printf("%s ", argv[optind++]); - printf("\n"); - } - - exit(0); + int c; + int digit_optind = 0; + + while (1) { + int this_option_optind = optind ? optind : 1; + + c = getopt(argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf("option %c\n", c); + break; + + case 'a': + printf("option a\n"); + break; + + case 'b': + printf("option b\n"); + break; + + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) { + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + } + + exit(0); } -#endif /* TEST */ +#endif /* TEST */ diff --git a/src/getopt.h b/src/getopt.h index 73ec1b7..e8fe13f 100644 --- a/src/getopt.h +++ b/src/getopt.h @@ -21,8 +21,7 @@ #define _GETOPT_H 1 #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /* For communication from `getopt' to the caller. @@ -31,7 +30,7 @@ extern "C" Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ - extern char *optarg; + extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller @@ -45,16 +44,16 @@ extern "C" Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ - extern int optind; + extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ - extern int opterr; + extern int opterr; /* Set to an option character which was unrecognized. */ - extern int optopt; + extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector @@ -77,19 +76,18 @@ extern "C" one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ - struct option - { + struct option { #if defined (__STDC__) && __STDC__ - const char *name; + const char *name; #else - char *name; + char *name; #endif - /* has_arg can't be an enum because some compilers complain about type - mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; - }; + /* has_arg can't be an enum because some compilers complain about type + mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; + }; /* Names for the values of the `has_arg' field of `struct option'. */ @@ -102,35 +100,31 @@ extern "C" /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ - extern int getopt(int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ + extern int getopt(int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ #ifndef __cplusplus /* C++ is more pedantic, and demands a full prototype, not this. Hope that stdlib.h has a prototype for `getopt'. */ - extern int getopt(); -#endif /* __cplusplus */ -#endif /* __GNU_LIBRARY__ */ - extern int getopt_long(int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); - extern int getopt_long_only(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); + extern int getopt(); +#endif /* __cplusplus */ +#endif /* __GNU_LIBRARY__ */ + extern int getopt_long(int argc, char *const *argv, + const char *shortopts, const struct option *longopts, int *longind); + extern int getopt_long_only(int argc, char *const *argv, + const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ - extern int _getopt_internal(int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ - extern int getopt(); - extern int getopt_long(); - extern int getopt_long_only(); - - extern int _getopt_internal(); -#endif /* __STDC__ */ + extern int _getopt_internal(int argc, char *const *argv, + const char *shortopts, const struct option *longopts, int *longind, int long_only); +#else /* not __STDC__ */ + extern int getopt(); + extern int getopt_long(); + extern int getopt_long_only(); + + extern int _getopt_internal(); +#endif /* __STDC__ */ #ifdef __cplusplus } #endif - -#endif /* getopt.h */ +#endif /* getopt.h */ diff --git a/src/getopt1.c b/src/getopt1.c index 24dd347..dd74680 100644 --- a/src/getopt1.c +++ b/src/getopt1.c @@ -51,7 +51,6 @@ #ifndef ELIDE_CODE - /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ @@ -62,15 +61,14 @@ #define NULL 0 #endif -int -getopt_long(argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +int getopt_long(argc, argv, options, long_options, opt_index) +int argc; +char *const *argv; +const char *options; +const struct option *long_options; +int *opt_index; { - return _getopt_internal(argc, argv, options, long_options, opt_index, 0); + return _getopt_internal(argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -78,110 +76,102 @@ getopt_long(argc, argv, options, long_options, opt_index) but does match a short option, it is parsed as a short option instead. */ -int -getopt_long_only(argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; +int getopt_long_only(argc, argv, options, long_options, opt_index) +int argc; +char *const *argv; +const char *options; +const struct option *long_options; +int *opt_index; { - return _getopt_internal(argc, argv, options, long_options, opt_index, 1); + return _getopt_internal(argc, argv, options, long_options, opt_index, 1); } - -#endif /* Not ELIDE_CODE. */ +#endif /* Not ELIDE_CODE. */ #ifdef TEST #include <stdio.h> -int -main(argc, argv) - int argc; - char **argv; +int main(argc, argv) +int argc; +char **argv; { - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = - getopt_long(argc, argv, "abc:d:0123456789", long_options, - &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf("option %s", long_options[option_index].name); - if (optarg) - printf(" with arg %s", optarg); - printf("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf("option %c\n", c); - break; - - case 'a': - printf("option a\n"); - break; - - case 'b': - printf("option b\n"); - break; - - case 'c': - printf("option c with value `%s'\n", optarg); - break; - - case 'd': - printf("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf("non-option ARGV-elements: "); - while (optind < argc) - printf("%s ", argv[optind++]); - printf("\n"); - } - - exit(0); + int c; + int digit_optind = 0; + + while (1) { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "abc:d:0123456789", long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 0: + printf("option %s", long_options[option_index].name); + if (optarg) + printf(" with arg %s", optarg); + printf("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf("option %c\n", c); + break; + + case 'a': + printf("option a\n"); + break; + + case 'b': + printf("option b\n"); + break; + + case 'c': + printf("option c with value `%s'\n", optarg); + break; + + case 'd': + printf("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) { + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + } + + exit(0); } -#endif /* TEST */ +#endif /* TEST */ 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); } diff --git a/src/index.c b/src/index.c index 90f34f8..5c13d19 100644 --- a/src/index.c +++ b/src/index.c @@ -34,578 +34,509 @@ static char *create_index_title_string(int num, int w, int h); /* TODO Break this up a bit ;) */ /* TODO s/bit/lot */ -void -init_index_mode(void) +void init_index_mode(void) { - Imlib_Image im_main; - Imlib_Image im_temp; - int w = 800, h = 600, ww = 0, hh = 0, www, hhh, xxx, yyy; - int x = 0, y = 0; - int bg_w = 0, bg_h = 0; - winwidget winwid = NULL; - Imlib_Image bg_im = NULL, im_thumb = NULL; - int tot_thumb_h; - int text_area_h = 50; - int title_area_h = 0; - Imlib_Font fn = NULL; - Imlib_Font title_fn = NULL; - int text_area_w = 0; - int tw = 0, th = 0; - int fw_name, fw_size, fw_dim, fw, fh; - int vertical = 0; - int max_column_w = 0; - int thumbnailcount = 0; - gib_list *l = NULL, *last = NULL; - feh_file *file = NULL; - int lines; - unsigned char trans_bg = 0; - int index_image_width, index_image_height; - int x_offset_name = 0, x_offset_dim = 0, x_offset_size = 0; - char *s; - - D_ENTER(3); - - if (opt.montage) { - mode = "montage"; - } else { - mode = "index"; - } - - fn = gib_imlib_load_font(opt.font); - - if (opt.title_font) - { - int fh, fw; - - title_fn = gib_imlib_load_font(opt.title_font); - if (!fn) - title_fn = gib_imlib_load_font(DEFAULT_FONT_TITLE); - gib_imlib_get_text_size(title_fn, "W", NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - title_area_h = fh + 4; - } - else - title_fn = gib_imlib_load_font(DEFAULT_FONT_TITLE); - - if ((!fn) || (!title_fn)) - eprintf("Error loading fonts"); - - /* Work out how tall the font is */ - gib_imlib_get_text_size(fn, "W", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); - /* For now, allow room for the right number of lines with small gaps */ - text_area_h = - ((th + 2) * (opt.index_show_name + opt.index_show_size + - opt.index_show_dim)) + 5; - - /* This includes the text area for index data */ - tot_thumb_h = opt.thumb_h + text_area_h; - - /* Use bg image dimensions for default size */ - if (opt.bg && opt.bg_file) - { - if (!strcmp(opt.bg_file, "trans")) - trans_bg = 1; - else - { - D(3, ("Time to apply a background to blend onto\n")); - if (feh_load_image_char(&bg_im, opt.bg_file) != 0) - { - bg_w = gib_imlib_image_get_width(bg_im); - bg_h = gib_imlib_image_get_height(bg_im); - } - } - } - - if (!opt.limit_w && !opt.limit_h) - { - if (bg_im) - { - if (opt.verbose) - fprintf(stdout, - PACKAGE " - No size restriction specified for index.\n" - " You did specify a background however, so the\n" - " index size has defaulted to the size of the image\n"); - opt.limit_w = bg_w; - opt.limit_h = bg_h; - } - else - { - if (opt.verbose) - fprintf(stdout, - PACKAGE " - No size restriction specified for index.\n" - " Using defaults (width limited to 800)\n"); - opt.limit_w = 800; - } - } - - - /* Here we need to whiz through the files, and look at the filenames and - info in the selected font, work out how much space we need, and - calculate the size of the image we will require */ - - if (opt.limit_w && opt.limit_h) - { - int rec_h = 0; - - w = opt.limit_w; - h = opt.limit_h; - - /* Work out if this is big enough, and give a warning if not */ - - /* Pretend we are limiting width by that specified, loop through, and - see it we fit in the height specified. If not, continue the loop, - and recommend the final value instead. Carry on and make the index - anyway. */ - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - text_area_w = opt.thumb_w; - if (opt.index_show_name) - { - gib_imlib_get_text_size(fn, file->name, NULL, &fw, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(fn, - create_index_dimension_string(1000, 1000), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(fn, - create_index_size_string(file->filename), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (text_area_w > opt.thumb_w) - text_area_w += 5; - - if ((x > w - text_area_w)) - { - x = 0; - y += tot_thumb_h; - } - - x += text_area_w; - } - rec_h = y + tot_thumb_h; - - if (h < rec_h) - { - weprintf("The image size you specified (%d by %d) is not large\n" - "enough to hold all the thumnails you specified (%d). To fit all\n" - "the thumnails, either decrease their size, choose a smaller font,\n" - "or use a larger image (may I recommend %d by %d?)", - opt.limit_w, opt.limit_h, filelist_len, opt.limit_w, rec_h); - } - } - else if (opt.limit_h) - { - vertical = 1; - h = opt.limit_h; - /* calc w */ - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - text_area_w = opt.thumb_w; - /* Calc width of text */ - if (opt.index_show_name) - { - gib_imlib_get_text_size(fn, file->name, NULL, &fw, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(fn, - create_index_dimension_string(1000, 1000), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(fn, - create_index_size_string(file->filename), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (text_area_w > opt.thumb_w) - text_area_w += 5; - - if (text_area_w > max_column_w) - max_column_w = text_area_w; - - if ((y > h - tot_thumb_h)) - { - y = 0; - x += max_column_w; - max_column_w = 0; - } - - y += tot_thumb_h; - } - w = x + text_area_w; - max_column_w = 0; - } - else if (opt.limit_w) - { - w = opt.limit_w; - /* calc h */ - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - text_area_w = opt.thumb_w; - if (opt.index_show_name) - { - gib_imlib_get_text_size(fn, file->name, NULL, &fw, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(fn, - create_index_dimension_string(1000, 1000), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(fn, - create_index_size_string(file->filename), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > text_area_w) - text_area_w = fw; - } - - if (text_area_w > opt.thumb_w) - text_area_w += 5; - - if ((x > w - text_area_w)) - { - x = 0; - y += tot_thumb_h; - } - - x += text_area_w; - } - h = y + tot_thumb_h; - } - - x = y = 0; - - index_image_width = w; - index_image_height = h + title_area_h; - im_main = imlib_create_image(index_image_width, index_image_height); - - if (!im_main) - eprintf("Imlib error creating index image, are you low on RAM?"); - - if (bg_im) - gib_imlib_blend_image_onto_image(im_main, bg_im, - gib_imlib_image_has_alpha(bg_im), 0, 0, - bg_w, bg_h, 0, 0, w, h, 1, 0, 0); - else if (trans_bg) - { - gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h + title_area_h, 0, 0, - 0, 0); - gib_imlib_image_set_has_alpha(im_main, 1); - } - else - { - /* Colour the background */ - gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h + title_area_h, 0, 0, - 0, 255); - } - - /* Create the window title at this point */ - - if (!opt.title) - s = estrdup(PACKAGE " [index mode]"); - else - s = estrdup(feh_printf(opt.title, NULL)); - - if (opt.display) - { - winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE); - winwidget_show(winwid); - } - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - if (last) - { - filelist = feh_file_remove_from_list(filelist, last); - filelist_len--; - last = NULL; - } - D(4, ("About to load image %s\n", file->filename)); - if (feh_load_image(&im_temp, file) != 0) - { - if (opt.verbose) - feh_display_status('.'); - D(4, ("Successfully loaded %s\n", file->filename)); - www = opt.thumb_w; - hhh = opt.thumb_h; - ww = gib_imlib_image_get_width(im_temp); - hh = gib_imlib_image_get_height(im_temp); - thumbnailcount++; - - if (opt.aspect) - { - double ratio = 0.0; - - /* Keep the aspect ratio for the thumbnail */ - ratio = ((double) ww / hh) / ((double) www / hhh); - - if (ratio > 1.0) - hhh = opt.thumb_h / ratio; - else if (ratio != 1.0) - www = opt.thumb_w * ratio; - } - - if ((!opt.stretch) && ((www > ww) || (hhh > hh))) - { - /* Don't make the image larger unless stretch is specified */ - www = ww; - hhh = hh; - } - - im_thumb = - gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, - hhh, 1); - gib_imlib_free_image_and_decache(im_temp); - - if (opt.alpha) - { - DATA8 atab[256]; - - D(3, ("Applying alpha options\n")); - gib_imlib_image_set_has_alpha(im_thumb, 1); - memset(atab, opt.alpha_level, sizeof(atab)); - gib_imlib_apply_color_modifier_to_rectangle(im_thumb, 0, 0, www, - hhh, NULL, NULL, NULL, - atab); - } - - text_area_w = opt.thumb_w; - /* Now draw on the info text */ - if (opt.index_show_name) - { - gib_imlib_get_text_size(fn, file->name, NULL, &fw_name, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw_name > text_area_w) - text_area_w = fw_name; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(fn, create_index_dimension_string(ww, hh), - NULL, &fw_dim, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw_dim > text_area_w) - text_area_w = fw_dim; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(fn, - create_index_size_string(file->filename), - NULL, &fw_size, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw_size > text_area_w) - text_area_w = fw_size; - } - if (text_area_w > opt.thumb_w) - text_area_w += 5; - - /* offsets for centering text */ - x_offset_name = (text_area_w - fw_name) / 2; - x_offset_dim = (text_area_w - fw_dim) / 2; - x_offset_size = (text_area_w - fw_size) / 2; - - if (vertical) - { - if (text_area_w > max_column_w) - max_column_w = text_area_w; - if (y > h - tot_thumb_h) - { - y = 0; - x += max_column_w; - max_column_w = 0; - } - if (x > w - text_area_w) - break; - } - else - { - if (x > w - text_area_w) - { - x = 0; - y += tot_thumb_h; - } - if (y > h - tot_thumb_h) - break; - } - - if (opt.aspect) - { - xxx = x + ((opt.thumb_w - www) / 2); - yyy = y + ((opt.thumb_h - hhh) / 2); - } - else - { - /* Ignore the aspect ratio and squash the image in */ - xxx = x; - yyy = y; - } - - /* Draw now */ - gib_imlib_blend_image_onto_image(im_main, im_thumb, - gib_imlib_image_has_alpha(im_thumb), - 0, 0, www, hhh, xxx, yyy, www, hhh, - 1, - gib_imlib_image_has_alpha(im_thumb), - 0); - - gib_imlib_free_image_and_decache(im_thumb); - - lines = 0; - if (opt.index_show_name) - gib_imlib_text_draw(im_main, fn, NULL, x + x_offset_name, - y + opt.thumb_h + (lines++ * (th + 2)) + 2, - file->name, IMLIB_TEXT_TO_RIGHT, 255, 255, - 255, 255); - if (opt.index_show_dim) - gib_imlib_text_draw(im_main, fn, NULL, x + x_offset_dim, - y + opt.thumb_h + (lines++ * (th + 2)) + 2, - create_index_dimension_string(ww, hh), - IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); - if (opt.index_show_size) - gib_imlib_text_draw(im_main, fn, NULL, x + x_offset_size, - y + opt.thumb_h + (lines++ * (th + 2)) + 2, - create_index_size_string(file->filename), - IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); - - if (vertical) - y += tot_thumb_h; - else - x += text_area_w; - - } - else - { - if (opt.verbose) - feh_display_status('x'); - last = l; - } - if (opt.display) - { - winwidget_render_image(winwid, 0, 0); - if (!feh_main_iteration(0)) - exit(0); - } - } - if (opt.verbose) - fprintf(stdout, "\n"); - - if (opt.title_font) - { - int fw, fh, fx, fy; - char *s; - - s = create_index_title_string(thumbnailcount, w, h); - gib_imlib_get_text_size(title_fn, s, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - fx = (index_image_width - fw) >> 1; - fy = index_image_height - fh - 2; - gib_imlib_text_draw(im_main, title_fn, NULL, fx, fy, s, IMLIB_TEXT_TO_RIGHT, - 255, 255, 255, 255); - } - - if (opt.output && opt.output_file) - { - char output_buf[1024]; - - if (opt.output_dir) - snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file); - else - strncpy(output_buf, opt.output_file, 1024); - - gib_imlib_save_image(im_main, output_buf); - if (opt.verbose) - { - int tw, th; - - tw = gib_imlib_image_get_width(im_main); - th = gib_imlib_image_get_height(im_main); - fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf); - fprintf(stdout, - " - Image is %dx%d pixels and contains %d thumbnails\n", - tw, th, thumbnailcount); - } - } - - if (!opt.display) - gib_imlib_free_image_and_decache(im_main); - - free(s); - D_RETURN_(3); + Imlib_Image im_main; + Imlib_Image im_temp; + int w = 800, h = 600, ww = 0, hh = 0, www, hhh, xxx, yyy; + int x = 0, y = 0; + int bg_w = 0, bg_h = 0; + winwidget winwid = NULL; + Imlib_Image bg_im = NULL, im_thumb = NULL; + int tot_thumb_h; + int text_area_h = 50; + int title_area_h = 0; + Imlib_Font fn = NULL; + Imlib_Font title_fn = NULL; + int text_area_w = 0; + int tw = 0, th = 0; + int fw_name, fw_size, fw_dim, fw, fh; + int vertical = 0; + int max_column_w = 0; + int thumbnailcount = 0; + gib_list *l = NULL, *last = NULL; + feh_file *file = NULL; + int lines; + unsigned char trans_bg = 0; + int index_image_width, index_image_height; + int x_offset_name = 0, x_offset_dim = 0, x_offset_size = 0; + char *s; + + D_ENTER(3); + + if (opt.montage) { + mode = "montage"; + } else { + mode = "index"; + } + + fn = gib_imlib_load_font(opt.font); + + if (opt.title_font) { + int fh, fw; + + title_fn = gib_imlib_load_font(opt.title_font); + if (!fn) + title_fn = gib_imlib_load_font(DEFAULT_FONT_TITLE); + gib_imlib_get_text_size(title_fn, "W", NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + title_area_h = fh + 4; + } else + title_fn = gib_imlib_load_font(DEFAULT_FONT_TITLE); + + if ((!fn) || (!title_fn)) + eprintf("Error loading fonts"); + + /* Work out how tall the font is */ + gib_imlib_get_text_size(fn, "W", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); + /* For now, allow room for the right number of lines with small gaps */ + text_area_h = ((th + 2) * (opt.index_show_name + opt.index_show_size + opt.index_show_dim)) + 5; + + /* This includes the text area for index data */ + tot_thumb_h = opt.thumb_h + text_area_h; + + /* Use bg image dimensions for default size */ + if (opt.bg && opt.bg_file) { + if (!strcmp(opt.bg_file, "trans")) + trans_bg = 1; + else { + D(3, ("Time to apply a background to blend onto\n")); + if (feh_load_image_char(&bg_im, opt.bg_file) != 0) { + bg_w = gib_imlib_image_get_width(bg_im); + bg_h = gib_imlib_image_get_height(bg_im); + } + } + } + + if (!opt.limit_w && !opt.limit_h) { + if (bg_im) { + if (opt.verbose) + fprintf(stdout, + PACKAGE + " - No size restriction specified for index.\n" + " You did specify a background however, so the\n" + " index size has defaulted to the size of the image\n"); + opt.limit_w = bg_w; + opt.limit_h = bg_h; + } else { + if (opt.verbose) + fprintf(stdout, + PACKAGE + " - No size restriction specified for index.\n" + " Using defaults (width limited to 800)\n"); + opt.limit_w = 800; + } + } + + /* Here we need to whiz through the files, and look at the filenames and + info in the selected font, work out how much space we need, and + calculate the size of the image we will require */ + + if (opt.limit_w && opt.limit_h) { + int rec_h = 0; + + w = opt.limit_w; + h = opt.limit_h; + + /* Work out if this is big enough, and give a warning if not */ + + /* Pretend we are limiting width by that specified, loop through, and + see it we fit in the height specified. If not, continue the loop, + and recommend the final value instead. Carry on and make the index + anyway. */ + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + text_area_w = opt.thumb_w; + if (opt.index_show_name) { + gib_imlib_get_text_size(fn, file->name, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(fn, + create_index_dimension_string + (1000, 1000), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(fn, + create_index_size_string + (file->filename), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (text_area_w > opt.thumb_w) + text_area_w += 5; + + if ((x > w - text_area_w)) { + x = 0; + y += tot_thumb_h; + } + + x += text_area_w; + } + rec_h = y + tot_thumb_h; + + if (h < rec_h) { + weprintf( + "The image size you specified (%d by %d) is not large\n" + "enough to hold all the thumnails you specified (%d). To fit all\n" + "the thumnails, either decrease their size, choose a smaller font,\n" + "or use a larger image (may I recommend %d by %d?)", + opt.limit_w, opt.limit_h, filelist_len, opt.limit_w, rec_h); + } + } else if (opt.limit_h) { + vertical = 1; + h = opt.limit_h; + /* calc w */ + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + text_area_w = opt.thumb_w; + /* Calc width of text */ + if (opt.index_show_name) { + gib_imlib_get_text_size(fn, file->name, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(fn, + create_index_dimension_string + (1000, 1000), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(fn, + create_index_size_string + (file->filename), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (text_area_w > opt.thumb_w) + text_area_w += 5; + + if (text_area_w > max_column_w) + max_column_w = text_area_w; + + if ((y > h - tot_thumb_h)) { + y = 0; + x += max_column_w; + max_column_w = 0; + } + + y += tot_thumb_h; + } + w = x + text_area_w; + max_column_w = 0; + } else if (opt.limit_w) { + w = opt.limit_w; + /* calc h */ + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + text_area_w = opt.thumb_w; + if (opt.index_show_name) { + gib_imlib_get_text_size(fn, file->name, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(fn, + create_index_dimension_string + (1000, 1000), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(fn, + create_index_size_string + (file->filename), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > text_area_w) + text_area_w = fw; + } + + if (text_area_w > opt.thumb_w) + text_area_w += 5; + + if ((x > w - text_area_w)) { + x = 0; + y += tot_thumb_h; + } + + x += text_area_w; + } + h = y + tot_thumb_h; + } + + x = y = 0; + + index_image_width = w; + index_image_height = h + title_area_h; + im_main = imlib_create_image(index_image_width, index_image_height); + + if (!im_main) + eprintf("Imlib error creating index image, are you low on RAM?"); + + if (bg_im) + gib_imlib_blend_image_onto_image(im_main, bg_im, + gib_imlib_image_has_alpha + (bg_im), 0, 0, bg_w, bg_h, 0, 0, w, h, 1, 0, 0); + else if (trans_bg) { + gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h + title_area_h, 0, 0, 0, 0); + gib_imlib_image_set_has_alpha(im_main, 1); + } else { + /* Colour the background */ + gib_imlib_image_fill_rectangle(im_main, 0, 0, w, h + title_area_h, 0, 0, 0, 255); + } + + /* Create the window title at this point */ + + if (!opt.title) + s = estrdup(PACKAGE " [index mode]"); + else + s = estrdup(feh_printf(opt.title, NULL)); + + if (opt.display) { + winwid = winwidget_create_from_image(im_main, s, WIN_TYPE_SINGLE); + winwidget_show(winwid); + } + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + if (last) { + filelist = feh_file_remove_from_list(filelist, last); + filelist_len--; + last = NULL; + } + D(4, ("About to load image %s\n", file->filename)); + if (feh_load_image(&im_temp, file) != 0) { + if (opt.verbose) + feh_display_status('.'); + D(4, ("Successfully loaded %s\n", file->filename)); + www = opt.thumb_w; + hhh = opt.thumb_h; + ww = gib_imlib_image_get_width(im_temp); + hh = gib_imlib_image_get_height(im_temp); + thumbnailcount++; + + if (opt.aspect) { + double ratio = 0.0; + + /* Keep the aspect ratio for the thumbnail */ + ratio = ((double) ww / hh) / ((double) www / hhh); + + if (ratio > 1.0) + hhh = opt.thumb_h / ratio; + else if (ratio != 1.0) + www = opt.thumb_w * ratio; + } + + if ((!opt.stretch) && ((www > ww) || (hhh > hh))) { + /* Don't make the image larger unless stretch is specified */ + www = ww; + hhh = hh; + } + + im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, hhh, 1); + gib_imlib_free_image_and_decache(im_temp); + + if (opt.alpha) { + DATA8 atab[256]; + + D(3, ("Applying alpha options\n")); + gib_imlib_image_set_has_alpha(im_thumb, 1); + memset(atab, opt.alpha_level, sizeof(atab)); + gib_imlib_apply_color_modifier_to_rectangle + (im_thumb, 0, 0, www, hhh, NULL, NULL, NULL, atab); + } + + text_area_w = opt.thumb_w; + /* Now draw on the info text */ + if (opt.index_show_name) { + gib_imlib_get_text_size(fn, file->name, NULL, &fw_name, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw_name > text_area_w) + text_area_w = fw_name; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(fn, + create_index_dimension_string + (ww, hh), NULL, &fw_dim, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw_dim > text_area_w) + text_area_w = fw_dim; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(fn, + create_index_size_string + (file->filename), NULL, &fw_size, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw_size > text_area_w) + text_area_w = fw_size; + } + if (text_area_w > opt.thumb_w) + text_area_w += 5; + + /* offsets for centering text */ + x_offset_name = (text_area_w - fw_name) / 2; + x_offset_dim = (text_area_w - fw_dim) / 2; + x_offset_size = (text_area_w - fw_size) / 2; + + if (vertical) { + if (text_area_w > max_column_w) + max_column_w = text_area_w; + if (y > h - tot_thumb_h) { + y = 0; + x += max_column_w; + max_column_w = 0; + } + if (x > w - text_area_w) + break; + } else { + if (x > w - text_area_w) { + x = 0; + y += tot_thumb_h; + } + if (y > h - tot_thumb_h) + break; + } + + if (opt.aspect) { + xxx = x + ((opt.thumb_w - www) / 2); + yyy = y + ((opt.thumb_h - hhh) / 2); + } else { + /* Ignore the aspect ratio and squash the image in */ + xxx = x; + yyy = y; + } + + /* Draw now */ + gib_imlib_blend_image_onto_image(im_main, im_thumb, + gib_imlib_image_has_alpha + (im_thumb), 0, 0, + www, hhh, xxx, + yyy, www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0); + + gib_imlib_free_image_and_decache(im_thumb); + + lines = 0; + if (opt.index_show_name) + gib_imlib_text_draw(im_main, fn, NULL, + x + x_offset_name, + y + opt.thumb_h + + (lines++ * (th + 2)) + + 2, file->name, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + if (opt.index_show_dim) + gib_imlib_text_draw(im_main, fn, NULL, + x + x_offset_dim, + y + opt.thumb_h + + (lines++ * (th + 2)) + + 2, + create_index_dimension_string + (ww, hh), IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + if (opt.index_show_size) + gib_imlib_text_draw(im_main, fn, NULL, + x + x_offset_size, + y + opt.thumb_h + + (lines++ * (th + 2)) + + 2, + create_index_size_string + (file->filename), IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + + if (vertical) + y += tot_thumb_h; + else + x += text_area_w; + + } else { + if (opt.verbose) + feh_display_status('x'); + last = l; + } + if (opt.display) { + winwidget_render_image(winwid, 0, 0); + if (!feh_main_iteration(0)) + exit(0); + } + } + if (opt.verbose) + fprintf(stdout, "\n"); + + if (opt.title_font) { + int fw, fh, fx, fy; + char *s; + + s = create_index_title_string(thumbnailcount, w, h); + gib_imlib_get_text_size(title_fn, s, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + fx = (index_image_width - fw) >> 1; + fy = index_image_height - fh - 2; + gib_imlib_text_draw(im_main, title_fn, NULL, fx, fy, s, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + } + + if (opt.output && opt.output_file) { + char output_buf[1024]; + + if (opt.output_dir) + snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file); + else + strncpy(output_buf, opt.output_file, 1024); + + gib_imlib_save_image(im_main, output_buf); + if (opt.verbose) { + int tw, th; + + tw = gib_imlib_image_get_width(im_main); + th = gib_imlib_image_get_height(im_main); + fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf); + fprintf(stdout, + " - Image is %dx%d pixels and contains %d thumbnails\n", tw, th, thumbnailcount); + } + } + + if (!opt.display) + gib_imlib_free_image_and_decache(im_main); + + free(s); + D_RETURN_(3); } - -char * -chop_file_from_full_path(char *str) +char *chop_file_from_full_path(char *str) { - D_ENTER(4); - D_RETURN(4, strrchr(str, '/') + 1); + D_ENTER(4); + D_RETURN(4, strrchr(str, '/') + 1); } -static char * -create_index_size_string(char *file) +static char *create_index_size_string(char *file) { - static char str[50]; - int size = 0; - double kbs = 0.0; - struct stat st; - - D_ENTER(4); - if (stat(file, &st)) - kbs = 0.0; - else - { - size = st.st_size; - kbs = (double) size / 1000; - } - - snprintf(str, sizeof(str), "%.2fKb", kbs); - D_RETURN(4, str); + static char str[50]; + int size = 0; + double kbs = 0.0; + struct stat st; + + D_ENTER(4); + if (stat(file, &st)) + kbs = 0.0; + else { + size = st.st_size; + kbs = (double) size / 1000; + } + + snprintf(str, sizeof(str), "%.2fKb", kbs); + D_RETURN(4, str); } -static char * -create_index_dimension_string(int w, int h) +static char *create_index_dimension_string(int w, int h) { - static char str[50]; + static char str[50]; - D_ENTER(4); - snprintf(str, sizeof(str), "%dx%d", w, h); - D_RETURN(4, str); + D_ENTER(4); + snprintf(str, sizeof(str), "%dx%d", w, h); + D_RETURN(4, str); } -static char * -create_index_title_string(int num, int w, int h) +static char *create_index_title_string(int num, int w, int h) { - static char str[50]; + static char str[50]; - D_ENTER(4); - snprintf(str, sizeof(str), - PACKAGE " index - %d thumbnails, %d by %d pixels", num, w, h); - D_RETURN(4, str); + D_ENTER(4); + snprintf(str, sizeof(str), PACKAGE " index - %d thumbnails, %d by %d pixels", num, w, h); + D_RETURN(4, str); } @@ -31,14 +31,15 @@ static int session_id = 0; static char *socket_name; static int socket_fd = 0; -int feh_ipc_create_socket(void) { - struct sockaddr_un saddr; - int i; - - if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) { - for (i = 0; ; i++) { - saddr.sun_family = AF_UNIX; - snprintf(saddr.sun_path, 108, "%s/feh_%s.%d", feh_get_tmp_dir(), feh_get_user_name(), i); +int feh_ipc_create_socket(void) +{ + struct sockaddr_un saddr; + int i; + + if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) { + for (i = 0;; i++) { + saddr.sun_family = AF_UNIX; + snprintf(saddr.sun_path, 108, "%s/feh_%s.%d", feh_get_tmp_dir(), feh_get_user_name(), i); /* if (!feh_remote_is_running(i)) { if ((unlink(saddr.sun_path) == -1) && errno != ENOENT) { @@ -49,46 +50,49 @@ int feh_ipc_create_socket(void) { continue; } */ - if (bind(socket_fd, (struct sockaddr *) &saddr, sizeof(saddr)) != -1) { - session_id = i; - socket_name = estrdup(saddr.sun_path); - listen(socket_fd, 50); - break; - } else { - close(socket_fd); - eprintf("feh_ipc_create_socket: failed to bind %s to a socket:", saddr.sun_path); - } - } - } else { - eprintf("feh_ipc_create_socket: failed to open socket:"); - } + if (bind(socket_fd, (struct sockaddr *) &saddr, sizeof(saddr)) != -1) { + session_id = i; + socket_name = estrdup(saddr.sun_path); + listen(socket_fd, 50); + break; + } else { + close(socket_fd); + eprintf("feh_ipc_create_socket: failed to bind %s to a socket:", saddr.sun_path); + } + } + } else { + eprintf("feh_ipc_create_socket: failed to open socket:"); + } } -int feh_ipc_get_session_id(void) { - return session_id; +int feh_ipc_get_session_id(void) +{ + return session_id; } -void feh_ipc_cleanup(void) { - close(socket_fd); - unlink(socket_name); - free(socket_name); +void feh_ipc_cleanup(void) +{ + close(socket_fd); + unlink(socket_name); + free(socket_name); } -static void feh_ipc_write_packet(int fd, void *data, int length) { - feh_ipc_server_header header; - header.version = FEH_IPC_VERSION; - header.data_length = length; - if (data && length > 0) { - write(fd, data, length); - } +static void feh_ipc_write_packet(int fd, void *data, int length) +{ + feh_ipc_server_header header; + header.version = FEH_IPC_VERSION; + header.data_length = length; + if (data && length > 0) { + write(fd, data, length); + } } -static void feh_ipc_write_int(int fd, int val) { - feh_ipc_write_packet(fd, &val, sizeof(int)); +static void feh_ipc_write_int(int fd, int val) +{ + feh_ipc_write_packet(fd, &val, sizeof(int)); } -static void feh_ipc_write_string(int fd, char *string) { - feh_ipc_write_packet(fd, &string, string ? strlen(string) + 1 : 0); +static void feh_ipc_write_string(int fd, char *string) +{ + feh_ipc_write_packet(fd, &string, string ? strlen(string) + 1 : 0); } - - @@ -31,27 +31,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. int feh_ipc_create_socket(void); int feh_ipc_get_session_id(void); -typedef struct -{ - unsigned int version; - unsigned int command; - unsigned int data_length; -} -feh_ipc_client_header; - -typedef struct -{ - unsigned int version; - unsigned int data_length; -} -feh_ipc_server_header; +typedef struct { + unsigned int version; + unsigned int command; + unsigned int data_length; +} feh_ipc_client_header; + +typedef struct { + unsigned int version; + unsigned int data_length; +} feh_ipc_server_header; enum { - IPC_CMD_QUIT, - IPC_CMD_FILELIST_NEXT, - IPC_CMD_FILELIST_PREV, + IPC_CMD_QUIT, + IPC_CMD_FILELIST_NEXT, + IPC_CMD_FILELIST_PREV, }; #endif - - diff --git a/src/jpegint.h b/src/jpegint.h index 95b00d4..e55a2be 100644 --- a/src/jpegint.h +++ b/src/jpegint.h @@ -10,7 +10,6 @@ * applications using the library shouldn't need to include this file. */ - /* Declarations for both compression & decompression */ typedef enum { /* Operating modes for buffer controllers */ @@ -29,7 +28,7 @@ typedef enum { /* Operating modes for buffer controllers */ #define DSTATE_START 200 /* after create_decompress */ #define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ #define DSTATE_READY 202 /* found SOS, ready for start_decompress */ -#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ +#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress */ #define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ #define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ #define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ @@ -38,229 +37,210 @@ typedef enum { /* Operating modes for buffer controllers */ #define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ #define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ - /* Declarations for compression modules */ /* Master control module */ struct jpeg_comp_master { - JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); - JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); + JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); - /* State variables made visible to other modules */ - boolean call_pass_startup; /* True if pass_startup must be called */ - boolean is_last_pass; /* True during last pass */ + /* State variables made visible to other modules */ + boolean call_pass_startup; /* True if pass_startup must be called */ + boolean is_last_pass; /* True during last pass */ }; /* Main buffer control (downsampled-data buffer) */ struct jpeg_c_main_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail)); + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, + (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION * in_row_ctr, JDIMENSION in_rows_avail)); }; /* Compression preprocessing (downsampling input buffer control) */ struct jpeg_c_prep_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, - JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, - JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail)); + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, pre_process_data, + (j_compress_ptr cinfo, JSAMPARRAY input_buf, + JDIMENSION * in_row_ctr, JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION * out_row_group_ctr, JDIMENSION out_row_groups_avail)); }; /* Coefficient buffer control */ struct jpeg_c_coef_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf)); + JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, JSAMPIMAGE input_buf)); }; /* Colorspace conversion */ struct jpeg_color_converter { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, color_convert, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows)); + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, color_convert, (j_compress_ptr cinfo, + JSAMPARRAY input_buf, + JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)); }; /* Downsampling */ struct jpeg_downsampler { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, downsample, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_index, - JSAMPIMAGE output_buf, - JDIMENSION out_row_group_index)); + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, downsample, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION in_row_index, JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)); - boolean need_context_rows; /* TRUE if need rows above & below */ + boolean need_context_rows; /* TRUE if need rows above & below */ }; /* Forward DCT (also controls coefficient quantization) */ struct jpeg_forward_dct { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - /* perhaps this should be an array??? */ - JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, - jpeg_component_info * compptr, - JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks)); + JMETHOD(void, start_pass, (j_compress_ptr cinfo)); + /* perhaps this should be an array??? */ + JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, + jpeg_component_info * compptr, + JSAMPARRAY sample_data, + JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, JDIMENSION num_blocks)); }; /* Entropy encoding */ struct jpeg_entropy_encoder { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); - JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); + JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW * MCU_data)); + JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); }; /* Marker writing */ struct jpeg_marker_writer { - JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); - JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); - /* These routines are exported to allow insertion of extra markers */ - /* Probably only COM and APPn markers should be written this way */ - JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, - unsigned int datalen)); - JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); + JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); + JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); + JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); + /* These routines are exported to allow insertion of extra markers */ + /* Probably only COM and APPn markers should be written this way */ + JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, unsigned int datalen)); + JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); }; - /* Declarations for decompression modules */ /* Master control module */ struct jpeg_decomp_master { - JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); - /* State variables made visible to other modules */ - boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ + /* State variables made visible to other modules */ + boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ }; /* Input control module */ struct jpeg_input_controller { - JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); - JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean has_multiple_scans; /* True if file has multiple scans */ - boolean eoi_reached; /* True when EOI has been consumed */ + JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); + JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); + + /* State variables made visible to other modules */ + boolean has_multiple_scans; /* True if file has multiple scans */ + boolean eoi_reached; /* True when EOI has been consumed */ }; /* Main buffer control (downsampled-data buffer) */ struct jpeg_d_main_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, process_data, + (j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION * out_row_ctr, JDIMENSION out_rows_avail)); }; /* Coefficient buffer control */ struct jpeg_d_coef_controller { - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); - JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, - JSAMPIMAGE output_buf)); - /* Pointer to array of coefficient virtual arrays, or NULL if none */ - jvirt_barray_ptr *coef_arrays; + JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); + JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); + JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); + /* Pointer to array of coefficient virtual arrays, or NULL if none */ + jvirt_barray_ptr *coef_arrays; }; /* Decompression postprocessing (color quantization buffer control) */ struct jpeg_d_post_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); + JMETHOD(void, post_process_data, + (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, + JDIMENSION * in_row_group_ctr, + JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf, + JDIMENSION * out_row_ctr, JDIMENSION out_rows_avail)); }; /* Marker reading & parsing */ struct jpeg_marker_reader { - JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); - /* Read markers until SOS or EOI. - * Returns same codes as are defined for jpeg_consume_input: - * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - */ - JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); - /* Read a restart marker --- exported for use by entropy decoder only */ - jpeg_marker_parser_method read_restart_marker; - - /* State of marker reader --- nominally internal, but applications - * supplying COM or APPn handlers might like to know the state. - */ - boolean saw_SOI; /* found SOI? */ - boolean saw_SOF; /* found SOF? */ - int next_restart_num; /* next restart number expected (0-7) */ - unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ + JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); + /* Read markers until SOS or EOI. + * Returns same codes as are defined for jpeg_consume_input: + * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. + */ + JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); + /* Read a restart marker --- exported for use by entropy decoder only */ + jpeg_marker_parser_method read_restart_marker; + + /* State of marker reader --- nominally internal, but applications + * supplying COM or APPn handlers might like to know the state. + */ + boolean saw_SOI; /* found SOI? */ + boolean saw_SOF; /* found SOF? */ + int next_restart_num; /* next restart number expected (0-7) */ + unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ }; /* Entropy decoding */ struct jpeg_entropy_decoder { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKROW * MCU_data)); - /* This is here to share code between baseline and progressive decoders; */ - /* other modules probably should not use it */ - boolean insufficient_data; /* set TRUE after emitting warning */ + /* This is here to share code between baseline and progressive decoders; */ + /* other modules probably should not use it */ + boolean insufficient_data; /* set TRUE after emitting warning */ }; /* Inverse DCT (also performs dequantization) */ typedef JMETHOD(void, inverse_DCT_method_ptr, (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col)); + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); struct jpeg_inverse_dct { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - /* It is useful to allow each component to have a separate IDCT method. */ - inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + /* It is useful to allow each component to have a separate IDCT method. */ + inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; }; /* Upsampling (note that upsampler must also call color converter) */ struct jpeg_upsampler { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, upsample, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); - - boolean need_context_rows; /* TRUE if need rows above & below */ + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, upsample, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION * in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, JDIMENSION * out_row_ctr, JDIMENSION out_rows_avail)); + + boolean need_context_rows; /* TRUE if need rows above & below */ }; /* Colorspace conversion */ struct jpeg_color_deconverter { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, color_convert, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows)); + JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, color_convert, (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, + JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows)); }; /* Color quantization or color precision reduction */ struct jpeg_color_quantizer { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); - JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, - int num_rows)); - JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); + JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); + JMETHOD(void, color_quantize, + (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)); + JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); }; - /* Miscellaneous useful macros */ #undef MAX @@ -268,7 +248,6 @@ struct jpeg_color_quantizer { #undef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) - /* We assume that right shift corresponds to signed division by 2 with * rounding towards minus infinity. This is correct for typical "arithmetic * shift" instructions that shift in copies of the sign bit. But some @@ -290,7 +269,6 @@ struct jpeg_color_quantizer { #define RIGHT_SHIFT(x,shft) ((x) >> (shft)) #endif - /* Short forms of external names for systems with brain-damaged linkers. */ #ifdef NEED_SHORT_EXTERNAL_NAMES @@ -327,66 +305,84 @@ struct jpeg_color_quantizer { #define jzero_far jZeroFar #define jpeg_zigzag_order jZIGTable #define jpeg_natural_order jZAGTable -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - +#endif /* NEED_SHORT_EXTERNAL_NAMES */ /* Compression module initialization routines */ -EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, - boolean transcode_only)); -EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); +EXTERN(void) +jinit_compress_master JPP((j_compress_ptr cinfo)); +EXTERN(void) +jinit_c_master_control JPP((j_compress_ptr cinfo, boolean transcode_only)); +EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, boolean need_full_buffer)); +EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, boolean need_full_buffer)); +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, boolean need_full_buffer)); +EXTERN(void) +jinit_color_converter JPP((j_compress_ptr cinfo)); +EXTERN(void) +jinit_downsampler JPP((j_compress_ptr cinfo)); +EXTERN(void) +jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN(void) +jinit_huff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) +jinit_phuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) +jinit_marker_writer JPP((j_compress_ptr cinfo)); /* Decompression module initialization routines */ -EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_master_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, boolean need_full_buffer)); +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, boolean need_full_buffer)); +EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, boolean need_full_buffer)); +EXTERN(void) +jinit_input_controller JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_marker_reader JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_huff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_upsampler JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_color_deconverter JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); +EXTERN(void) +jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); /* Memory manager initialization */ -EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); +EXTERN(void) +jinit_memory_mgr JPP((j_common_ptr cinfo)); /* Utility routines in jutils.c */ -EXTERN(long) jdiv_round_up JPP((long a, long b)); -EXTERN(long) jround_up JPP((long a, long b)); -EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols)); -EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks)); -EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); +EXTERN(long) +jdiv_round_up JPP((long a, long b)); +EXTERN(long) +jround_up JPP((long a, long b)); +EXTERN(void) +jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, + JSAMPARRAY output_array, int dest_row, int num_rows, JDIMENSION num_cols)); +EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, JDIMENSION num_blocks)); +EXTERN(void) +jzero_far JPP((void FAR * target, size_t bytestozero)); /* Constant tables in jutils.c */ #if 0 /* This table is not actually needed in v6a */ -extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ +extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ #endif -extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ +extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ /* Suppress undefined-structure complaints if necessary. */ #ifdef INCOMPLETE_TYPES_BROKEN #ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ -struct jvirt_sarray_control { long dummy; }; -struct jvirt_barray_control { long dummy; }; +struct jvirt_sarray_control { + long dummy; +}; +struct jvirt_barray_control { + long dummy; +}; #endif -#endif /* INCOMPLETE_TYPES_BROKEN */ +#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/src/keyevents.c b/src/keyevents.c index 85f2fdb..5171c51 100644 --- a/src/keyevents.c +++ b/src/keyevents.c @@ -29,419 +29,404 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "winwidget.h" #include "options.h" -void -feh_event_invoke_action(winwidget winwid, char *action) +void feh_event_invoke_action(winwidget winwid, char *action) { - D_ENTER(4); - D(4, ("action is '%s'\n", action)); - D(4, ("winwid is '%p'\n", winwid)); - if (action) - { - if (opt.slideshow) - { - feh_action_run(FEH_FILE(winwid->file->data),action); - slideshow_change_image(winwid, SLIDE_NEXT); - } - else if ((winwid->type == WIN_TYPE_SINGLE) - || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) - { - feh_action_run(FEH_FILE(winwid->file->data),action); - winwidget_destroy(winwid); - } - else if (winwid->type == WIN_TYPE_THUMBNAIL) - { - printf("actions from the main thumb window aren't currentl supported!\n"); - printf("For now, open the image to perform the action on it.\n"); - } - } - D_RETURN_(4); + D_ENTER(4); + D(4, ("action is '%s'\n", action)); + D(4, ("winwid is '%p'\n", winwid)); + if (action) { + if (opt.slideshow) { + feh_action_run(FEH_FILE(winwid->file->data), action); + slideshow_change_image(winwid, SLIDE_NEXT); + } else if ((winwid->type == WIN_TYPE_SINGLE) + || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) { + feh_action_run(FEH_FILE(winwid->file->data), action); + winwidget_destroy(winwid); + } else if (winwid->type == WIN_TYPE_THUMBNAIL) { + printf("actions from the main thumb window aren't currentl supported!\n"); + printf("For now, open the image to perform the action on it.\n"); + } + } + D_RETURN_(4); } -void -feh_event_handle_keypress(XEvent * ev) +void feh_event_handle_keypress(XEvent * ev) { - int len; - char kbuf[20]; - KeySym keysym; - XKeyEvent *kev; - winwidget winwid = NULL; - int curr_screen = 0; - feh_menu_item *selected_item; - feh_menu *selected_menu; + int len; + char kbuf[20]; + KeySym keysym; + XKeyEvent *kev; + winwidget winwid = NULL; + int curr_screen = 0; + feh_menu_item *selected_item; + feh_menu *selected_menu; - D_ENTER(4); + D_ENTER(4); - winwid = winwidget_get_from_window(ev->xkey.window); - - /* nuke dupe events, unless we're typing text */ - if (winwid && !winwid->caption_entry) { - while (XCheckTypedWindowEvent(disp, ev->xkey.window, KeyPress, ev)); - } + winwid = winwidget_get_from_window(ev->xkey.window); - kev = (XKeyEvent *) ev; - len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL); + /* nuke dupe events, unless we're typing text */ + if (winwid && !winwid->caption_entry) { + while (XCheckTypedWindowEvent(disp, ev->xkey.window, KeyPress, ev)); + } - /* menus are showing, so this is a menu control keypress */ - if (ev->xbutton.window == menu_cover) { - selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); - switch (keysym) { - case XK_Escape: - feh_menu_hide(menu_root, True); - break; - case XK_Left: - feh_menu_select_parent(selected_menu, selected_item); - break; - case XK_Down: - feh_menu_select_next(selected_menu, selected_item); - break; - case XK_Up: - feh_menu_select_prev(selected_menu, selected_item); - break; - case XK_Right: - feh_menu_select_submenu(selected_menu, selected_item); - break; - case XK_Return: - feh_menu_item_activate(selected_menu, selected_item); - break; - default: - break; - } - if (len <= 0 || len > (int) sizeof(kbuf)) - D_RETURN_(4); - kbuf[len] = '\0'; + kev = (XKeyEvent *) ev; + len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL); - switch (*kbuf) - { - case 'h': - feh_menu_select_parent(selected_menu, selected_item); - break; - case 'j': - feh_menu_select_next(selected_menu, selected_item); - break; - case 'k': - feh_menu_select_prev(selected_menu, selected_item); - break; - case 'l': - feh_menu_select_submenu(selected_menu, selected_item); - break; - case ' ': - feh_menu_item_activate(selected_menu, selected_item); - break; - default: - break; - } - - D_RETURN_(4); - } + /* menus are showing, so this is a menu control keypress */ + if (ev->xbutton.window == menu_cover) { + selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); + switch (keysym) { + case XK_Escape: + feh_menu_hide(menu_root, True); + break; + case XK_Left: + feh_menu_select_parent(selected_menu, selected_item); + break; + case XK_Down: + feh_menu_select_next(selected_menu, selected_item); + break; + case XK_Up: + feh_menu_select_prev(selected_menu, selected_item); + break; + case XK_Right: + feh_menu_select_submenu(selected_menu, selected_item); + break; + case XK_Return: + feh_menu_item_activate(selected_menu, selected_item); + break; + default: + break; + } + if (len <= 0 || len > (int) sizeof(kbuf)) + D_RETURN_(4); + kbuf[len] = '\0'; - if (winwid == NULL) - D_RETURN_(4); + switch (*kbuf) { + case 'h': + feh_menu_select_parent(selected_menu, selected_item); + break; + case 'j': + feh_menu_select_next(selected_menu, selected_item); + break; + case 'k': + feh_menu_select_prev(selected_menu, selected_item); + break; + case 'l': + feh_menu_select_submenu(selected_menu, selected_item); + break; + case ' ': + feh_menu_item_activate(selected_menu, selected_item); + break; + default: + break; + } - if (winwid->caption_entry) { - switch(keysym) { - case XK_Return: - if (kev->state & ControlMask) { - /* insert actual newline */ - ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n"); - winwidget_render_image_cached(winwid); - } else { - /* finish caption entry, write to captions file */ - FILE *fp; - char *caption_filename; - caption_filename = build_caption_filename(FEH_FILE(winwid->file->data)); - winwid->caption_entry = 0; - winwidget_render_image_cached(winwid); - XFreePixmap(disp, winwid->bg_pmap_cache); - winwid->bg_pmap_cache = 0; - fp = fopen(caption_filename, "w"); - if (!fp) { - weprintf("couldn't write to captions file %s:", caption_filename); - D_RETURN_(4); - } - fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption); - free(caption_filename); - fclose(fp); - } - break; - case XK_Escape: - /* cancel, revert caption */ - winwid->caption_entry = 0; - free(FEH_FILE(winwid->file->data)->caption); - FEH_FILE(winwid->file->data)->caption = NULL; - winwidget_render_image_cached(winwid); - XFreePixmap(disp, winwid->bg_pmap_cache); - winwid->bg_pmap_cache = 0; - break; - case XK_BackSpace: - /* backspace */ - ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1); - winwidget_render_image_cached(winwid); - break; - default: - if(isascii(keysym)) { - /* append to caption */ - ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym); - winwidget_render_image_cached(winwid); - } - break; - } - D_RETURN_(4); - } - - - switch (keysym) - { - case XK_Left: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_PREV); - break; - case XK_Right: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_NEXT); - break; - case XK_Page_Up: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_JUMP_BACK); - break; - case XK_Escape: - winwidget_destroy_all(); - break; - case XK_Page_Down: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_JUMP_FWD); - break; - case XK_Delete: - /* Holding ctrl gets you a filesystem deletion and removal from the * - filelist. Just DEL gets you filelist removal only. */ - if (kev->state & ControlMask) - { - if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) - feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1); - feh_filelist_image_remove(winwid, 1); - } - else - { - if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) - feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0); - feh_filelist_image_remove(winwid, 0); - } - break; - case XK_Home: - case XK_KP_Home: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_FIRST); - break; - case XK_End: - case XK_KP_End: - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_LAST); - break; - case XK_Return: - feh_event_invoke_action(winwid,opt.actions[0]); - break; - case XK_0: - feh_event_invoke_action(winwid,opt.actions[0]); - break; - case XK_1: - feh_event_invoke_action(winwid,opt.actions[1]); - break; - case XK_2: - feh_event_invoke_action(winwid,opt.actions[2]); - break; - case XK_3: - feh_event_invoke_action(winwid,opt.actions[3]); - break; - case XK_4: - feh_event_invoke_action(winwid,opt.actions[4]); - break; - case XK_5: - feh_event_invoke_action(winwid,opt.actions[5]); - break; - case XK_6: - feh_event_invoke_action(winwid,opt.actions[6]); - break; - case XK_7: - feh_event_invoke_action(winwid,opt.actions[7]); - break; - case XK_8: - feh_event_invoke_action(winwid,opt.actions[8]); - break; - case XK_9: - feh_event_invoke_action(winwid,opt.actions[9]); - break; - case XK_KP_Left: - winwid->im_x = winwid->im_x - 10; - winwidget_render_image(winwid, 0, 0); - break; - case XK_KP_Right: - winwid->im_x = winwid->im_x + 10; - winwidget_render_image(winwid, 0, 0); - break; - case XK_KP_Up: - winwid->im_y = winwid->im_y - 10; - winwidget_render_image(winwid, 0, 0); - break; - case XK_KP_Down: - winwid->im_y = winwid->im_y + 10; - winwidget_render_image(winwid, 0, 0); - break; - case XK_KP_Add: - /* erroneously recognized as '+' in the *kbuf switch. Work around this. */ - len = 0; - winwid->zoom = winwid->zoom * 1.25; - winwidget_render_image(winwid, 0, 0); - break; - case XK_KP_Subtract: - len = 0; - winwid->zoom = winwid->zoom * 0.75; - winwidget_render_image(winwid, 0, 0); - break; - case XK_KP_Multiply: - len = 0; - winwid->zoom = 1; - winwidget_render_image(winwid, 0, 0); - break; - case XK_KP_Divide: - len = 0; - feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); - winwidget_render_image(winwid, 0, 1); - break; - case XK_KP_Begin: - winwidget_render_image(winwid, 0, 1); - break; - default: - break; - } + D_RETURN_(4); + } - if (len <= 0 || len > (int) sizeof(kbuf)) - D_RETURN_(4); - kbuf[len] = '\0'; + if (winwid == NULL) + D_RETURN_(4); - switch (*kbuf) - { - case 'a': - case 'A': - opt.draw_actions = !opt.draw_actions; - winwidget_rerender_all(0, 1); - break; - case 'd': - case 'D': - opt.draw_filename = !opt.draw_filename; - winwidget_rerender_all(0, 1); - break; - case 'n': - case 'N': - case ' ': - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_NEXT); - break; - case 'p': - case 'P': - case '\b': - if (opt.slideshow) - slideshow_change_image(winwid, SLIDE_PREV); - break; - case 'q': - case 'Q': - winwidget_destroy_all(); - break; - case 'c': - case 'C': - if (opt.caption_path) - winwid->caption_entry = 1; - winwidget_render_image(winwid, 0, 1); - break; - case 'r': - case 'R': - feh_reload_image(winwid, 0, 0); - break; - case 'h': - case 'H': - slideshow_pause_toggle(winwid); - break; - case 's': - case 'S': - slideshow_save_image(winwid); - break; - case 'f': - case 'F': - feh_save_filelist(); - break; - case 'w': - case 'W': - winwidget_size_to_image(winwid); - break; - case 'm': - case 'M': - winwidget_show_menu(winwid); - break; - case 'x': - case 'X': - winwidget_destroy(winwid); - break; - case '>': - feh_edit_inplace_orient(winwid, 1); - break; - case '<': - feh_edit_inplace_orient(winwid, 3); - break; - case 'v': - case 'V': + if (winwid->caption_entry) { + switch (keysym) { + case XK_Return: + if (kev->state & ControlMask) { + /* insert actual newline */ + ESTRAPPEND(FEH_FILE(winwid->file->data)->caption, "\n"); + winwidget_render_image_cached(winwid); + } else { + /* finish caption entry, write to captions file */ + FILE *fp; + char *caption_filename; + caption_filename = build_caption_filename(FEH_FILE(winwid->file->data)); + winwid->caption_entry = 0; + winwidget_render_image_cached(winwid); + XFreePixmap(disp, winwid->bg_pmap_cache); + winwid->bg_pmap_cache = 0; + fp = fopen(caption_filename, "w"); + if (!fp) { + weprintf("couldn't write to captions file %s:", caption_filename); + D_RETURN_(4); + } + fprintf(fp, "%s", FEH_FILE(winwid->file->data)->caption); + free(caption_filename); + fclose(fp); + } + break; + case XK_Escape: + /* cancel, revert caption */ + winwid->caption_entry = 0; + free(FEH_FILE(winwid->file->data)->caption); + FEH_FILE(winwid->file->data)->caption = NULL; + winwidget_render_image_cached(winwid); + XFreePixmap(disp, winwid->bg_pmap_cache); + winwid->bg_pmap_cache = 0; + break; + case XK_BackSpace: + /* backspace */ + ESTRTRUNC(FEH_FILE(winwid->file->data)->caption, 1); + winwidget_render_image_cached(winwid); + break; + default: + if (isascii(keysym)) { + /* append to caption */ + ESTRAPPEND_CHAR(FEH_FILE(winwid->file->data)->caption, keysym); + winwidget_render_image_cached(winwid); + } + break; + } + D_RETURN_(4); + } + + switch (keysym) { + case XK_Left: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_PREV); + break; + case XK_Right: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_NEXT); + break; + case XK_Page_Up: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_JUMP_BACK); + break; + case XK_Escape: + winwidget_destroy_all(); + break; + case XK_Page_Down: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_JUMP_FWD); + break; + case XK_Delete: + /* Holding ctrl gets you a filesystem deletion and removal from the * + filelist. Just DEL gets you filelist removal only. */ + if (kev->state & ControlMask) { + if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) + feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 1); + feh_filelist_image_remove(winwid, 1); + } else { + if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) + feh_thumbnail_mark_removed(FEH_FILE(winwid->file->data), 0); + feh_filelist_image_remove(winwid, 0); + } + break; + case XK_Home: + case XK_KP_Home: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_FIRST); + break; + case XK_End: + case XK_KP_End: + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_LAST); + break; + case XK_Return: + feh_event_invoke_action(winwid, opt.actions[0]); + break; + case XK_0: + feh_event_invoke_action(winwid, opt.actions[0]); + break; + case XK_1: + feh_event_invoke_action(winwid, opt.actions[1]); + break; + case XK_2: + feh_event_invoke_action(winwid, opt.actions[2]); + break; + case XK_3: + feh_event_invoke_action(winwid, opt.actions[3]); + break; + case XK_4: + feh_event_invoke_action(winwid, opt.actions[4]); + break; + case XK_5: + feh_event_invoke_action(winwid, opt.actions[5]); + break; + case XK_6: + feh_event_invoke_action(winwid, opt.actions[6]); + break; + case XK_7: + feh_event_invoke_action(winwid, opt.actions[7]); + break; + case XK_8: + feh_event_invoke_action(winwid, opt.actions[8]); + break; + case XK_9: + feh_event_invoke_action(winwid, opt.actions[9]); + break; + case XK_KP_Left: + winwid->im_x = winwid->im_x - 10; + winwidget_render_image(winwid, 0, 0); + break; + case XK_KP_Right: + winwid->im_x = winwid->im_x + 10; + winwidget_render_image(winwid, 0, 0); + break; + case XK_KP_Up: + winwid->im_y = winwid->im_y - 10; + winwidget_render_image(winwid, 0, 0); + break; + case XK_KP_Down: + winwid->im_y = winwid->im_y + 10; + winwidget_render_image(winwid, 0, 0); + break; + case XK_KP_Add: + /* erroneously recognized as '+' in the *kbuf switch. Work around this. */ + len = 0; + winwid->zoom = winwid->zoom * 1.25; + winwidget_render_image(winwid, 0, 0); + break; + case XK_KP_Subtract: + len = 0; + winwid->zoom = winwid->zoom * 0.75; + winwidget_render_image(winwid, 0, 0); + break; + case XK_KP_Multiply: + len = 0; + winwid->zoom = 1; + winwidget_render_image(winwid, 0, 0); + break; + case XK_KP_Divide: + len = 0; + feh_calc_needed_zoom(&winwid->zoom, winwid->im_w, winwid->im_h, winwid->w, winwid->h); + winwidget_render_image(winwid, 0, 1); + break; + case XK_KP_Begin: + winwidget_render_image(winwid, 0, 1); + break; + default: + break; + } + + if (len <= 0 || len > (int) sizeof(kbuf)) + D_RETURN_(4); + kbuf[len] = '\0'; + + switch (*kbuf) { + case 'a': + case 'A': + opt.draw_actions = !opt.draw_actions; + winwidget_rerender_all(0, 1); + break; + case 'd': + case 'D': + opt.draw_filename = !opt.draw_filename; + winwidget_rerender_all(0, 1); + break; + case 'n': + case 'N': + case ' ': + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_NEXT); + break; + case 'p': + case 'P': + case '\b': + if (opt.slideshow) + slideshow_change_image(winwid, SLIDE_PREV); + break; + case 'q': + case 'Q': + winwidget_destroy_all(); + break; + case 'c': + case 'C': + if (opt.caption_path) + winwid->caption_entry = 1; + winwidget_render_image(winwid, 0, 1); + break; + case 'r': + case 'R': + feh_reload_image(winwid, 0, 0); + break; + case 'h': + case 'H': + slideshow_pause_toggle(winwid); + break; + case 's': + case 'S': + slideshow_save_image(winwid); + break; + case 'f': + case 'F': + feh_save_filelist(); + break; + case 'w': + case 'W': + winwidget_size_to_image(winwid); + break; + case 'm': + case 'M': + winwidget_show_menu(winwid); + break; + case 'x': + case 'X': + winwidget_destroy(winwid); + break; + case '>': + feh_edit_inplace_orient(winwid, 1); + break; + case '<': + feh_edit_inplace_orient(winwid, 3); + break; + case 'v': + case 'V': #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - int i, rect[4]; + if (opt.xinerama && xinerama_screens) { + int i, rect[4]; - winwidget_get_geometry(winwid, rect); - /* printf("window: (%d, %d)\n", rect[0], rect[1]); - printf("found %d screens.\n", num_xinerama_screens); */ - for (i = 0; i < num_xinerama_screens; i++) { - xinerama_screen = 0; - /* printf("%d: [%d, %d, %d, %d] (%d, %d)\n", - i, - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height, - rect[0], rect[1]);*/ - if (XY_IN_RECT(rect[0], rect[1], - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height)) { - curr_screen = xinerama_screen = i; - break; - } - } - } -#endif /* HAVE_LIBXINERAMA */ - winwid->full_screen = !winwid->full_screen; - winwidget_destroy_xwin(winwid); - winwidget_create_window(winwid, winwid->im_w, winwid->im_h); - winwidget_render_image(winwid, 1, 1); - winwidget_show(winwid); + winwidget_get_geometry(winwid, rect); + /* printf("window: (%d, %d)\n", rect[0], rect[1]); + printf("found %d screens.\n", num_xinerama_screens); */ + for (i = 0; i < num_xinerama_screens; i++) { + xinerama_screen = 0; + /* printf("%d: [%d, %d, %d, %d] (%d, %d)\n", + i, + xinerama_screens[i].x_org, xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height, + rect[0], rect[1]); */ + if (XY_IN_RECT(rect[0], rect[1], + xinerama_screens[i].x_org, + xinerama_screens[i].y_org, + xinerama_screens[i].width, + xinerama_screens[i].height)) { + curr_screen = xinerama_screen = i; + break; + } + } + } +#endif /* HAVE_LIBXINERAMA */ + winwid->full_screen = !winwid->full_screen; + winwidget_destroy_xwin(winwid); + winwidget_create_window(winwid, winwid->im_w, winwid->im_h); + winwidget_render_image(winwid, 1, 1); + winwidget_show(winwid); #ifdef HAVE_LIBXINERAMA - /* if we have xinerama and we're using it, then full screen the window - * on the head that the window was active on */ - if (winwid->full_screen == TRUE && - opt.xinerama && xinerama_screens) { - xinerama_screen = curr_screen; - winwidget_move(winwid, - xinerama_screens[curr_screen].x_org, - xinerama_screens[curr_screen].y_org); - } -#endif /* HAVE_LIBXINERAMA */ - case '=': - case '+': - if (opt.reload < SLIDESHOW_RELOAD_MAX) - opt.reload++; - else if (opt.verbose) - weprintf("Cannot set RELOAD higher than %d seconds.", opt.reload); - break; - case '-': - case '_': - if (opt.reload > 1) - opt.reload--; - else if (opt.verbose) - weprintf("Cannot set RELOAD lower than 1 second."); - break; - default: - break; - } - D_RETURN_(4); + /* if we have xinerama and we're using it, then full screen the window + * on the head that the window was active on */ + if (winwid->full_screen == TRUE && opt.xinerama && xinerama_screens) { + xinerama_screen = curr_screen; + winwidget_move(winwid, + xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org); + } +#endif /* HAVE_LIBXINERAMA */ + case '=': + case '+': + if (opt.reload < SLIDESHOW_RELOAD_MAX) + opt.reload++; + else if (opt.verbose) + weprintf("Cannot set RELOAD higher than %d seconds.", opt.reload); + break; + case '-': + case '_': + if (opt.reload > 1) + opt.reload--; + else if (opt.verbose) + weprintf("Cannot set RELOAD lower than 1 second."); + break; + default: + break; + } + D_RETURN_(4); } @@ -27,90 +27,78 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "filelist.h" #include "options.h" -void -init_list_mode(void) +void init_list_mode(void) { - gib_list *l; - feh_file *file = NULL; - int j = 0; - - D_ENTER(4); - - mode = "list"; - - if (!opt.customlist) - printf - ("NUM\tFORMAT\tWIDTH\tHEIGHT\tPIXELS\tSIZE(bytes)\tALPHA\tFILENAME\n"); - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - if (opt.customlist) - printf("%s\n", feh_printf(opt.customlist, file)); - else - printf("%d\t%s\t%d\t%d\t%d\t%d\t\t%c\t%s\n", ++j, file->info->format, - file->info->width, file->info->height, file->info->pixels, - file->info->size, file->info->has_alpha ? 'X' : '-', - file->filename); - - feh_action_run(file,opt.actions[0]); - } - exit(0); + gib_list *l; + feh_file *file = NULL; + int j = 0; + + D_ENTER(4); + + mode = "list"; + + if (!opt.customlist) + printf("NUM\tFORMAT\tWIDTH\tHEIGHT\tPIXELS\tSIZE(bytes)\tALPHA\tFILENAME\n"); + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + if (opt.customlist) + printf("%s\n", feh_printf(opt.customlist, file)); + else + printf("%d\t%s\t%d\t%d\t%d\t%d\t\t%c\t%s\n", ++j, + file->info->format, file->info->width, + file->info->height, file->info->pixels, + file->info->size, + file->info->has_alpha ? 'X' : '-', file->filename); + + feh_action_run(file, opt.actions[0]); + } + exit(0); } -void -init_loadables_mode(void) +void init_loadables_mode(void) { - D_ENTER(4); - mode = "loadables"; - real_loadables_mode(1); - D_RETURN_(4); + D_ENTER(4); + mode = "loadables"; + real_loadables_mode(1); + D_RETURN_(4); } -void -init_unloadables_mode(void) +void init_unloadables_mode(void) { - D_ENTER(4); - mode = "unloadables"; - real_loadables_mode(0); - D_RETURN_(4); + D_ENTER(4); + mode = "unloadables"; + real_loadables_mode(0); + D_RETURN_(4); } - -void -real_loadables_mode(int loadable) +void real_loadables_mode(int loadable) { - feh_file *file; - gib_list *l; - - D_ENTER(4); - opt.quiet = 1; - - for (l = filelist; l; l = l->next) - { - Imlib_Image im = NULL; - - file = FEH_FILE(l->data); - - if (feh_load_image(&im, file)) - { - /* loaded ok */ - if (loadable) - { - fprintf(stdout, "%s\n", file->filename); - feh_action_run(file,opt.actions[0]); - } - gib_imlib_free_image_and_decache(im); - } - else - { - /* Oh dear. */ - if (!loadable) - { - fprintf(stdout, "%s\n", file->filename); - feh_action_run(file,opt.actions[0]); - } - } - } - exit(0); + feh_file *file; + gib_list *l; + + D_ENTER(4); + opt.quiet = 1; + + for (l = filelist; l; l = l->next) { + Imlib_Image im = NULL; + + file = FEH_FILE(l->data); + + if (feh_load_image(&im, file)) { + /* loaded ok */ + if (loadable) { + fprintf(stdout, "%s\n", file->filename); + feh_action_run(file, opt.actions[0]); + } + gib_imlib_free_image_and_decache(im); + } else { + /* Oh dear. */ + if (!loadable) { + fprintf(stdout, "%s\n", file->filename); + feh_action_run(file, opt.actions[0]); + } + } + } + exit(0); } @@ -36,40 +36,38 @@ int cmdargc = 0; int call_level = 0; char *mode = NULL; -int -main(int argc, char **argv) +int main(int argc, char **argv) { - D_ENTER(4); - atexit(feh_clean_exit); - - init_parse_options(argc, argv); - - init_imlib_fonts(); - - if (opt.display) - init_x_and_imlib(); - - feh_event_init(); - - if (opt.index) - init_index_mode(); - else if (opt.collage) - init_collage_mode(); - else if (opt.multiwindow) - init_multiwindow_mode(); - else if (opt.list || opt.customlist) - init_list_mode(); - else if (opt.loadables) - init_loadables_mode(); - else if (opt.unloadables) - init_unloadables_mode(); - else if (opt.thumbs) - init_thumbnail_mode(); - else if(opt.bgmode) - { - feh_wm_set_bg_file(opt.output_file, opt.bgmode); - exit(0); - } + D_ENTER(4); + atexit(feh_clean_exit); + + init_parse_options(argc, argv); + + init_imlib_fonts(); + + if (opt.display) + init_x_and_imlib(); + + feh_event_init(); + + if (opt.index) + init_index_mode(); + else if (opt.collage) + init_collage_mode(); + else if (opt.multiwindow) + init_multiwindow_mode(); + else if (opt.list || opt.customlist) + init_list_mode(); + else if (opt.loadables) + init_loadables_mode(); + else if (opt.unloadables) + init_unloadables_mode(); + else if (opt.thumbs) + init_thumbnail_mode(); + else if (opt.bgmode) { + feh_wm_set_bg_file(opt.output_file, opt.bgmode); + exit(0); + } /* else if (opt.fmmode) { fmmode(); @@ -77,146 +75,132 @@ main(int argc, char **argv) init_slideshow_mode(); } */ - else - { - /* Slideshow mode is the default. Because it's spiffy */ - opt.slideshow = 1; - init_slideshow_mode(); - } + else { + /* Slideshow mode is the default. Because it's spiffy */ + opt.slideshow = 1; + init_slideshow_mode(); + } - /* main event loop */ - while (feh_main_iteration(1)); + /* main event loop */ + while (feh_main_iteration(1)); - D_RETURN(4,0); + D_RETURN(4, 0); } - /* Return 0 to stop iterating, 1 if ok to continue. */ -int -feh_main_iteration(int block) +int feh_main_iteration(int block) { - static int first = 1; - static int xfd = 0; - static int fdsize = 0; - static double pt = 0.0; - XEvent ev; - struct timeval tval; - fd_set fdset; - int count = 0; - double t1 = 0.0, t2 = 0.0; - fehtimer ft; - - D_ENTER(5); - - if (window_num == 0) - D_RETURN(5,0); - - if (first) - { - /* Only need to set these up the first time */ - xfd = ConnectionNumber(disp); - fdsize = xfd + 1; - pt = feh_get_time(); - first = 0; - } - - /* Timers */ - t1 = feh_get_time(); - t2 = t1 - pt; - pt = t1; - while (XPending(disp)) - { - XNextEvent(disp, &ev); - if (ev_handler[ev.type]) - (*(ev_handler[ev.type])) (&ev); - - if (window_num == 0) - D_RETURN(5,0); - } - XFlush(disp); - - feh_redraw_menus(); - - FD_ZERO(&fdset); - FD_SET(xfd, &fdset); - - /* Timers */ - ft = first_timer; - /* Don't do timers if we're zooming/panning/etc or if we are paused*/ - if (ft && (opt.mode == MODE_NORMAL) && !opt.paused) - { - D(5,("There are timers in the queue\n")); - if (ft->just_added) - { - D(5,("The first timer has just been added\n")); - D(5,("ft->in = %f\n", ft->in)); - ft->just_added = 0; - t1 = ft->in; - } - else - { - D(5,("The first timer was not just added\n")); - t1 = ft->in - t2; - if (t1 < 0.0) - t1 = 0.0; - ft->in = t1; - } - - XSync(disp, False); - D(5,("I next need to action a timer in %f seconds\n", t1)); - /* Only do a blocking select if there's a timer due, or no events - waiting */ - if (t1 == 0.0 || (block && !XPending(disp))) - { - tval.tv_sec = (long) t1; - tval.tv_usec = (long) ((t1 - ((double) tval.tv_sec)) * 1000000); - if (tval.tv_sec < 0) - tval.tv_sec = 0; - if (tval.tv_usec <= 1000) - tval.tv_usec = 1000; - errno = 0; - D(5,("Performing blocking select - waiting for timer or event\n")); - count = select(fdsize, &fdset, NULL, NULL, &tval); - if ((count < 0) - && ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) - eprintf("Connection to X display lost"); - if ((ft) && (count == 0)) - { - /* This means the timer is due to be executed. If count was > 0, - that would mean an X event had woken us, we're not interested - in that */ - feh_handle_timer(); - } - } - } - else - { - /* Don't block if there are events in the queue. That's a bit rude ;-) */ - if (block && !XPending(disp)) - { - errno = 0; - D(5,("Performing blocking select - no timers, or zooming\n")); - count = select(fdsize, &fdset, NULL, NULL, NULL); - if ((count < 0) - && ((errno == ENOMEM) || (errno == EINVAL) || (errno == EBADF))) - eprintf("Connection to X display lost"); - } - } - if (window_num == 0) - D_RETURN(5,0); - D_RETURN(5,1); + static int first = 1; + static int xfd = 0; + static int fdsize = 0; + static double pt = 0.0; + XEvent ev; + struct timeval tval; + fd_set fdset; + int count = 0; + double t1 = 0.0, t2 = 0.0; + fehtimer ft; + + D_ENTER(5); + + if (window_num == 0) + D_RETURN(5, 0); + + if (first) { + /* Only need to set these up the first time */ + xfd = ConnectionNumber(disp); + fdsize = xfd + 1; + pt = feh_get_time(); + first = 0; + } + + /* Timers */ + t1 = feh_get_time(); + t2 = t1 - pt; + pt = t1; + while (XPending(disp)) { + XNextEvent(disp, &ev); + if (ev_handler[ev.type]) + (*(ev_handler[ev.type])) (&ev); + + if (window_num == 0) + D_RETURN(5, 0); + } + XFlush(disp); + + feh_redraw_menus(); + + FD_ZERO(&fdset); + FD_SET(xfd, &fdset); + + /* Timers */ + ft = first_timer; + /* Don't do timers if we're zooming/panning/etc or if we are paused */ + if (ft && (opt.mode == MODE_NORMAL) && !opt.paused) { + D(5, ("There are timers in the queue\n")); + if (ft->just_added) { + D(5, ("The first timer has just been added\n")); + D(5, ("ft->in = %f\n", ft->in)); + ft->just_added = 0; + t1 = ft->in; + } else { + D(5, ("The first timer was not just added\n")); + t1 = ft->in - t2; + if (t1 < 0.0) + t1 = 0.0; + ft->in = t1; + } + + XSync(disp, False); + D(5, ("I next need to action a timer in %f seconds\n", t1)); + /* Only do a blocking select if there's a timer due, or no events + waiting */ + if (t1 == 0.0 || (block && !XPending(disp))) { + tval.tv_sec = (long) t1; + tval.tv_usec = (long) ((t1 - ((double) tval.tv_sec)) * 1000000); + if (tval.tv_sec < 0) + tval.tv_sec = 0; + if (tval.tv_usec <= 1000) + tval.tv_usec = 1000; + errno = 0; + D(5, ("Performing blocking select - waiting for timer or event\n")); + count = select(fdsize, &fdset, NULL, NULL, &tval); + if ((count < 0) + && ((errno == ENOMEM) || (errno == EINVAL) + || (errno == EBADF))) + eprintf("Connection to X display lost"); + if ((ft) && (count == 0)) { + /* This means the timer is due to be executed. If count was > 0, + that would mean an X event had woken us, we're not interested + in that */ + feh_handle_timer(); + } + } + } else { + /* Don't block if there are events in the queue. That's a bit rude ;-) */ + if (block && !XPending(disp)) { + errno = 0; + D(5, ("Performing blocking select - no timers, or zooming\n")); + count = select(fdsize, &fdset, NULL, NULL, NULL); + if ((count < 0) + && ((errno == ENOMEM) || (errno == EINVAL) + || (errno == EBADF))) + eprintf("Connection to X display lost"); + } + } + if (window_num == 0) + D_RETURN(5, 0); + D_RETURN(5, 1); } - -void -feh_clean_exit(void) +void feh_clean_exit(void) { - D_ENTER(4); + D_ENTER(4); - delete_rm_files(); + delete_rm_files(); - if (opt.filelistfile) - feh_write_filelist(filelist, opt.filelistfile); + if (opt.filelistfile) + feh_write_filelist(filelist, opt.filelistfile); - D_RETURN_(4); + D_RETURN_(4); } @@ -49,35 +49,34 @@ #include <string.h> main() { - static const char *const test[7] = { - "", /*d41d8cd98f00b204e9800998ecf8427e*/ - "a", /*0cc175b9c0f1b6a831c399e269772661*/ - "abc", /*900150983cd24fb0d6963f7d28e17f72*/ - "message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/ - "abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - /*d174ab98d277d9f5a5611c2c9f419d9f*/ - "12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/ - }; - int i; - - for (i = 0; i < 7; ++i) { - md5_state_t state; - md5_byte_t digest[16]; - int di; - - md5_init(&state); - md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i])); - md5_finish(&state, digest); - printf("MD5 (\"%s\") = ", test[i]); - for (di = 0; di < 16; ++di) - printf("%02x", digest[di]); - printf("\n"); - } - return 0; + static const char *const test[7] = { + "", /*d41d8cd98f00b204e9800998ecf8427e */ + "a", /*0cc175b9c0f1b6a831c399e269772661 */ + "abc", /*900150983cd24fb0d6963f7d28e17f72 */ + "message digest", /*f96b697d7cb7938d525a2f31aaf161d0 */ + "abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b */ + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + /*d174ab98d277d9f5a5611c2c9f419d9f */ + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a */ + }; + int i; + + for (i = 0; i < 7; ++i) { + md5_state_t state; + md5_byte_t digest[16]; + int di; + + md5_init(&state); + md5_append(&state, (const md5_byte_t *) test[i], strlen(test[i])); + md5_finish(&state, digest); + printf("MD5 (\"%s\") = ", test[i]); + for (di = 0; di < 16; ++di) + printf("%02x", digest[di]); + printf("\n"); + } + return 0; } -#endif /* TEST */ - +#endif /* TEST */ /* * For reference, here is the program that computed the T values. @@ -86,12 +85,12 @@ main() #include <math.h> main() { - int i; - for (i = 1; i <= 64; ++i) { - unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); - printf("#define T%d 0x%08lx\n", i, v); - } - return 0; + int i; + for (i = 1; i <= 64; ++i) { + unsigned long v = (unsigned long) (4294967296.0 * fabs(sin((double) i))); + printf("#define T%d 0x%08lx\n", i, v); + } + return 0; } #endif /* @@ -162,231 +161,225 @@ main() #define T63 0x2ad7d2bb #define T64 0xeb86d391 -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) +static void md5_process(md5_state_t * pms, const md5_byte_t * data /*[64] */ ) { - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; + md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; #ifndef ARCH_IS_BIG_ENDIAN # define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */ #endif #if ARCH_IS_BIG_ENDIAN - /* - * On big-endian machines, we must arrange the bytes in the right - * order. (This also works on machines of unknown byte order.) - */ - md5_word_t X[16]; - const md5_byte_t *xp = data; - int i; - - for (i = 0; i < 16; ++i, xp += 4) - X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - -#else /* !ARCH_IS_BIG_ENDIAN */ - - /* - * On little-endian machines, we can process properly aligned data - * without copying it. - */ - md5_word_t xbuf[16]; - const md5_word_t *X; - - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } + /* + * On big-endian machines, we must arrange the bytes in the right + * order. (This also works on machines of unknown byte order.) + */ + md5_word_t X[16]; + const md5_byte_t *xp = data; + int i; + + for (i = 0; i < 16; ++i, xp += 4) + X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + +#else /* !ARCH_IS_BIG_ENDIAN */ + + /* + * On little-endian machines, we can process properly aligned data + * without copying it. + */ + md5_word_t xbuf[16]; + const md5_word_t *X; + + if (!((data - (const md5_byte_t *) 0) & 3)) { + /* data are properly aligned */ + X = (const md5_word_t *) data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } #endif #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); #undef SET - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); #undef SET - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); #undef SET - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); #undef SET - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; } -void -md5_init(md5_state_t *pms) +void md5_init(md5_state_t * pms) { - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = 0xefcdab89; - pms->abcd[2] = 0x98badcfe; - pms->abcd[3] = 0x10325476; + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = 0xefcdab89; + pms->abcd[2] = 0x98badcfe; + pms->abcd[3] = 0x10325476; } -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) +void md5_append(md5_state_t * pms, const md5_byte_t * data, int nbytes) { - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); + const md5_byte_t *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = (md5_word_t) (nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); } -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) +void md5_finish(md5_state_t * pms, md5_byte_t digest[16]) { - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); + static const md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (md5_byte_t) (pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (md5_byte_t) (pms->abcd[i >> 2] >> ((i & 3) << 3)); } @@ -51,44 +51,42 @@ * ARCH_IS_BIG_ENDIAN. */ -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ +typedef unsigned char md5_byte_t; /* 8-bit byte */ +typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /* Initialize the algorithm. */ #ifdef P1 -void md5_init(P1(md5_state_t *pms)); + void md5_init(P1(md5_state_t * pms)); #else -void md5_init(md5_state_t *pms); + void md5_init(md5_state_t * pms); #endif /* Append a string to the message. */ #ifdef P3 -void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes)); + void md5_append(P3(md5_state_t * pms, const md5_byte_t * data, int nbytes)); #else -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); + void md5_append(md5_state_t * pms, const md5_byte_t * data, int nbytes); #endif /* Finish the message and return the digest. */ #ifdef P2 -void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16])); + void md5_finish(P2(md5_state_t * pms, md5_byte_t digest[16])); #else -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + void md5_finish(md5_state_t * pms, md5_byte_t digest[16]); #endif #ifdef __cplusplus -} /* end extern "C" */ +} /* end extern "C" */ #endif - -#endif /* md5_INCLUDED */ +#endif /* md5_INCLUDED */ @@ -41,2100 +41,1726 @@ feh_menu *menu_bg = NULL; static feh_menu_list *menus = NULL; static int common_menus = 0; -static void feh_menu_cb_about(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_close(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_exit(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_reload(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_remove(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_delete(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_reset(feh_menu * m, - feh_menu_item * i, - void *data); - -static void feh_menu_cb_remove_thumb(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_delete_thumb(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_background_set_tiled(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_background_set_scaled(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_background_set_seamless(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_background_set_centered(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_background_set_tiled_no_file(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_background_set_scaled_no_file(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_background_set_centered_no_file(feh_menu * m, - feh_menu_item * i, - void *data); - -static void feh_menu_cb_sort_filename(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_sort_imagename(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_sort_filesize(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_sort_randomize(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_jump_to(feh_menu * m, - feh_menu_item * i, - void *data); -static feh_menu *feh_menu_func_gen_jump(feh_menu * m, - feh_menu_item * i, - void *data); -static feh_menu *feh_menu_func_gen_info(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_func_free_info(feh_menu * m, - void *data); -static void feh_menu_cb_save_image(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_save_filelist(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_fit(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_opt_draw_filename(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_opt_keep_http(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_opt_freeze_window(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_opt_fullscreen(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_func_free_options(feh_menu * m, - void *data); -static feh_menu *feh_menu_func_gen_options(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_edit_rotate(feh_menu * m, - feh_menu_item * i, - void *data); -static void feh_menu_cb_opt_auto_zoom(feh_menu * m, - feh_menu_item * i, - void *data); +static void feh_menu_cb_about(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_close(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_exit(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_reload(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_remove(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_delete(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_reset(feh_menu * m, feh_menu_item * i, void *data); + +static void feh_menu_cb_remove_thumb(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_delete_thumb(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_background_set_tiled(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_background_set_scaled(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_background_set_seamless(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_background_set_centered(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_background_set_tiled_no_file(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_background_set_scaled_no_file(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_background_set_centered_no_file(feh_menu * m, feh_menu_item * i, void *data); + +static void feh_menu_cb_sort_filename(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_sort_imagename(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_sort_filesize(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_sort_randomize(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_jump_to(feh_menu * m, feh_menu_item * i, void *data); +static feh_menu *feh_menu_func_gen_jump(feh_menu * m, feh_menu_item * i, void *data); +static feh_menu *feh_menu_func_gen_info(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_func_free_info(feh_menu * m, void *data); +static void feh_menu_cb_save_image(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_save_filelist(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_fit(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_opt_draw_filename(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_opt_keep_http(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_opt_freeze_window(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_func_free_options(feh_menu * m, void *data); +static feh_menu *feh_menu_func_gen_options(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_edit_rotate(feh_menu * m, feh_menu_item * i, void *data); +static void feh_menu_cb_opt_auto_zoom(feh_menu * m, feh_menu_item * i, void *data); #ifdef HAVE_LIBXINERAMA -static void feh_menu_cb_opt_xinerama(feh_menu * m, - feh_menu_item * i, - void *data); -#endif /* HAVE_LIBXINERAMA */ - - -feh_menu * -feh_menu_new(void) -{ - feh_menu *m; - XSetWindowAttributes attr; - feh_menu_list *l; - static Imlib_Image bg = NULL; - static Imlib_Border border; - - D_ENTER(4); - - m = (feh_menu *) emalloc(sizeof(feh_menu)); - - attr.backing_store = NotUseful; - attr.override_redirect = True; - attr.colormap = cm; - attr.border_pixel = 0; - attr.background_pixmap = None; - attr.save_under = False; - attr.do_not_propagate_mask = True; - - m->win = - XCreateWindow(disp, root, 1, 1, 1, 1, 0, depth, InputOutput, vis, - CWOverrideRedirect | CWSaveUnder | CWBackingStore | - CWColormap | CWBackPixmap | CWBorderPixel | CWDontPropagate, - &attr); - XSelectInput(disp, m->win, - ButtonPressMask | ButtonReleaseMask | EnterWindowMask | - LeaveWindowMask | PointerMotionMask | ButtonMotionMask); - - m->name = NULL; - m->fehwin = NULL; - m->pmap = 0; - m->x = 0; - m->y = 0; - m->w = 0; - m->h = 0; - m->visible = 0; - m->items = NULL; - m->next = NULL; - m->prev = NULL; - m->updates = NULL; - m->needs_redraw = 1; - m->func_free = NULL; - m->data = NULL; - m->calc = 0; - m->bg = NULL; - - l = emalloc(sizeof(feh_menu_list)); - l->menu = m; - l->next = menus; - menus = l; - - if (!bg) { - feh_load_image_char(&bg, opt.menu_bg); - if (bg) { - border.left = opt.menu_border; - border.right = opt.menu_border; - border.top = opt.menu_border; - border.bottom = opt.menu_border; - imlib_context_set_image(bg); - imlib_image_set_border(&border); - } - } - - if (bg) - m->bg = gib_imlib_clone_image(bg); - - D_RETURN(4, m); -} - -void -feh_menu_free(feh_menu * m) -{ - feh_menu_item *i; - feh_menu_list *l, *pl = NULL; - - D_ENTER(4); - - if (m->name) - free(m->name); - XDestroyWindow(disp, m->win); - if (m->pmap) - XFreePixmap(disp, m->pmap); - if (m->updates) - imlib_updates_free(m->updates); - for (i = m->items; i;) { - feh_menu_item *ii; - - ii = i; - i = i->next; - if (ii->func_free) - (ii->func_free) (ii->data); - if (ii->text) - free(ii->text); - if (ii->submenu) - free(ii->submenu); - free(ii); - } - - for (l = menus; l; l = l->next) { - if (l->menu == m) { - if (pl) - pl->next = l->next; - else - menus = l->next; - free(l); - break; - } - pl = l; - } - free(m); - - D_RETURN_(4); -} - -feh_menu_item * -feh_menu_find_selected(feh_menu * m) -{ - feh_menu_item *i; - - D_ENTER(4); - - D(5, ("menu %p\n", m)); - - for (i = m->items; i; i = i->next) { - if (MENU_ITEM_IS_SELECTED(i)) - D_RETURN(4, i); - } - D_RETURN(4, NULL); -} - -feh_menu_item * -feh_menu_find_selected_r(feh_menu * m, feh_menu **parent) -{ - feh_menu_item *i, *ii; - feh_menu *mm; - - D_ENTER(4); - - D(5, ("menu %p\n", m)); - - for (i = m->items; i; i = i->next) { - if (MENU_ITEM_IS_SELECTED(i)) { - if (parent) - *parent = m; - D_RETURN(4, i); - } else if (i->submenu) { - mm = feh_menu_find(i->submenu); - if (mm) { - ii = feh_menu_find_selected_r(mm, parent); - if (ii) - D_RETURN(4, ii); - } - } - } - if (parent) - *parent = m; - D_RETURN(4, NULL); -} - -void -feh_menu_select_next(feh_menu *selected_menu, feh_menu_item *selected_item) { - feh_menu_item *i; - if (!selected_item) { - /* jump to first item, select it */ - feh_menu_select(selected_menu, selected_menu->items); - } else { - i = selected_item; - while (1) { - i = i->next; - if (!i) - i = selected_menu->items; - if (i->func || i->submenu || i->func_gen_sub || i->text) { - break; - } - } - feh_menu_deselect_selected(selected_menu); - feh_menu_select(selected_menu, i); - } -} - -void -feh_menu_select_prev(feh_menu *selected_menu, feh_menu_item *selected_item) { - feh_menu_item *i, *ii; - if (!selected_item) { - /* jump to last item, select it */ - for (i = selected_menu->items; i->next; i = i->next); - feh_menu_select(selected_menu, i); - } else { - i = selected_item; - while (1) { - i = i->prev; - if (!i) { - i = selected_menu->items; - for (ii = selected_menu->items; ii->next; ii = ii->next); - i = ii; - } - if (i->func || i->submenu || i->func_gen_sub || i->text) { - break; - } - } - feh_menu_deselect_selected(selected_menu); - feh_menu_select(selected_menu, i); - } -} - -void -feh_menu_select_parent(feh_menu *selected_menu, feh_menu_item *selected_item) { - feh_menu *m; - feh_menu_item *i; - /* find the parent menu's item which refers to this menu's name */ - if (selected_menu->prev) { - m = selected_menu->prev; - for (i = m->items; i; i = i->next) { - if(i->submenu && !strcmp(i->submenu, selected_menu->name)) - break; - } - /* shouldn't ever happen */ - if (i == NULL) - i = m->items; - feh_menu_deselect_selected(selected_menu); - feh_menu_select(m, i); - } -} - -void -feh_menu_select_submenu(feh_menu *selected_menu, feh_menu_item *selected_item) { - if (selected_menu->next) { - feh_menu_deselect_selected(selected_menu); - feh_menu_select(selected_menu->next, selected_menu->next->items); - } -} - -void feh_menu_item_activate(feh_menu *m, - feh_menu_item *i) { - /* watch out for this. I put it this way around so the menu - goes away *before* we perform the action, if we start - freeing menus on hiding, it will break ;-) */ - if ((i) && (i->func)) { - feh_menu_hide(menu_root, False); - feh_main_iteration(0); - (i->func) (m, i, i->data); - if(m->func_free) - m->func_free(m, m->data); - } -} - -feh_menu_item * -feh_menu_find_at_xy(feh_menu * m, - int x, - int y) -{ - feh_menu_item *i; - - D_ENTER(4); - D(4, ("looking for menu item at %d,%d\n", x, y)); - for (i = m->items; i; i = i->next) { - if (XY_IN_RECT(x, y, i->x, i->y, i->w, i->h)) { - D(4, ("Found an item\n")); - D_RETURN(4, i); - } - } - D(4, ("didn't find an item\n")); - D_RETURN(4, NULL); -} - -void -feh_menu_deselect_selected(feh_menu * m) -{ - feh_menu_item *i; - - D_ENTER(4); - - if (!m) - D_RETURN_(4); - - i = feh_menu_find_selected(m); - if (i) { - D(4, ("found a selected menu, deselecting it\n")); - MENU_ITEM_SET_NORMAL(i); - m->updates = imlib_update_append_rect(m->updates, i->x, i->y, i->w, i->h); - m->needs_redraw = 1; - } - D_RETURN_(4); -} - -void -feh_menu_select(feh_menu * m, - feh_menu_item * i) -{ - D_ENTER(4); - MENU_ITEM_SET_SELECTED(i); - m->updates = imlib_update_append_rect(m->updates, i->x, i->y, i->w, i->h); - m->needs_redraw = 1; - if (m->next) { - m->next->prev = NULL; - feh_menu_hide(m->next, TRUE); - m->next = NULL; - } - if (i->submenu) { - feh_menu *mm; - - mm = feh_menu_find(i->submenu); - if (mm) - feh_menu_show_at_submenu(mm, m, i); - else if (i->func_gen_sub) - feh_menu_show_at_submenu(i->func_gen_sub(m, i, i->data), m, i); - } - D_RETURN_(4); -} - -void -feh_menu_show_at(feh_menu * m, int x, int y) -{ - D_ENTER(4); - - if (m->calc) - feh_menu_calc_size(m); - if (!menu_cover) { - XSetWindowAttributes attr; - - D(4, ("creating menu cover window\n")); - attr.override_redirect = True; - attr.do_not_propagate_mask = True; - menu_cover = - XCreateWindow(disp, root, 0, 0, scr->width, scr->height, 0, 0, - InputOnly, vis, CWOverrideRedirect | CWDontPropagate, - &attr); - XSelectInput(disp, menu_cover, - KeyPressMask | ButtonPressMask | ButtonReleaseMask | - EnterWindowMask | LeaveWindowMask | PointerMotionMask | - ButtonMotionMask); - - XRaiseWindow(disp, menu_cover); - XMapWindow(disp, menu_cover); - menu_root = m; - XUngrabPointer(disp, CurrentTime); - XSetInputFocus(disp, menu_cover, RevertToPointerRoot, CurrentTime); - } - m->visible = 1; - XMoveWindow(disp, m->win, x, y); - m->x = x; - m->y = y; - XRaiseWindow(disp, m->win); - feh_menu_redraw(m); - XMapWindow(disp, m->win); - D_RETURN_(4); -} - -void -feh_menu_show_at_xy(feh_menu * m, - winwidget winwid, - int x, - int y) -{ - D_ENTER(4); - - if (!m) - D_RETURN_(4); - - if (m->calc) - feh_menu_calc_size(m); - m->fehwin = winwid; - if ((x + m->w) > scr->width) - x = scr->width - m->w; - if ((y + m->h) > scr->height) - y = scr->height - m->h; - -#if 0 +static void feh_menu_cb_opt_xinerama(feh_menu * m, feh_menu_item * i, void *data); +#endif /* HAVE_LIBXINERAMA */ + +feh_menu *feh_menu_new(void) +{ + feh_menu *m; + XSetWindowAttributes attr; + feh_menu_list *l; + static Imlib_Image bg = NULL; + static Imlib_Border border; + + D_ENTER(4); + + m = (feh_menu *) emalloc(sizeof(feh_menu)); + + attr.backing_store = NotUseful; + attr.override_redirect = True; + attr.colormap = cm; + attr.border_pixel = 0; + attr.background_pixmap = None; + attr.save_under = False; + attr.do_not_propagate_mask = True; + + m->win = XCreateWindow( + disp, root, 1, 1, 1, 1, 0, depth, InputOutput, vis, + CWOverrideRedirect | CWSaveUnder | CWBackingStore + | CWColormap | CWBackPixmap | CWBorderPixel | CWDontPropagate, &attr); + XSelectInput(disp, m->win, + ButtonPressMask | ButtonReleaseMask | EnterWindowMask + | LeaveWindowMask | PointerMotionMask | ButtonMotionMask); + + m->name = NULL; + m->fehwin = NULL; + m->pmap = 0; + m->x = 0; + m->y = 0; + m->w = 0; + m->h = 0; + m->visible = 0; + m->items = NULL; + m->next = NULL; + m->prev = NULL; + m->updates = NULL; + m->needs_redraw = 1; + m->func_free = NULL; + m->data = NULL; + m->calc = 0; + m->bg = NULL; + + l = emalloc(sizeof(feh_menu_list)); + l->menu = m; + l->next = menus; + menus = l; + + if (!bg) { + feh_load_image_char(&bg, opt.menu_bg); + if (bg) { + border.left = opt.menu_border; + border.right = opt.menu_border; + border.top = opt.menu_border; + border.bottom = opt.menu_border; + imlib_context_set_image(bg); + imlib_image_set_border(&border); + } + } + + if (bg) + m->bg = gib_imlib_clone_image(bg); + + D_RETURN(4, m); +} + +void feh_menu_free(feh_menu * m) +{ + feh_menu_item *i; + feh_menu_list *l, *pl = NULL; + + D_ENTER(4); + + if (m->name) + free(m->name); + XDestroyWindow(disp, m->win); + if (m->pmap) + XFreePixmap(disp, m->pmap); + if (m->updates) + imlib_updates_free(m->updates); + for (i = m->items; i;) { + feh_menu_item *ii; + + ii = i; + i = i->next; + if (ii->func_free) + (ii->func_free) (ii->data); + if (ii->text) + free(ii->text); + if (ii->submenu) + free(ii->submenu); + free(ii); + } + + for (l = menus; l; l = l->next) { + if (l->menu == m) { + if (pl) + pl->next = l->next; + else + menus = l->next; + free(l); + break; + } + pl = l; + } + free(m); + + D_RETURN_(4); +} + +feh_menu_item *feh_menu_find_selected(feh_menu * m) +{ + feh_menu_item *i; + + D_ENTER(4); + + D(5, ("menu %p\n", m)); + + for (i = m->items; i; i = i->next) { + if (MENU_ITEM_IS_SELECTED(i)) + D_RETURN(4, i); + } + D_RETURN(4, NULL); +} + +feh_menu_item *feh_menu_find_selected_r(feh_menu * m, feh_menu ** parent) +{ + feh_menu_item *i, *ii; + feh_menu *mm; + + D_ENTER(4); + + D(5, ("menu %p\n", m)); + + for (i = m->items; i; i = i->next) { + if (MENU_ITEM_IS_SELECTED(i)) { + if (parent) + *parent = m; + D_RETURN(4, i); + } else if (i->submenu) { + mm = feh_menu_find(i->submenu); + if (mm) { + ii = feh_menu_find_selected_r(mm, parent); + if (ii) + D_RETURN(4, ii); + } + } + } + if (parent) + *parent = m; + D_RETURN(4, NULL); +} + +void feh_menu_select_next(feh_menu * selected_menu, feh_menu_item * selected_item) +{ + feh_menu_item *i; + if (!selected_item) { + /* jump to first item, select it */ + feh_menu_select(selected_menu, selected_menu->items); + } else { + i = selected_item; + while (1) { + i = i->next; + if (!i) + i = selected_menu->items; + if (i->func || i->submenu || i->func_gen_sub || i->text) { + break; + } + } + feh_menu_deselect_selected(selected_menu); + feh_menu_select(selected_menu, i); + } +} + +void feh_menu_select_prev(feh_menu * selected_menu, feh_menu_item * selected_item) +{ + feh_menu_item *i, *ii; + if (!selected_item) { + /* jump to last item, select it */ + for (i = selected_menu->items; i->next; i = i->next); + feh_menu_select(selected_menu, i); + } else { + i = selected_item; + while (1) { + i = i->prev; + if (!i) { + i = selected_menu->items; + for (ii = selected_menu->items; ii->next; ii = ii->next); + i = ii; + } + if (i->func || i->submenu || i->func_gen_sub || i->text) { + break; + } + } + feh_menu_deselect_selected(selected_menu); + feh_menu_select(selected_menu, i); + } +} + +void feh_menu_select_parent(feh_menu * selected_menu, feh_menu_item * selected_item) +{ + feh_menu *m; + feh_menu_item *i; + /* find the parent menu's item which refers to this menu's name */ + if (selected_menu->prev) { + m = selected_menu->prev; + for (i = m->items; i; i = i->next) { + if (i->submenu && !strcmp(i->submenu, selected_menu->name)) + break; + } + /* shouldn't ever happen */ + if (i == NULL) + i = m->items; + feh_menu_deselect_selected(selected_menu); + feh_menu_select(m, i); + } +} + +void feh_menu_select_submenu(feh_menu * selected_menu, feh_menu_item * selected_item) +{ + if (selected_menu->next) { + feh_menu_deselect_selected(selected_menu); + feh_menu_select(selected_menu->next, selected_menu->next->items); + } +} + +void feh_menu_item_activate(feh_menu * m, feh_menu_item * i) +{ + /* watch out for this. I put it this way around so the menu + goes away *before* we perform the action, if we start + freeing menus on hiding, it will break ;-) */ + if ((i) && (i->func)) { + feh_menu_hide(menu_root, False); + feh_main_iteration(0); + (i->func) (m, i, i->data); + if (m->func_free) + m->func_free(m, m->data); + } +} + +feh_menu_item *feh_menu_find_at_xy(feh_menu * m, int x, int y) +{ + feh_menu_item *i; + + D_ENTER(4); + D(4, ("looking for menu item at %d,%d\n", x, y)); + for (i = m->items; i; i = i->next) { + if (XY_IN_RECT(x, y, i->x, i->y, i->w, i->h)) { + D(4, ("Found an item\n")); + D_RETURN(4, i); + } + } + D(4, ("didn't find an item\n")); + D_RETURN(4, NULL); +} + +void feh_menu_deselect_selected(feh_menu * m) +{ + feh_menu_item *i; + + D_ENTER(4); + + if (!m) + D_RETURN_(4); + + i = feh_menu_find_selected(m); + if (i) { + D(4, ("found a selected menu, deselecting it\n")); + MENU_ITEM_SET_NORMAL(i); + m->updates = imlib_update_append_rect(m->updates, i->x, i->y, i->w, i->h); + m->needs_redraw = 1; + } + D_RETURN_(4); +} + +void feh_menu_select(feh_menu * m, feh_menu_item * i) +{ + D_ENTER(4); + MENU_ITEM_SET_SELECTED(i); + m->updates = imlib_update_append_rect(m->updates, i->x, i->y, i->w, i->h); + m->needs_redraw = 1; + if (m->next) { + m->next->prev = NULL; + feh_menu_hide(m->next, TRUE); + m->next = NULL; + } + if (i->submenu) { + feh_menu *mm; + + mm = feh_menu_find(i->submenu); + if (mm) + feh_menu_show_at_submenu(mm, m, i); + else if (i->func_gen_sub) + feh_menu_show_at_submenu(i->func_gen_sub(m, i, i->data), m, i); + } + D_RETURN_(4); +} + +void feh_menu_show_at(feh_menu * m, int x, int y) +{ + D_ENTER(4); + + if (m->calc) + feh_menu_calc_size(m); + if (!menu_cover) { + XSetWindowAttributes attr; + + D(4, ("creating menu cover window\n")); + attr.override_redirect = True; + attr.do_not_propagate_mask = True; + menu_cover = XCreateWindow( + disp, root, 0, 0, scr->width, + scr->height, 0, 0, InputOnly, vis, + CWOverrideRedirect | CWDontPropagate, &attr); + XSelectInput(disp, menu_cover, + KeyPressMask | ButtonPressMask | + ButtonReleaseMask | EnterWindowMask | + LeaveWindowMask | PointerMotionMask | ButtonMotionMask); + + XRaiseWindow(disp, menu_cover); + XMapWindow(disp, menu_cover); + menu_root = m; + XUngrabPointer(disp, CurrentTime); + XSetInputFocus(disp, menu_cover, RevertToPointerRoot, CurrentTime); + } + m->visible = 1; + XMoveWindow(disp, m->win, x, y); + m->x = x; + m->y = y; + XRaiseWindow(disp, m->win); + feh_menu_redraw(m); + XMapWindow(disp, m->win); + D_RETURN_(4); +} + +void feh_menu_show_at_xy(feh_menu * m, winwidget winwid, int x, int y) +{ + D_ENTER(4); + + if (!m) + D_RETURN_(4); + + if (m->calc) + feh_menu_calc_size(m); + m->fehwin = winwid; + if ((x + m->w) > scr->width) + x = scr->width - m->w; + if ((y + m->h) > scr->height) + y = scr->height - m->h; + +#if 0 /* #ifdef HAVE_LIBXINERAMA */ /* this doesn't work correctly :( -- pabs */ - if (opt.xinerama && xinerama_screens) { - if ((x + m->w) > xinerama_screens[xinerama_screen].width) - x = xinerama_screens[xinerama_screen].width - m->w; - if ((y + m->h) > xinerama_screens[xinerama_screen].height) - y = xinerama_screens[xinerama_screen].height - m->h; - - } -#endif /* HAVE_LIBXINERAMA */ - - if (x < 0) - x = 0; - if (y < 0) - y = 0; - feh_menu_move(m, x, y); - feh_menu_show(m); - D_RETURN_(4); -} - -void -feh_menu_show_at_submenu(feh_menu * m, - feh_menu * parent_m, - feh_menu_item * i) -{ - int mx, my; - - D_ENTER(4); - - if (!m) - D_RETURN_(4); - - if (m->calc) - feh_menu_calc_size(m); - mx = parent_m->x + parent_m->w; - my = parent_m->y + i->y - FEH_MENU_PAD_TOP; - m->fehwin = parent_m->fehwin; - parent_m->next = m; - m->prev = parent_m; - feh_menu_move(m, mx, my); - feh_menu_show(m); - D_RETURN_(4); -} - -void -feh_menu_move(feh_menu * m, - int x, - int y) -{ - int dx, dy; - - D_ENTER(4); - - if (!m) - D_RETURN_(4); - dx = x - m->x; - dy = y - m->y; - if (m->visible) - XMoveWindow(disp, m->win, x, y); - m->x = x; - m->y = y; - D_RETURN_(4); -} - -void -feh_menu_slide_all_menus_relative(int dx, - int dy) -{ - int i; - feh_menu_list *m; - double vector_len = 0; - int stepx = 0; - int stepy = 0; - - D_ENTER(4); - vector_len = sqrt(dx * dx + dy * dy); - if (vector_len) { - if (dx) - stepx = rint(dx / vector_len); - - if (dy) - stepy = rint(dy / vector_len); - - } - for (i = 0; i < vector_len; i++) { - for (m = menus; m; m = m->next) { - if (m->menu->visible) - feh_menu_move(m->menu, m->menu->x + stepx, m->menu->y + stepy); - - } - XWarpPointer(disp, None, None, 0, 0, 0, 0, stepx, stepy); - } - D_RETURN_(4); -} - -void -feh_menu_hide(feh_menu * m, - int func_free) -{ - D_ENTER(4); - - if (!m->visible) - D_RETURN_(4); - if (m->next) { - m->next->prev = NULL; - feh_menu_hide(m->next, func_free); - m->next = NULL; - } - if (m == menu_root) { - if (menu_cover) { - D(4, ("DESTROYING menu cover\n")); - XDestroyWindow(disp, menu_cover); - menu_cover = 0; - } - menu_root = NULL; - } - m->visible = 0; - XUnmapWindow(disp, m->win); - if (func_free && m->func_free) - m->func_free(m, m->data); - else - feh_menu_deselect_selected(m); - D_RETURN_(4); -} - -void -feh_menu_show(feh_menu * m) -{ - D_ENTER(4); - if (!m) - D_RETURN_(4); - feh_menu_show_at(m, m->x, m->y); - D_RETURN_(4); -} - -feh_menu_item * -feh_menu_add_toggle_entry(feh_menu * m, - char *text, - Imlib_Image icon, - char *submenu, - menu_func func, - void *data, - void (*func_free) (void *data), - int setting) -{ - feh_menu_item *mi; - - D_ENTER(4); - mi = feh_menu_add_entry(m, text, icon, submenu, func, data, func_free); - mi->is_toggle = TRUE; - MENU_ITEM_TOGGLE_SET(mi, setting); - D_RETURN(4, mi); -} - -feh_menu_item * -feh_menu_add_entry(feh_menu * m, - char *text, - Imlib_Image icon, - char *submenu, - menu_func func, - void *data, - void (*func_free) (void *data)) -{ - feh_menu_item *mi, *ptr; - - D_ENTER(4); - - mi = (feh_menu_item *) emalloc(sizeof(feh_menu_item)); - mi->state = MENU_ITEM_STATE_NORMAL; - mi->icon = icon; - mi->is_toggle = FALSE; - if (text) - mi->text = estrdup(text); - else - mi->text = NULL; - if (submenu) - mi->submenu = estrdup(submenu); - else - mi->submenu = NULL; - mi->func = func; - mi->func_free = func_free; - mi->data = data; - mi->func_gen_sub = NULL; - mi->next = NULL; - mi->prev = NULL; - - if (!m->items) - m->items = mi; - else { - for (ptr = m->items; ptr; ptr = ptr->next) { - if (!ptr->next) { - ptr->next = mi; - mi->prev = ptr; - break; - } - } - } - m->calc = 1; - D_RETURN(4, mi); -} - - -void -feh_menu_entry_get_size(feh_menu * m, - feh_menu_item * i, - int *w, - int *h) -{ - int tw, th; - - D_ENTER(4); - - if (i->text) { - gib_imlib_get_text_size(opt.menu_fn, i->text, opt.menu_style_l, &tw, &th, - IMLIB_TEXT_TO_RIGHT); - *w = - tw + FEH_MENUITEM_PAD_LEFT + FEH_MENUITEM_PAD_RIGHT; - *h = - th + FEH_MENUITEM_PAD_TOP + FEH_MENUITEM_PAD_BOTTOM; - } else { - *w = FEH_MENUITEM_PAD_LEFT + FEH_MENUITEM_PAD_RIGHT; - *h = FEH_MENUITEM_PAD_TOP + FEH_MENUITEM_PAD_BOTTOM; - } - - D_RETURN_(4); - m = NULL; -} - -void -feh_menu_calc_size(feh_menu * m) -{ - int prev_w, prev_h; - feh_menu_item *i; - int j = 0, count = 0, max_w = 0, max_h = 0, icon_w = 0, next_w = 0; - int toggle_w = 0; - - D_ENTER(4); - - prev_w = m->w; - prev_h = m->h; - m->calc = 0; - - for (i = m->items; i; i = i->next) { - int w, h; - - feh_menu_entry_get_size(m, i, &w, &h); - if (w > max_w) - max_w = w; - if (h > max_h) - max_h = h; - if (i->submenu) { - next_w = FEH_MENU_SUBMENU_W; - if (FEH_MENU_SUBMENU_H > max_h) - max_h = FEH_MENU_SUBMENU_H; - } - if (i->is_toggle) { - toggle_w = FEH_MENU_TOGGLE_W + FEH_MENU_TOGGLE_PAD; - if (FEH_MENU_TOGGLE_H > max_h) - max_h = FEH_MENU_TOGGLE_H; - } - count++; - } - - for (i = m->items; i; i = i->next) { - if (i->icon) { - Imlib_Image im; - - im = i->icon; - if (im) { - int iw, ih, ow, oh; - - iw = gib_imlib_image_get_width(im); - ih = gib_imlib_image_get_height(im); - if (ih <= max_h) { - ow = iw; - oh = ih; - } else { - ow = (iw * max_h) / ih; - oh = max_h; - } - if (ow > icon_w) - icon_w = ow; - } - } - } - m->h = FEH_MENU_PAD_TOP; - for (i = m->items; i; i = i->next) { - i->x = FEH_MENU_PAD_LEFT; - i->y = m->h; - i->w = max_w + icon_w + toggle_w + next_w; - i->icon_x = FEH_MENUITEM_PAD_LEFT; - i->toggle_x = i->icon_x + icon_w; - i->text_x = i->toggle_x + toggle_w; - i->sub_x = i->text_x + max_w; - if (i->text) - i->h = max_h; - else - i->h = FEH_MENU_SEP_MAX_H; - m->h += i->h; - j++; - } - m->h += FEH_MENU_PAD_BOTTOM; - m->w = - next_w + toggle_w + icon_w + max_w + FEH_MENU_PAD_LEFT + - FEH_MENU_PAD_RIGHT; - - if ((prev_w != m->w) || (prev_h != m->h)) { - if (m->pmap) - XFreePixmap(disp, m->pmap); - m->pmap = 0; - m->needs_redraw = 1; - XResizeWindow(disp, m->win, m->w, m->h); - m->updates = imlib_update_append_rect(m->updates, 0, 0, m->w, m->h); - } - D(4, ("menu size calculated. w=%d h=%d\n", m->w, m->h)); - - /* Make sure bg is same size */ - if (m->bg) { - int bg_w, bg_h; - - bg_w = gib_imlib_image_get_width(m->bg); - bg_h = gib_imlib_image_get_height(m->bg); - - if (m->w != bg_w || m->h != bg_h) { - Imlib_Image newim = imlib_create_image(m->w, m->h); - - D(3, ("resizing bg to %dx%d\n", m->w, m->h)); - - gib_imlib_blend_image_onto_image(newim, m->bg, 0, 0, 0, bg_w, bg_h, 0, - 0, m->w, m->h, 0, 0, 1); - gib_imlib_free_image_and_decache(m->bg); - m->bg = newim; - } - } - - D_RETURN_(4); -} - -void -feh_menu_draw_item(feh_menu * m, - feh_menu_item * i, - Imlib_Image im, - int ox, - int oy) -{ - D_ENTER(5); - - D(5, - ("drawing item %p (text %s) on menu %p (name %s)\n", i, i->text, m, - m->name)); - - if (i->text) { - D(5, ("text item\n")); - if (MENU_ITEM_IS_SELECTED(i)) { - D(5, ("selected item\n")); - /* draw selected image */ - feh_menu_item_draw_at(i->x, i->y, i->w, i->h, im, ox, oy, 1); - } else { - D(5, ("unselected item\n")); - /* draw unselected image */ - feh_menu_item_draw_at(i->x, i->y, i->w, i->h, im, ox, oy, 0); - } - - /* draw text */ - gib_imlib_text_draw(im, opt.menu_fn, opt.menu_style_l, - i->x - ox + i->text_x, - i->y - oy + FEH_MENUITEM_PAD_TOP, i->text, - IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255); - if (i->icon) { - Imlib_Image im2; - - D(5, ("icon item\n")); - - im2 = i->icon; - if (im2) { - int iw, ih, ow, oh; - - iw = gib_imlib_image_get_width(im2); - ih = gib_imlib_image_get_height(im2); - if (ih <= (i->h - FEH_MENUITEM_PAD_TOP - FEH_MENUITEM_PAD_BOTTOM)) { - ow = iw; - oh = ih; - } else { - ow = - (iw * (i->h - FEH_MENUITEM_PAD_TOP - FEH_MENUITEM_PAD_BOTTOM)) / - ih; - oh = i->h - FEH_MENUITEM_PAD_TOP - FEH_MENUITEM_PAD_BOTTOM; - } - gib_imlib_blend_image_onto_image(im, im2, 0, 0, 0, iw, ih, - i->x + i->icon_x - ox, - i->y + FEH_MENUITEM_PAD_TOP + - (((i->h - FEH_MENUITEM_PAD_TOP - - FEH_MENUITEM_PAD_BOTTOM) - - oh) / 2) - oy, ow, oh, 1, 1, 1); - gib_imlib_free_image(im2); - } - } - if (i->submenu) { - D(5, ("submenu item\n")); - feh_menu_draw_submenu_at(i->x + i->sub_x, - i->y + FEH_MENUITEM_PAD_TOP + - ((i->h - FEH_MENUITEM_PAD_TOP - - FEH_MENUITEM_PAD_BOTTOM - - FEH_MENU_SUBMENU_H) / 2), FEH_MENU_SUBMENU_W, - FEH_MENU_SUBMENU_H, im, ox, oy, - MENU_ITEM_IS_SELECTED(i)); - } - if (i->is_toggle) { - D(5, ("toggleable item\n")); - feh_menu_draw_toggle_at(i->x + i->toggle_x, - i->y + FEH_MENUITEM_PAD_TOP + - ((i->h - FEH_MENUITEM_PAD_TOP - - FEH_MENUITEM_PAD_BOTTOM - - FEH_MENU_TOGGLE_H) / 2), FEH_MENU_TOGGLE_W, - FEH_MENU_TOGGLE_H, im, ox, oy, - MENU_ITEM_IS_ON(i)); - } - } else { - D(5, ("separator item\n")); - feh_menu_draw_separator_at(i->x, i->y, i->w, i->h, im, ox, oy); - } - D_RETURN_(5); - m = NULL; -} - -void -feh_menu_redraw(feh_menu * m) -{ - Imlib_Updates u, uu; - - D_ENTER(5); - - if ((!m->needs_redraw) || (!m->visible) || (!m->updates)) - D_RETURN_(5); - m->needs_redraw = 0; - if (!m->pmap) - m->pmap = XCreatePixmap(disp, m->win, m->w, m->h, depth); - XSetWindowBackgroundPixmap(disp, m->win, m->pmap); - - u = imlib_updates_merge_for_rendering(m->updates, m->w, m->h); - m->updates = NULL; - if (u) { - D(5, ("I have updates to render\n")); - for (uu = u; u; u = imlib_updates_get_next(u)) { - int x, y, w, h; - Imlib_Image im; - - imlib_updates_get_coordinates(u, &x, &y, &w, &h); - D(5, ("update coords %d,%d %d*%d\n", x, y, w, h)); - im = imlib_create_image(w, h); - gib_imlib_image_fill_rectangle(im, 0, 0, w, h, 0, 0, 0, 0); - if (im) { - feh_menu_draw_to_buf(m, im, x, y); - gib_imlib_render_image_on_drawable(m->pmap, im, x, y, 1, 0, 0); - gib_imlib_free_image(im); - XClearArea(disp, m->win, x, y, w, h, False); - } - } - imlib_updates_free(uu); - } - D_RETURN_(5); -} - -feh_menu * -feh_menu_find(char *name) -{ - feh_menu_list *l; - - D_ENTER(4); - for (l = menus; l; l = l->next) { - if ((l->menu->name) && (!strcmp(l->menu->name, name))) - D_RETURN(4, l->menu); - } - D_RETURN(4, NULL); -} - -void -feh_menu_draw_to_buf(feh_menu * m, - Imlib_Image im, - int ox, - int oy) -{ - feh_menu_item *i; - int w, h; - - D_ENTER(5); - w = gib_imlib_image_get_width(im); - h = gib_imlib_image_get_height(im); - - feh_menu_draw_menu_bg(m, im, ox, oy); - - for (i = m->items; i; i = i->next) { - if (RECTS_INTERSECT(i->x, i->y, i->w, i->h, ox, oy, w, h)) - feh_menu_draw_item(m, i, im, ox, oy); - } - D_RETURN_(5); -} - -void -feh_menu_draw_menu_bg(feh_menu * m, - Imlib_Image im, - int ox, - int oy) -{ - int w, h; - - D_ENTER(5); - - w = gib_imlib_image_get_width(im); - h = gib_imlib_image_get_height(im); - - if (m->bg) - gib_imlib_blend_image_onto_image(im, m->bg, 0, ox, oy, w, h, 0, 0, w, h, - 0, 0, 0); - else - gib_imlib_image_fill_rectangle(im, 0, 0, w, h, 205, 203, 176, 255); - - D_RETURN_(5); -} - -void -feh_menu_draw_toggle_at(int x, - int y, - int w, - int h, - Imlib_Image dst, - int ox, - int oy, - int on) -{ - D_ENTER(5); - x -= ox; - y -= oy; - if (on) - gib_imlib_image_fill_rectangle(dst, x, y, w, h, 0, 0, 0, 255); - else - gib_imlib_image_draw_rectangle(dst, x, y, w, h, 0, 0, 0, 255); - D_RETURN_(5); -} - -void -feh_menu_draw_submenu_at(int x, - int y, - int w, - int h, - Imlib_Image dst, - int ox, - int oy, - int selected) + if (opt.xinerama && xinerama_screens) { + if ((x + m->w) > xinerama_screens[xinerama_screen].width) + x = xinerama_screens[xinerama_screen].width - m->w; + if ((y + m->h) > xinerama_screens[xinerama_screen].height) + y = xinerama_screens[xinerama_screen].height - m->h; + + } +#endif /* HAVE_LIBXINERAMA */ + + if (x < 0) + x = 0; + if (y < 0) + y = 0; + feh_menu_move(m, x, y); + feh_menu_show(m); + D_RETURN_(4); +} + +void feh_menu_show_at_submenu(feh_menu * m, feh_menu * parent_m, feh_menu_item * i) +{ + int mx, my; + + D_ENTER(4); + + if (!m) + D_RETURN_(4); + + if (m->calc) + feh_menu_calc_size(m); + mx = parent_m->x + parent_m->w; + my = parent_m->y + i->y - FEH_MENU_PAD_TOP; + m->fehwin = parent_m->fehwin; + parent_m->next = m; + m->prev = parent_m; + feh_menu_move(m, mx, my); + feh_menu_show(m); + D_RETURN_(4); +} + +void feh_menu_move(feh_menu * m, int x, int y) { - ImlibPolygon poly; + int dx, dy; + + D_ENTER(4); + + if (!m) + D_RETURN_(4); + dx = x - m->x; + dy = y - m->y; + if (m->visible) + XMoveWindow(disp, m->win, x, y); + m->x = x; + m->y = y; + D_RETURN_(4); +} + +void feh_menu_slide_all_menus_relative(int dx, int dy) +{ + int i; + feh_menu_list *m; + double vector_len = 0; + int stepx = 0; + int stepy = 0; + + D_ENTER(4); + vector_len = sqrt(dx * dx + dy * dy); + if (vector_len) { + if (dx) + stepx = rint(dx / vector_len); + + if (dy) + stepy = rint(dy / vector_len); + + } + for (i = 0; i < vector_len; i++) { + for (m = menus; m; m = m->next) { + if (m->menu->visible) + feh_menu_move(m->menu, m->menu->x + stepx, m->menu->y + stepy); + + } + XWarpPointer(disp, None, None, 0, 0, 0, 0, stepx, stepy); + } + D_RETURN_(4); +} + +void feh_menu_hide(feh_menu * m, int func_free) +{ + D_ENTER(4); + + if (!m->visible) + D_RETURN_(4); + if (m->next) { + m->next->prev = NULL; + feh_menu_hide(m->next, func_free); + m->next = NULL; + } + if (m == menu_root) { + if (menu_cover) { + D(4, ("DESTROYING menu cover\n")); + XDestroyWindow(disp, menu_cover); + menu_cover = 0; + } + menu_root = NULL; + } + m->visible = 0; + XUnmapWindow(disp, m->win); + if (func_free && m->func_free) + m->func_free(m, m->data); + else + feh_menu_deselect_selected(m); + D_RETURN_(4); +} + +void feh_menu_show(feh_menu * m) +{ + D_ENTER(4); + if (!m) + D_RETURN_(4); + feh_menu_show_at(m, m->x, m->y); + D_RETURN_(4); +} + +feh_menu_item *feh_menu_add_toggle_entry(feh_menu * m, char *text, + Imlib_Image icon, char *submenu, menu_func func, + void *data, void (*func_free) (void *data), int setting) +{ + feh_menu_item *mi; + + D_ENTER(4); + mi = feh_menu_add_entry(m, text, icon, submenu, func, data, func_free); + mi->is_toggle = TRUE; + MENU_ITEM_TOGGLE_SET(mi, setting); + D_RETURN(4, mi); +} + +feh_menu_item *feh_menu_add_entry(feh_menu * m, char *text, Imlib_Image icon, + char *submenu, menu_func func, void *data, void (*func_free) (void *data)) +{ + feh_menu_item *mi, *ptr; + + D_ENTER(4); + + mi = (feh_menu_item *) emalloc(sizeof(feh_menu_item)); + mi->state = MENU_ITEM_STATE_NORMAL; + mi->icon = icon; + mi->is_toggle = FALSE; + if (text) + mi->text = estrdup(text); + else + mi->text = NULL; + if (submenu) + mi->submenu = estrdup(submenu); + else + mi->submenu = NULL; + mi->func = func; + mi->func_free = func_free; + mi->data = data; + mi->func_gen_sub = NULL; + mi->next = NULL; + mi->prev = NULL; + + if (!m->items) + m->items = mi; + else { + for (ptr = m->items; ptr; ptr = ptr->next) { + if (!ptr->next) { + ptr->next = mi; + mi->prev = ptr; + break; + } + } + } + m->calc = 1; + D_RETURN(4, mi); +} + +void feh_menu_entry_get_size(feh_menu * m, feh_menu_item * i, int *w, int *h) +{ + int tw, th; + + D_ENTER(4); + + if (i->text) { + gib_imlib_get_text_size(opt.menu_fn, i->text, opt.menu_style_l, &tw, &th, IMLIB_TEXT_TO_RIGHT); + *w = tw + FEH_MENUITEM_PAD_LEFT + FEH_MENUITEM_PAD_RIGHT; + *h = th + FEH_MENUITEM_PAD_TOP + FEH_MENUITEM_PAD_BOTTOM; + } else { + *w = FEH_MENUITEM_PAD_LEFT + FEH_MENUITEM_PAD_RIGHT; + *h = FEH_MENUITEM_PAD_TOP + FEH_MENUITEM_PAD_BOTTOM; + } + + D_RETURN_(4); + m = NULL; +} + +void feh_menu_calc_size(feh_menu * m) +{ + int prev_w, prev_h; + feh_menu_item *i; + int j = 0, count = 0, max_w = 0, max_h = 0, icon_w = 0, next_w = 0; + int toggle_w = 0; + + D_ENTER(4); + + prev_w = m->w; + prev_h = m->h; + m->calc = 0; + + for (i = m->items; i; i = i->next) { + int w, h; + + feh_menu_entry_get_size(m, i, &w, &h); + if (w > max_w) + max_w = w; + if (h > max_h) + max_h = h; + if (i->submenu) { + next_w = FEH_MENU_SUBMENU_W; + if (FEH_MENU_SUBMENU_H > max_h) + max_h = FEH_MENU_SUBMENU_H; + } + if (i->is_toggle) { + toggle_w = FEH_MENU_TOGGLE_W + FEH_MENU_TOGGLE_PAD; + if (FEH_MENU_TOGGLE_H > max_h) + max_h = FEH_MENU_TOGGLE_H; + } + count++; + } + + for (i = m->items; i; i = i->next) { + if (i->icon) { + Imlib_Image im; + + im = i->icon; + if (im) { + int iw, ih, ow, oh; + + iw = gib_imlib_image_get_width(im); + ih = gib_imlib_image_get_height(im); + if (ih <= max_h) { + ow = iw; + oh = ih; + } else { + ow = (iw * max_h) / ih; + oh = max_h; + } + if (ow > icon_w) + icon_w = ow; + } + } + } + m->h = FEH_MENU_PAD_TOP; + for (i = m->items; i; i = i->next) { + i->x = FEH_MENU_PAD_LEFT; + i->y = m->h; + i->w = max_w + icon_w + toggle_w + next_w; + i->icon_x = FEH_MENUITEM_PAD_LEFT; + i->toggle_x = i->icon_x + icon_w; + i->text_x = i->toggle_x + toggle_w; + i->sub_x = i->text_x + max_w; + if (i->text) + i->h = max_h; + else + i->h = FEH_MENU_SEP_MAX_H; + m->h += i->h; + j++; + } + m->h += FEH_MENU_PAD_BOTTOM; + m->w = next_w + toggle_w + icon_w + max_w + FEH_MENU_PAD_LEFT + FEH_MENU_PAD_RIGHT; + + if ((prev_w != m->w) || (prev_h != m->h)) { + if (m->pmap) + XFreePixmap(disp, m->pmap); + m->pmap = 0; + m->needs_redraw = 1; + XResizeWindow(disp, m->win, m->w, m->h); + m->updates = imlib_update_append_rect(m->updates, 0, 0, m->w, m->h); + } + D(4, ("menu size calculated. w=%d h=%d\n", m->w, m->h)); + + /* Make sure bg is same size */ + if (m->bg) { + int bg_w, bg_h; + + bg_w = gib_imlib_image_get_width(m->bg); + bg_h = gib_imlib_image_get_height(m->bg); + + if (m->w != bg_w || m->h != bg_h) { + Imlib_Image newim = imlib_create_image(m->w, m->h); + + D(3, ("resizing bg to %dx%d\n", m->w, m->h)); + + gib_imlib_blend_image_onto_image(newim, m->bg, 0, 0, 0, bg_w, bg_h, 0, 0, m->w, m->h, 0, 0, 1); + gib_imlib_free_image_and_decache(m->bg); + m->bg = newim; + } + } + + D_RETURN_(4); +} + +void feh_menu_draw_item(feh_menu * m, feh_menu_item * i, Imlib_Image im, int ox, int oy) +{ + D_ENTER(5); + + D(5, ("drawing item %p (text %s) on menu %p (name %s)\n", i, i->text, m, m->name)); + + if (i->text) { + D(5, ("text item\n")); + if (MENU_ITEM_IS_SELECTED(i)) { + D(5, ("selected item\n")); + /* draw selected image */ + feh_menu_item_draw_at(i->x, i->y, i->w, i->h, im, ox, oy, 1); + } else { + D(5, ("unselected item\n")); + /* draw unselected image */ + feh_menu_item_draw_at(i->x, i->y, i->w, i->h, im, ox, oy, 0); + } + + /* draw text */ + gib_imlib_text_draw(im, opt.menu_fn, opt.menu_style_l, + i->x - ox + i->text_x, i->y - oy + FEH_MENUITEM_PAD_TOP, + i->text, IMLIB_TEXT_TO_RIGHT, 0, 0, 0, 255); + if (i->icon) { + Imlib_Image im2; + + D(5, ("icon item\n")); + + im2 = i->icon; + if (im2) { + int iw, ih, ow, oh; + + iw = gib_imlib_image_get_width(im2); + ih = gib_imlib_image_get_height(im2); + if (ih <= (i->h - FEH_MENUITEM_PAD_TOP - FEH_MENUITEM_PAD_BOTTOM)) { + ow = iw; + oh = ih; + } else { + ow = (iw * (i->h - FEH_MENUITEM_PAD_TOP - FEH_MENUITEM_PAD_BOTTOM)) / ih; + oh = i->h - FEH_MENUITEM_PAD_TOP - FEH_MENUITEM_PAD_BOTTOM; + } + gib_imlib_blend_image_onto_image(im, im2, + 0, 0, 0, + iw, ih, + i->x + + i->icon_x - + ox, + i->y + + FEH_MENUITEM_PAD_TOP + + + (((i->h - + FEH_MENUITEM_PAD_TOP - FEH_MENUITEM_PAD_BOTTOM) + - oh) / 2) - oy, ow, oh, 1, 1, 1); + gib_imlib_free_image(im2); + } + } + if (i->submenu) { + D(5, ("submenu item\n")); + feh_menu_draw_submenu_at(i->x + i->sub_x, + i->y + + FEH_MENUITEM_PAD_TOP + + ((i->h - + FEH_MENUITEM_PAD_TOP - + FEH_MENUITEM_PAD_BOTTOM + - + FEH_MENU_SUBMENU_H) / + 2), FEH_MENU_SUBMENU_W, + FEH_MENU_SUBMENU_H, im, ox, oy, MENU_ITEM_IS_SELECTED(i)); + } + if (i->is_toggle) { + D(5, ("toggleable item\n")); + feh_menu_draw_toggle_at(i->x + i->toggle_x, + i->y + + FEH_MENUITEM_PAD_TOP + + ((i->h - + FEH_MENUITEM_PAD_TOP - + FEH_MENUITEM_PAD_BOTTOM - + FEH_MENU_TOGGLE_H) / 2), + FEH_MENU_TOGGLE_W, FEH_MENU_TOGGLE_H, im, ox, oy, MENU_ITEM_IS_ON(i)); + } + } else { + D(5, ("separator item\n")); + feh_menu_draw_separator_at(i->x, i->y, i->w, i->h, im, ox, oy); + } + D_RETURN_(5); + m = NULL; +} + +void feh_menu_redraw(feh_menu * m) +{ + Imlib_Updates u, uu; + + D_ENTER(5); + + if ((!m->needs_redraw) || (!m->visible) || (!m->updates)) + D_RETURN_(5); + m->needs_redraw = 0; + if (!m->pmap) + m->pmap = XCreatePixmap(disp, m->win, m->w, m->h, depth); + XSetWindowBackgroundPixmap(disp, m->win, m->pmap); + + u = imlib_updates_merge_for_rendering(m->updates, m->w, m->h); + m->updates = NULL; + if (u) { + D(5, ("I have updates to render\n")); + for (uu = u; u; u = imlib_updates_get_next(u)) { + int x, y, w, h; + Imlib_Image im; + + imlib_updates_get_coordinates(u, &x, &y, &w, &h); + D(5, ("update coords %d,%d %d*%d\n", x, y, w, h)); + im = imlib_create_image(w, h); + gib_imlib_image_fill_rectangle(im, 0, 0, w, h, 0, 0, 0, 0); + if (im) { + feh_menu_draw_to_buf(m, im, x, y); + gib_imlib_render_image_on_drawable(m->pmap, im, x, y, 1, 0, 0); + gib_imlib_free_image(im); + XClearArea(disp, m->win, x, y, w, h, False); + } + } + imlib_updates_free(uu); + } + D_RETURN_(5); +} + +feh_menu *feh_menu_find(char *name) +{ + feh_menu_list *l; + + D_ENTER(4); + for (l = menus; l; l = l->next) { + if ((l->menu->name) && (!strcmp(l->menu->name, name))) + D_RETURN(4, l->menu); + } + D_RETURN(4, NULL); +} + +void feh_menu_draw_to_buf(feh_menu * m, Imlib_Image im, int ox, int oy) +{ + feh_menu_item *i; + int w, h; + + D_ENTER(5); + w = gib_imlib_image_get_width(im); + h = gib_imlib_image_get_height(im); + + feh_menu_draw_menu_bg(m, im, ox, oy); - D_ENTER(5); + for (i = m->items; i; i = i->next) { + if (RECTS_INTERSECT(i->x, i->y, i->w, i->h, ox, oy, w, h)) + feh_menu_draw_item(m, i, im, ox, oy); + } + D_RETURN_(5); +} + +void feh_menu_draw_menu_bg(feh_menu * m, Imlib_Image im, int ox, int oy) +{ + int w, h; - x -= ox; - y -= oy; + D_ENTER(5); - imlib_context_set_image(dst); - poly = imlib_polygon_new(); - imlib_polygon_add_point(poly, x + 2, y + 5); - imlib_polygon_add_point(poly, x + 5, y + 7); - imlib_polygon_add_point(poly, x + 2, y + 11); - imlib_context_set_color(0, 0, 0, 60); - imlib_image_fill_polygon(poly); - imlib_polygon_free(poly); + w = gib_imlib_image_get_width(im); + h = gib_imlib_image_get_height(im); - poly = imlib_polygon_new(); - imlib_polygon_add_point(poly, x, y + 3); - imlib_polygon_add_point(poly, x + 3, y + 6); - imlib_polygon_add_point(poly, x, y + 9); - imlib_context_set_color(0, 0, 0, 255); - imlib_image_fill_polygon(poly); - imlib_polygon_free(poly); + if (m->bg) + gib_imlib_blend_image_onto_image(im, m->bg, 0, ox, oy, w, h, 0, 0, w, h, 0, 0, 0); + else + gib_imlib_image_fill_rectangle(im, 0, 0, w, h, 205, 203, 176, 255); - D_RETURN_(5); - selected = 0; + D_RETURN_(5); } +void feh_menu_draw_toggle_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy, int on) +{ + D_ENTER(5); + x -= ox; + y -= oy; + if (on) + gib_imlib_image_fill_rectangle(dst, x, y, w, h, 0, 0, 0, 255); + else + gib_imlib_image_draw_rectangle(dst, x, y, w, h, 0, 0, 0, 255); + D_RETURN_(5); +} -void -feh_menu_draw_separator_at(int x, - int y, - int w, - int h, - Imlib_Image dst, - int ox, - int oy) +void feh_menu_draw_submenu_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy, int selected) { - D_ENTER(5); - gib_imlib_image_fill_rectangle(dst, x - ox + 2, y - oy + 2, w - 4, h - 4, 0, - 0, 0, 255); - D_RETURN_(5); + ImlibPolygon poly; + + D_ENTER(5); + + x -= ox; + y -= oy; + + imlib_context_set_image(dst); + poly = imlib_polygon_new(); + imlib_polygon_add_point(poly, x + 2, y + 5); + imlib_polygon_add_point(poly, x + 5, y + 7); + imlib_polygon_add_point(poly, x + 2, y + 11); + imlib_context_set_color(0, 0, 0, 60); + imlib_image_fill_polygon(poly); + imlib_polygon_free(poly); + + poly = imlib_polygon_new(); + imlib_polygon_add_point(poly, x, y + 3); + imlib_polygon_add_point(poly, x + 3, y + 6); + imlib_polygon_add_point(poly, x, y + 9); + imlib_context_set_color(0, 0, 0, 255); + imlib_image_fill_polygon(poly); + imlib_polygon_free(poly); + + D_RETURN_(5); + selected = 0; } -void -feh_menu_item_draw_at(int x, - int y, - int w, - int h, - Imlib_Image dst, - int ox, - int oy, - int selected) +void feh_menu_draw_separator_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy) { - D_ENTER(5); - imlib_context_set_image(dst); - if (selected) - gib_imlib_image_fill_rectangle(dst, x - ox, y - oy, w, h, 255, 255, 255, - 178); - D_RETURN_(5); + D_ENTER(5); + gib_imlib_image_fill_rectangle(dst, x - ox + 2, y - oy + 2, w - 4, h - 4, 0, 0, 0, 255); + D_RETURN_(5); } +void feh_menu_item_draw_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy, int selected) +{ + D_ENTER(5); + imlib_context_set_image(dst); + if (selected) + gib_imlib_image_fill_rectangle(dst, x - ox, y - oy, w, h, 255, 255, 255, 178); + D_RETURN_(5); +} -void -feh_raise_all_menus(void) +void feh_raise_all_menus(void) { - feh_menu_list *l; + feh_menu_list *l; - D_ENTER(5); + D_ENTER(5); - for (l = menus; l; l = l->next) { - if (l->menu->visible) - XRaiseWindow(disp, l->menu->win); - } - D_RETURN_(5); + for (l = menus; l; l = l->next) { + if (l->menu->visible) + XRaiseWindow(disp, l->menu->win); + } + D_RETURN_(5); } -void -feh_redraw_menus(void) +void feh_redraw_menus(void) { - feh_menu_list *l; + feh_menu_list *l; - D_ENTER(5); + D_ENTER(5); - for (l = menus; l; l = l->next) { - if (l->menu->needs_redraw) - feh_menu_redraw(l->menu); - } + for (l = menus; l; l = l->next) { + if (l->menu->needs_redraw) + feh_menu_redraw(l->menu); + } - D_RETURN_(5); + D_RETURN_(5); } -feh_menu * -feh_menu_get_from_window(Window win) +feh_menu *feh_menu_get_from_window(Window win) { - feh_menu_list *l; + feh_menu_list *l; - D_ENTER(5); - for (l = menus; l; l = l->next) - if (l->menu->win == win) - D_RETURN(5, l->menu); - D_RETURN(5, NULL); + D_ENTER(5); + for (l = menus; l; l = l->next) + if (l->menu->win == win) + D_RETURN(5, l->menu); + D_RETURN(5, NULL); } -void -feh_menu_init_main(void) +void feh_menu_init_main(void) { - feh_menu *m; - feh_menu_item *mi; + feh_menu *m; + feh_menu_item *mi; - D_ENTER(4); - if (!common_menus) - feh_menu_init_common(); + D_ENTER(4); + if (!common_menus) + feh_menu_init_common(); - menu_main = feh_menu_new(); - menu_main->name = estrdup("MAIN"); + menu_main = feh_menu_new(); + menu_main->name = estrdup("MAIN"); - feh_menu_add_entry(menu_main, "File", NULL, "FILE", NULL, NULL, NULL); - if (opt.slideshow || opt.multiwindow) { + feh_menu_add_entry(menu_main, "File", NULL, "FILE", NULL, NULL, NULL); + if (opt.slideshow || opt.multiwindow) { #if 0 - feh_menu_item *mi; + feh_menu_item *mi; - mi = - feh_menu_add_entry(menu_main, "Jump to", NULL, "JUMP", NULL, NULL, - NULL); - mi->func_gen_sub = feh_menu_func_gen_jump; + mi = feh_menu_add_entry(menu_main, "Jump to", NULL, "JUMP", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_jump; #endif - feh_menu_add_entry(menu_main, "Sort List", NULL, "SORT", NULL, NULL, - NULL); - mi = - feh_menu_add_entry(menu_main, "Image Info", NULL, "INFO", NULL, NULL, - NULL); - mi->func_gen_sub = feh_menu_func_gen_info; - feh_menu_add_entry(menu_main, NULL, NULL, NULL, NULL, NULL, NULL); - } - mi = - feh_menu_add_entry(menu_main, "Options", NULL, "OPTIONS", NULL, NULL, - NULL); - mi->func_gen_sub = feh_menu_func_gen_options; - - if (!opt.full_screen) - feh_menu_add_entry(menu_main, "About " PACKAGE, NULL, NULL, - feh_menu_cb_about, NULL, NULL); - if (opt.multiwindow) - feh_menu_add_entry(menu_main, "Close", NULL, NULL, feh_menu_cb_close, - NULL, NULL); - feh_menu_add_entry(menu_main, "Exit", NULL, NULL, feh_menu_cb_exit, NULL, - NULL); - - m = feh_menu_new(); - m->name = estrdup("FILE"); - feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); - feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, - NULL); - feh_menu_add_entry(m, "Reload", NULL, NULL, feh_menu_cb_reload, NULL, NULL); - feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, - NULL, NULL); - feh_menu_add_entry(m, "Save List", NULL, NULL, - feh_menu_cb_save_filelist, NULL, NULL); - feh_menu_add_entry(m, "Edit in Place", NULL, "EDIT", NULL, NULL, NULL); - feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); - feh_menu_add_entry(m, NULL, NULL, NULL, NULL, NULL, NULL); - feh_menu_add_entry(m, "Hide", NULL, NULL, feh_menu_cb_remove, NULL, NULL); - feh_menu_add_entry(m, "Delete", NULL, "CONFIRM", NULL, NULL, NULL); - - D_RETURN_(4); -} - - -void -feh_menu_init_common() -{ - int num_desks, i; - char buf[30]; - feh_menu *m; - - D_ENTER(4); - - if (!opt.menu_fn) { - opt.menu_fn = gib_imlib_load_font(opt.menu_font); - if (!opt.menu_fn) - eprintf - ("couldn't load menu font %s, did you make install?\nAre you specifying a nonexistant font?\nDid you tell feh where to find it with --fontpath?", - opt.menu_font); - } - if (!opt.menu_style_l) { - opt.menu_style_l = gib_style_new_from_ascii(opt.menu_style); - if (!opt.menu_style_l) { - weprintf - ("couldn't load style file for menu fonts, (%s).\nDid you make install? Menus will look boring without the style file.", - opt.menu_style); - } - } - - m = feh_menu_new(); - m->name = estrdup("SORT"); - - feh_menu_add_entry(m, "By File Name", NULL, NULL, feh_menu_cb_sort_filename, - NULL, NULL); - feh_menu_add_entry(m, "By Image Name", NULL, NULL, - feh_menu_cb_sort_imagename, NULL, NULL); - if (opt.preload || (opt.sort > SORT_FILENAME)) - feh_menu_add_entry(m, "By File Size", NULL, NULL, - feh_menu_cb_sort_filesize, NULL, NULL); - feh_menu_add_entry(m, "Randomize", NULL, NULL, feh_menu_cb_sort_randomize, - NULL, NULL); - - m = feh_menu_new(); - m->name = estrdup("CONFIRM"); - feh_menu_add_entry(m, "Confirm", NULL, NULL, feh_menu_cb_delete, NULL, - NULL); - - m = feh_menu_new(); - m->name = estrdup("EDIT"); - feh_menu_add_entry(m, "Rotate 90 CW", NULL, NULL, feh_menu_cb_edit_rotate, - (void *) 1, NULL); - feh_menu_add_entry(m, "Rotate 180", NULL, NULL, feh_menu_cb_edit_rotate, - (void *) 2, NULL); - feh_menu_add_entry(m, "Rotate 90 CCW", NULL, NULL, feh_menu_cb_edit_rotate, - (void *) 3, NULL); - - menu_bg = feh_menu_new(); - menu_bg->name = estrdup("BACKGROUND"); - - num_desks = feh_wm_get_num_desks(); - if (num_desks > 1) { - feh_menu_add_entry(menu_bg, "Set Tiled", NULL, "TILED", NULL, NULL, NULL); - feh_menu_add_entry(menu_bg, "Set Seamless", NULL, "SEAMLESS", NULL, NULL, - NULL); - feh_menu_add_entry(menu_bg, "Set Scaled", NULL, "SCALED", NULL, NULL, - NULL); - feh_menu_add_entry(menu_bg, "Set Centered", NULL, "CENTERED", NULL, NULL, - NULL); - - m = feh_menu_new(); - m->name = estrdup("TILED"); - for (i = 0; i < num_desks; i++) { - snprintf(buf, sizeof(buf), "Desktop %d", i + 1); - if (opt.slideshow || opt.multiwindow) - feh_menu_add_entry(m, buf, NULL, NULL, - feh_menu_cb_background_set_tiled, (void *) i, - NULL); - else - feh_menu_add_entry(m, buf, NULL, NULL, - feh_menu_cb_background_set_tiled_no_file, - (void *) i, NULL); - } - - m = feh_menu_new(); - m->name = estrdup("SEAMLESS"); - for (i = 0; i < num_desks; i++) { - snprintf(buf, sizeof(buf), "Desktop %d", i + 1); - feh_menu_add_entry(m, buf, NULL, NULL, - feh_menu_cb_background_set_seamless, (void *) i, - NULL); - } - - - m = feh_menu_new(); - m->name = estrdup("SCALED"); - for (i = 0; i < num_desks; i++) { - snprintf(buf, sizeof(buf), "Desktop %d", i + 1); - - if (opt.slideshow || opt.multiwindow) - feh_menu_add_entry(m, buf, NULL, NULL, - feh_menu_cb_background_set_scaled, (void *) i, - NULL); - else - feh_menu_add_entry(m, buf, NULL, NULL, - feh_menu_cb_background_set_scaled_no_file, - (void *) i, NULL); - } - - m = feh_menu_new(); - m->name = estrdup("CENTERED"); - for (i = 0; i < num_desks; i++) { - snprintf(buf, sizeof(buf), "Desktop %d", i + 1); - if (opt.slideshow || opt.multiwindow) - feh_menu_add_entry(m, buf, NULL, NULL, - feh_menu_cb_background_set_centered, (void *) i, - NULL); - else - feh_menu_add_entry(m, buf, NULL, NULL, - feh_menu_cb_background_set_centered_no_file, - (void *) i, NULL); - } - } else { - if (opt.slideshow || opt.multiwindow) { - feh_menu_add_entry(menu_bg, "Set Tiled", NULL, NULL, - feh_menu_cb_background_set_tiled, NULL, NULL); - feh_menu_add_entry(menu_bg, "Set Seamless", NULL, NULL, - feh_menu_cb_background_set_seamless, NULL, NULL); - feh_menu_add_entry(menu_bg, "Set Scaled", NULL, NULL, - feh_menu_cb_background_set_scaled, NULL, NULL); - feh_menu_add_entry(menu_bg, "Set Centered", NULL, NULL, - feh_menu_cb_background_set_centered, NULL, NULL); - } else { - feh_menu_add_entry(menu_bg, "Set Tiled", NULL, NULL, - feh_menu_cb_background_set_tiled_no_file, NULL, - NULL); - feh_menu_add_entry(menu_bg, "Set Seamless", NULL, NULL, - feh_menu_cb_background_set_seamless, NULL, NULL); - feh_menu_add_entry(menu_bg, "Set Scaled", NULL, NULL, - feh_menu_cb_background_set_scaled_no_file, NULL, - NULL); - feh_menu_add_entry(menu_bg, "Set Centered", NULL, NULL, - feh_menu_cb_background_set_centered_no_file, NULL, - NULL); - } - } - common_menus = 1; - - D_RETURN_(4); -} - -void -feh_menu_init_about_win(void) -{ - D_ENTER(4); - - menu_about_win = feh_menu_new(); - menu_about_win->name = estrdup("ABOUTWIN"); - - feh_menu_add_entry(menu_about_win, "Close", NULL, NULL, feh_menu_cb_close, - NULL, NULL); - feh_menu_add_entry(menu_about_win, "Exit", NULL, NULL, feh_menu_cb_exit, - NULL, NULL); - - D_RETURN_(4); -} - -void -feh_menu_init_single_win(void) -{ - feh_menu *m; - feh_menu_item *mi; - - D_ENTER(4); - if (!common_menus) - feh_menu_init_common(); - - menu_single_win = feh_menu_new(); - menu_single_win->name = estrdup("SINGLEWIN"); - - feh_menu_add_entry(menu_single_win, "File", NULL, "SINGLEWIN_FILE", NULL, - NULL, NULL); - m = feh_menu_new(); - m->name = estrdup("SINGLEWIN_FILE"); - feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); - feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, - NULL); - feh_menu_add_entry(m, "Reload", NULL, NULL, feh_menu_cb_reload, NULL, NULL); - feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, - NULL, NULL); - feh_menu_add_entry(m, "Save List", NULL, NULL, - feh_menu_cb_save_filelist, NULL, NULL); - feh_menu_add_entry(m, "Edit in Place", NULL, "EDIT", NULL, NULL, NULL); - feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); - if (opt.multiwindow || opt.slideshow) { - feh_menu_add_entry(m, NULL, NULL, NULL, NULL, NULL, NULL); - feh_menu_add_entry(m, "Hide", NULL, NULL, feh_menu_cb_remove, NULL, NULL); - feh_menu_add_entry(m, "Delete", NULL, "CONFIRM", NULL, NULL, NULL); - } - - mi = - feh_menu_add_entry(menu_single_win, "Image Info", NULL, "INFO", NULL, - NULL, NULL); - mi->func_gen_sub = feh_menu_func_gen_info; - feh_menu_add_entry(menu_single_win, NULL, NULL, NULL, NULL, NULL, NULL); - mi = - feh_menu_add_entry(menu_single_win, "Options", NULL, "OPTIONS", NULL, - NULL, NULL); - mi->func_gen_sub = feh_menu_func_gen_options; - feh_menu_add_entry(menu_single_win, "About " PACKAGE, NULL, NULL, - feh_menu_cb_about, NULL, NULL); - feh_menu_add_entry(menu_single_win, "Close", NULL, NULL, feh_menu_cb_close, - NULL, NULL); - feh_menu_add_entry(menu_single_win, "Exit", NULL, NULL, feh_menu_cb_exit, - NULL, NULL); - - D_RETURN_(4); -} - -void -feh_menu_init_thumbnail_win(void) -{ - feh_menu *m; - feh_menu_item *mi; - - D_ENTER(4); - if (!common_menus) - feh_menu_init_common(); - - menu_thumbnail_win = feh_menu_new(); - menu_thumbnail_win->name = estrdup("THUMBWIN"); - - feh_menu_add_entry(menu_thumbnail_win, "File", NULL, "THUMBWIN_FILE", NULL, - NULL, NULL); - m = feh_menu_new(); - m->name = estrdup("THUMBWIN_FILE"); - feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); - feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, - NULL); - feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, - NULL, NULL); - feh_menu_add_entry(m, "Save List", NULL, NULL, - feh_menu_cb_save_filelist, NULL, NULL); - feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); - feh_menu_add_entry(menu_thumbnail_win, NULL, NULL, NULL, NULL, NULL, NULL); - mi = - feh_menu_add_entry(menu_thumbnail_win, "Options", NULL, "OPTIONS", NULL, - NULL, NULL); - mi->func_gen_sub = feh_menu_func_gen_options; - feh_menu_add_entry(menu_thumbnail_win, "About " PACKAGE, NULL, NULL, - feh_menu_cb_about, NULL, NULL); - feh_menu_add_entry(menu_thumbnail_win, "Close", NULL, NULL, - feh_menu_cb_close, NULL, NULL); - feh_menu_add_entry(menu_thumbnail_win, "Exit", NULL, NULL, feh_menu_cb_exit, - NULL, NULL); - D_RETURN_(4); -} - - -void -feh_menu_init_thumbnail_viewer(void) -{ - feh_menu *m; - feh_menu_item *mi; - - D_ENTER(4); - if (!common_menus) - feh_menu_init_common(); - - menu_thumbnail_viewer = feh_menu_new(); - menu_thumbnail_viewer->name = estrdup("THUMBVIEW"); - - feh_menu_add_entry(menu_thumbnail_viewer, "File", NULL, "THUMBVIEW_FILE", - NULL, NULL, NULL); - m = feh_menu_new(); - m->name = estrdup("THUMBVIEW_FILE"); - feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); - feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, - NULL); - feh_menu_add_entry(m, "Reload", NULL, NULL, feh_menu_cb_reload, NULL, NULL); - feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, - NULL, NULL); - feh_menu_add_entry(m, "Save List", NULL, NULL, - feh_menu_cb_save_filelist, NULL, NULL); - feh_menu_add_entry(m, "Edit in Place", NULL, "EDIT", NULL, NULL, NULL); - feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); - feh_menu_add_entry(m, NULL, NULL, NULL, NULL, NULL, NULL); - feh_menu_add_entry(m, "Hide", NULL, NULL, feh_menu_cb_remove_thumb, NULL, - NULL); - feh_menu_add_entry(m, "Delete", NULL, "THUMBVIEW_CONFIRM", NULL, NULL, - NULL); - mi = - feh_menu_add_entry(menu_thumbnail_viewer, "Image Info", NULL, "INFO", - NULL, NULL, NULL); - mi->func_gen_sub = feh_menu_func_gen_info; - feh_menu_add_entry(menu_thumbnail_viewer, NULL, NULL, NULL, NULL, NULL, - NULL); - mi = - feh_menu_add_entry(menu_thumbnail_viewer, "Options", NULL, "OPTIONS", - NULL, NULL, NULL); - mi->func_gen_sub = feh_menu_func_gen_options; - feh_menu_add_entry(menu_thumbnail_viewer, "About " PACKAGE, NULL, NULL, - feh_menu_cb_about, NULL, NULL); - feh_menu_add_entry(menu_thumbnail_viewer, "Close", NULL, NULL, - feh_menu_cb_close, NULL, NULL); - feh_menu_add_entry(menu_thumbnail_viewer, "Exit", NULL, NULL, - feh_menu_cb_exit, NULL, NULL); - m = feh_menu_new(); - m->name = estrdup("THUMBVIEW_CONFIRM"); - feh_menu_add_entry(m, "Confirm", NULL, NULL, feh_menu_cb_delete_thumb, NULL, - NULL); - D_RETURN_(4); -} - -static void -feh_menu_cb_background_set_tiled(feh_menu * m, - feh_menu_item * i, - void *data) -{ - char *path; - - D_ENTER(4); - path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); - feh_wm_set_bg(path, m->fehwin->im, 0, 0, (int) data, 1); - free(path); - D_RETURN_(4); - i = NULL; -} - -static void -feh_menu_cb_background_set_seamless(feh_menu * m, - feh_menu_item * i, - void *data) -{ - Imlib_Image im; - - D_ENTER(4); - im = gib_imlib_clone_image(m->fehwin->im); - gib_imlib_image_tile(im); - feh_wm_set_bg(NULL, im, 0, 0, (int) data, 1); - gib_imlib_free_image_and_decache(im); - D_RETURN_(4); - i = NULL; -} - -static void -feh_menu_cb_background_set_scaled(feh_menu * m, - feh_menu_item * i, - void *data) -{ - char *path; - - D_ENTER(4); - path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); - feh_wm_set_bg(path, m->fehwin->im, 0, 1, (int) data, 1); - free(path); - D_RETURN_(4); - i = NULL; -} - -static void -feh_menu_cb_background_set_centered(feh_menu * m, - feh_menu_item * i, - void *data) -{ - char *path; - - D_ENTER(4); - path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); - feh_wm_set_bg(path, m->fehwin->im, 1, 0, (int) data, 1); - free(path); - D_RETURN_(4); - i = NULL; -} - -static void -feh_menu_cb_background_set_tiled_no_file(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, (int) data, 1); - D_RETURN_(4); - i = NULL; -} - -static void -feh_menu_cb_background_set_scaled_no_file(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_wm_set_bg(NULL, m->fehwin->im, 0, 1, (int) data, 1); - D_RETURN_(4); - i = NULL; -} - -static void -feh_menu_cb_background_set_centered_no_file(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_wm_set_bg(NULL, m->fehwin->im, 1, 0, (int) data, 1); - D_RETURN_(4); - i = NULL; -} - -static void -feh_menu_cb_about(feh_menu * m, - feh_menu_item * i, - void *data) + feh_menu_add_entry(menu_main, "Sort List", NULL, "SORT", NULL, NULL, NULL); + mi = feh_menu_add_entry(menu_main, "Image Info", NULL, "INFO", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_info; + feh_menu_add_entry(menu_main, NULL, NULL, NULL, NULL, NULL, NULL); + } + mi = feh_menu_add_entry(menu_main, "Options", NULL, "OPTIONS", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_options; + + if (!opt.full_screen) + feh_menu_add_entry(menu_main, "About " PACKAGE, NULL, NULL, feh_menu_cb_about, NULL, NULL); + if (opt.multiwindow) + feh_menu_add_entry(menu_main, "Close", NULL, NULL, feh_menu_cb_close, NULL, NULL); + feh_menu_add_entry(menu_main, "Exit", NULL, NULL, feh_menu_cb_exit, NULL, NULL); + + m = feh_menu_new(); + m->name = estrdup("FILE"); + feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); + feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, NULL); + feh_menu_add_entry(m, "Reload", NULL, NULL, feh_menu_cb_reload, NULL, NULL); + feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, NULL, NULL); + feh_menu_add_entry(m, "Save List", NULL, NULL, feh_menu_cb_save_filelist, NULL, NULL); + feh_menu_add_entry(m, "Edit in Place", NULL, "EDIT", NULL, NULL, NULL); + feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); + feh_menu_add_entry(m, NULL, NULL, NULL, NULL, NULL, NULL); + feh_menu_add_entry(m, "Hide", NULL, NULL, feh_menu_cb_remove, NULL, NULL); + feh_menu_add_entry(m, "Delete", NULL, "CONFIRM", NULL, NULL, NULL); + + D_RETURN_(4); +} + +void feh_menu_init_common() +{ + int num_desks, i; + char buf[30]; + feh_menu *m; + + D_ENTER(4); + + if (!opt.menu_fn) { + opt.menu_fn = gib_imlib_load_font(opt.menu_font); + if (!opt.menu_fn) + eprintf + ("couldn't load menu font %s, did you make install?\nAre you specifying a nonexistant font?\nDid you tell feh where to find it with --fontpath?", + opt.menu_font); + } + if (!opt.menu_style_l) { + opt.menu_style_l = gib_style_new_from_ascii(opt.menu_style); + if (!opt.menu_style_l) { + weprintf + ("couldn't load style file for menu fonts, (%s).\nDid you make install? Menus will look boring without the style file.", + opt.menu_style); + } + } + + m = feh_menu_new(); + m->name = estrdup("SORT"); + + feh_menu_add_entry(m, "By File Name", NULL, NULL, feh_menu_cb_sort_filename, NULL, NULL); + feh_menu_add_entry(m, "By Image Name", NULL, NULL, feh_menu_cb_sort_imagename, NULL, NULL); + if (opt.preload || (opt.sort > SORT_FILENAME)) + feh_menu_add_entry(m, "By File Size", NULL, NULL, feh_menu_cb_sort_filesize, NULL, NULL); + feh_menu_add_entry(m, "Randomize", NULL, NULL, feh_menu_cb_sort_randomize, NULL, NULL); + + m = feh_menu_new(); + m->name = estrdup("CONFIRM"); + feh_menu_add_entry(m, "Confirm", NULL, NULL, feh_menu_cb_delete, NULL, NULL); + + m = feh_menu_new(); + m->name = estrdup("EDIT"); + feh_menu_add_entry(m, "Rotate 90 CW", NULL, NULL, feh_menu_cb_edit_rotate, (void *) 1, NULL); + feh_menu_add_entry(m, "Rotate 180", NULL, NULL, feh_menu_cb_edit_rotate, (void *) 2, NULL); + feh_menu_add_entry(m, "Rotate 90 CCW", NULL, NULL, feh_menu_cb_edit_rotate, (void *) 3, NULL); + + menu_bg = feh_menu_new(); + menu_bg->name = estrdup("BACKGROUND"); + + num_desks = feh_wm_get_num_desks(); + if (num_desks > 1) { + feh_menu_add_entry(menu_bg, "Set Tiled", NULL, "TILED", NULL, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Seamless", NULL, "SEAMLESS", NULL, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Scaled", NULL, "SCALED", NULL, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Centered", NULL, "CENTERED", NULL, NULL, NULL); + + m = feh_menu_new(); + m->name = estrdup("TILED"); + for (i = 0; i < num_desks; i++) { + snprintf(buf, sizeof(buf), "Desktop %d", i + 1); + if (opt.slideshow || opt.multiwindow) + feh_menu_add_entry(m, buf, NULL, NULL, + feh_menu_cb_background_set_tiled, (void *) i, NULL); + else + feh_menu_add_entry(m, buf, NULL, NULL, + feh_menu_cb_background_set_tiled_no_file, (void *) i, NULL); + } + + m = feh_menu_new(); + m->name = estrdup("SEAMLESS"); + for (i = 0; i < num_desks; i++) { + snprintf(buf, sizeof(buf), "Desktop %d", i + 1); + feh_menu_add_entry(m, buf, NULL, NULL, feh_menu_cb_background_set_seamless, (void *) i, NULL); + } + + m = feh_menu_new(); + m->name = estrdup("SCALED"); + for (i = 0; i < num_desks; i++) { + snprintf(buf, sizeof(buf), "Desktop %d", i + 1); + + if (opt.slideshow || opt.multiwindow) + feh_menu_add_entry(m, buf, NULL, NULL, + feh_menu_cb_background_set_scaled, (void *) i, NULL); + else + feh_menu_add_entry(m, buf, NULL, NULL, + feh_menu_cb_background_set_scaled_no_file, (void *) i, NULL); + } + + m = feh_menu_new(); + m->name = estrdup("CENTERED"); + for (i = 0; i < num_desks; i++) { + snprintf(buf, sizeof(buf), "Desktop %d", i + 1); + if (opt.slideshow || opt.multiwindow) + feh_menu_add_entry(m, buf, NULL, NULL, + feh_menu_cb_background_set_centered, (void *) i, NULL); + else + feh_menu_add_entry(m, buf, NULL, NULL, + feh_menu_cb_background_set_centered_no_file, (void *) i, NULL); + } + } else { + if (opt.slideshow || opt.multiwindow) { + feh_menu_add_entry(menu_bg, "Set Tiled", NULL, + NULL, feh_menu_cb_background_set_tiled, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Seamless", NULL, + NULL, feh_menu_cb_background_set_seamless, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Scaled", NULL, + NULL, feh_menu_cb_background_set_scaled, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Centered", NULL, + NULL, feh_menu_cb_background_set_centered, NULL, NULL); + } else { + feh_menu_add_entry(menu_bg, "Set Tiled", NULL, + NULL, feh_menu_cb_background_set_tiled_no_file, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Seamless", NULL, + NULL, feh_menu_cb_background_set_seamless, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Scaled", NULL, + NULL, feh_menu_cb_background_set_scaled_no_file, NULL, NULL); + feh_menu_add_entry(menu_bg, "Set Centered", NULL, + NULL, feh_menu_cb_background_set_centered_no_file, NULL, NULL); + } + } + common_menus = 1; + + D_RETURN_(4); +} + +void feh_menu_init_about_win(void) +{ + D_ENTER(4); + + menu_about_win = feh_menu_new(); + menu_about_win->name = estrdup("ABOUTWIN"); + + feh_menu_add_entry(menu_about_win, "Close", NULL, NULL, feh_menu_cb_close, NULL, NULL); + feh_menu_add_entry(menu_about_win, "Exit", NULL, NULL, feh_menu_cb_exit, NULL, NULL); + + D_RETURN_(4); +} + +void feh_menu_init_single_win(void) +{ + feh_menu *m; + feh_menu_item *mi; + + D_ENTER(4); + if (!common_menus) + feh_menu_init_common(); + + menu_single_win = feh_menu_new(); + menu_single_win->name = estrdup("SINGLEWIN"); + + feh_menu_add_entry(menu_single_win, "File", NULL, "SINGLEWIN_FILE", NULL, NULL, NULL); + m = feh_menu_new(); + m->name = estrdup("SINGLEWIN_FILE"); + feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); + feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, NULL); + feh_menu_add_entry(m, "Reload", NULL, NULL, feh_menu_cb_reload, NULL, NULL); + feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, NULL, NULL); + feh_menu_add_entry(m, "Save List", NULL, NULL, feh_menu_cb_save_filelist, NULL, NULL); + feh_menu_add_entry(m, "Edit in Place", NULL, "EDIT", NULL, NULL, NULL); + feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); + if (opt.multiwindow || opt.slideshow) { + feh_menu_add_entry(m, NULL, NULL, NULL, NULL, NULL, NULL); + feh_menu_add_entry(m, "Hide", NULL, NULL, feh_menu_cb_remove, NULL, NULL); + feh_menu_add_entry(m, "Delete", NULL, "CONFIRM", NULL, NULL, NULL); + } + + mi = feh_menu_add_entry(menu_single_win, "Image Info", NULL, "INFO", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_info; + feh_menu_add_entry(menu_single_win, NULL, NULL, NULL, NULL, NULL, NULL); + mi = feh_menu_add_entry(menu_single_win, "Options", NULL, "OPTIONS", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_options; + feh_menu_add_entry(menu_single_win, "About " PACKAGE, NULL, NULL, feh_menu_cb_about, NULL, NULL); + feh_menu_add_entry(menu_single_win, "Close", NULL, NULL, feh_menu_cb_close, NULL, NULL); + feh_menu_add_entry(menu_single_win, "Exit", NULL, NULL, feh_menu_cb_exit, NULL, NULL); + + D_RETURN_(4); +} + +void feh_menu_init_thumbnail_win(void) +{ + feh_menu *m; + feh_menu_item *mi; + + D_ENTER(4); + if (!common_menus) + feh_menu_init_common(); + + menu_thumbnail_win = feh_menu_new(); + menu_thumbnail_win->name = estrdup("THUMBWIN"); + + feh_menu_add_entry(menu_thumbnail_win, "File", NULL, "THUMBWIN_FILE", NULL, NULL, NULL); + m = feh_menu_new(); + m->name = estrdup("THUMBWIN_FILE"); + feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); + feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, NULL); + feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, NULL, NULL); + feh_menu_add_entry(m, "Save List", NULL, NULL, feh_menu_cb_save_filelist, NULL, NULL); + feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); + feh_menu_add_entry(menu_thumbnail_win, NULL, NULL, NULL, NULL, NULL, NULL); + mi = feh_menu_add_entry(menu_thumbnail_win, "Options", NULL, "OPTIONS", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_options; + feh_menu_add_entry(menu_thumbnail_win, "About " PACKAGE, NULL, NULL, feh_menu_cb_about, NULL, NULL); + feh_menu_add_entry(menu_thumbnail_win, "Close", NULL, NULL, feh_menu_cb_close, NULL, NULL); + feh_menu_add_entry(menu_thumbnail_win, "Exit", NULL, NULL, feh_menu_cb_exit, NULL, NULL); + D_RETURN_(4); +} + +void feh_menu_init_thumbnail_viewer(void) +{ + feh_menu *m; + feh_menu_item *mi; + + D_ENTER(4); + if (!common_menus) + feh_menu_init_common(); + + menu_thumbnail_viewer = feh_menu_new(); + menu_thumbnail_viewer->name = estrdup("THUMBVIEW"); + + feh_menu_add_entry(menu_thumbnail_viewer, "File", NULL, "THUMBVIEW_FILE", NULL, NULL, NULL); + m = feh_menu_new(); + m->name = estrdup("THUMBVIEW_FILE"); + feh_menu_add_entry(m, "Reset", NULL, NULL, feh_menu_cb_reset, NULL, NULL); + feh_menu_add_entry(m, "Resize Window", NULL, NULL, feh_menu_cb_fit, NULL, NULL); + feh_menu_add_entry(m, "Reload", NULL, NULL, feh_menu_cb_reload, NULL, NULL); + feh_menu_add_entry(m, "Save Image", NULL, NULL, feh_menu_cb_save_image, NULL, NULL); + feh_menu_add_entry(m, "Save List", NULL, NULL, feh_menu_cb_save_filelist, NULL, NULL); + feh_menu_add_entry(m, "Edit in Place", NULL, "EDIT", NULL, NULL, NULL); + feh_menu_add_entry(m, "Background", NULL, "BACKGROUND", NULL, NULL, NULL); + feh_menu_add_entry(m, NULL, NULL, NULL, NULL, NULL, NULL); + feh_menu_add_entry(m, "Hide", NULL, NULL, feh_menu_cb_remove_thumb, NULL, NULL); + feh_menu_add_entry(m, "Delete", NULL, "THUMBVIEW_CONFIRM", NULL, NULL, NULL); + mi = feh_menu_add_entry(menu_thumbnail_viewer, "Image Info", NULL, "INFO", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_info; + feh_menu_add_entry(menu_thumbnail_viewer, NULL, NULL, NULL, NULL, NULL, NULL); + mi = feh_menu_add_entry(menu_thumbnail_viewer, "Options", NULL, "OPTIONS", NULL, NULL, NULL); + mi->func_gen_sub = feh_menu_func_gen_options; + feh_menu_add_entry(menu_thumbnail_viewer, "About " PACKAGE, NULL, NULL, feh_menu_cb_about, NULL, NULL); + feh_menu_add_entry(menu_thumbnail_viewer, "Close", NULL, NULL, feh_menu_cb_close, NULL, NULL); + feh_menu_add_entry(menu_thumbnail_viewer, "Exit", NULL, NULL, feh_menu_cb_exit, NULL, NULL); + m = feh_menu_new(); + m->name = estrdup("THUMBVIEW_CONFIRM"); + feh_menu_add_entry(m, "Confirm", NULL, NULL, feh_menu_cb_delete_thumb, NULL, NULL); + D_RETURN_(4); +} + +static void feh_menu_cb_background_set_tiled(feh_menu * m, feh_menu_item * i, void *data) +{ + char *path; + + D_ENTER(4); + path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); + feh_wm_set_bg(path, m->fehwin->im, 0, 0, (int) data, 1); + free(path); + D_RETURN_(4); + i = NULL; +} + +static void feh_menu_cb_background_set_seamless(feh_menu * m, feh_menu_item * i, void *data) +{ + Imlib_Image im; + + D_ENTER(4); + im = gib_imlib_clone_image(m->fehwin->im); + gib_imlib_image_tile(im); + feh_wm_set_bg(NULL, im, 0, 0, (int) data, 1); + gib_imlib_free_image_and_decache(im); + D_RETURN_(4); + i = NULL; +} + +static void feh_menu_cb_background_set_scaled(feh_menu * m, feh_menu_item * i, void *data) +{ + char *path; + + D_ENTER(4); + path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); + feh_wm_set_bg(path, m->fehwin->im, 0, 1, (int) data, 1); + free(path); + D_RETURN_(4); + i = NULL; +} + +static void feh_menu_cb_background_set_centered(feh_menu * m, feh_menu_item * i, void *data) { - Imlib_Image im; - winwidget winwid; - - D_ENTER(4); - if (feh_load_image_char(&im, PREFIX "/share/feh/images/about.png") != 0) { - winwid = - winwidget_create_from_image(im, "About " PACKAGE, WIN_TYPE_ABOUT); - winwid->file = - gib_list_add_front(NULL, - feh_file_new(PREFIX "/share/feh/images/about.png")); - winwidget_show(winwid); - } - D_RETURN_(4); - m = NULL; - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_close(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - winwidget_destroy(m->fehwin); - D_RETURN_(4); - i = NULL; - data = NULL; -} + char *path; -static void -feh_menu_cb_exit(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - winwidget_destroy_all(); - D_RETURN_(4); - m = NULL; - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_reset(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - if (m->fehwin->has_rotated) { - m->fehwin->im_w = gib_imlib_image_get_width(m->fehwin->im); - m->fehwin->im_h = gib_imlib_image_get_height(m->fehwin->im); - winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); - } - winwidget_reset_image(m->fehwin); - winwidget_render_image(m->fehwin, 1, 1); - D_RETURN_(4); - i = NULL; - data = NULL; -} - - -static void -feh_menu_cb_reload(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_reload_image(m->fehwin, 0, 0); - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_remove(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_filelist_image_remove(m->fehwin, 0); - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_delete(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_filelist_image_remove(m->fehwin, 1); - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_remove_thumb(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 0); - feh_filelist_image_remove(m->fehwin, 0); - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_delete_thumb(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 1); - feh_filelist_image_remove(m->fehwin, 1); - D_RETURN_(4); - i = NULL; - data = NULL; -} - - -static void -feh_menu_cb_sort_filename(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - filelist = gib_list_sort(filelist, feh_cmp_filename); - if(!opt.no_jump_on_resort){ - slideshow_change_image(m->fehwin, SLIDE_FIRST); - }; - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_sort_imagename(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - filelist = gib_list_sort(filelist, feh_cmp_name); - if(!opt.no_jump_on_resort){ - slideshow_change_image(m->fehwin, SLIDE_FIRST); - }; - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_sort_filesize(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - filelist = gib_list_sort(filelist, feh_cmp_size); - if(!opt.no_jump_on_resort){ - slideshow_change_image(m->fehwin, SLIDE_FIRST); - }; - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static void -feh_menu_cb_sort_randomize(feh_menu * m, - feh_menu_item * i, - void *data) -{ - D_ENTER(4); - filelist = gib_list_randomize(filelist); - if(!opt.no_jump_on_resort){ - slideshow_change_image(m->fehwin, SLIDE_FIRST); - }; - D_RETURN_(4); - i = NULL; - data = NULL; -} - -static feh_menu * -feh_menu_func_gen_jump(feh_menu * m, - feh_menu_item * i, - void *data) -{ - feh_menu *mm; - gib_list *l; - - D_ENTER(4); - mm = feh_menu_new(); - mm->name = estrdup("JUMP"); - for (l = filelist; l; l = l->next) { - feh_menu_add_entry(mm, FEH_FILE(l->data)->name, NULL, NULL, - feh_menu_cb_jump_to, l, NULL); - } - D_RETURN(4, mm); - m = NULL; - i = NULL; - data = NULL; -} - -static feh_menu * -feh_menu_func_gen_info(feh_menu * m, - feh_menu_item * i, - void *data) -{ - Imlib_Image im; - feh_menu *mm; - feh_file *file; - char buffer[400]; - - D_ENTER(4); - if (!m->fehwin->file) - D_RETURN(4, NULL); - file = FEH_FILE(m->fehwin->file->data); - im = m->fehwin->im; - if (!im) - D_RETURN(4, NULL); - mm = feh_menu_new(); - mm->name = estrdup("INFO"); - snprintf(buffer, sizeof(buffer), "Filename: %s", file->name); - feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); - if (!file->info) - feh_file_info_load(file, im); - if (file->info) { - snprintf(buffer, sizeof(buffer), "Size: %dKb", file->info->size / 1024); - feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); - snprintf(buffer, sizeof(buffer), "Dimensions: %dx%d", file->info->width, - file->info->height); - feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); - snprintf(buffer, sizeof(buffer), "Type: %s", file->info->format); - feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); - } - - mm->func_free = feh_menu_func_free_info; - D_RETURN(4, mm); - i = NULL; - data = NULL; -} - -static void -feh_menu_func_free_info(feh_menu * m, - void *data) -{ - D_ENTER(4); - feh_menu_free(m); - D_RETURN_(4); - data = NULL; -} - - -static feh_menu * -feh_menu_func_gen_options(feh_menu * m, - feh_menu_item * i, - void *data) -{ - feh_menu *mm; - - D_ENTER(4); - mm = feh_menu_new(); - mm->name = estrdup("OPTIONS"); - mm->fehwin = m->fehwin; - feh_menu_add_toggle_entry(mm, "Auto-Zoom", NULL, NULL, - feh_menu_cb_opt_auto_zoom, NULL, NULL, - opt.auto_zoom); - feh_menu_add_toggle_entry(mm, "Freeze Window Size", NULL, NULL, - feh_menu_cb_opt_freeze_window, NULL, NULL, - opt.geom_flags); - feh_menu_add_toggle_entry(mm, "Fullscreen", NULL, NULL, - feh_menu_cb_opt_fullscreen, NULL, NULL, - m->fehwin->full_screen); + D_ENTER(4); + path = feh_absolute_path(FEH_FILE(m->fehwin->file->data)->filename); + feh_wm_set_bg(path, m->fehwin->im, 1, 0, (int) data, 1); + free(path); + D_RETURN_(4); + i = NULL; +} + +static void feh_menu_cb_background_set_tiled_no_file(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_wm_set_bg(NULL, m->fehwin->im, 0, 0, (int) data, 1); + D_RETURN_(4); + i = NULL; +} + +static void feh_menu_cb_background_set_scaled_no_file(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_wm_set_bg(NULL, m->fehwin->im, 0, 1, (int) data, 1); + D_RETURN_(4); + i = NULL; +} + +static void feh_menu_cb_background_set_centered_no_file(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_wm_set_bg(NULL, m->fehwin->im, 1, 0, (int) data, 1); + D_RETURN_(4); + i = NULL; +} + +static void feh_menu_cb_about(feh_menu * m, feh_menu_item * i, void *data) +{ + Imlib_Image im; + winwidget winwid; + + D_ENTER(4); + if (feh_load_image_char(&im, PREFIX "/share/feh/images/about.png") + != 0) { + winwid = winwidget_create_from_image(im, "About " PACKAGE, WIN_TYPE_ABOUT); + winwid->file = gib_list_add_front(NULL, feh_file_new(PREFIX "/share/feh/images/about.png")); + winwidget_show(winwid); + } + D_RETURN_(4); + m = NULL; + i = NULL; + data = NULL; +} + +static void feh_menu_cb_close(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + winwidget_destroy(m->fehwin); + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_exit(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + winwidget_destroy_all(); + D_RETURN_(4); + m = NULL; + i = NULL; + data = NULL; +} + +static void feh_menu_cb_reset(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + if (m->fehwin->has_rotated) { + m->fehwin->im_w = gib_imlib_image_get_width(m->fehwin->im); + m->fehwin->im_h = gib_imlib_image_get_height(m->fehwin->im); + winwidget_resize(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); + } + winwidget_reset_image(m->fehwin); + winwidget_render_image(m->fehwin, 1, 1); + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_reload(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_reload_image(m->fehwin, 0, 0); + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_remove(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_filelist_image_remove(m->fehwin, 0); + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_delete(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_filelist_image_remove(m->fehwin, 1); + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_remove_thumb(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 0); + feh_filelist_image_remove(m->fehwin, 0); + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_delete_thumb(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + feh_thumbnail_mark_removed(FEH_FILE(m->fehwin->file->data), 1); + feh_filelist_image_remove(m->fehwin, 1); + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_sort_filename(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + filelist = gib_list_sort(filelist, feh_cmp_filename); + if (!opt.no_jump_on_resort) { + slideshow_change_image(m->fehwin, SLIDE_FIRST); + }; + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_sort_imagename(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + filelist = gib_list_sort(filelist, feh_cmp_name); + if (!opt.no_jump_on_resort) { + slideshow_change_image(m->fehwin, SLIDE_FIRST); + }; + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_sort_filesize(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + filelist = gib_list_sort(filelist, feh_cmp_size); + if (!opt.no_jump_on_resort) { + slideshow_change_image(m->fehwin, SLIDE_FIRST); + }; + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static void feh_menu_cb_sort_randomize(feh_menu * m, feh_menu_item * i, void *data) +{ + D_ENTER(4); + filelist = gib_list_randomize(filelist); + if (!opt.no_jump_on_resort) { + slideshow_change_image(m->fehwin, SLIDE_FIRST); + }; + D_RETURN_(4); + i = NULL; + data = NULL; +} + +static feh_menu *feh_menu_func_gen_jump(feh_menu * m, feh_menu_item * i, void *data) +{ + feh_menu *mm; + gib_list *l; + + D_ENTER(4); + mm = feh_menu_new(); + mm->name = estrdup("JUMP"); + for (l = filelist; l; l = l->next) { + feh_menu_add_entry(mm, FEH_FILE(l->data)->name, NULL, NULL, feh_menu_cb_jump_to, l, NULL); + } + D_RETURN(4, mm); + m = NULL; + i = NULL; + data = NULL; +} + +static feh_menu *feh_menu_func_gen_info(feh_menu * m, feh_menu_item * i, void *data) +{ + Imlib_Image im; + feh_menu *mm; + feh_file *file; + char buffer[400]; + + D_ENTER(4); + if (!m->fehwin->file) + D_RETURN(4, NULL); + file = FEH_FILE(m->fehwin->file->data); + im = m->fehwin->im; + if (!im) + D_RETURN(4, NULL); + mm = feh_menu_new(); + mm->name = estrdup("INFO"); + snprintf(buffer, sizeof(buffer), "Filename: %s", file->name); + feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); + if (!file->info) + feh_file_info_load(file, im); + if (file->info) { + snprintf(buffer, sizeof(buffer), "Size: %dKb", file->info->size / 1024); + feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); + snprintf(buffer, sizeof(buffer), "Dimensions: %dx%d", file->info->width, file->info->height); + feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); + snprintf(buffer, sizeof(buffer), "Type: %s", file->info->format); + feh_menu_add_entry(mm, buffer, NULL, NULL, NULL, NULL, NULL); + } + + mm->func_free = feh_menu_func_free_info; + D_RETURN(4, mm); + i = NULL; + data = NULL; +} + +static void feh_menu_func_free_info(feh_menu * m, void *data) +{ + D_ENTER(4); + feh_menu_free(m); + D_RETURN_(4); + data = NULL; +} + +static feh_menu *feh_menu_func_gen_options(feh_menu * m, feh_menu_item * i, void *data) +{ + feh_menu *mm; + + D_ENTER(4); + mm = feh_menu_new(); + mm->name = estrdup("OPTIONS"); + mm->fehwin = m->fehwin; + feh_menu_add_toggle_entry(mm, "Auto-Zoom", NULL, NULL, feh_menu_cb_opt_auto_zoom, NULL, NULL, opt.auto_zoom); + feh_menu_add_toggle_entry(mm, "Freeze Window Size", NULL, NULL, + feh_menu_cb_opt_freeze_window, NULL, NULL, opt.geom_flags); + feh_menu_add_toggle_entry(mm, "Fullscreen", NULL, NULL, + feh_menu_cb_opt_fullscreen, NULL, NULL, m->fehwin->full_screen); #ifdef HAVE_LIBXINERAMA - feh_menu_add_toggle_entry(mm, "Use Xinerama", NULL, NULL, - feh_menu_cb_opt_xinerama, NULL, NULL, - opt.xinerama); -#endif /* HAVE_LIBXINERAMA */ - feh_menu_add_entry(mm, NULL, NULL, NULL, NULL, NULL, NULL); - feh_menu_add_toggle_entry(mm, "Draw Filename", NULL, NULL, - feh_menu_cb_opt_draw_filename, NULL, NULL, - opt.draw_filename); - feh_menu_add_toggle_entry(mm, "Keep HTTP Files", NULL, NULL, - feh_menu_cb_opt_keep_http, NULL, NULL, - opt.keep_http); - mm->func_free = feh_menu_func_free_options; - D_RETURN(4, mm); - i = NULL; - data = NULL; + feh_menu_add_toggle_entry(mm, "Use Xinerama", NULL, NULL, feh_menu_cb_opt_xinerama, NULL, NULL, opt.xinerama); +#endif /* HAVE_LIBXINERAMA */ + feh_menu_add_entry(mm, NULL, NULL, NULL, NULL, NULL, NULL); + feh_menu_add_toggle_entry(mm, "Draw Filename", NULL, NULL, + feh_menu_cb_opt_draw_filename, NULL, NULL, opt.draw_filename); + feh_menu_add_toggle_entry(mm, "Keep HTTP Files", NULL, NULL, + feh_menu_cb_opt_keep_http, NULL, NULL, opt.keep_http); + mm->func_free = feh_menu_func_free_options; + D_RETURN(4, mm); + i = NULL; + data = NULL; } -static void -feh_menu_func_free_options(feh_menu * m, - void *data) -{ - D_ENTER(4); - feh_menu_free(m); - D_RETURN_(4); - data = NULL; +static void feh_menu_func_free_options(feh_menu * m, void *data) +{ + D_ENTER(4); + feh_menu_free(m); + D_RETURN_(4); + data = NULL; } -static void -feh_menu_cb_jump_to(feh_menu * m, - feh_menu_item * i, - void *data) -{ - gib_list *l; +static void feh_menu_cb_jump_to(feh_menu * m, feh_menu_item * i, void *data) +{ + gib_list *l; - D_ENTER(4); - l = (gib_list *) data; - if (l->prev) { - current_file = l->prev; - slideshow_change_image(m->fehwin, SLIDE_NEXT); - } else if (l->next) { - current_file = l->next; - slideshow_change_image(m->fehwin, SLIDE_PREV); - } + D_ENTER(4); + l = (gib_list *) data; + if (l->prev) { + current_file = l->prev; + slideshow_change_image(m->fehwin, SLIDE_NEXT); + } else if (l->next) { + current_file = l->next; + slideshow_change_image(m->fehwin, SLIDE_PREV); + } - D_RETURN_(4); - i = NULL; - m = NULL; + D_RETURN_(4); + i = NULL; + m = NULL; } -static void -feh_menu_cb_fit(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_fit(feh_menu * m, feh_menu_item * i, void *data) { - D_ENTER(4); - winwidget_size_to_image(m->fehwin); - D_RETURN_(4); - data = NULL; + D_ENTER(4); + winwidget_size_to_image(m->fehwin); + D_RETURN_(4); + data = NULL; } -static void -feh_menu_cb_edit_rotate(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_edit_rotate(feh_menu * m, feh_menu_item * i, void *data) { - D_ENTER(4); - feh_edit_inplace_orient(m->fehwin, (int) data); - D_RETURN_(4); + D_ENTER(4); + feh_edit_inplace_orient(m->fehwin, (int) data); + D_RETURN_(4); } -static void -feh_menu_cb_save_image(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_save_image(feh_menu * m, feh_menu_item * i, void *data) { - slideshow_save_image(m->fehwin); + slideshow_save_image(m->fehwin); } -static void -feh_menu_cb_save_filelist(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_save_filelist(feh_menu * m, feh_menu_item * i, void *data) { - feh_save_filelist(); + feh_save_filelist(); } -static void -feh_menu_cb_opt_draw_filename(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_opt_draw_filename(feh_menu * m, feh_menu_item * i, void *data) { - MENU_ITEM_TOGGLE(i); - if (MENU_ITEM_IS_ON(i)) - opt.draw_filename = TRUE; - else - opt.draw_filename = FALSE; - winwidget_rerender_all(0, 1); + MENU_ITEM_TOGGLE(i); + if (MENU_ITEM_IS_ON(i)) + opt.draw_filename = TRUE; + else + opt.draw_filename = FALSE; + winwidget_rerender_all(0, 1); } -static void -feh_menu_cb_opt_keep_http(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_opt_keep_http(feh_menu * m, feh_menu_item * i, void *data) { - MENU_ITEM_TOGGLE(i); - if (MENU_ITEM_IS_ON(i)) - opt.keep_http = TRUE; - else - opt.keep_http = FALSE; + MENU_ITEM_TOGGLE(i); + if (MENU_ITEM_IS_ON(i)) + opt.keep_http = TRUE; + else + opt.keep_http = FALSE; } -static void -feh_menu_cb_opt_freeze_window(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_opt_freeze_window(feh_menu * m, feh_menu_item * i, void *data) { - MENU_ITEM_TOGGLE(i); - if (MENU_ITEM_IS_ON(i)) { - opt.geom_flags = (WidthValue | HeightValue); - opt.geom_w = m->fehwin->w; - opt.geom_h = m->fehwin->h; - } else { - opt.geom_flags = 0; - } + MENU_ITEM_TOGGLE(i); + if (MENU_ITEM_IS_ON(i)) { + opt.geom_flags = (WidthValue | HeightValue); + opt.geom_w = m->fehwin->w; + opt.geom_h = m->fehwin->h; + } else { + opt.geom_flags = 0; + } } -static void -feh_menu_cb_opt_fullscreen(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i, void *data) { - int curr_screen = 0; + int curr_screen = 0; - MENU_ITEM_TOGGLE(i); - if (MENU_ITEM_IS_ON(i)) - m->fehwin->full_screen = TRUE; - else - m->fehwin->full_screen = FALSE; + MENU_ITEM_TOGGLE(i); + if (MENU_ITEM_IS_ON(i)) + m->fehwin->full_screen = TRUE; + else + m->fehwin->full_screen = FALSE; #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - int i, rect[4]; - - winwidget_get_geometry(m->fehwin, rect); - /* printf("window: (%d, %d)\n", rect[0], rect[1]); - printf("found %d screens.\n", num_xinerama_screens); */ - for (i = 0; i < num_xinerama_screens; i++) { - xinerama_screen = 0; - /* printf("%d: [%d, %d, %d, %d] (%d, %d)\n", - i, - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height, - rect[0], rect[1]);*/ - if (XY_IN_RECT(rect[0], rect[1], - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height)) { - curr_screen = xinerama_screen = i; - break; - } - - } - } -#endif /* HAVE_LIBXINERAMA */ - - winwidget_destroy_xwin(m->fehwin); - winwidget_create_window(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); - - winwidget_render_image(m->fehwin, 1, 1); - winwidget_show(m->fehwin); + if (opt.xinerama && xinerama_screens) { + int i, rect[4]; + + winwidget_get_geometry(m->fehwin, rect); + /* printf("window: (%d, %d)\n", rect[0], rect[1]); + printf("found %d screens.\n", num_xinerama_screens); */ + for (i = 0; i < num_xinerama_screens; i++) { + xinerama_screen = 0; + /* printf("%d: [%d, %d, %d, %d] (%d, %d)\n", + i, + xinerama_screens[i].x_org, xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height, + rect[0], rect[1]); */ + if (XY_IN_RECT(rect[0], rect[1], + xinerama_screens[i].x_org, + xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height)) { + curr_screen = xinerama_screen = i; + break; + } + + } + } +#endif /* HAVE_LIBXINERAMA */ + + winwidget_destroy_xwin(m->fehwin); + winwidget_create_window(m->fehwin, m->fehwin->im_w, m->fehwin->im_h); + + winwidget_render_image(m->fehwin, 1, 1); + winwidget_show(m->fehwin); #ifdef HAVE_LIBXINERAMA - /* if we have xinerama and we're using it, then full screen the window - * on the head that the window was active on */ - if (m->fehwin->full_screen == TRUE && opt.xinerama && xinerama_screens) { - xinerama_screen = curr_screen; - winwidget_move(m->fehwin, - xinerama_screens[curr_screen].x_org, - xinerama_screens[curr_screen].y_org); - } -#endif /* HAVE_LIBXINERAMA */ + /* if we have xinerama and we're using it, then full screen the window + * on the head that the window was active on */ + if (m->fehwin->full_screen == TRUE && opt.xinerama && xinerama_screens) { + xinerama_screen = curr_screen; + winwidget_move(m->fehwin, xinerama_screens[curr_screen].x_org, xinerama_screens[curr_screen].y_org); + } +#endif /* HAVE_LIBXINERAMA */ } -static void -feh_menu_cb_opt_auto_zoom(feh_menu * m, - feh_menu_item * i, - void *data) +static void feh_menu_cb_opt_auto_zoom(feh_menu * m, feh_menu_item * i, void *data) { - MENU_ITEM_TOGGLE(i); - opt.auto_zoom = MENU_ITEM_IS_ON(i) ? 1 : 0; - winwidget_rerender_all(1, 1); + MENU_ITEM_TOGGLE(i); + opt.auto_zoom = MENU_ITEM_IS_ON(i) ? 1 : 0; + winwidget_rerender_all(1, 1); } #ifdef HAVE_LIBXINERAMA -static void -feh_menu_cb_opt_xinerama(feh_menu * m, - feh_menu_item * i, - void *data) -{ - MENU_ITEM_TOGGLE(i); - opt.xinerama = MENU_ITEM_IS_ON(i) ? 1 : 0; - - if (opt.xinerama) { - init_xinerama(); - } else { - XFree(xinerama_screens); - xinerama_screens = NULL; - } - winwidget_rerender_all(1, 1); -} -#endif /* HAVE_LIBXINERAMA */ +static void feh_menu_cb_opt_xinerama(feh_menu * m, feh_menu_item * i, void *data) +{ + MENU_ITEM_TOGGLE(i); + opt.xinerama = MENU_ITEM_IS_ON(i) ? 1 : 0; + + if (opt.xinerama) { + init_xinerama(); + } else { + XFree(xinerama_screens); + xinerama_screens = NULL; + } + winwidget_rerender_all(1, 1); +} +#endif /* HAVE_LIBXINERAMA */ @@ -30,7 +30,6 @@ typedef struct _feh_menu feh_menu; typedef struct _feh_menu_item feh_menu_item; typedef struct _feh_menu_list feh_menu_list; - #define MENU_ITEM_STATE_NORMAL 0x00 #define MENU_ITEM_STATE_SELECTED 0x01 #define MENU_ITEM_STATE_ON 0x02 @@ -53,13 +52,11 @@ typedef struct _feh_menu_list feh_menu_list; #define MENU_ITEM_TOGGLE(item) \ (((item)->state & MENU_ITEM_STATE_ON) ? MENU_ITEM_TOGGLE_OFF(item) : MENU_ITEM_TOGGLE_ON(item)) - #define RECTS_INTERSECT(x, y, w, h, xx, yy, ww, hh) \ ((SPANS_COMMON((x), (w), (xx), (ww))) && (SPANS_COMMON((y), (h), (yy), (hh)))) #define SPANS_COMMON(x1, w1, x2, w2) \ (!((((x2) + (w2)) <= (x1)) || ((x2) >= ((x1) + (w1))))) - #define FEH_MENU_PAD_LEFT 3 #define FEH_MENU_PAD_RIGHT 3 #define FEH_MENU_PAD_TOP 3 @@ -80,50 +77,46 @@ typedef struct _feh_menu_list feh_menu_list; #define FEH_MENU_TOGGLE_PAD 3 typedef void (*menu_func) (feh_menu * m, feh_menu_item * i, void *data); -typedef feh_menu *(*menuitem_func_gen) (feh_menu * m, feh_menu_item * i, - void *data); +typedef feh_menu *(*menuitem_func_gen) (feh_menu * m, feh_menu_item * i, void *data); -struct _feh_menu_list -{ - feh_menu *menu; - feh_menu_list *next; +struct _feh_menu_list { + feh_menu *menu; + feh_menu_list *next; }; -struct _feh_menu_item -{ - int state; - Imlib_Image icon; - char *text; - char *submenu; - menu_func func; - void (*func_free) (void *data); - void *data; - feh_menu_item *next; - feh_menu_item *prev; - unsigned char is_toggle; - int text_x, icon_x, sub_x, toggle_x; - int x, y, w, h; - menuitem_func_gen func_gen_sub; +struct _feh_menu_item { + int state; + Imlib_Image icon; + char *text; + char *submenu; + menu_func func; + void (*func_free) (void *data); + void *data; + feh_menu_item *next; + feh_menu_item *prev; + unsigned char is_toggle; + int text_x, icon_x, sub_x, toggle_x; + int x, y, w, h; + menuitem_func_gen func_gen_sub; }; -struct _feh_menu -{ - char *name; - winwidget fehwin; - Window win; - Pixmap pmap; - int x, y, w, h; - int item_w, item_h; - int visible; - feh_menu_item *items; - feh_menu *next; - feh_menu *prev; - Imlib_Updates updates; - Imlib_Image bg; - int needs_redraw; - void *data; - int calc; - void (*func_free) (feh_menu * m, void *data); +struct _feh_menu { + char *name; + winwidget fehwin; + Window win; + Pixmap pmap; + int x, y, w, h; + int item_w, item_h; + int visible; + feh_menu_item *items; + feh_menu *next; + feh_menu *prev; + Imlib_Updates updates; + Imlib_Image bg; + int needs_redraw; + void *data; + int calc; + void (*func_free) (feh_menu * m, void *data); }; feh_menu *feh_menu_new(void); @@ -134,21 +127,18 @@ void feh_menu_deselect_selected(feh_menu * m); void feh_menu_select(feh_menu * m, feh_menu_item * i); void feh_menu_show_at(feh_menu * m, int x, int y); void feh_menu_show_at_xy(feh_menu * m, winwidget winwin, int x, int y); -void feh_menu_show_at_submenu(feh_menu * m, feh_menu * parent_m, - feh_menu_item * i); +void feh_menu_show_at_submenu(feh_menu * m, feh_menu * parent_m, feh_menu_item * i); void feh_menu_hide(feh_menu * m, int func_free); void feh_menu_show(feh_menu * m); -feh_menu_item *feh_menu_add_entry(feh_menu * m, char *text, Imlib_Image icon, - char *submenu, menu_func func, void *data, - void (*func_free) (void *data)); -feh_menu_item * -feh_menu_add_toggle_entry(feh_menu * m, char *text, Imlib_Image icon, - char *submenu, menu_func func, void *data, - void (*func_free) (void *data), int setting); +feh_menu_item *feh_menu_add_entry(feh_menu * m, char *text, + Imlib_Image icon, char *submenu, + menu_func func, void *data, void (*func_free) (void *data)); +feh_menu_item *feh_menu_add_toggle_entry(feh_menu * m, char *text, + Imlib_Image icon, char *submenu, + menu_func func, void *data, void (*func_free) (void *data), int setting); void feh_menu_entry_get_size(feh_menu * m, feh_menu_item * i, int *w, int *h); void feh_menu_calc_size(feh_menu * m); -void feh_menu_draw_item(feh_menu * m, feh_menu_item * i, Imlib_Image im, - int ox, int oy); +void feh_menu_draw_item(feh_menu * m, feh_menu_item * i, Imlib_Image im, int ox, int oy); void feh_menu_redraw(feh_menu * m); void feh_menu_move(feh_menu * m, int x, int y); void feh_menu_slide_all_menus_relative(int dx, int dy); @@ -160,27 +150,22 @@ void feh_menu_init_thumbnail_viewer(void); void feh_menu_init_thumbnail_win(void); void feh_menu_draw_to_buf(feh_menu * m, Imlib_Image im, int ox, int oy); void feh_menu_draw_menu_bg(feh_menu * m, Imlib_Image im, int ox, int oy); -void feh_menu_draw_submenu_at(int x, int y, int w, int h, Imlib_Image dst, - int ox, int oy, int selected); -void feh_menu_draw_separator_at(int x, int y, int w, int h, Imlib_Image dst, - int ox, int oy); -void feh_menu_item_draw_at(int x, int y, int w, int h, Imlib_Image dst, - int ox, int oy, int selected); -void feh_menu_draw_toggle_at(int x, int y, int w, int h, Imlib_Image dst, - int ox, int oy, int on); +void feh_menu_draw_submenu_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy, int selected); +void feh_menu_draw_separator_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy); +void feh_menu_item_draw_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy, int selected); +void feh_menu_draw_toggle_at(int x, int y, int w, int h, Imlib_Image dst, int ox, int oy, int on); void feh_redraw_menus(void); feh_menu *feh_menu_find(char *name); void feh_redraw_menus(void); feh_menu *feh_menu_get_from_window(Window win); void feh_raise_all_menus(void); void feh_menu_free(feh_menu * m); -feh_menu_item *feh_menu_find_selected_r(feh_menu *m, feh_menu **parent); -void feh_menu_select_prev(feh_menu *selected_menu, feh_menu_item *selected_item); -void feh_menu_select_next(feh_menu *selected_menu, feh_menu_item *selected_item); -void feh_menu_item_activate(feh_menu *selected_menu, - feh_menu_item *selected_item); -void feh_menu_select_parent(feh_menu *selected_menu, feh_menu_item *selected_item); -void feh_menu_select_submenu(feh_menu *selected_menu, feh_menu_item *selected_item); +feh_menu_item *feh_menu_find_selected_r(feh_menu * m, feh_menu ** parent); +void feh_menu_select_prev(feh_menu * selected_menu, feh_menu_item * selected_item); +void feh_menu_select_next(feh_menu * selected_menu, feh_menu_item * selected_item); +void feh_menu_item_activate(feh_menu * selected_menu, feh_menu_item * selected_item); +void feh_menu_select_parent(feh_menu * selected_menu, feh_menu_item * selected_item); +void feh_menu_select_submenu(feh_menu * selected_menu, feh_menu_item * selected_item); extern feh_menu *menu_root; extern feh_menu *menu_single_win; diff --git a/src/multiwindow.c b/src/multiwindow.c index 60d5660..cd4e82c 100644 --- a/src/multiwindow.c +++ b/src/multiwindow.c @@ -29,50 +29,41 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "filelist.h" #include "options.h" -void -init_multiwindow_mode(void) +void init_multiwindow_mode(void) { - winwidget w = NULL; - gib_list *l; - feh_file *file = NULL; + winwidget w = NULL; + gib_list *l; + feh_file *file = NULL; - D_ENTER(2); + D_ENTER(2); - mode = "multiwindow"; + mode = "multiwindow"; - for (l = filelist; l; l = l->next) - { - char *s = NULL; - int len = 0; - file = FEH_FILE(l->data); - current_file = l; + for (l = filelist; l; l = l->next) { + char *s = NULL; + int len = 0; + file = FEH_FILE(l->data); + current_file = l; - if (!opt.title) - { - len = strlen(PACKAGE " - ") + strlen(file->filename) + 1; - s = emalloc(len); - snprintf(s, len, PACKAGE " - %s", file->filename); - } - else - { - s = estrdup(feh_printf(opt.title, file)); - } + if (!opt.title) { + len = strlen(PACKAGE " - ") + strlen(file->filename) + 1; + s = emalloc(len); + snprintf(s, len, PACKAGE " - %s", file->filename); + } else { + s = estrdup(feh_printf(opt.title, file)); + } - if ((w = winwidget_create_from_file(l, s, WIN_TYPE_SINGLE)) != NULL) - { - winwidget_show(w); - if (opt.reload > 0) - feh_add_unique_timer(cb_reload_timer, w, opt.reload); - if (!feh_main_iteration(0)) - exit(0); - } - else - { - D(3, - ("EEEK. Couldn't load image in multiwindow mode. " - "I 'm not sure if this is a problem\n")); - } - free(s); - } - D_RETURN_(2); + if ((w = winwidget_create_from_file(l, s, WIN_TYPE_SINGLE)) != NULL) { + winwidget_show(w); + if (opt.reload > 0) + feh_add_unique_timer(cb_reload_timer, w, opt.reload); + if (!feh_main_iteration(0)) + exit(0); + } else { + D(3, ("EEEK. Couldn't load image in multiwindow mode. " + "I 'm not sure if this is a problem\n")); + } + free(s); + } + D_RETURN_(2); } diff --git a/src/options.c b/src/options.c index 38be2fa..4e05c9c 100644 --- a/src/options.c +++ b/src/options.c @@ -37,1202 +37,1157 @@ static char *theme; fehoptions opt; -void -init_parse_options(int argc, char **argv) +void init_parse_options(int argc, char **argv) { - D_ENTER(4); - - /* For setting the command hint on X windows */ - cmdargc = argc; - cmdargv = argv; - - /* Set default options */ - memset(&opt, 0, sizeof(fehoptions)); - opt.display = 1; - opt.aspect = 1; - opt.slideshow_delay = -1.0; - opt.thumb_w = 60; - opt.thumb_h = 60; - opt.menu_font = estrdup(DEFAULT_MENU_FONT); - opt.font = estrdup(DEFAULT_FONT); - opt.image_bg = estrdup("default"); - opt.menu_bg = estrdup(PREFIX "/share/feh/images/menubg_default.png"); - opt.menu_style = estrdup(PREFIX "/share/feh/fonts/menu.style"); - opt.menu_border = 4; - - opt.reload_button = 0; - opt.pan_button = 1; - opt.zoom_button = 2; - opt.menu_button = 3; - opt.menu_ctrl_mask = 0; - opt.prev_button = 4; - opt.next_button = 5; - - opt.rotate_button = 2; - opt.no_rotate_ctrl_mask = 0; - opt.blur_button = 1; - opt.no_blur_ctrl_mask = 0; - - opt.no_jump_on_resort = 0; - - opt.builtin_http = 0; - - opt.xinerama = 0; - opt.screen_clip = 1; + D_ENTER(4); + + /* For setting the command hint on X windows */ + cmdargc = argc; + cmdargv = argv; + + /* Set default options */ + memset(&opt, 0, sizeof(fehoptions)); + opt.display = 1; + opt.aspect = 1; + opt.slideshow_delay = -1.0; + opt.thumb_w = 60; + opt.thumb_h = 60; + opt.menu_font = estrdup(DEFAULT_MENU_FONT); + opt.font = estrdup(DEFAULT_FONT); + opt.image_bg = estrdup("default"); + opt.menu_bg = estrdup(PREFIX "/share/feh/images/menubg_default.png"); + opt.menu_style = estrdup(PREFIX "/share/feh/fonts/menu.style"); + opt.menu_border = 4; + + opt.reload_button = 0; + opt.pan_button = 1; + opt.zoom_button = 2; + opt.menu_button = 3; + opt.menu_ctrl_mask = 0; + opt.prev_button = 4; + opt.next_button = 5; + + opt.rotate_button = 2; + opt.no_rotate_ctrl_mask = 0; + opt.blur_button = 1; + opt.no_blur_ctrl_mask = 0; + + opt.no_jump_on_resort = 0; + + opt.builtin_http = 0; + + opt.xinerama = 0; + opt.screen_clip = 1; #ifdef HAVE_LIBXINERAMA - /* if we're using xinerama, then enable it by default */ - opt.xinerama = 1; -#endif /* HAVE_LIBXINERAMA */ - - opt.fmmode = 0; - - D(3, ("About to parse env options (if any)\n")); - /* Check for and parse any options in FEH_OPTIONS */ - feh_parse_environment_options(); - - D(3, ("About to parse commandline options\n")); - /* Parse the cmdline args */ - feh_parse_option_array(argc, argv); - - D(3, ("About to check for theme configuration\n")); - feh_check_theme_options(argc, argv); - - /* If we have a filelist to read, do it now */ - if (opt.filelistfile) - { - /* joining two reverse-sorted lists in this manner works nicely for us - here, as files specified on the commandline end up at the *end* of - the combined filelist, in the specified order. */ - D(3, ("About to load filelist from file\n")); - filelist = gib_list_cat(filelist, feh_read_filelist(opt.filelistfile)); - } - - D(4, ("Options parsed\n")); - - if(opt.bgmode) - D_RETURN_(4); - - filelist_len = gib_list_length(filelist); - if (!filelist_len) - show_mini_usage(); - - check_options(); - - feh_prepare_filelist(); - D_RETURN_(4); + /* if we're using xinerama, then enable it by default */ + opt.xinerama = 1; +#endif /* HAVE_LIBXINERAMA */ + + opt.fmmode = 0; + + D(3, ("About to parse env options (if any)\n")); + /* Check for and parse any options in FEH_OPTIONS */ + feh_parse_environment_options(); + + D(3, ("About to parse commandline options\n")); + /* Parse the cmdline args */ + feh_parse_option_array(argc, argv); + + D(3, ("About to check for theme configuration\n")); + feh_check_theme_options(argc, argv); + + /* If we have a filelist to read, do it now */ + if (opt.filelistfile) { + /* joining two reverse-sorted lists in this manner works nicely for us + here, as files specified on the commandline end up at the *end* of + the combined filelist, in the specified order. */ + D(3, ("About to load filelist from file\n")); + filelist = gib_list_cat(filelist, feh_read_filelist(opt.filelistfile)); + } + + D(4, ("Options parsed\n")); + + if (opt.bgmode) + D_RETURN_(4); + + filelist_len = gib_list_length(filelist); + if (!filelist_len) + show_mini_usage(); + + check_options(); + + feh_prepare_filelist(); + D_RETURN_(4); } -static void -feh_check_theme_options(int arg, char **argv) +static void feh_check_theme_options(int arg, char **argv) { - D_ENTER(4); - if (!theme) - { - /* This prevents screw up when running src/feh or ./feh */ - char *pos = strrchr(argv[0], '/'); - - if (pos) - theme = estrdup(pos + 1); - else - theme = estrdup(argv[0]); - } - D(3, ("Theme name is %s\n", theme)); - - feh_load_options_for_theme(theme); - - free(theme); - D_RETURN_(4); - arg = 0; + D_ENTER(4); + if (!theme) { + /* This prevents screw up when running src/feh or ./feh */ + char *pos = strrchr(argv[0], '/'); + + if (pos) + theme = estrdup(pos + 1); + else + theme = estrdup(argv[0]); + } + D(3, ("Theme name is %s\n", theme)); + + feh_load_options_for_theme(theme); + + free(theme); + D_RETURN_(4); + arg = 0; } -static void -feh_load_options_for_theme(char *theme) +static void feh_load_options_for_theme(char *theme) { - FILE *fp = NULL; - char *home; - char *rcpath = NULL; - char s[1024], s1[1024], s2[1024]; - - D_ENTER(4); - - if (opt.rcfile) - { - if ((fp = fopen(opt.rcfile, "r")) == NULL) - { - weprintf("couldn't load the specified rcfile %s\n", opt.rcfile); - D_RETURN_(4); - } - } - else - { - home = getenv("HOME"); - if (!home) - eprintf("D'oh! Please define HOME in your environment!" - "It would really help me out...\n"); - rcpath = estrjoin("/", home, ".fehrc", NULL); - D(3, ("Trying %s for config\n", rcpath)); - fp = fopen(rcpath, "r"); - - if (!fp && ((fp = fopen("/etc/fehrc", "r")) == NULL)) - { - feh_create_default_config(rcpath); - - if ((fp = fopen(rcpath, "r")) == NULL) - D_RETURN_(4); - } - - free(rcpath); - } - - /* Oooh. We have an options file :) */ - for (; fgets(s, sizeof(s), fp);) - { - s1[0] = '\0'; - s2[0] = '\0'; - sscanf(s, "%s %[^\n]\n", (char *) &s1, (char *) &s2); - if (!(*s1) || (!*s2) || (*s1 == '\n') || (*s1 == '#')) - continue; - D(5, ("Got theme/options pair %s/%s\n", s1, s2)); - if (!strcmp(s1, theme)) - { - D(4, ("A match. Using options %s\n", s2)); - feh_parse_options_from_string(s2); - break; - } - } - fclose(fp); - D_RETURN_(4); + FILE *fp = NULL; + char *home; + char *rcpath = NULL; + char s[1024], s1[1024], s2[1024]; + + D_ENTER(4); + + if (opt.rcfile) { + if ((fp = fopen(opt.rcfile, "r")) == NULL) { + weprintf("couldn't load the specified rcfile %s\n", opt.rcfile); + D_RETURN_(4); + } + } else { + home = getenv("HOME"); + if (!home) + eprintf("D'oh! Please define HOME in your environment!" "It would really help me out...\n"); + rcpath = estrjoin("/", home, ".fehrc", NULL); + D(3, ("Trying %s for config\n", rcpath)); + fp = fopen(rcpath, "r"); + + if (!fp && ((fp = fopen("/etc/fehrc", "r")) == NULL)) { + feh_create_default_config(rcpath); + + if ((fp = fopen(rcpath, "r")) == NULL) + D_RETURN_(4); + } + + free(rcpath); + } + + /* Oooh. We have an options file :) */ + for (; fgets(s, sizeof(s), fp);) { + s1[0] = '\0'; + s2[0] = '\0'; + sscanf(s, "%s %[^\n]\n", (char *) &s1, (char *) &s2); + if (!(*s1) || (!*s2) || (*s1 == '\n') || (*s1 == '#')) + continue; + D(5, ("Got theme/options pair %s/%s\n", s1, s2)); + if (!strcmp(s1, theme)) { + D(4, ("A match. Using options %s\n", s2)); + feh_parse_options_from_string(s2); + break; + } + } + fclose(fp); + D_RETURN_(4); } -static void -feh_parse_environment_options(void) +static void feh_parse_environment_options(void) { - char *opts; + char *opts; - D_ENTER(4); + D_ENTER(4); - if ((opts = getenv("FEH_OPTIONS")) == NULL) - D_RETURN_(4); + if ((opts = getenv("FEH_OPTIONS")) == NULL) + D_RETURN_(4); - weprintf - ("The FEH_OPTIONS configuration method is depreciated and will soon die.\n" - "Use the .fehrc configuration file instead."); + weprintf + ("The FEH_OPTIONS configuration method is depreciated and will soon die.\n" + "Use the .fehrc configuration file instead."); - /* We definitely have some options to parse */ - feh_parse_options_from_string(opts); - D_RETURN_(4); + /* We definitely have some options to parse */ + feh_parse_options_from_string(opts); + D_RETURN_(4); } /* FIXME This function is a crufty bitch ;) */ -static void -feh_parse_options_from_string(char *opts) +static void feh_parse_options_from_string(char *opts) { - char **list = NULL; - int num = 0; - char *s; - char *t; - char last = 0; - int inquote = 0; - int i = 0; - - D_ENTER(4); - - /* So we don't reinvent the wheel (not again, anyway), we use the - getopt_long function to do this parsing as well. This means it has to - look like the real argv ;) */ - - list = malloc(sizeof(char *)); - - list[num++] = estrdup(PACKAGE); - - for (s = opts, t = opts;; t++) - { - if ((*t == ' ') && !(inquote)) - { - *t = '\0'; - num++; - list = erealloc(list, sizeof(char *) * num); - - list[num - 1] = feh_string_normalize(s); - s = t + 1; - } - else if (*t == '\0') - { - num++; - list = erealloc(list, sizeof(char *) * num); - - list[num - 1] = feh_string_normalize(s); - break; - } - else if (*t == '\"' && last != '\\') - inquote = !(inquote); - last = *t; - } - - feh_parse_option_array(num, list); - - for (i = 0; i < num; i++) - if (list[i]) - free(list[i]); - if (list) - free(list); - D_RETURN_(4); + char **list = NULL; + int num = 0; + char *s; + char *t; + char last = 0; + int inquote = 0; + int i = 0; + + D_ENTER(4); + + /* So we don't reinvent the wheel (not again, anyway), we use the + getopt_long function to do this parsing as well. This means it has to + look like the real argv ;) */ + + list = malloc(sizeof(char *)); + + list[num++] = estrdup(PACKAGE); + + for (s = opts, t = opts;; t++) { + if ((*t == ' ') && !(inquote)) { + *t = '\0'; + num++; + list = erealloc(list, sizeof(char *) * num); + + list[num - 1] = feh_string_normalize(s); + s = t + 1; + } else if (*t == '\0') { + num++; + list = erealloc(list, sizeof(char *) * num); + + list[num - 1] = feh_string_normalize(s); + break; + } else if (*t == '\"' && last != '\\') + inquote = !(inquote); + last = *t; + } + + feh_parse_option_array(num, list); + + for (i = 0; i < num; i++) + if (list[i]) + free(list[i]); + if (list) + free(list); + D_RETURN_(4); } -char * -feh_string_normalize(char *str) +char *feh_string_normalize(char *str) { - char ret[4096]; - char *s; - int i = 0; - char last = 0; - - D_ENTER(4); - D(4, ("normalizing %s\n", str)); - ret[0] = '\0'; - - for (s = str;; s++) - { - if (*s == '\0') - break; - else if ((*s == '\"') && (last == '\\')) - ret[i++] = '\"'; - else if ((*s == '\"') && (last == 0)) - ; - else if ((*s == ' ') && (last == '\\')) - ret[i++] = ' '; - else - ret[i++] = *s; - - last = *s; - } - if (i && ret[i - 1] == '\"') - ret[i - 1] = '\0'; - else - ret[i] = '\0'; - D(4, ("normalized to %s\n", ret)); - - D_RETURN(4, estrdup(ret)); + char ret[4096]; + char *s; + int i = 0; + char last = 0; + + D_ENTER(4); + D(4, ("normalizing %s\n", str)); + ret[0] = '\0'; + + for (s = str;; s++) { + if (*s == '\0') + break; + else if ((*s == '\"') && (last == '\\')) + ret[i++] = '\"'; + else if ((*s == '\"') && (last == 0)); + else if ((*s == ' ') && (last == '\\')) + ret[i++] = ' '; + else + ret[i++] = *s; + + last = *s; + } + if (i && ret[i - 1] == '\"') + ret[i - 1] = '\0'; + else + ret[i] = '\0'; + D(4, ("normalized to %s\n", ret)); + + D_RETURN(4, estrdup(ret)); } -static void -feh_parse_option_array(int argc, char **argv) +static void feh_parse_option_array(int argc, char **argv) { - static char stropts[] = - "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:klL:mM:nNo:O:pqQrR:sS:tT:uUvVwW:xXy:zZ0:1:2:4:5:8:9:.@:^:~:):|:_:+:"; - static struct option lopts[] = { - /* actions */ - {"help", 0, 0, 'h'}, /* okay */ - {"version", 0, 0, 'v'}, /* okay */ - /* toggles */ - {"montage", 0, 0, 'm'}, /* okay */ - {"collage", 0, 0, 'c'}, /* okay */ - {"index", 0, 0, 'i'}, /* okay */ - {"fullindex", 0, 0, 'I'}, /* okay */ - {"verbose", 0, 0, 'V'}, /* okay */ - {"borderless", 0, 0, 'x'}, /* okay */ - {"keep-http", 0, 0, 'k'}, /* okay */ - {"stretch", 0, 0, 's'}, /* okay */ - {"multiwindow", 0, 0, 'w'}, /* okay */ - {"recursive", 0, 0, 'r'}, /* okay */ - {"randomize", 0, 0, 'z'}, /* okay */ - {"list", 0, 0, 'l'}, /* okay */ - {"quiet", 0, 0, 'q'}, /* okay */ - {"loadable", 0, 0, 'U'}, /* okay */ - {"unloadable", 0, 0, 'u'}, /* okay */ - {"no-menus", 0, 0, 'N'}, - {"full-screen", 0, 0, 'F'}, - {"auto-zoom", 0, 0, 'Z'}, - {"ignore-aspect", 0, 0, 'X'}, - {"draw-filename", 0, 0, 'd'}, - {"preload", 0, 0, 'p'}, - {"reverse", 0, 0, 'n'}, - {"thumbnails", 0, 0, 't'}, - {"wget-timestamp", 0, 0, 'G'}, - {"builtin", 0, 0, 'Q'}, - {"menu-ctrl-mask", 0, 0, 228}, /* okay */ - {"scale-down", 0, 0, '.'}, /* okay */ - {"no-rotate-ctrl-mask", 0, 0, 226}, - {"no-blur-ctrl-mask", 0, 0, 227}, - {"no-xinerama", 0, 0, 225}, - {"no-jump-on-resort",0,0,220}, - {"hide-pointer",0,0,221}, - /* options with values */ - {"output", 1, 0, 'o'}, /* okay */ - {"output-only", 1, 0, 'O'}, /* okay */ - {"action", 1, 0, 'A'}, /* okay */ - {"limit-width", 1, 0, 'W'}, /* okay */ - {"limit-height", 1, 0, 'H'}, /* okay */ - {"reload", 1, 0, 'R'}, /* okay */ - {"alpha", 1, 0, 'a'}, /* okay */ - {"sort", 1, 0, 'S'}, /* okay */ - {"theme", 1, 0, 'T'}, /* okay */ - {"filelist", 1, 0, 'f'}, /* okay */ - {"customlist", 1, 0, 'L'}, /* okay */ - {"geometry", 1, 0, 'g'}, /* okay */ - {"menu-font", 1, 0, 'M'}, - {"thumb-width", 1, 0, 'y'}, - {"thumb-height", 1, 0, 'E'}, - {"slideshow-delay", 1, 0, 'D'}, - {"font", 1, 0, 'e'}, - {"title-font", 1, 0, '@'}, - {"title", 1, 0, '^'}, - {"thumb-title", 1, 0, '~'}, - {"bg", 1, 0, 'b'}, - {"fontpath", 1, 0, 'C'}, - {"menu-bg", 1, 0, ')'}, - {"image-bg", 1, 0, 'B'}, - {"reload-button", 1, 0, '0'}, - {"pan-button", 1, 0, '1'}, - {"zoom-button", 1, 0, '2'}, - {"menu-button", 1, 0, '3'}, - {"prev-button", 1, 0, '4'}, - {"next-button", 1, 0, '5'}, - {"rotate-button", 1, 0, '8'}, - {"blur-button", 1, 0, '9'}, - {"start-at", 1, 0, '|'}, - {"rcfile", 1, 0, '_'}, - {"debug-level", 1, 0, '+'}, - {"output-dir", 1, 0, 'j'}, - {"bg-tile", 1, 0, 200}, - {"bg-center", 1, 0, 201}, - {"bg-scale", 1, 0, 202}, - {"bg-seamless", 1, 0, 203}, - {"menu-style", 1, 0, 204}, - {"zoom", 1, 0, 205}, - {"screen-clip", 1, 0, 207}, - {"menu-border", 1, 0, 208}, - {"caption-path", 1, 0, 209}, - {"action1", 1, 0, 210}, - {"action2", 1, 0, 211}, - {"action3", 1, 0, 212}, - {"action4", 1, 0, 213}, - {"action5", 1, 0, 214}, - {"action6", 1, 0, 215}, - {"action7", 1, 0, 216}, - {"action8", 1, 0, 217}, - {"action9", 1, 0, 218}, - {"fmmode", 0, 0, 219}, - {"draw-actions", 0, 0, 222}, - {"cache-thumbnails", 0, 0, 223}, - {"cycle-once", 0, 0, 224}, - {0, 0, 0, 0} - }; - int optch = 0, cmdx = 0, i = 0; - int geomret; - - D_ENTER(4); - - /* Now to pass some optionarinos */ - while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) - { - D(5, ("Got option, getopt calls it %d, or %c\n", optch, optch)); - switch (optch) - { - case 0: - break; - case 'h': - show_usage(); - break; - case 'v': - show_version(); - break; - case 'm': - opt.index = 1; - opt.index_show_name = 0; - opt.index_show_size = 0; - opt.index_show_dim = 0; - break; - case 'c': - opt.collage = 1; - break; - case 'i': - opt.index = 1; - opt.index_show_name = 1; - opt.index_show_size = 0; - opt.index_show_dim = 0; - break; - case '.': - opt.scale_down = 1; - break; - case 'I': - opt.index = 1; - opt.index_show_name = 1; - opt.index_show_size = 1; - opt.index_show_dim = 1; - break; - case 'l': - opt.list = 1; - opt.display = 0; - break; - case 'G': - opt.wget_timestamp = 1; - break; - case 'Q': - opt.builtin_http = 1; - break; - case 'L': - opt.customlist = estrdup(optarg); - break; - case 'M': - free(opt.menu_font); - opt.menu_font = estrdup(optarg); - break; - case '+': - opt.debug_level = atoi(optarg); - break; - case 'n': - opt.reverse = 1; - break; - case 'g': - opt.geom_flags = XParseGeometry(optarg, &opt.geom_x, &opt.geom_y, &opt.geom_w, &opt.geom_h); - break; - case 'N': - opt.no_menus = 1; - break; - case 'V': - opt.verbose = 1; - break; - case 'q': - opt.quiet = 1; - break; - case 'x': - opt.borderless = 1; - break; - case 'k': - opt.keep_http = 1; - break; - case 's': - opt.stretch = 1; - break; - case 'w': - opt.multiwindow = 1; - break; - case 'r': - opt.recursive = 1; - break; - case 'z': - opt.randomize = 1; - break; - case 'd': - opt.draw_filename = 1; - break; - case 'F': - opt.full_screen = 1; - break; - case 'Z': - opt.auto_zoom = 1; - break; - case 'U': - opt.loadables = 1; - break; - case 'u': - opt.unloadables = 1; - break; - case 'p': - opt.preload = 1; - break; - case 'X': - opt.aspect = 0; - break; - case 'S': - if (!strcasecmp(optarg, "name")) - opt.sort = SORT_NAME; - else if (!strcasecmp(optarg, "filename")) - opt.sort = SORT_FILENAME; - else if (!strcasecmp(optarg, "width")) - opt.sort = SORT_WIDTH; - else if (!strcasecmp(optarg, "height")) - opt.sort = SORT_HEIGHT; - else if (!strcasecmp(optarg, "pixels")) - opt.sort = SORT_PIXELS; - else if (!strcasecmp(optarg, "size")) - opt.sort = SORT_SIZE; - else if (!strcasecmp(optarg, "format")) - opt.sort = SORT_FORMAT; - else - { - weprintf - ("Unrecognised sort mode \"%s\". Defaulting to sort by filename", - optarg); - opt.sort = SORT_FILENAME; - } - break; - case 'o': - opt.output = 1; - opt.output_file = estrdup(optarg); - break; - case 'O': - opt.output = 1; - opt.output_file = estrdup(optarg); - opt.display = 0; - break; - case 'T': - theme = estrdup(optarg); - break; - case 'C': - D(3, ("adding fontpath %s\n", optarg)); - imlib_add_path_to_font_path(optarg); - break; - case 'e': - opt.font = estrdup(optarg); - break; - case '@': - opt.title_font = estrdup(optarg); - break; - case '^': - opt.title = estrdup(optarg); - break; - case '~': - opt.thumb_title = estrdup(optarg); - break; - case 'b': - opt.bg = 1; - opt.bg_file = estrdup(optarg); - break; - case '_': - opt.rcfile = estrdup(optarg); - break; - case 'A': - opt.actions[0] = estrdup(optarg); - break; - case 'W': - opt.limit_w = atoi(optarg); - break; - case 'H': - opt.limit_h = atoi(optarg); - break; - case 'y': - opt.thumb_w = atoi(optarg); - break; - case 'E': - opt.thumb_h = atoi(optarg); - break; - case ')': - free(opt.menu_bg); - opt.menu_bg = estrdup(optarg); - break; - case 'B': - free(opt.image_bg); - opt.image_bg = estrdup(optarg); - break; - case 'D': - opt.slideshow_delay = atof(optarg); - break; - case 'R': - opt.reload = atoi(optarg); - break; - case 'a': - opt.alpha = 1; - opt.alpha_level = 255 - atoi(optarg); - break; - case 'f': - opt.filelistfile = estrdup(optarg); - break; - case '0': - opt.reload_button = atoi(optarg); - break; - case '1': - opt.pan_button = atoi(optarg); - break; - case '2': - opt.zoom_button = atoi(optarg); - break; - case '3': - opt.menu_button = atoi(optarg); - break; - case '4': - opt.prev_button = atoi(optarg); - break; - case '5': - opt.next_button = atoi(optarg); - break; - case 228: - opt.menu_ctrl_mask = 1; - break; - case '8': - opt.rotate_button = atoi(optarg); - break; - case 226: - opt.no_rotate_ctrl_mask = 1; - break; - case '9': - opt.blur_button = atoi(optarg); - break; - case 227: - opt.no_blur_ctrl_mask = 1; - break; - case '|': - opt.start_list_at = atoi(optarg); - break; - case 't': - opt.thumbs = 1; - opt.index_show_name = 1; - opt.index_show_size = 0; - opt.index_show_dim = 0; - break; - case 'j': - opt.output_dir = estrdup(optarg); - break; - case 200: - opt.bgmode = BG_MODE_TILE; - opt.output_file = estrdup(optarg); - break; - case 201: - opt.bgmode = BG_MODE_CENTER; - opt.output_file = estrdup(optarg); - break; - case 202: - opt.bgmode = BG_MODE_SCALE; - opt.output_file = estrdup(optarg); - break; - case 203: - opt.bgmode = BG_MODE_SEAMLESS; - opt.output_file = estrdup(optarg); - break; - case 204: - free(opt.menu_style); - opt.menu_style = estrdup(optarg); - break; - case 205: - opt.default_zoom = atoi(optarg); - break; - case 207: - opt.screen_clip = atoi(optarg); - break; - case 208: - opt.menu_border = atoi(optarg); - break; - case 209: - opt.caption_path = estrdup(optarg); - break; - case 210: - opt.actions[1] = estrdup(optarg); - break; - case 211: - opt.actions[2] = estrdup(optarg); - break; - case 212: - opt.actions[3] = estrdup(optarg); - break; - case 213: - opt.actions[4] = estrdup(optarg); - break; - case 214: - opt.actions[5] = estrdup(optarg); - break; - case 215: - opt.actions[6] = estrdup(optarg); - break; - case 216: - opt.actions[7] = estrdup(optarg); - break; - case 217: - opt.actions[8] = estrdup(optarg); - break; - case 218: - opt.actions[9] = estrdup(optarg); - break; - case 220: - opt.no_jump_on_resort = 1; - break; - case 221: - opt.hide_pointer = 1; - break; - case 219: - opt.fmmode = 1; - opt.sort = SORT_FILENAME; - break; - case 222: - opt.draw_actions = 1; - break; - case 223: - opt.cache_thumbnails = 1; - break; - case 224: - opt.cycle_once = 1; - break; - case 225: - opt.xinerama = 0; - break; - default: - break; - } - } - - /* Now the leftovers, which must be files */ - if (optind < argc) - { - while (optind < argc) - { - /* If recursive is NOT set, but the only argument is a directory - name, we grab all the files in there, but not subdirs */ - add_file_to_filelist_recursively(argv[optind++], FILELIST_FIRST); - } - } - - /* So that we can safely be called again */ - optind = 1; - D_RETURN_(4); + static char stropts[] = + "a:A:b:B:cC:dD:e:E:f:Fg:GhH:iIj:klL:mM:nNo:O:pqQrR:sS:tT:uUvVwW:xXy:zZ0:1:2:4:5:8:9:.@:^:~:):|:_:+:"; + static struct option lopts[] = { + /* actions */ + {"help", 0, 0, 'h'}, /* okay */ + {"version", 0, 0, 'v'}, /* okay */ + /* toggles */ + {"montage", 0, 0, 'm'}, /* okay */ + {"collage", 0, 0, 'c'}, /* okay */ + {"index", 0, 0, 'i'}, /* okay */ + {"fullindex", 0, 0, 'I'}, /* okay */ + {"verbose", 0, 0, 'V'}, /* okay */ + {"borderless", 0, 0, 'x'}, /* okay */ + {"keep-http", 0, 0, 'k'}, /* okay */ + {"stretch", 0, 0, 's'}, /* okay */ + {"multiwindow", 0, 0, 'w'}, /* okay */ + {"recursive", 0, 0, 'r'}, /* okay */ + {"randomize", 0, 0, 'z'}, /* okay */ + {"list", 0, 0, 'l'}, /* okay */ + {"quiet", 0, 0, 'q'}, /* okay */ + {"loadable", 0, 0, 'U'}, /* okay */ + {"unloadable", 0, 0, 'u'}, /* okay */ + {"no-menus", 0, 0, 'N'}, + {"full-screen", 0, 0, 'F'}, + {"auto-zoom", 0, 0, 'Z'}, + {"ignore-aspect", 0, 0, 'X'}, + {"draw-filename", 0, 0, 'd'}, + {"preload", 0, 0, 'p'}, + {"reverse", 0, 0, 'n'}, + {"thumbnails", 0, 0, 't'}, + {"wget-timestamp", 0, 0, 'G'}, + {"builtin", 0, 0, 'Q'}, + {"menu-ctrl-mask", 0, 0, 228}, /* okay */ + {"scale-down", 0, 0, '.'}, /* okay */ + {"no-rotate-ctrl-mask", 0, 0, 226}, + {"no-blur-ctrl-mask", 0, 0, 227}, + {"no-xinerama", 0, 0, 225}, + {"no-jump-on-resort", 0, 0, 220}, + {"hide-pointer", 0, 0, 221}, + /* options with values */ + {"output", 1, 0, 'o'}, /* okay */ + {"output-only", 1, 0, 'O'}, /* okay */ + {"action", 1, 0, 'A'}, /* okay */ + {"limit-width", 1, 0, 'W'}, /* okay */ + {"limit-height", 1, 0, 'H'}, /* okay */ + {"reload", 1, 0, 'R'}, /* okay */ + {"alpha", 1, 0, 'a'}, /* okay */ + {"sort", 1, 0, 'S'}, /* okay */ + {"theme", 1, 0, 'T'}, /* okay */ + {"filelist", 1, 0, 'f'}, /* okay */ + {"customlist", 1, 0, 'L'}, /* okay */ + {"geometry", 1, 0, 'g'}, /* okay */ + {"menu-font", 1, 0, 'M'}, + {"thumb-width", 1, 0, 'y'}, + {"thumb-height", 1, 0, 'E'}, + {"slideshow-delay", 1, 0, 'D'}, + {"font", 1, 0, 'e'}, + {"title-font", 1, 0, '@'}, + {"title", 1, 0, '^'}, + {"thumb-title", 1, 0, '~'}, + {"bg", 1, 0, 'b'}, + {"fontpath", 1, 0, 'C'}, + {"menu-bg", 1, 0, ')'}, + {"image-bg", 1, 0, 'B'}, + {"reload-button", 1, 0, '0'}, + {"pan-button", 1, 0, '1'}, + {"zoom-button", 1, 0, '2'}, + {"menu-button", 1, 0, '3'}, + {"prev-button", 1, 0, '4'}, + {"next-button", 1, 0, '5'}, + {"rotate-button", 1, 0, '8'}, + {"blur-button", 1, 0, '9'}, + {"start-at", 1, 0, '|'}, + {"rcfile", 1, 0, '_'}, + {"debug-level", 1, 0, '+'}, + {"output-dir", 1, 0, 'j'}, + {"bg-tile", 1, 0, 200}, + {"bg-center", 1, 0, 201}, + {"bg-scale", 1, 0, 202}, + {"bg-seamless", 1, 0, 203}, + {"menu-style", 1, 0, 204}, + {"zoom", 1, 0, 205}, + {"screen-clip", 1, 0, 207}, + {"menu-border", 1, 0, 208}, + {"caption-path", 1, 0, 209}, + {"action1", 1, 0, 210}, + {"action2", 1, 0, 211}, + {"action3", 1, 0, 212}, + {"action4", 1, 0, 213}, + {"action5", 1, 0, 214}, + {"action6", 1, 0, 215}, + {"action7", 1, 0, 216}, + {"action8", 1, 0, 217}, + {"action9", 1, 0, 218}, + {"fmmode", 0, 0, 219}, + {"draw-actions", 0, 0, 222}, + {"cache-thumbnails", 0, 0, 223}, + {"cycle-once", 0, 0, 224}, + {0, 0, 0, 0} + }; + int optch = 0, cmdx = 0, i = 0; + int geomret; + + D_ENTER(4); + + /* Now to pass some optionarinos */ + while ((optch = getopt_long(argc, argv, stropts, lopts, &cmdx)) != EOF) { + D(5, ("Got option, getopt calls it %d, or %c\n", optch, optch)); + switch (optch) { + case 0: + break; + case 'h': + show_usage(); + break; + case 'v': + show_version(); + break; + case 'm': + opt.index = 1; + opt.index_show_name = 0; + opt.index_show_size = 0; + opt.index_show_dim = 0; + break; + case 'c': + opt.collage = 1; + break; + case 'i': + opt.index = 1; + opt.index_show_name = 1; + opt.index_show_size = 0; + opt.index_show_dim = 0; + break; + case '.': + opt.scale_down = 1; + break; + case 'I': + opt.index = 1; + opt.index_show_name = 1; + opt.index_show_size = 1; + opt.index_show_dim = 1; + break; + case 'l': + opt.list = 1; + opt.display = 0; + break; + case 'G': + opt.wget_timestamp = 1; + break; + case 'Q': + opt.builtin_http = 1; + break; + case 'L': + opt.customlist = estrdup(optarg); + break; + case 'M': + free(opt.menu_font); + opt.menu_font = estrdup(optarg); + break; + case '+': + opt.debug_level = atoi(optarg); + break; + case 'n': + opt.reverse = 1; + break; + case 'g': + opt.geom_flags = XParseGeometry(optarg, &opt.geom_x, &opt.geom_y, &opt.geom_w, &opt.geom_h); + break; + case 'N': + opt.no_menus = 1; + break; + case 'V': + opt.verbose = 1; + break; + case 'q': + opt.quiet = 1; + break; + case 'x': + opt.borderless = 1; + break; + case 'k': + opt.keep_http = 1; + break; + case 's': + opt.stretch = 1; + break; + case 'w': + opt.multiwindow = 1; + break; + case 'r': + opt.recursive = 1; + break; + case 'z': + opt.randomize = 1; + break; + case 'd': + opt.draw_filename = 1; + break; + case 'F': + opt.full_screen = 1; + break; + case 'Z': + opt.auto_zoom = 1; + break; + case 'U': + opt.loadables = 1; + break; + case 'u': + opt.unloadables = 1; + break; + case 'p': + opt.preload = 1; + break; + case 'X': + opt.aspect = 0; + break; + case 'S': + if (!strcasecmp(optarg, "name")) + opt.sort = SORT_NAME; + else if (!strcasecmp(optarg, "filename")) + opt.sort = SORT_FILENAME; + else if (!strcasecmp(optarg, "width")) + opt.sort = SORT_WIDTH; + else if (!strcasecmp(optarg, "height")) + opt.sort = SORT_HEIGHT; + else if (!strcasecmp(optarg, "pixels")) + opt.sort = SORT_PIXELS; + else if (!strcasecmp(optarg, "size")) + opt.sort = SORT_SIZE; + else if (!strcasecmp(optarg, "format")) + opt.sort = SORT_FORMAT; + else { + weprintf("Unrecognised sort mode \"%s\". Defaulting to sort by filename", optarg); + opt.sort = SORT_FILENAME; + } + break; + case 'o': + opt.output = 1; + opt.output_file = estrdup(optarg); + break; + case 'O': + opt.output = 1; + opt.output_file = estrdup(optarg); + opt.display = 0; + break; + case 'T': + theme = estrdup(optarg); + break; + case 'C': + D(3, ("adding fontpath %s\n", optarg)); + imlib_add_path_to_font_path(optarg); + break; + case 'e': + opt.font = estrdup(optarg); + break; + case '@': + opt.title_font = estrdup(optarg); + break; + case '^': + opt.title = estrdup(optarg); + break; + case '~': + opt.thumb_title = estrdup(optarg); + break; + case 'b': + opt.bg = 1; + opt.bg_file = estrdup(optarg); + break; + case '_': + opt.rcfile = estrdup(optarg); + break; + case 'A': + opt.actions[0] = estrdup(optarg); + break; + case 'W': + opt.limit_w = atoi(optarg); + break; + case 'H': + opt.limit_h = atoi(optarg); + break; + case 'y': + opt.thumb_w = atoi(optarg); + break; + case 'E': + opt.thumb_h = atoi(optarg); + break; + case ')': + free(opt.menu_bg); + opt.menu_bg = estrdup(optarg); + break; + case 'B': + free(opt.image_bg); + opt.image_bg = estrdup(optarg); + break; + case 'D': + opt.slideshow_delay = atof(optarg); + break; + case 'R': + opt.reload = atoi(optarg); + break; + case 'a': + opt.alpha = 1; + opt.alpha_level = 255 - atoi(optarg); + break; + case 'f': + opt.filelistfile = estrdup(optarg); + break; + case '0': + opt.reload_button = atoi(optarg); + break; + case '1': + opt.pan_button = atoi(optarg); + break; + case '2': + opt.zoom_button = atoi(optarg); + break; + case '3': + opt.menu_button = atoi(optarg); + break; + case '4': + opt.prev_button = atoi(optarg); + break; + case '5': + opt.next_button = atoi(optarg); + break; + case 228: + opt.menu_ctrl_mask = 1; + break; + case '8': + opt.rotate_button = atoi(optarg); + break; + case 226: + opt.no_rotate_ctrl_mask = 1; + break; + case '9': + opt.blur_button = atoi(optarg); + break; + case 227: + opt.no_blur_ctrl_mask = 1; + break; + case '|': + opt.start_list_at = atoi(optarg); + break; + case 't': + opt.thumbs = 1; + opt.index_show_name = 1; + opt.index_show_size = 0; + opt.index_show_dim = 0; + break; + case 'j': + opt.output_dir = estrdup(optarg); + break; + case 200: + opt.bgmode = BG_MODE_TILE; + opt.output_file = estrdup(optarg); + break; + case 201: + opt.bgmode = BG_MODE_CENTER; + opt.output_file = estrdup(optarg); + break; + case 202: + opt.bgmode = BG_MODE_SCALE; + opt.output_file = estrdup(optarg); + break; + case 203: + opt.bgmode = BG_MODE_SEAMLESS; + opt.output_file = estrdup(optarg); + break; + case 204: + free(opt.menu_style); + opt.menu_style = estrdup(optarg); + break; + case 205: + opt.default_zoom = atoi(optarg); + break; + case 207: + opt.screen_clip = atoi(optarg); + break; + case 208: + opt.menu_border = atoi(optarg); + break; + case 209: + opt.caption_path = estrdup(optarg); + break; + case 210: + opt.actions[1] = estrdup(optarg); + break; + case 211: + opt.actions[2] = estrdup(optarg); + break; + case 212: + opt.actions[3] = estrdup(optarg); + break; + case 213: + opt.actions[4] = estrdup(optarg); + break; + case 214: + opt.actions[5] = estrdup(optarg); + break; + case 215: + opt.actions[6] = estrdup(optarg); + break; + case 216: + opt.actions[7] = estrdup(optarg); + break; + case 217: + opt.actions[8] = estrdup(optarg); + break; + case 218: + opt.actions[9] = estrdup(optarg); + break; + case 220: + opt.no_jump_on_resort = 1; + break; + case 221: + opt.hide_pointer = 1; + break; + case 219: + opt.fmmode = 1; + opt.sort = SORT_FILENAME; + break; + case 222: + opt.draw_actions = 1; + break; + case 223: + opt.cache_thumbnails = 1; + break; + case 224: + opt.cycle_once = 1; + break; + case 225: + opt.xinerama = 0; + break; + default: + break; + } + } + + /* Now the leftovers, which must be files */ + if (optind < argc) { + while (optind < argc) { + /* If recursive is NOT set, but the only argument is a directory + name, we grab all the files in there, but not subdirs */ + add_file_to_filelist_recursively(argv[optind++], FILELIST_FIRST); + } + } + + /* So that we can safely be called again */ + optind = 1; + D_RETURN_(4); } - -static void -check_options(void) +static void check_options(void) { - D_ENTER(4); - if ((opt.index + opt.collage) > 1) - { - weprintf("you can't use collage mode and index mode together.\n" - " I'm going with index"); - opt.collage = 0; - } - - if (opt.full_screen && opt.multiwindow) - { - weprintf - ("you shouldn't combine multiwindow mode with full-screen mode,\n" - " Multiwindow mode has been disabled."); - opt.multiwindow = 0; - } - - if (opt.list && (opt.multiwindow || opt.index || opt.collage)) - { - weprintf("list mode can't be combined with other processing modes,\n" - " list mode disabled."); - opt.list = 0; - } - - if (opt.sort && opt.randomize) - { - weprintf("You cant sort AND randomize the filelist...\n" - "randomize mode has been unset\n"); - opt.randomize = 0; - } - - if (opt.loadables && opt.unloadables) - { - weprintf("You cant show loadables AND unloadables...\n" - "you might as well use ls ;)\n" - "loadables only will be shown\n"); - opt.unloadables = 0; - } - - if (opt.thumb_title && (!opt.thumbs)) - { - weprintf("Doesn't make sense to set thumbnail title when not in\n" - "thumbnail mode.\n"); - free(opt.thumb_title); - opt.thumb_title = NULL; - } - D_RETURN_(4); + D_ENTER(4); + if ((opt.index + opt.collage) > 1) { + weprintf("you can't use collage mode and index mode together.\n" " I'm going with index"); + opt.collage = 0; + } + + if (opt.full_screen && opt.multiwindow) { + weprintf + ("you shouldn't combine multiwindow mode with full-screen mode,\n" + " Multiwindow mode has been disabled."); + opt.multiwindow = 0; + } + + if (opt.list && (opt.multiwindow || opt.index || opt.collage)) { + weprintf("list mode can't be combined with other processing modes,\n" " list mode disabled."); + opt.list = 0; + } + + if (opt.sort && opt.randomize) { + weprintf("You cant sort AND randomize the filelist...\n" "randomize mode has been unset\n"); + opt.randomize = 0; + } + + if (opt.loadables && opt.unloadables) { + weprintf("You cant show loadables AND unloadables...\n" + "you might as well use ls ;)\n" "loadables only will be shown\n"); + opt.unloadables = 0; + } + + if (opt.thumb_title && (!opt.thumbs)) { + weprintf("Doesn't make sense to set thumbnail title when not in\n" "thumbnail mode.\n"); + free(opt.thumb_title); + opt.thumb_title = NULL; + } + D_RETURN_(4); } -void -show_version(void) +void show_version(void) { - printf(PACKAGE " version " VERSION "\n"); - exit(0); + printf(PACKAGE " version " VERSION "\n"); + exit(0); } -void -show_mini_usage(void) +void show_mini_usage(void) { - fprintf(stdout, - PACKAGE " - No loadable images specified.\nUse " PACKAGE - " --help for detailed usage information\n"); - exit(0); + fprintf(stdout, + PACKAGE " - No loadable images specified.\nUse " PACKAGE " --help for detailed usage information\n"); + exit(0); } -void -show_usage(void) +void show_usage(void) { - fprintf(stdout, -"Usage : " PACKAGE " [OPTIONS]... FILES...\n" -" Where a FILE is an image file or a directory.\n" -" Multiple files are supported.\n" -" Urls are supported. They must begin with http:// or ftp:// and you must\n" -" have wget installed to download the files for viewing.\n" -" Options can also be specified in the in the feh configuration file. See\n" -" man feh for more details\n" -" -h, --help display this help and exit\n" -" -v, --version output version information and exit\n" -" -V, --verbose output useful information, progress bars, etc\n" -" -q, --quiet Don't report non-fatal errors for failed loads\n" -" Verbose and quiet modes are not mutually exclusive,\n" -" the first controls informational messages, the\n" -" second only errors.\n" -" -T, --theme THEME Load options from config file with name THEME\n" -" see man feh for more info.\n" -" -_, --rcfile FILE Use FILE to parse themes and options from,\n" -" instead of the default ~/.fehrc, /etc/fehrc files.\n" -" -r, --recursive Recursively expand any directories in FILE to\n" -" the content of those directories. (Take it easy)\n" -" -z, --randomize When viewing multiple files in a slideshow,\n" -" randomise the file list before displaying\n" -" --no-jump-on-resort Don't jump to the first image when the filelist\n" -" is resorted.\n" -" -g, --geometry STRING Limit (and don't change) the window size. Takes\n" -" an X-style geometry string like 640x480.\n" -" Note that larger images will be zoomed out to fit\n" -" but you can see them at 1:1 by clicking the zoom\n" -" button.\n" -" -f, --filelist FILE This option is similar to the playlists used by\n" -" music software. If FILE exists, it will be read\n" -" for a list of files to load, in the order they\n" -" appear. The format is a list of image filenames,\n" -" absolute or relative to the current directory,\n" -" one filename per line.\n" -" If FILE doesn't exist, it will be created from the\n" -" internal filelist at the end of a viewing session.\n" -" This is best used to store the results of complex\n" -" sorts (-Spixels for example) for later viewing.\n" -" Any changes to the internal filelist (such as\n" -" deleting a file or it being pruned for being\n" -" unloadable) will be saved to FILE when feh exits.\n" -" You can add files to filelists by specifying them\n" -" on the commandline when also specifying the list.\n" -" -|, --start-at POSITION Start at POSITION in the filelist\n" -" -p, --preload Preload images. This doesn't mean hold them in\n" -" RAM, it means run through and eliminate unloadable\n" -" images first. Otherwise they will be removed as you\n" -" flick through.\n" -" -., --scale-down Automatically scale down images too big for the\n" -" screen. Currently only works with -P\n" -" -F, --full-screen Make the window fullscreen\n" -" -Z, --auto-zoom Zoom picture to screen size in fullscreen mode,\n" -" is affected by the option --stretch\n" -" --zoom PERCENT Zooms images by a PERCENT, when in full screen\n" -" mode or when window geometry is fixed. If combined\n" -" with --auto-zoom, zooming will be limited to the\n" -" the size.\n" -" -w, --multiwindow Disable slideshow mode. With this setting,\n" -" instead of opening multiple files in slideshow\n" -" mode, multiple windows will be opened.\n" -" -x, --borderless Create borderless windows\n" -" -d, --draw-filename Draw the filename at the top-left of the image.\n" -" -^, --title TITLE Use TITLE as the window title in slideshow mode.\n" -" -D, --slideshow-delay NUM For slideshow mode, specifies time delay (seconds,\n" -" can be a decimal) between automatically changing\n" -" slides.\n" -" --cycle-once exit feh after one loop through a slideshow\n" -" -R, --reload NUM Use this option to tell feh to reload an image\n" -" after NUM seconds. Useful for viewing webcams\n" -" via http, or even on your local machine.\n" -" -Q, --builtin Use builtin http grabber to grab remote files\n" -" instead of wget.\n" -" mechanism, useful if don't have wget.\n" -" -k, --keep-http When viewing files using http, feh normally\n" -" deletes the local copies after viewing, or,\n" -" if caching, on exit. This option prevents this\n" -" so that you get to keep the local copies.\n" -" They will be in the current working directory\n" -" with \"feh\" in the name.\n" -" --caption-path PATH Path to directory containing image captions.\n" -" This turns on caption viewing, and if captions\n" -" are found in PATH, which is relative to the\n" -" directory of each image, they are overlayed\n" -" on the displayed image.\n" -" e.g with caption path \"captions\", and viewing\n" -" image images/foo.jpg, caption will be looked for\n" -" as \"images/captions/foo.jpg.txt\"\n" -" -j, --output-dir Output directory for saved files. Really only\n" -" useful with the -k flag.\n" -" -G, --wget-timestamp When viewing http images with reload set (eg\n" -" webcams), try to only reload the image if the\n" -" remote file has changed.\n" -" -l, --list Don't display images. Analyse them and display an\n" -" 'ls' style listing. Useful in scripts hunt out\n" -" images of a certain size/resolution/type etc.\n" -" -L, --customlist FORMAT Use FORMAT as the format specifier for list\n" -" output. FORMAT is a printf-like string containing\n" -" image info specifiers. See FORMAT SPECIFIERS.\n" -" -U, --loadable Don't display images. Just print out their name\n" -" if imlib2 can successfully load them.\n" -" -u, --unloadable Don't display images. Just print out their name\n" -" if imlib2 can NOT successfully load them.\n" -" -S, --sort SORT_TYPE The file list may be sorted according to image\n" -" parameters. Allowed sort types are: name,\n" -" filename, width, height, pixels, size, format.\n" -" For sort modes other than name or filename, a\n" -" preload run will be necessary, causing a delay\n" -" proportional to the number of images in the list\n" -" -n, --reverse Reverse the sort order. Use this to invert the order\n" -" of the filelist. Eg to sort in reverse width order,\n" -" use -nSwidth\n" -" -A, --action ACTION Specify a string as an action to perform on the\n" -" image. In slideshow or multiwindow modes, the action\n" -" in list mode, or loadable|unloadable modes, the\n" -" action will be run for each file.\n" -" The action will be executed by /bin/sh. Use\n" -" format specifiers to refer to image info. See\n" -" FORMAT SPECIFIERS for examples\n" -" Eg. -A \"mv %%f ~/images/%%n\"\n" -" In slideshow mode, the next image will be shown\n" -" after running the command, in multiwindow mode,\n" -" the window will be closed.\n" -" --action1 ACTION These extra action options allow you to specify\n" -" --action2 ACTION multiple additional actions which can be invoked\n" -" ... using the appropriate number key 1-9\n" -" --action9 ACTION\n" -" --draw-actions Show the defined actions and what they do\n" -" -m, --montage Enable montage mode. Montage mode creates a new\n" -" image consisting of a grid of thumbnails of the\n" -" images specified using FILE... When montage mode\n" -" is selected, certain other options become\n" -" available. See MONTAGE MODE OPTIONS\n" -" -c, --collage Same as montage mode, but the thumbnails are\n" -" distributed randomly. You must specify width and\n" -" height or supply a background image or both\n" -" -i, --index Enable Index mode. Index mode is similar to\n" -" montage mode, and accepts the same options. It\n" -" creates an index print of thumbails, printing the\n" -" images name beneath each thumbnail. Index mode\n" -" enables certain other options, see INDEX MODE\n" -" OPTIONS\n" -" -t, --thumbnails As --index, but clicking an image will open it in\n" -" a new viewing window\n" -" --cache-thumbnails Enable thumbnail caching\n" -" -~, --thumb-title STRING Set window title for images opened from thumbnail mode.\n" -" Supports format specifiers, see there.\n" -" -I, --fullindex Same as index mode, but below each thumbnail you\n" -" get image name, size and dimensions\n" -" --bg-tile FILE\n" -" --bg-center FILE\n" -" --bg-scale FILE\n" -" --bg-seamless FILE Set your desktop background to FILE. Feh can\n" -" use enlightenment IPC if you are running it,\n" -" or will fall back to X methods.\n" -" Feh stores the commandline necessary to restore\n" -" the background you chose in ~/.fehbg. So to have\n" -" feh-set backgrounds restored when you restart X,\n" -" add the line \"eval `cat $HOME/.fehbg`\" to your\n" -" X startup script (e.g. ~/.xsession). Note that\n" -" you only need to do this for non E window\n" -" managers.\n" -" -C, --fontpath PATH Specify an extra directory to look in for fonts,\n" -" can be used multiple times to add multiple paths.\n" -" -M, --menu-font FONT Use FONT for the font in menus.\n" -" --menu-style FILE Use FILE as the style descriptor for menu text.\n" -" -), --menu-bg BG Use BG for the background image in menus.\n" -" --menu-border INT Specify number of pixels that define the menu\n" -" background's border. Borders are not stretched\n" -" when images are scaled.\n" -" -B, --image-bg STYLE Set background for transparent images and the like.\n" -" Accepted values: white, black, default\n" -" -N, --no-menus Don't load or show any menus.\n" -" -0, --reload-button B Use button B to reload the image (defaults to 0)\n" -" -1, --pan-button B Use button B pan the image (hold button down, move\n" -" the mouse to move the image around. Advancesto the\n" -" next image when the mouse is not moved (defaults to\n" -" 1, usually the left button).\n" -" -2, --zoom-button B Use button B to zoom the current image in any\n" -" mode (defaults to 2, usually the middle button).\n" -" -3, --menu-button B Use CTRL+Button B to activate the menu in any\n" -" mode. Set to 0 for any button. This option\n" -" is disabled if the -N or --no-menus option is set\n" -" (defaults to 3, usually the right button).\n" -" --menu-ctrl-mask Require CTRL+Button for menu activation in\n" -" any mode (default=off).\n" -" -4, --prev-button B Use button B to switch to the previous image\n" -" (defaults to 4, which usually is <mousewheel up>).\n" -" -5, --next-button B Use button B to switch to the next image\n" -" (defaults to 5, which usually is <mousewheel down>).\n" -" -8, --rotate-button B Use CTRL+Button B to rotate the current image in\n" -" any mode (default=2).\n" -" --no-rotate-ctrl-mask Don't require CTRL+Button for rotation in\n" -" any mode -- just use the button (default=off).\n" -" -9, --blur-button B Use CTRL+Button B to blur the current image in\n" -" any mode (default=1).\n" -" --no-blur-ctrl-mask Don't require CTRL+Button for blurring in\n" -" any mode -- just use the button (default=off).\n" -" --no-xinerama Disable Xinerama support. Only useful if\n" -" you have Xinerama compiled in.\n" -" --screen-clip [0|1] Enable/disable window clipping based on screen\n" -" size. WARNING: with this option disabled,\n" -" image windows could become very large, making\n" -" them unmanageable in certain window managers.\n" -" --hide-pointer In full screen mode, hide the X mouse pointer.\n" -" FORMAT SPECIFIERS\n" -" %%f image path/filename\n" -" %%n image name\n" -" %%s image size (bytes)\n" -" %%p image pixel size\n" -" %%w image width\n" -" %%h image height\n" -" %%t image format\n" -" %%P prints feh\n" -" %%v prints the version\n" -" %%m prints the mode (slideshow, multiwindow...)\n" -" %%l prints the total number of files in the filelist\n" -" %%u prints the current file number\n" -" \\n prints a newline\n" -" Eg. feh -A \"mv %%f ~/images/%%n\" *\n" -" MONTAGE MODE OPTIONS\n" -" -X, --ignore-aspect By default, the montage thumbnails will retain\n" -" their aspect ratios, while fitting in --thumb-width\n" -" and --thumb-height. This option will force them to\n" -" be the size set by --thumb-width and --thumb-height\n" -" This will prevent any whitespace in the final\n" -" montage\n" -" -s, --stretch Normally, if an image is smaller than the specified\n" -" thumbnail size, it will not be enlarged. If this\n" -" option is set, the image will be scaled up to fit\n" -" the thumbnail size. (Aspect ratio will be maintained\n" -" unless --ignore-aspect is specified)\n" -" -y, --thumb-width NUM Set thumbnail width in pixels\n" -" -E, --thumb-height NUM Set thumbnail height in pixels\n" -" Thumbnails default to 20x20 pixels\n" -" -W, --limit-width NUM Limit the width of the montage in pixels\n" -" -H, --limit-height NUM Limit the height of the montage in pixels\n" -" These options can be used together (to define the\n" -" image size exactly), or separately. If only one is\n" -" specified, theother is calculated from the number\n" -" of files specified and the size of the thumbnails.\n" -" The default is to limit width to 800 pixels and\n" -" calculate the height\n" -" -b, --bg FILE|trans Use FILE as a background for your montage. With\n" -" this option specified, the size of the montage will\n" -" default to the size of FILE if no size restrictions\n" -" are specified. Alternatively, if FILE is \"trans\",\n" -" make the background transparent.\n" -" -a, --alpha NUM When drawing thumbnails onto the background, apply\n" -" them with a transparency level of NUM (0-255).\n" -" -o, --output FILE Save the created montage to FILE\n" -" -O, --output-only FILE Just save the created montage to FILE\n" -" WITHOUT displaying it (use in scripts)\n" -" INDEX MODE OPTIONS\n" -" -e, --font FONT Use FONT to print the information under each\n" -" thumbnail. FONT should be defined in the form\n" -" fontname/size(points). eg -e myfont/12\n" -" -@, --title-font FONT Use FONT to print a title on the index, if no\n" -" font is specified, a title will not be printed\n" -" SLIDESHOW KEYS\n" -" The default mode for viewing mulitple images is Slideshow mode\n" -" When viewing a slideshow, the following keys may be used:\n" -" p, P, <BACKSPACE>, <LEFT> Goto previous slide\n" -" n, N, <SPACE>, <RIGHT> Goto next slide\n" -" r, R Reload image (good for webcams)\n" -" v, V Toggle fullscreen\n" -" m, M Show popup menu\n" -" c, C Caption entry mode. If --caption-path has been\n" -" specified, then this enables caption editing.\n" -" The caption will turn yellow and be editable,\n" -" hit enter to confirm and save the caption, or\n" -" hit escape to cancel and revert the caption.\n" -" w, W Size window to current image dimensions\n" -" h, H Pause the slideshow (only useful when using\n" -" timed reloading or image changes)\n" -" a, A Toggle action display (--draw-actions)\n" -" d, D Toggle filename display (--draw-filename)\n" -" s, S Save current image to unique filename\n" -" f, F Save current filelist to unique filename\n" -" <, > In place editing, rotate 90 degrees right/left\n" -" <HOME> Goto first slide\n" -" <END> Goto last slide\n" -" <ESCAPE> Quit the slideshow\n" -" +, = Increase reload delay\n" -" -, _ Decrease reload delay\n" -" <DELETE> Remove the currently viewed file from the filelist\n" -" <CTRL+DELETE> Delete the currently viewed file and remove it\n" -" from the filelist\n" -" x, X Close current window\n" -" q, Q Quit the slideshow\n" -" <KEYPAD LEFT> Move the image to the left\n" -" <KEYPAD RIGHT> Move the image to the right\n" -" <KEYPAD UP> Move the image up\n" -" <KEYPAD DOWN> Move the image down\n" -" <KEYPAD BEGIN> Antialias the image\n" -" <KEYPAD +> Zoom in\n" -" <KEYPAD -> Zoom out\n" -" <KEYPAD *> Zoom to 100%%\n" -" <KEYPAD /> Zoom to fit the window\n" -" <ENTER>,0 Run action specified by --action option\n" -" 1-9 Run action 1-9 specified by --action[1-9] options\n" -"\n" -" MOUSE ACTIONS\n" -" When viewing an image, a click of mouse button 1 moves to the next image\n" -" (slideshow mode only), a drag of mouse button 1 pans the image, if the\n" -" viewable window is smaller than the image, button 2 zooms (click and drag\n" -" left->right to zoom in, right->left to zoom out, click once to restore\n" -" 1x zoom), and mouse button 3 pans.\n" -" Ctrl+button 1 blurs or sharpens the image (drag left to blur and right to\n" -" sharpen). Ctrl+button 2 rotates the image around the center point.\n" -" Button 3 activates the context-sensitive menu. Buttons can be redefined\n" -" with the -1 through -9 (or --*-button) cmdline flags. All you people\n" -" with million button mice can remove the ctrl mask with the --no-*-ctrl-mask\n" -" options.\n" "\n" "See 'man feh' for more detailed information\n" -"\n" -"This program is free software see the file COPYING for licensing info.\n" -"Copyright Tom Gilbert (and various contributors) 1999-2003\n" -"Email bugs to <feh_sucks@linuxbrit.co.uk>\n"); - exit(0); + fprintf(stdout, + "Usage : " PACKAGE " [OPTIONS]... FILES...\n" + " Where a FILE is an image file or a directory.\n" + " Multiple files are supported.\n" + " Urls are supported. They must begin with http:// or ftp:// and you must\n" + " have wget installed to download the files for viewing.\n" + " Options can also be specified in the in the feh configuration file. See\n" + " man feh for more details\n" + " -h, --help display this help and exit\n" + " -v, --version output version information and exit\n" + " -V, --verbose output useful information, progress bars, etc\n" + " -q, --quiet Don't report non-fatal errors for failed loads\n" + " Verbose and quiet modes are not mutually exclusive,\n" + " the first controls informational messages, the\n" + " second only errors.\n" + " -T, --theme THEME Load options from config file with name THEME\n" + " see man feh for more info.\n" + " -_, --rcfile FILE Use FILE to parse themes and options from,\n" + " instead of the default ~/.fehrc, /etc/fehrc files.\n" + " -r, --recursive Recursively expand any directories in FILE to\n" + " the content of those directories. (Take it easy)\n" + " -z, --randomize When viewing multiple files in a slideshow,\n" + " randomise the file list before displaying\n" + " --no-jump-on-resort Don't jump to the first image when the filelist\n" + " is resorted.\n" + " -g, --geometry STRING Limit (and don't change) the window size. Takes\n" + " an X-style geometry string like 640x480.\n" + " Note that larger images will be zoomed out to fit\n" + " but you can see them at 1:1 by clicking the zoom\n" + " button.\n" + " -f, --filelist FILE This option is similar to the playlists used by\n" + " music software. If FILE exists, it will be read\n" + " for a list of files to load, in the order they\n" + " appear. The format is a list of image filenames,\n" + " absolute or relative to the current directory,\n" + " one filename per line.\n" + " If FILE doesn't exist, it will be created from the\n" + " internal filelist at the end of a viewing session.\n" + " This is best used to store the results of complex\n" + " sorts (-Spixels for example) for later viewing.\n" + " Any changes to the internal filelist (such as\n" + " deleting a file or it being pruned for being\n" + " unloadable) will be saved to FILE when feh exits.\n" + " You can add files to filelists by specifying them\n" + " on the commandline when also specifying the list.\n" + " -|, --start-at POSITION Start at POSITION in the filelist\n" + " -p, --preload Preload images. This doesn't mean hold them in\n" + " RAM, it means run through and eliminate unloadable\n" + " images first. Otherwise they will be removed as you\n" + " flick through.\n" + " -., --scale-down Automatically scale down images too big for the\n" + " screen. Currently only works with -P\n" + " -F, --full-screen Make the window fullscreen\n" + " -Z, --auto-zoom Zoom picture to screen size in fullscreen mode,\n" + " is affected by the option --stretch\n" + " --zoom PERCENT Zooms images by a PERCENT, when in full screen\n" + " mode or when window geometry is fixed. If combined\n" + " with --auto-zoom, zooming will be limited to the\n" + " the size.\n" + " -w, --multiwindow Disable slideshow mode. With this setting,\n" + " instead of opening multiple files in slideshow\n" + " mode, multiple windows will be opened.\n" + " -x, --borderless Create borderless windows\n" + " -d, --draw-filename Draw the filename at the top-left of the image.\n" + " -^, --title TITLE Use TITLE as the window title in slideshow mode.\n" + " -D, --slideshow-delay NUM For slideshow mode, specifies time delay (seconds,\n" + " can be a decimal) between automatically changing\n" + " slides.\n" + " --cycle-once exit feh after one loop through a slideshow\n" + " -R, --reload NUM Use this option to tell feh to reload an image\n" + " after NUM seconds. Useful for viewing webcams\n" + " via http, or even on your local machine.\n" + " -Q, --builtin Use builtin http grabber to grab remote files\n" + " instead of wget.\n" + " mechanism, useful if don't have wget.\n" + " -k, --keep-http When viewing files using http, feh normally\n" + " deletes the local copies after viewing, or,\n" + " if caching, on exit. This option prevents this\n" + " so that you get to keep the local copies.\n" + " They will be in the current working directory\n" + " with \"feh\" in the name.\n" + " --caption-path PATH Path to directory containing image captions.\n" + " This turns on caption viewing, and if captions\n" + " are found in PATH, which is relative to the\n" + " directory of each image, they are overlayed\n" + " on the displayed image.\n" + " e.g with caption path \"captions\", and viewing\n" + " image images/foo.jpg, caption will be looked for\n" + " as \"images/captions/foo.jpg.txt\"\n" + " -j, --output-dir Output directory for saved files. Really only\n" + " useful with the -k flag.\n" + " -G, --wget-timestamp When viewing http images with reload set (eg\n" + " webcams), try to only reload the image if the\n" + " remote file has changed.\n" + " -l, --list Don't display images. Analyse them and display an\n" + " 'ls' style listing. Useful in scripts hunt out\n" + " images of a certain size/resolution/type etc.\n" + " -L, --customlist FORMAT Use FORMAT as the format specifier for list\n" + " output. FORMAT is a printf-like string containing\n" + " image info specifiers. See FORMAT SPECIFIERS.\n" + " -U, --loadable Don't display images. Just print out their name\n" + " if imlib2 can successfully load them.\n" + " -u, --unloadable Don't display images. Just print out their name\n" + " if imlib2 can NOT successfully load them.\n" + " -S, --sort SORT_TYPE The file list may be sorted according to image\n" + " parameters. Allowed sort types are: name,\n" + " filename, width, height, pixels, size, format.\n" + " For sort modes other than name or filename, a\n" + " preload run will be necessary, causing a delay\n" + " proportional to the number of images in the list\n" + " -n, --reverse Reverse the sort order. Use this to invert the order\n" + " of the filelist. Eg to sort in reverse width order,\n" + " use -nSwidth\n" + " -A, --action ACTION Specify a string as an action to perform on the\n" + " image. In slideshow or multiwindow modes, the action\n" + " in list mode, or loadable|unloadable modes, the\n" + " action will be run for each file.\n" + " The action will be executed by /bin/sh. Use\n" + " format specifiers to refer to image info. See\n" + " FORMAT SPECIFIERS for examples\n" + " Eg. -A \"mv %%f ~/images/%%n\"\n" + " In slideshow mode, the next image will be shown\n" + " after running the command, in multiwindow mode,\n" + " the window will be closed.\n" + " --action1 ACTION These extra action options allow you to specify\n" + " --action2 ACTION multiple additional actions which can be invoked\n" + " ... using the appropriate number key 1-9\n" + " --action9 ACTION\n" + " --draw-actions Show the defined actions and what they do\n" + " -m, --montage Enable montage mode. Montage mode creates a new\n" + " image consisting of a grid of thumbnails of the\n" + " images specified using FILE... When montage mode\n" + " is selected, certain other options become\n" + " available. See MONTAGE MODE OPTIONS\n" + " -c, --collage Same as montage mode, but the thumbnails are\n" + " distributed randomly. You must specify width and\n" + " height or supply a background image or both\n" + " -i, --index Enable Index mode. Index mode is similar to\n" + " montage mode, and accepts the same options. It\n" + " creates an index print of thumbails, printing the\n" + " images name beneath each thumbnail. Index mode\n" + " enables certain other options, see INDEX MODE\n" + " OPTIONS\n" + " -t, --thumbnails As --index, but clicking an image will open it in\n" + " a new viewing window\n" + " --cache-thumbnails Enable thumbnail caching\n" + " -~, --thumb-title STRING Set window title for images opened from thumbnail mode.\n" + " Supports format specifiers, see there.\n" + " -I, --fullindex Same as index mode, but below each thumbnail you\n" + " get image name, size and dimensions\n" + " --bg-tile FILE\n" + " --bg-center FILE\n" + " --bg-scale FILE\n" + " --bg-seamless FILE Set your desktop background to FILE. Feh can\n" + " use enlightenment IPC if you are running it,\n" + " or will fall back to X methods.\n" + " Feh stores the commandline necessary to restore\n" + " the background you chose in ~/.fehbg. So to have\n" + " feh-set backgrounds restored when you restart X,\n" + " add the line \"eval `cat $HOME/.fehbg`\" to your\n" + " X startup script (e.g. ~/.xsession). Note that\n" + " you only need to do this for non E window\n" + " managers.\n" + " -C, --fontpath PATH Specify an extra directory to look in for fonts,\n" + " can be used multiple times to add multiple paths.\n" + " -M, --menu-font FONT Use FONT for the font in menus.\n" + " --menu-style FILE Use FILE as the style descriptor for menu text.\n" + " -), --menu-bg BG Use BG for the background image in menus.\n" + " --menu-border INT Specify number of pixels that define the menu\n" + " background's border. Borders are not stretched\n" + " when images are scaled.\n" + " -B, --image-bg STYLE Set background for transparent images and the like.\n" + " Accepted values: white, black, default\n" + " -N, --no-menus Don't load or show any menus.\n" + " -0, --reload-button B Use button B to reload the image (defaults to 0)\n" + " -1, --pan-button B Use button B pan the image (hold button down, move\n" + " the mouse to move the image around. Advancesto the\n" + " next image when the mouse is not moved (defaults to\n" + " 1, usually the left button).\n" + " -2, --zoom-button B Use button B to zoom the current image in any\n" + " mode (defaults to 2, usually the middle button).\n" + " -3, --menu-button B Use CTRL+Button B to activate the menu in any\n" + " mode. Set to 0 for any button. This option\n" + " is disabled if the -N or --no-menus option is set\n" + " (defaults to 3, usually the right button).\n" + " --menu-ctrl-mask Require CTRL+Button for menu activation in\n" + " any mode (default=off).\n" + " -4, --prev-button B Use button B to switch to the previous image\n" + " (defaults to 4, which usually is <mousewheel up>).\n" + " -5, --next-button B Use button B to switch to the next image\n" + " (defaults to 5, which usually is <mousewheel down>).\n" + " -8, --rotate-button B Use CTRL+Button B to rotate the current image in\n" + " any mode (default=2).\n" + " --no-rotate-ctrl-mask Don't require CTRL+Button for rotation in\n" + " any mode -- just use the button (default=off).\n" + " -9, --blur-button B Use CTRL+Button B to blur the current image in\n" + " any mode (default=1).\n" + " --no-blur-ctrl-mask Don't require CTRL+Button for blurring in\n" + " any mode -- just use the button (default=off).\n" + " --no-xinerama Disable Xinerama support. Only useful if\n" + " you have Xinerama compiled in.\n" + " --screen-clip [0|1] Enable/disable window clipping based on screen\n" + " size. WARNING: with this option disabled,\n" + " image windows could become very large, making\n" + " them unmanageable in certain window managers.\n" + " --hide-pointer In full screen mode, hide the X mouse pointer.\n" + " FORMAT SPECIFIERS\n" + " %%f image path/filename\n" + " %%n image name\n" + " %%s image size (bytes)\n" + " %%p image pixel size\n" + " %%w image width\n" + " %%h image height\n" + " %%t image format\n" + " %%P prints feh\n" + " %%v prints the version\n" + " %%m prints the mode (slideshow, multiwindow...)\n" + " %%l prints the total number of files in the filelist\n" + " %%u prints the current file number\n" + " \\n prints a newline\n" + " Eg. feh -A \"mv %%f ~/images/%%n\" *\n" + " MONTAGE MODE OPTIONS\n" + " -X, --ignore-aspect By default, the montage thumbnails will retain\n" + " their aspect ratios, while fitting in --thumb-width\n" + " and --thumb-height. This option will force them to\n" + " be the size set by --thumb-width and --thumb-height\n" + " This will prevent any whitespace in the final\n" + " montage\n" + " -s, --stretch Normally, if an image is smaller than the specified\n" + " thumbnail size, it will not be enlarged. If this\n" + " option is set, the image will be scaled up to fit\n" + " the thumbnail size. (Aspect ratio will be maintained\n" + " unless --ignore-aspect is specified)\n" + " -y, --thumb-width NUM Set thumbnail width in pixels\n" + " -E, --thumb-height NUM Set thumbnail height in pixels\n" + " Thumbnails default to 20x20 pixels\n" + " -W, --limit-width NUM Limit the width of the montage in pixels\n" + " -H, --limit-height NUM Limit the height of the montage in pixels\n" + " These options can be used together (to define the\n" + " image size exactly), or separately. If only one is\n" + " specified, theother is calculated from the number\n" + " of files specified and the size of the thumbnails.\n" + " The default is to limit width to 800 pixels and\n" + " calculate the height\n" + " -b, --bg FILE|trans Use FILE as a background for your montage. With\n" + " this option specified, the size of the montage will\n" + " default to the size of FILE if no size restrictions\n" + " are specified. Alternatively, if FILE is \"trans\",\n" + " make the background transparent.\n" + " -a, --alpha NUM When drawing thumbnails onto the background, apply\n" + " them with a transparency level of NUM (0-255).\n" + " -o, --output FILE Save the created montage to FILE\n" + " -O, --output-only FILE Just save the created montage to FILE\n" + " WITHOUT displaying it (use in scripts)\n" + " INDEX MODE OPTIONS\n" + " -e, --font FONT Use FONT to print the information under each\n" + " thumbnail. FONT should be defined in the form\n" + " fontname/size(points). eg -e myfont/12\n" + " -@, --title-font FONT Use FONT to print a title on the index, if no\n" + " font is specified, a title will not be printed\n" + " SLIDESHOW KEYS\n" + " The default mode for viewing mulitple images is Slideshow mode\n" + " When viewing a slideshow, the following keys may be used:\n" + " p, P, <BACKSPACE>, <LEFT> Goto previous slide\n" + " n, N, <SPACE>, <RIGHT> Goto next slide\n" + " r, R Reload image (good for webcams)\n" + " v, V Toggle fullscreen\n" + " m, M Show popup menu\n" + " c, C Caption entry mode. If --caption-path has been\n" + " specified, then this enables caption editing.\n" + " The caption will turn yellow and be editable,\n" + " hit enter to confirm and save the caption, or\n" + " hit escape to cancel and revert the caption.\n" + " w, W Size window to current image dimensions\n" + " h, H Pause the slideshow (only useful when using\n" + " timed reloading or image changes)\n" + " a, A Toggle action display (--draw-actions)\n" + " d, D Toggle filename display (--draw-filename)\n" + " s, S Save current image to unique filename\n" + " f, F Save current filelist to unique filename\n" + " <, > In place editing, rotate 90 degrees right/left\n" + " <HOME> Goto first slide\n" + " <END> Goto last slide\n" + " <ESCAPE> Quit the slideshow\n" + " +, = Increase reload delay\n" + " -, _ Decrease reload delay\n" + " <DELETE> Remove the currently viewed file from the filelist\n" + " <CTRL+DELETE> Delete the currently viewed file and remove it\n" + " from the filelist\n" + " x, X Close current window\n" + " q, Q Quit the slideshow\n" + " <KEYPAD LEFT> Move the image to the left\n" + " <KEYPAD RIGHT> Move the image to the right\n" + " <KEYPAD UP> Move the image up\n" + " <KEYPAD DOWN> Move the image down\n" + " <KEYPAD BEGIN> Antialias the image\n" + " <KEYPAD +> Zoom in\n" + " <KEYPAD -> Zoom out\n" + " <KEYPAD *> Zoom to 100%%\n" + " <KEYPAD /> Zoom to fit the window\n" + " <ENTER>,0 Run action specified by --action option\n" + " 1-9 Run action 1-9 specified by --action[1-9] options\n" + "\n" + " MOUSE ACTIONS\n" + " When viewing an image, a click of mouse button 1 moves to the next image\n" + " (slideshow mode only), a drag of mouse button 1 pans the image, if the\n" + " viewable window is smaller than the image, button 2 zooms (click and drag\n" + " left->right to zoom in, right->left to zoom out, click once to restore\n" + " 1x zoom), and mouse button 3 pans.\n" + " Ctrl+button 1 blurs or sharpens the image (drag left to blur and right to\n" + " sharpen). Ctrl+button 2 rotates the image around the center point.\n" + " Button 3 activates the context-sensitive menu. Buttons can be redefined\n" + " with the -1 through -9 (or --*-button) cmdline flags. All you people\n" + " with million button mice can remove the ctrl mask with the --no-*-ctrl-mask\n" + " options.\n" "\n" + "See 'man feh' for more detailed information\n" "\n" + "This program is free software see the file COPYING for licensing info.\n" + "Copyright Tom Gilbert (and various contributors) 1999-2003\n" + "Email bugs to <feh_sucks@linuxbrit.co.uk>\n"); + exit(0); } -void -feh_create_default_config(char *rcfile) +void feh_create_default_config(char *rcfile) { - FILE *fp; - - D_ENTER(4); - - if ((fp = fopen(rcfile, "w")) == NULL) - { - weprintf("Unable to create default config file %s\n", rcfile); - D_RETURN_(4); - } - - fprintf(fp, - "# Feh configuration file.\n" - "# Lines starting with # are comments. Don't use comments mid-line.\n" - "\n" "# Feh expects to find this as ~/.fehrc or /etc/fehrc\n" - "# If both are available, ~/.fehrc will be used\n" "\n" - "# Options defined in theme_name/options pairs.\n" - "# Separate themename and options by whitespace.\n" "\n" - "# There are two ways of specifying the theme. Either use feh -Tthemename,\n" - "# or use a symbolic link to feh with the name of the theme. eg\n" - "# ln -s `which feh` ~/bin/mkindex\n" - "# Now when you run 'mkindex', feh will load the config specified for the\n" - "# mkindex theme.\n" "\n" "# ======================\n" - "# Some examples of usage\n" "# ======================\n" "\n" - "# Set the default feh options to be recursive and verbose\n" - "# feh -rV\n" "\n" - "# Multiple options can of course be used. They should all be on one line\n" - "# imagemap -rV --quiet -W 400 -H 300 --thumb-width 40 --thumb-height 30\n" - "\n" "# ================================================\n" - "# Here I set some useful themes for you to try out\n" - "# ================================================\n" "\n" - "# Webcam mode, simply specify the url(s).\n" - "# e.g. feh -Twebcam http://cam1 http://cam2\n" - "webcam --multiwindow --reload 20\n" "\n" - "# Create an index of the current directory. This version uses . as the\n" - "# current dir, so you don't even need any commandline arguments.\n" - "mkindex -iVO index.jpg .\n" "\n" "# More ambitious version...\n" - "imgidx -iVO .fehindex.jpg --limit-width 1200 --thumb-width 90 --thumb-height 90 .\n" - "\n" "# Show a presentation\n" - "present --full-screen --sort name\n" - "\n" - "# Booth mode ;-)\n" - "booth --full-screen --hide-pointer --slideshow-delay 20\n" - "\n" - "# Screw xscreensaver, use feh =)\n" - "screensave --full-screen --randomize --slideshow-delay 5\n" "\n" - "# Add <img> tags to your html with ease :-)\n" - "newimg -q -L \"<img src=\\\"%%f\\\" alt=\\\"%%n\\\" border=\\\"0\\\" width=\\\"%%w\\\" height=\\\"%%h\\\">\"\n" - "\n" - "# Different menus\n" - "chrome --menu-bg " PREFIX" /share/feh/images/menubg_chrome.png\n" - "brushed --menu-bg " PREFIX "/share/feh/images/menubg_brushed.png\n" - "pastel --menu-bg " PREFIX "/share/feh/images/menubg_pastel.png\n" - "aluminium --menu-bg " PREFIX "/share/feh/images/menubg_aluminium.png\n" - "wood --menu-bg " PREFIX "/share/feh/images/menubg_wood.png\n" - "aqua --menu-bg " PREFIX "/share/feh/images/menubg_aqua.png\n" - "sky --menu-bg " PREFIX "/share/feh/images/menubg_sky.png\n" - "orange --menu-bg " PREFIX "/share/feh/images/menubg_orange.png\n" - "light --menu-bg " PREFIX "/share/feh/images/menubg_light.png\n" - "black --menu-bg " PREFIX "/share/feh/images/menubg_black.png --menu-style " PREFIX "/share/feh/fonts/black.style\n" - ); - fclose(fp); - - D_RETURN_(4); + FILE *fp; + + D_ENTER(4); + + if ((fp = fopen(rcfile, "w")) == NULL) { + weprintf("Unable to create default config file %s\n", rcfile); + D_RETURN_(4); + } + + fprintf(fp, + "# Feh configuration file.\n" + "# Lines starting with # are comments. Don't use comments mid-line.\n" + "\n" + "# Feh expects to find this as ~/.fehrc or /etc/fehrc\n" + "# If both are available, ~/.fehrc will be used\n" "\n" + "# Options defined in theme_name/options pairs.\n" + "# Separate themename and options by whitespace.\n" "\n" + "# There are two ways of specifying the theme. Either use feh -Tthemename,\n" + "# or use a symbolic link to feh with the name of the theme. eg\n" + "# ln -s `which feh` ~/bin/mkindex\n" + "# Now when you run 'mkindex', feh will load the config specified for the\n" + "# mkindex theme.\n" "\n" "# ======================\n" + "# Some examples of usage\n" "# ======================\n" + "\n" + "# Set the default feh options to be recursive and verbose\n" + "# feh -rV\n" "\n" + "# Multiple options can of course be used. They should all be on one line\n" + "# imagemap -rV --quiet -W 400 -H 300 --thumb-width 40 --thumb-height 30\n" + "\n" "# ================================================\n" + "# Here I set some useful themes for you to try out\n" + "# ================================================\n" "\n" + "# Webcam mode, simply specify the url(s).\n" + "# e.g. feh -Twebcam http://cam1 http://cam2\n" + "webcam --multiwindow --reload 20\n" "\n" + "# Create an index of the current directory. This version uses . as the\n" + "# current dir, so you don't even need any commandline arguments.\n" + "mkindex -iVO index.jpg .\n" "\n" + "# More ambitious version...\n" + "imgidx -iVO .fehindex.jpg --limit-width 1200 --thumb-width 90 --thumb-height 90 .\n" + "\n" "# Show a presentation\n" + "present --full-screen --sort name\n" "\n" + "# Booth mode ;-)\n" + "booth --full-screen --hide-pointer --slideshow-delay 20\n" + "\n" "# Screw xscreensaver, use feh =)\n" + "screensave --full-screen --randomize --slideshow-delay 5\n" + "\n" "# Add <img> tags to your html with ease :-)\n" + "newimg -q -L \"<img src=\\\"%%f\\\" alt=\\\"%%n\\\" border=\\\"0\\\" width=\\\"%%w\\\" height=\\\"%%h\\\">\"\n" + "\n" "# Different menus\n" "chrome --menu-bg " PREFIX + " /share/feh/images/menubg_chrome.png\n" + "brushed --menu-bg " PREFIX + "/share/feh/images/menubg_brushed.png\n" + "pastel --menu-bg " PREFIX + "/share/feh/images/menubg_pastel.png\n" + "aluminium --menu-bg " PREFIX + "/share/feh/images/menubg_aluminium.png\n" + "wood --menu-bg " PREFIX + "/share/feh/images/menubg_wood.png\n" "aqua --menu-bg " + PREFIX "/share/feh/images/menubg_aqua.png\n" + "sky --menu-bg " PREFIX + "/share/feh/images/menubg_sky.png\n" "orange --menu-bg " + PREFIX "/share/feh/images/menubg_orange.png\n" + "light --menu-bg " PREFIX + "/share/feh/images/menubg_light.png\n" "black --menu-bg " + PREFIX "/share/feh/images/menubg_black.png --menu-style " PREFIX "/share/feh/fonts/black.style\n"); + fclose(fp); + + D_RETURN_(4); } diff --git a/src/options.h b/src/options.h index ba88fc8..cba2b37 100644 --- a/src/options.h +++ b/src/options.h @@ -26,109 +26,108 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef OPTIONS_H #define OPTIONS_H -struct __fehoptions -{ - unsigned char multiwindow; - unsigned char montage; - unsigned char collage; - unsigned char index; - unsigned char index_show_name; - unsigned char index_show_dim; - unsigned char index_show_size; - unsigned char thumbs; - unsigned char slideshow; - unsigned char recursive; - unsigned char output; - unsigned char verbose; - unsigned char display; - unsigned char bg; - unsigned char alpha; - unsigned char alpha_level; - unsigned char aspect; - unsigned char stretch; - unsigned char keep_http; - unsigned char borderless; - unsigned char randomize; - unsigned char no_jump_on_resort; - unsigned char full_screen; - unsigned char auto_zoom; - unsigned char draw_filename; - unsigned char list; - unsigned char quiet; - unsigned char preload; - unsigned char loadables; - unsigned char unloadables; - unsigned char reverse; - unsigned char no_menus; - unsigned char scale_down; - unsigned char builtin_http; - unsigned char wget_timestamp; - unsigned char bgmode; - unsigned char xinerama; - unsigned char screen_clip; - unsigned char hide_pointer; - unsigned char fmmode; - unsigned char draw_actions; - unsigned char cache_thumbnails; - unsigned char cycle_once; - - char *output_file; - char *output_dir; - char *bg_file; - char *font; - char *title_font; - char *title; - char *thumb_title; - char *actions[10]; - char *fontpath; - char *filelistfile; - char *menu_font; - char *customlist; - char *menu_bg; - char *image_bg; - char *rcfile; - char *menu_style; - char *caption_path; - - gib_style *menu_style_l; - - unsigned char pan_button; - unsigned char zoom_button; - unsigned char menu_button; - unsigned char menu_ctrl_mask; - unsigned char prev_button; - unsigned char next_button; - - unsigned char rotate_button; - unsigned char blur_button; - unsigned char reload_button; - unsigned char no_rotate_ctrl_mask; - unsigned char no_blur_ctrl_mask; - unsigned char no_pan_ctrl_mask; - - int thumb_w; - int thumb_h; - int limit_w; - int limit_h; - int reload; - int sort; - int debug_level; - int geom_flags; - int geom_x; - int geom_y; - int geom_w; - int geom_h; - int default_zoom; - int menu_border; - unsigned char adjust_reload; - unsigned int start_list_at; - - unsigned char mode; - unsigned char paused; - - double slideshow_delay; - - Imlib_Font menu_fn; +struct __fehoptions { + unsigned char multiwindow; + unsigned char montage; + unsigned char collage; + unsigned char index; + unsigned char index_show_name; + unsigned char index_show_dim; + unsigned char index_show_size; + unsigned char thumbs; + unsigned char slideshow; + unsigned char recursive; + unsigned char output; + unsigned char verbose; + unsigned char display; + unsigned char bg; + unsigned char alpha; + unsigned char alpha_level; + unsigned char aspect; + unsigned char stretch; + unsigned char keep_http; + unsigned char borderless; + unsigned char randomize; + unsigned char no_jump_on_resort; + unsigned char full_screen; + unsigned char auto_zoom; + unsigned char draw_filename; + unsigned char list; + unsigned char quiet; + unsigned char preload; + unsigned char loadables; + unsigned char unloadables; + unsigned char reverse; + unsigned char no_menus; + unsigned char scale_down; + unsigned char builtin_http; + unsigned char wget_timestamp; + unsigned char bgmode; + unsigned char xinerama; + unsigned char screen_clip; + unsigned char hide_pointer; + unsigned char fmmode; + unsigned char draw_actions; + unsigned char cache_thumbnails; + unsigned char cycle_once; + + char *output_file; + char *output_dir; + char *bg_file; + char *font; + char *title_font; + char *title; + char *thumb_title; + char *actions[10]; + char *fontpath; + char *filelistfile; + char *menu_font; + char *customlist; + char *menu_bg; + char *image_bg; + char *rcfile; + char *menu_style; + char *caption_path; + + gib_style *menu_style_l; + + unsigned char pan_button; + unsigned char zoom_button; + unsigned char menu_button; + unsigned char menu_ctrl_mask; + unsigned char prev_button; + unsigned char next_button; + + unsigned char rotate_button; + unsigned char blur_button; + unsigned char reload_button; + unsigned char no_rotate_ctrl_mask; + unsigned char no_blur_ctrl_mask; + unsigned char no_pan_ctrl_mask; + + int thumb_w; + int thumb_h; + int limit_w; + int limit_h; + int reload; + int sort; + int debug_level; + int geom_flags; + int geom_x; + int geom_y; + int geom_w; + int geom_h; + int default_zoom; + int menu_border; + unsigned char adjust_reload; + unsigned int start_list_at; + + unsigned char mode; + unsigned char paused; + + double slideshow_delay; + + Imlib_Font menu_fn; }; void init_parse_options(int argc, char **argv); diff --git a/src/slideshow.c b/src/slideshow.c index 3afbafe..97b1f92 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -29,561 +29,493 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "winwidget.h" #include "options.h" -void -init_slideshow_mode(void) +void init_slideshow_mode(void) { - winwidget w = NULL; - int success = 0; - char *s = NULL; - gib_list *l = NULL, *last = NULL; - feh_file *file = NULL; - - D_ENTER(3); - - mode = "slideshow"; - if (opt.start_list_at) - { - l = gib_list_nth(filelist, opt.start_list_at); - opt.start_list_at = 0; /* for next time */ - } - else - { - l = filelist; - } - for (; l; l = l->next) - { - file = FEH_FILE(l->data); - if (last) - { - filelist = feh_file_remove_from_list(filelist, last); - filelist_len--; - last = NULL; - } - current_file = l; - s = slideshow_create_name(file); - if ((w = winwidget_create_from_file(l, s, WIN_TYPE_SLIDESHOW)) != NULL) - { - free(s); - success = 1; - winwidget_show(w); - if (opt.slideshow_delay >= 0.0) - feh_add_timer(cb_slide_timer, w, opt.slideshow_delay, - "SLIDE_CHANGE"); - else if (opt.reload > 0) - feh_add_unique_timer(cb_reload_timer, w, opt.reload); - break; - } - else - { - free(s); - last = l; - } - } - if (!success) - show_mini_usage(); - D_RETURN_(3); + winwidget w = NULL; + int success = 0; + char *s = NULL; + gib_list *l = NULL, *last = NULL; + feh_file *file = NULL; + + D_ENTER(3); + + mode = "slideshow"; + if (opt.start_list_at) { + l = gib_list_nth(filelist, opt.start_list_at); + opt.start_list_at = 0; /* for next time */ + } else { + l = filelist; + } + for (; l; l = l->next) { + file = FEH_FILE(l->data); + if (last) { + filelist = feh_file_remove_from_list(filelist, last); + filelist_len--; + last = NULL; + } + current_file = l; + s = slideshow_create_name(file); + if ((w = winwidget_create_from_file(l, s, WIN_TYPE_SLIDESHOW)) != NULL) { + free(s); + success = 1; + winwidget_show(w); + if (opt.slideshow_delay >= 0.0) + feh_add_timer(cb_slide_timer, w, opt.slideshow_delay, "SLIDE_CHANGE"); + else if (opt.reload > 0) + feh_add_unique_timer(cb_reload_timer, w, opt.reload); + break; + } else { + free(s); + last = l; + } + } + if (!success) + show_mini_usage(); + D_RETURN_(3); } -void -cb_slide_timer(void *data) +void cb_slide_timer(void *data) { - D_ENTER(4); - slideshow_change_image((winwidget) data, SLIDE_NEXT); - D_RETURN_(4); + D_ENTER(4); + slideshow_change_image((winwidget) data, SLIDE_NEXT); + D_RETURN_(4); } -void -cb_reload_timer(void *data) +void cb_reload_timer(void *data) { - winwidget w = (winwidget) data; + winwidget w = (winwidget) data; - D_ENTER(4); - feh_reload_image(w, 0, 0); - feh_add_unique_timer(cb_reload_timer, w, opt.reload); - D_RETURN_(4); + D_ENTER(4); + feh_reload_image(w, 0, 0); + feh_add_unique_timer(cb_reload_timer, w, opt.reload); + D_RETURN_(4); } -void -feh_reload_image(winwidget w, int resize, int force_new) +void feh_reload_image(winwidget w, int resize, int force_new) { - char *title, *new_title; - int len; - Imlib_Image tmp; - - D_ENTER(4); - - if (!w->file) { - weprintf("couldn't reload, this image has no file associated with it."); - D_RETURN_(4); - } - - free(FEH_FILE(w->file->data)->caption); - FEH_FILE(w->file->data)->caption = NULL; - - len = strlen(w->name) + sizeof("Reloading: ") + 1; - new_title = emalloc(len); - snprintf(new_title, len, "Reloading: %s", w->name); - title = estrdup(w->name); - winwidget_rename(w, new_title); - - - /* force imlib2 not to cache */ - if (force_new) { - winwidget_free_image(w); - } - - /* if the image has changed in dimensions - we gotta resize */ - if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) { - if (force_new) { - eprintf("failed to reload image\n"); - } else { - weprintf("Couldn't reload image. Is it still there?"); - } - winwidget_rename(w, title); - free(title); - free(new_title); - D_RETURN_(4); - } - if (force_new) { - w->im = tmp; - resize = 1; - winwidget_reset_image(w); - } else { - if ((gib_imlib_image_get_width(w->im) != gib_imlib_image_get_width(tmp)) || (gib_imlib_image_get_height(w->im) != gib_imlib_image_get_height(tmp))) { - resize = 1; - winwidget_reset_image(w); - } - winwidget_free_image(w); - w->im = tmp; - } - - w->mode = MODE_NORMAL; - if ((w->im_w != gib_imlib_image_get_width(w->im)) - || (w->im_h != gib_imlib_image_get_height(w->im))) - w->had_resize = 1; - if (w->has_rotated) - { - Imlib_Image temp; - - temp = gib_imlib_create_rotated_image(w->im, 0.0); - w->im_w = gib_imlib_image_get_width(temp); - w->im_h = gib_imlib_image_get_height(temp); - gib_imlib_free_image_and_decache(temp); - } - else - { - w->im_w = gib_imlib_image_get_width(w->im); - w->im_h = gib_imlib_image_get_height(w->im); - } - winwidget_render_image(w, resize, 1); - - winwidget_rename(w, title); - free(title); - free(new_title); - - D_RETURN_(4); + char *title, *new_title; + int len; + Imlib_Image tmp; + + D_ENTER(4); + + if (!w->file) { + weprintf("couldn't reload, this image has no file associated with it."); + D_RETURN_(4); + } + + free(FEH_FILE(w->file->data)->caption); + FEH_FILE(w->file->data)->caption = NULL; + + len = strlen(w->name) + sizeof("Reloading: ") + 1; + new_title = emalloc(len); + snprintf(new_title, len, "Reloading: %s", w->name); + title = estrdup(w->name); + winwidget_rename(w, new_title); + + /* force imlib2 not to cache */ + if (force_new) { + winwidget_free_image(w); + } + + /* if the image has changed in dimensions - we gotta resize */ + if ((feh_load_image(&tmp, FEH_FILE(w->file->data))) == 0) { + if (force_new) { + eprintf("failed to reload image\n"); + } else { + weprintf("Couldn't reload image. Is it still there?"); + } + winwidget_rename(w, title); + free(title); + free(new_title); + D_RETURN_(4); + } + if (force_new) { + w->im = tmp; + resize = 1; + winwidget_reset_image(w); + } else { + if ((gib_imlib_image_get_width(w->im) != gib_imlib_image_get_width(tmp)) + || (gib_imlib_image_get_height(w->im) != gib_imlib_image_get_height(tmp))) { + resize = 1; + winwidget_reset_image(w); + } + winwidget_free_image(w); + w->im = tmp; + } + + w->mode = MODE_NORMAL; + if ((w->im_w != gib_imlib_image_get_width(w->im)) + || (w->im_h != gib_imlib_image_get_height(w->im))) + w->had_resize = 1; + if (w->has_rotated) { + Imlib_Image temp; + + temp = gib_imlib_create_rotated_image(w->im, 0.0); + w->im_w = gib_imlib_image_get_width(temp); + w->im_h = gib_imlib_image_get_height(temp); + gib_imlib_free_image_and_decache(temp); + } else { + w->im_w = gib_imlib_image_get_width(w->im); + w->im_h = gib_imlib_image_get_height(w->im); + } + winwidget_render_image(w, resize, 1); + + winwidget_rename(w, title); + free(title); + free(new_title); + + D_RETURN_(4); } - -void -slideshow_change_image(winwidget winwid, int change) +void slideshow_change_image(winwidget winwid, int change) { - int success = 0; - gib_list *last = NULL; - int i = 0; - int jmp = 1; - char *s; - - D_ENTER(4); - - /* Without this, clicking a one-image slideshow reloads it. Not very * - intelligent behaviour :-) */ - if (filelist_len < 2 && opt.cycle_once == 0) - D_RETURN_(4); - - /* Ok. I do this in such an odd way to ensure that if the last or first * - image is not loadable, it will go through in the right direction to * - find the correct one. Otherwise SLIDE_LAST would try the last file, * - then loop forward to find a loadable one. */ - if (change == SLIDE_FIRST) - { - current_file = gib_list_last(filelist); - change = SLIDE_NEXT; - } - else if (change == SLIDE_LAST) - { - current_file = filelist; - change = SLIDE_PREV; - } - - /* The for loop prevents us looping infinitely */ - for (i = 0; i < filelist_len; i++) - { - winwidget_free_image(winwid); - switch (change) - { - case SLIDE_NEXT: - current_file = feh_list_jump(filelist, current_file, FORWARD, 1); - break; - case SLIDE_PREV: - current_file = feh_list_jump(filelist, current_file, BACK, 1); - break; - case SLIDE_JUMP_FWD: - if (filelist_len < 5) - jmp = 1; - else if (filelist_len < 40) - jmp = 2; - else - jmp = filelist_len / 20; - if (!jmp) - jmp = 2; - current_file = feh_list_jump(filelist, current_file, FORWARD, jmp); - /* important. if the load fails, we only want to step on ONCE to - try the next file, not another jmp */ - change = SLIDE_NEXT; - break; - case SLIDE_JUMP_BACK: - if (filelist_len < 5) - jmp = 1; - else if (filelist_len < 40) - jmp = 2; - else - jmp = filelist_len / 20; - if (!jmp) - jmp = 2; - current_file = feh_list_jump(filelist, current_file, BACK, jmp); - /* important. if the load fails, we only want to step back ONCE to - try the previous file, not another jmp */ - change = SLIDE_NEXT; - break; - default: - eprintf("BUG!\n"); - break; - } - - if (last) - { - filelist = feh_file_remove_from_list(filelist, last); - filelist_len--; - last = NULL; - } - s = slideshow_create_name(FEH_FILE(current_file->data)); - - winwidget_rename(winwid, s); - free(s); - - if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data))) != 0) - { - success = 1; - winwid->mode = MODE_NORMAL; - winwid->file = current_file; - if ((winwid->im_w != gib_imlib_image_get_width(winwid->im)) - || (winwid->im_h != gib_imlib_image_get_height(winwid->im))) - winwid->had_resize = 1; - winwidget_reset_image(winwid); - winwid->im_w = gib_imlib_image_get_width(winwid->im); - winwid->im_h = gib_imlib_image_get_height(winwid->im); - winwidget_render_image(winwid, 1, 1); - break; - } - else - last = current_file; - } - if (!success) - { - /* We get here if three files in a row could not be loaded. - * However, it seems that this piece of code is never reached when feh - * would otherwise fail; it's only executed in the aforementioned case, - * causing slideshows to exit although there still are lots of working slides. - * - * So far, there is one known case were we should exit here: - * When viewing a set of files, externally removing all of them and then resizing - * the window in feh, feh will print lots of imlib errors and eventually segfault. - */ - weprintf("No more slides in show?"); - } - if (opt.slideshow_delay >= 0.0) - feh_add_timer(cb_slide_timer, winwid, opt.slideshow_delay, - "SLIDE_CHANGE"); - D_RETURN_(4); + int success = 0; + gib_list *last = NULL; + int i = 0; + int jmp = 1; + char *s; + + D_ENTER(4); + + /* Without this, clicking a one-image slideshow reloads it. Not very * + intelligent behaviour :-) */ + if (filelist_len < 2 && opt.cycle_once == 0) + D_RETURN_(4); + + /* Ok. I do this in such an odd way to ensure that if the last or first * + image is not loadable, it will go through in the right direction to * + find the correct one. Otherwise SLIDE_LAST would try the last file, * + then loop forward to find a loadable one. */ + if (change == SLIDE_FIRST) { + current_file = gib_list_last(filelist); + change = SLIDE_NEXT; + } else if (change == SLIDE_LAST) { + current_file = filelist; + change = SLIDE_PREV; + } + + /* The for loop prevents us looping infinitely */ + for (i = 0; i < filelist_len; i++) { + winwidget_free_image(winwid); + switch (change) { + case SLIDE_NEXT: + current_file = feh_list_jump(filelist, current_file, FORWARD, 1); + break; + case SLIDE_PREV: + current_file = feh_list_jump(filelist, current_file, BACK, 1); + break; + case SLIDE_JUMP_FWD: + if (filelist_len < 5) + jmp = 1; + else if (filelist_len < 40) + jmp = 2; + else + jmp = filelist_len / 20; + if (!jmp) + jmp = 2; + current_file = feh_list_jump(filelist, current_file, FORWARD, jmp); + /* important. if the load fails, we only want to step on ONCE to + try the next file, not another jmp */ + change = SLIDE_NEXT; + break; + case SLIDE_JUMP_BACK: + if (filelist_len < 5) + jmp = 1; + else if (filelist_len < 40) + jmp = 2; + else + jmp = filelist_len / 20; + if (!jmp) + jmp = 2; + current_file = feh_list_jump(filelist, current_file, BACK, jmp); + /* important. if the load fails, we only want to step back ONCE to + try the previous file, not another jmp */ + change = SLIDE_NEXT; + break; + default: + eprintf("BUG!\n"); + break; + } + + if (last) { + filelist = feh_file_remove_from_list(filelist, last); + filelist_len--; + last = NULL; + } + s = slideshow_create_name(FEH_FILE(current_file->data)); + + winwidget_rename(winwid, s); + free(s); + + if ((winwidget_loadimage(winwid, FEH_FILE(current_file->data))) + != 0) { + success = 1; + winwid->mode = MODE_NORMAL; + winwid->file = current_file; + if ((winwid->im_w != gib_imlib_image_get_width(winwid->im)) + || (winwid->im_h != gib_imlib_image_get_height(winwid->im))) + winwid->had_resize = 1; + winwidget_reset_image(winwid); + winwid->im_w = gib_imlib_image_get_width(winwid->im); + winwid->im_h = gib_imlib_image_get_height(winwid->im); + winwidget_render_image(winwid, 1, 1); + break; + } else + last = current_file; + } + if (!success) { + /* We get here if three files in a row could not be loaded. + * However, it seems that this piece of code is never reached when feh + * would otherwise fail; it's only executed in the aforementioned case, + * causing slideshows to exit although there still are lots of working slides. + * + * So far, there is one known case were we should exit here: + * When viewing a set of files, externally removing all of them and then resizing + * the window in feh, feh will print lots of imlib errors and eventually segfault. + */ + weprintf("No more slides in show?"); + } + if (opt.slideshow_delay >= 0.0) + feh_add_timer(cb_slide_timer, winwid, opt.slideshow_delay, "SLIDE_CHANGE"); + D_RETURN_(4); } -void -slideshow_pause_toggle(winwidget w) +void slideshow_pause_toggle(winwidget w) { - char *title, *new_title; - int len; - - if (!opt.paused) - { - opt.paused = 1; - - len = strlen(w->name) + sizeof(" [Paused]") + 1; - new_title = emalloc(len); - snprintf(new_title, len, "%s [Paused]", w->name); - title = estrdup(w->name); - winwidget_rename(w, new_title); - } - else - { - opt.paused = 0; - } + char *title, *new_title; + int len; + + if (!opt.paused) { + opt.paused = 1; + + len = strlen(w->name) + sizeof(" [Paused]") + 1; + new_title = emalloc(len); + snprintf(new_title, len, "%s [Paused]", w->name); + title = estrdup(w->name); + winwidget_rename(w, new_title); + } else { + opt.paused = 0; + } } -char * -slideshow_create_name(feh_file * file) +char *slideshow_create_name(feh_file * file) { - char *s = NULL; - int len = 0; - - D_ENTER(4); - if (!opt.title) - { - len = - strlen(PACKAGE " [slideshow mode] - ") + strlen(file->filename) + 1; - s = emalloc(len); - snprintf(s, len, PACKAGE " [%d of %d] - %s", - gib_list_num(filelist, current_file) + 1, - gib_list_length(filelist), file->filename); - } - else - { - s = estrdup(feh_printf(opt.title, file)); - } - - D_RETURN(4, s); + char *s = NULL; + int len = 0; + + D_ENTER(4); + if (!opt.title) { + len = strlen(PACKAGE " [slideshow mode] - ") + strlen(file->filename) + 1; + s = emalloc(len); + snprintf(s, len, PACKAGE " [%d of %d] - %s", + gib_list_num(filelist, current_file) + 1, gib_list_length(filelist), file->filename); + } else { + s = estrdup(feh_printf(opt.title, file)); + } + + D_RETURN(4, s); } -void -feh_action_run(feh_file * file, char *action) +void feh_action_run(feh_file * file, char *action) { - D_ENTER(4); - if (action) - { - char *sys; - D(3, ("Running action %s\n", action)); - sys = feh_printf(action, file); - - if (opt.verbose && !opt.list && !opt.customlist) - fprintf(stderr, "Running action -->%s<--\n", sys); - system(sys); - } - D_RETURN_(4); + D_ENTER(4); + if (action) { + char *sys; + D(3, ("Running action %s\n", action)); + sys = feh_printf(action, file); + + if (opt.verbose && !opt.list && !opt.customlist) + fprintf(stderr, "Running action -->%s<--\n", sys); + system(sys); + } + D_RETURN_(4); } -char * -feh_printf(char *str, feh_file * file) +char *feh_printf(char *str, feh_file * file) { - char *c; - char buf[20]; - static char ret[4096]; - - D_ENTER(4); - - ret[0] = '\0'; - - for (c = str; *c != '\0'; c++) - { - if (*c == '%') - { - c++; - switch (*c) - { - case 'f': - if (file) - strcat(ret, file->filename); - break; - case 'n': - if (file) - strcat(ret, file->name); - break; - case 'w': - if (file) - { - if (!file->info) - feh_file_info_load(file, NULL); - snprintf(buf, sizeof(buf), "%d", file->info->width); - strcat(ret, buf); - } - break; - case 'h': - if (file) - { - if (!file->info) - feh_file_info_load(file, NULL); - snprintf(buf, sizeof(buf), "%d", file->info->height); - strcat(ret, buf); - } - break; - case 's': - if (file) - { - if (!file->info) - feh_file_info_load(file, NULL); - snprintf(buf, sizeof(buf), "%d", file->info->size); - strcat(ret, buf); - } - break; - case 'p': - if (file) - { - if (!file->info) - feh_file_info_load(file, NULL); - snprintf(buf, sizeof(buf), "%d", file->info->pixels); - strcat(ret, buf); - } - break; - case 't': - if (file) - { - if (!file->info) - feh_file_info_load(file, NULL); - strcat(ret, file->info->format); - } - break; - case 'P': - strcat(ret, PACKAGE); - break; - case 'v': - strcat(ret, VERSION); - break; - case 'm': - strcat(ret, mode); - break; - case 'l': - snprintf(buf, sizeof(buf), "%d", gib_list_length(filelist)); - strcat(ret, buf); - break; - case 'u': - snprintf(buf, sizeof(buf), "%d", - current_file != NULL ? gib_list_num(filelist, - current_file) + - 1 : 0); - strcat(ret, buf); - break; - default: - strncat(ret, c, 1); - break; - } - } - else if (*c == '\\') - { - c++; - switch (*c) - { - case 'n': - strcat(ret, "\n"); - break; - default: - strncat(ret, c, 1); - break; - } - } - else - strncat(ret, c, 1); - } - D_RETURN(4, ret); + char *c; + char buf[20]; + static char ret[4096]; + + D_ENTER(4); + + ret[0] = '\0'; + + for (c = str; *c != '\0'; c++) { + if (*c == '%') { + c++; + switch (*c) { + case 'f': + if (file) + strcat(ret, file->filename); + break; + case 'n': + if (file) + strcat(ret, file->name); + break; + case 'w': + if (file) { + if (!file->info) + feh_file_info_load(file, NULL); + snprintf(buf, sizeof(buf), "%d", file->info->width); + strcat(ret, buf); + } + break; + case 'h': + if (file) { + if (!file->info) + feh_file_info_load(file, NULL); + snprintf(buf, sizeof(buf), "%d", file->info->height); + strcat(ret, buf); + } + break; + case 's': + if (file) { + if (!file->info) + feh_file_info_load(file, NULL); + snprintf(buf, sizeof(buf), "%d", file->info->size); + strcat(ret, buf); + } + break; + case 'p': + if (file) { + if (!file->info) + feh_file_info_load(file, NULL); + snprintf(buf, sizeof(buf), "%d", file->info->pixels); + strcat(ret, buf); + } + break; + case 't': + if (file) { + if (!file->info) + feh_file_info_load(file, NULL); + strcat(ret, file->info->format); + } + break; + case 'P': + strcat(ret, PACKAGE); + break; + case 'v': + strcat(ret, VERSION); + break; + case 'm': + strcat(ret, mode); + break; + case 'l': + snprintf(buf, sizeof(buf), "%d", gib_list_length(filelist)); + strcat(ret, buf); + break; + case 'u': + snprintf(buf, sizeof(buf), "%d", + current_file != NULL ? gib_list_num(filelist, current_file) + + 1 : 0); + strcat(ret, buf); + break; + default: + strncat(ret, c, 1); + break; + } + } else if (*c == '\\') { + c++; + switch (*c) { + case 'n': + strcat(ret, "\n"); + break; + default: + strncat(ret, c, 1); + break; + } + } else + strncat(ret, c, 1); + } + D_RETURN(4, ret); } -void -feh_filelist_image_remove(winwidget winwid, char do_delete) +void feh_filelist_image_remove(winwidget winwid, char do_delete) { - if (winwid->type == WIN_TYPE_SLIDESHOW) - { - char *s; - gib_list *doomed; - - doomed = current_file; - slideshow_change_image(winwid, SLIDE_NEXT); - filelist_len--; - if (do_delete) - filelist = feh_file_rm_and_free(filelist, doomed); - else - filelist = feh_file_remove_from_list(filelist, doomed); - if (!filelist) - { - /* No more images. Game over ;-) */ - winwidget_destroy(winwid); - return; - } - s = slideshow_create_name(FEH_FILE(winwid->file->data)); - winwidget_rename(winwid, s); - free(s); - } - else if ((winwid->type == WIN_TYPE_SINGLE) - || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) - { - filelist_len--; - if (do_delete) - filelist = feh_file_rm_and_free(filelist, winwid->file); - else - filelist = feh_file_remove_from_list(filelist, winwid->file); - winwidget_destroy(winwid); - } + if (winwid->type == WIN_TYPE_SLIDESHOW) { + char *s; + gib_list *doomed; + + doomed = current_file; + slideshow_change_image(winwid, SLIDE_NEXT); + filelist_len--; + if (do_delete) + filelist = feh_file_rm_and_free(filelist, doomed); + else + filelist = feh_file_remove_from_list(filelist, doomed); + if (!filelist) { + /* No more images. Game over ;-) */ + winwidget_destroy(winwid); + return; + } + s = slideshow_create_name(FEH_FILE(winwid->file->data)); + winwidget_rename(winwid, s); + free(s); + } else if ((winwid->type == WIN_TYPE_SINGLE) + || (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER)) { + filelist_len--; + if (do_delete) + filelist = feh_file_rm_and_free(filelist, winwid->file); + else + filelist = feh_file_remove_from_list(filelist, winwid->file); + winwidget_destroy(winwid); + } } void slideshow_save_image(winwidget win) { - char *tmpname; - - D_ENTER(4); - if(win->file) { - tmpname = feh_unique_filename("", FEH_FILE(win->file->data)->name); - } else if(mode) { - char *tmp; - tmp = estrjoin(".", mode, "png", NULL); - tmpname = feh_unique_filename("", tmp); - free(tmp); - } else { - tmpname = feh_unique_filename("", "noname.png"); - } - - if(!opt.quiet) - printf("saving image to filename '%s'\n", tmpname); - - gib_imlib_save_image(win->im, tmpname); - free(tmpname); - D_RETURN_(4); + char *tmpname; + + D_ENTER(4); + if (win->file) { + tmpname = feh_unique_filename("", FEH_FILE(win->file->data)->name); + } else if (mode) { + char *tmp; + tmp = estrjoin(".", mode, "png", NULL); + tmpname = feh_unique_filename("", tmp); + free(tmp); + } else { + tmpname = feh_unique_filename("", "noname.png"); + } + + if (!opt.quiet) + printf("saving image to filename '%s'\n", tmpname); + + gib_imlib_save_image(win->im, tmpname); + free(tmpname); + D_RETURN_(4); } -gib_list * -feh_list_jump(gib_list * root, gib_list * l, int direction, int num) +gib_list *feh_list_jump(gib_list * root, gib_list * l, int direction, int num) { - int i; - gib_list *ret = NULL; - - if (!root) - return (NULL); - if (!l) - return (root); - - ret = l; - - for (i = 0; i < num; i++) - { - if (direction == FORWARD) - { - if (ret->next) - { - ret = ret->next; - } - else - { - if (opt.cycle_once) - { - exit(0); - } - ret = root; - } - } - else - { - if (ret->prev) - ret = ret->prev; - else - ret = gib_list_last(ret); - } - } - return (ret); + int i; + gib_list *ret = NULL; + + if (!root) + return (NULL); + if (!l) + return (root); + + ret = l; + + for (i = 0; i < num; i++) { + if (direction == FORWARD) { + if (ret->next) { + ret = ret->next; + } else { + if (opt.cycle_once) { + exit(0); + } + ret = root; + } + } else { + if (ret->prev) + ret = ret->prev; + else + ret = gib_list_last(ret); + } + } + return (ret); } - diff --git a/src/support.c b/src/support.c index ee214cf..abe18ce 100644 --- a/src/support.c +++ b/src/support.c @@ -41,632 +41,545 @@ static unsigned char timeout = 0; */ static char e17_fake_ipc = 0; -void -feh_wm_set_bg_file(char *file, unsigned char bgmode) +void feh_wm_set_bg_file(char *file, unsigned char bgmode) { - Imlib_Image im; - feh_file *fil; - - fil = feh_file_new(file); - if (fil) - { - if (feh_load_image(&im, fil) == 0) - eprintf("Couldn't load image in order to set bg"); - switch (bgmode) - { - case BG_MODE_SEAMLESS: - gib_imlib_image_tile(im); - feh_wm_set_bg(NULL, im, 0, 0, 0, 1); - break; - case BG_MODE_TILE: - feh_wm_set_bg(file, im, 0, 0, 0, 1); - break; - case BG_MODE_SCALE: - feh_wm_set_bg(file, im, 0, 1, 0, 1); - break; - default: - feh_wm_set_bg(file, im, 1, 0, 0, 1); - break; - } - gib_imlib_free_image_and_decache(im); - feh_file_free(fil); - } + Imlib_Image im; + feh_file *fil; + + fil = feh_file_new(file); + if (fil) { + if (feh_load_image(&im, fil) == 0) + eprintf("Couldn't load image in order to set bg"); + switch (bgmode) { + case BG_MODE_SEAMLESS: + gib_imlib_image_tile(im); + feh_wm_set_bg(NULL, im, 0, 0, 0, 1); + break; + case BG_MODE_TILE: + feh_wm_set_bg(file, im, 0, 0, 0, 1); + break; + case BG_MODE_SCALE: + feh_wm_set_bg(file, im, 0, 1, 0, 1); + break; + default: + feh_wm_set_bg(file, im, 1, 0, 0, 1); + break; + } + gib_imlib_free_image_and_decache(im); + feh_file_free(fil); + } } -void -feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, - int desktop, int set) +void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, int desktop, int set) { - char bgname[20]; - int num = (int) rand(); - char bgfil[4096]; - char sendbuf[4096]; - - D_ENTER(4); - - snprintf(bgname, sizeof(bgname), "FEHBG_%d", num); - - if (!fil) - { - snprintf(bgfil, sizeof(bgfil), "%s/.%s.png", getenv("HOME"), bgname); - imlib_context_set_image(im); - imlib_image_set_format("png"); - gib_imlib_save_image(im, bgfil); - D(3, ("bg saved as %s\n", bgfil)); - fil = bgfil; - } - D(3, ("Setting bg %s\n", fil)); - - if (feh_wm_get_wm_is_e() && (enl_ipc_get_win() != None)) - { - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.file %s", bgname, - fil); - enl_ipc_send(sendbuf); - - if (scaled) - { - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.solid 0 0 0", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.tile 0", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.xjust 512", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.yjust 512", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.xperc 1024", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.yperc 1024", - bgname); - enl_ipc_send(sendbuf); - } - else if (centered) - { - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.solid 0 0 0", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.tile 0", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.xjust 512", - bgname); - enl_ipc_send(sendbuf); - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.yjust 512", - bgname); - enl_ipc_send(sendbuf); - } - else - { - snprintf(sendbuf, sizeof(sendbuf), "background %s bg.tile 1", - bgname); - enl_ipc_send(sendbuf); - } - - if (set) - { - snprintf(sendbuf, sizeof(sendbuf), "use_bg %s %d", bgname, desktop); - enl_ipc_send(sendbuf); - } - enl_ipc_sync(); - } - else - { - Atom prop_root, prop_esetroot, type; - int format; - unsigned long length, after; - unsigned char *data_root, *data_esetroot; - Pixmap pmap_d1, pmap_d2; - /* string for sticking in ~/.fehbg */ - char *fehbg = NULL; - char *home; - char filbuf[PATH_MAX]; - - /* local display to set closedownmode on */ - Display *disp2; - Window root2; - int depth2; - XGCValues gcvalues; - GC gc; - int in, out, w, h; - - D(3, ("Falling back to XSetRootWindowPixmap\n")); - - /* Put the filename in filbuf between ' and escape ' in the filename */ - out = 0; - filbuf[out++] = '\''; - for (in = 0; fil[in] && out < (PATH_MAX-4); in++) { - if (fil[in] == '\'') { - filbuf[out++] = '\\'; - } - filbuf[out++] = fil[in]; - } - filbuf[out++] = '\''; - filbuf[out++] = 0; - - if (scaled) { - w = scr->width; - h = scr->height; + char bgname[20]; + int num = (int) rand(); + char bgfil[4096]; + char sendbuf[4096]; + + D_ENTER(4); + + snprintf(bgname, sizeof(bgname), "FEHBG_%d", num); + + if (!fil) { + snprintf(bgfil, sizeof(bgfil), "%s/.%s.png", getenv("HOME"), bgname); + imlib_context_set_image(im); + imlib_image_set_format("png"); + gib_imlib_save_image(im, bgfil); + D(3, ("bg saved as %s\n", bgfil)); + fil = bgfil; + } + D(3, ("Setting bg %s\n", fil)); + + if (feh_wm_get_wm_is_e() && (enl_ipc_get_win() != None)) { + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.file %s", bgname, fil); + enl_ipc_send(sendbuf); + + if (scaled) { + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.solid 0 0 0", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.tile 0", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.xjust 512", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.yjust 512", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.xperc 1024", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.yperc 1024", bgname); + enl_ipc_send(sendbuf); + } else if (centered) { + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.solid 0 0 0", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.tile 0", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.xjust 512", bgname); + enl_ipc_send(sendbuf); + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.yjust 512", bgname); + enl_ipc_send(sendbuf); + } else { + snprintf(sendbuf, sizeof(sendbuf), "background %s bg.tile 1", bgname); + enl_ipc_send(sendbuf); + } + + if (set) { + snprintf(sendbuf, sizeof(sendbuf), "use_bg %s %d", bgname, desktop); + enl_ipc_send(sendbuf); + } + enl_ipc_sync(); + } else { + Atom prop_root, prop_esetroot, type; + int format; + unsigned long length, after; + unsigned char *data_root, *data_esetroot; + Pixmap pmap_d1, pmap_d2; + /* string for sticking in ~/.fehbg */ + char *fehbg = NULL; + char *home; + char filbuf[PATH_MAX]; + + /* local display to set closedownmode on */ + Display *disp2; + Window root2; + int depth2; + XGCValues gcvalues; + GC gc; + int in, out, w, h; + + D(3, ("Falling back to XSetRootWindowPixmap\n")); + + /* Put the filename in filbuf between ' and escape ' in the filename */ + out = 0; + filbuf[out++] = '\''; + for (in = 0; fil[in] && out < (PATH_MAX - 4); in++) { + if (fil[in] == '\'') { + filbuf[out++] = '\\'; + } + filbuf[out++] = fil[in]; + } + filbuf[out++] = '\''; + filbuf[out++] = 0; + + if (scaled) { + w = scr->width; + h = scr->height; /* disable xinerama check for setting background */ #if 0 /* #ifdef HAVE_LIBXINERAMA */ - if (opt.xinerama && xinerama_screens) { - w = xinerama_screens[xinerama_screen].width; - h = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - - pmap_d1 = XCreatePixmap(disp, root, w, h, depth); - gib_imlib_render_image_on_drawable_at_size(pmap_d1, im, 0, 0, w, h, - 1, 0, 1); - fehbg = estrjoin(" ", "feh --bg-scale", filbuf, NULL); - } else if (centered) { - XGCValues gcval; - GC gc; - int x, y; - - D(3, ("centering\n")); - w = scr->width; - h = scr->height; + if (opt.xinerama && xinerama_screens) { + w = xinerama_screens[xinerama_screen].width; + h = xinerama_screens[xinerama_screen].height; + } +#endif /* HAVE_LIBXINERAMA */ + + pmap_d1 = XCreatePixmap(disp, root, w, h, depth); + gib_imlib_render_image_on_drawable_at_size(pmap_d1, im, 0, 0, w, h, 1, 0, 1); + fehbg = estrjoin(" ", "feh --bg-scale", filbuf, NULL); + } else if (centered) { + XGCValues gcval; + GC gc; + int x, y; + + D(3, ("centering\n")); + w = scr->width; + h = scr->height; /* disable xinerama check for setting background */ #if 0 /* #ifdef HAVE_LIBXINERAMA */ - if (opt.xinerama && xinerama_screens) { - w = xinerama_screens[xinerama_screen].width; - h = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - - pmap_d1 = XCreatePixmap(disp, root, w, h, depth); - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); - gc = XCreateGC(disp, root, GCForeground, &gcval); - XFillRectangle(disp, pmap_d1, gc, 0, 0, w, h); - x = (w - gib_imlib_image_get_width(im)) >> 1; - y = (h - gib_imlib_image_get_height(im)) >> 1; - gib_imlib_render_image_on_drawable(pmap_d1, im, x, y, 1, 0, 0); - XFreeGC(disp, gc); - fehbg = estrjoin(" ", "feh --bg-center", filbuf, NULL); - } else { - w = gib_imlib_image_get_width(im); - h = gib_imlib_image_get_height(im); - pmap_d1 = - XCreatePixmap(disp, root, w, h, depth); - gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 0, 0); - fehbg = estrjoin(" ", "feh --bg-tile", filbuf, NULL); - } - - if (fehbg) { - home = getenv("HOME"); - if(home) { - FILE *fp; - char *path; - path = estrjoin("/", home, ".fehbg", NULL); - if ((fp = fopen(path, "w")) == NULL) { - weprintf("Can't open %s for write", path); - } else { - fprintf(fp, "%s\n", fehbg); - fclose(fp); - } - free(path); - } - free(fehbg); - } - - /* create new display, copy pixmap to new display */ - disp2 = XOpenDisplay(NULL); - if (!disp2) - eprintf("Can't reopen X display."); - root2 = RootWindow(disp2, DefaultScreen(disp2)); - depth2 = DefaultDepth(disp2, DefaultScreen(disp2)); - XSync(disp, False); - pmap_d2 = XCreatePixmap(disp2, root2, scr->width, scr->height, depth2); - gcvalues.fill_style = FillTiled; - gcvalues.tile = pmap_d1; - gc = XCreateGC(disp2, pmap_d2, GCFillStyle|GCTile, &gcvalues); - XFillRectangle(disp2, pmap_d2, gc, 0, 0, scr->width, scr->height); - XFreeGC(disp2, gc); - XSync(disp2, False); - XSync(disp, False); - XFreePixmap(disp, pmap_d1); - - prop_root = XInternAtom(disp2, "_XROOTPMAP_ID", True); - prop_esetroot = XInternAtom(disp2, "ESETROOT_PMAP_ID", True); - - if (prop_root != None && prop_esetroot != None) - { - XGetWindowProperty(disp2, root2, prop_root, 0L, 1L, False, - AnyPropertyType, &type, &format, &length, &after, - &data_root); - if (type == XA_PIXMAP) - { - XGetWindowProperty(disp2, root2, prop_esetroot, 0L, 1L, False, - AnyPropertyType, &type, &format, &length, - &after, &data_esetroot); - if (data_root && data_esetroot) - { - if (type == XA_PIXMAP - && *((Pixmap *) data_root) == *((Pixmap *) data_esetroot)) - { - XKillClient(disp2, *((Pixmap *) data_root)); - } - } - } - } - /* This will locate the property, creating it if it doesn't exist */ - prop_root = XInternAtom(disp2, "_XROOTPMAP_ID", False); - prop_esetroot = XInternAtom(disp2, "ESETROOT_PMAP_ID", False); - - if (prop_root == None || prop_esetroot == None) - weprintf("creation of pixmap property failed."); - - XChangeProperty(disp2, root2, prop_root, XA_PIXMAP, 32, PropModeReplace, - (unsigned char *) &pmap_d2, 1); - XChangeProperty(disp2, root2, prop_esetroot, XA_PIXMAP, 32, - PropModeReplace, (unsigned char *) &pmap_d2, 1); - - XSetWindowBackgroundPixmap(disp2, root2, pmap_d2); - XClearWindow(disp2, root2); - XFlush(disp2); - XSetCloseDownMode(disp2, RetainPermanent); - XCloseDisplay(disp2); - } - D_RETURN_(4); + if (opt.xinerama && xinerama_screens) { + w = xinerama_screens[xinerama_screen].width; + h = xinerama_screens[xinerama_screen].height; + } +#endif /* HAVE_LIBXINERAMA */ + + pmap_d1 = XCreatePixmap(disp, root, w, h, depth); + gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + gc = XCreateGC(disp, root, GCForeground, &gcval); + XFillRectangle(disp, pmap_d1, gc, 0, 0, w, h); + x = (w - gib_imlib_image_get_width(im)) >> 1; + y = (h - gib_imlib_image_get_height(im)) >> 1; + gib_imlib_render_image_on_drawable(pmap_d1, im, x, y, 1, 0, 0); + XFreeGC(disp, gc); + fehbg = estrjoin(" ", "feh --bg-center", filbuf, NULL); + } else { + w = gib_imlib_image_get_width(im); + h = gib_imlib_image_get_height(im); + pmap_d1 = XCreatePixmap(disp, root, w, h, depth); + gib_imlib_render_image_on_drawable(pmap_d1, im, 0, 0, 1, 0, 0); + fehbg = estrjoin(" ", "feh --bg-tile", filbuf, NULL); + } + + if (fehbg) { + home = getenv("HOME"); + if (home) { + FILE *fp; + char *path; + path = estrjoin("/", home, ".fehbg", NULL); + if ((fp = fopen(path, "w")) == NULL) { + weprintf("Can't open %s for write", path); + } else { + fprintf(fp, "%s\n", fehbg); + fclose(fp); + } + free(path); + } + free(fehbg); + } + + /* create new display, copy pixmap to new display */ + disp2 = XOpenDisplay(NULL); + if (!disp2) + eprintf("Can't reopen X display."); + root2 = RootWindow(disp2, DefaultScreen(disp2)); + depth2 = DefaultDepth(disp2, DefaultScreen(disp2)); + XSync(disp, False); + pmap_d2 = XCreatePixmap(disp2, root2, scr->width, scr->height, depth2); + gcvalues.fill_style = FillTiled; + gcvalues.tile = pmap_d1; + gc = XCreateGC(disp2, pmap_d2, GCFillStyle | GCTile, &gcvalues); + XFillRectangle(disp2, pmap_d2, gc, 0, 0, scr->width, scr->height); + XFreeGC(disp2, gc); + XSync(disp2, False); + XSync(disp, False); + XFreePixmap(disp, pmap_d1); + + prop_root = XInternAtom(disp2, "_XROOTPMAP_ID", True); + prop_esetroot = XInternAtom(disp2, "ESETROOT_PMAP_ID", True); + + if (prop_root != None && prop_esetroot != None) { + XGetWindowProperty(disp2, root2, prop_root, 0L, 1L, + False, AnyPropertyType, &type, &format, &length, &after, &data_root); + if (type == XA_PIXMAP) { + XGetWindowProperty(disp2, root2, + prop_esetroot, 0L, 1L, + False, AnyPropertyType, + &type, &format, &length, &after, &data_esetroot); + if (data_root && data_esetroot) { + if (type == XA_PIXMAP && *((Pixmap *) data_root) == *((Pixmap *) data_esetroot)) { + XKillClient(disp2, *((Pixmap *) + data_root)); + } + } + } + } + /* This will locate the property, creating it if it doesn't exist */ + prop_root = XInternAtom(disp2, "_XROOTPMAP_ID", False); + prop_esetroot = XInternAtom(disp2, "ESETROOT_PMAP_ID", False); + + if (prop_root == None || prop_esetroot == None) + weprintf("creation of pixmap property failed."); + + XChangeProperty(disp2, root2, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pmap_d2, 1); + XChangeProperty(disp2, root2, prop_esetroot, XA_PIXMAP, 32, + PropModeReplace, (unsigned char *) &pmap_d2, 1); + + XSetWindowBackgroundPixmap(disp2, root2, pmap_d2); + XClearWindow(disp2, root2); + XFlush(disp2); + XSetCloseDownMode(disp2, RetainPermanent); + XCloseDisplay(disp2); + } + D_RETURN_(4); } -signed char -feh_wm_get_wm_is_e(void) +signed char feh_wm_get_wm_is_e(void) { - static signed char e = -1; - - D_ENTER(4); - - /* check if E is actually running */ - if (e == -1) - { - /* XXX: This only covers E17 prior to 6/22/05 */ - if ((XInternAtom(disp, "ENLIGHTENMENT_COMMS", True) != None) && - (XInternAtom(disp, "ENLIGHTENMENT_VERSION", True) != None)) - { - D(3, ("Enlightenment detected.\n")); - e = 1; - } - else - { - D(3, ("Enlightenment not detected.\n")); - e = 0; - } - } - D_RETURN(4, e); + static signed char e = -1; + + D_ENTER(4); + + /* check if E is actually running */ + if (e == -1) { + /* XXX: This only covers E17 prior to 6/22/05 */ + if ((XInternAtom(disp, "ENLIGHTENMENT_COMMS", True) != None) + && (XInternAtom(disp, "ENLIGHTENMENT_VERSION", True) != None)) { + D(3, ("Enlightenment detected.\n")); + e = 1; + } else { + D(3, ("Enlightenment not detected.\n")); + e = 0; + } + } + D_RETURN(4, e); } -int -feh_wm_get_num_desks(void) +int feh_wm_get_num_desks(void) { - char *buf, *ptr; - int desks; + char *buf, *ptr; + int desks; - D_ENTER(4); + D_ENTER(4); - if (!feh_wm_get_wm_is_e()) - D_RETURN(4, -1); + if (!feh_wm_get_wm_is_e()) + D_RETURN(4, -1); - buf = enl_send_and_wait("num_desks ?"); - if (buf == IPC_FAKE) /* Fake E17 IPC */ - D_RETURN(4, -1); - D(3, ("Got from E IPC: %s\n", buf)); - ptr = buf; - while (ptr && !isdigit(*ptr)) - ptr++; - desks = atoi(ptr); + buf = enl_send_and_wait("num_desks ?"); + if (buf == IPC_FAKE) /* Fake E17 IPC */ + D_RETURN(4, -1); + D(3, ("Got from E IPC: %s\n", buf)); + ptr = buf; + while (ptr && !isdigit(*ptr)) + ptr++; + desks = atoi(ptr); D_RETURN(4, desks)} -Window -enl_ipc_get_win(void) +Window enl_ipc_get_win(void) { - unsigned char *str = NULL; - Atom prop, prop2, ever; - unsigned long num, after; - int format; - Window dummy_win; - int dummy_int; - unsigned int dummy_uint; - - D_ENTER(4); - - D(3, ("Searching for IPC window.\n")); - - /* - * Shortcircuit this entire func - * if we already know it's an e17 fake - */ - if (e17_fake_ipc) - D_RETURN(4, ipc_win) - - prop = XInternAtom(disp, "ENLIGHTENMENT_COMMS", True); - if (prop == None) - { - D(3, ("Enlightenment is not running.\n")); - D_RETURN(4, None); - } else { - /* XXX: This will only work with E17 prior to 6/22/2005 */ - ever = XInternAtom(disp, "ENLIGHTENMENT_VERSION", True); - if (ever == None) { - /* This is an E without ENLIGHTENMENT_VERSION */ - D(3, ("E16 IPC Protocol not supported")); - D_RETURN(4, None); - } - } - XGetWindowProperty(disp, root, prop, 0, 14, False, AnyPropertyType, &prop2, - &format, &num, &after, &str); - if (str) - { - sscanf((char *) str, "%*s %x", (unsigned int *) &ipc_win); - XFree(str); - } - if (ipc_win != None) - { - if (!XGetGeometry - (disp, ipc_win, &dummy_win, &dummy_int, &dummy_int, &dummy_uint, - &dummy_uint, &dummy_uint, &dummy_uint)) - { - D(3, - (" -> IPC Window property is valid, but the window doesn't exist.\n")); - ipc_win = None; - } - str = NULL; - if (ipc_win != None) - { - XGetWindowProperty(disp, ipc_win, prop, 0, 14, False, - AnyPropertyType, &prop2, &format, &num, &after, - &str); - if (str) - { - XFree(str); - } - else - { - D(3, - (" -> IPC Window lacks the proper atom. I can't talk to fake IPC windows....\n")); - ipc_win = None; - } - } - } - if (ipc_win != None) - { - - XGetWindowProperty(disp, ipc_win, ever, 0, 14, False, AnyPropertyType, - &prop2, &format, &num, &after, &str); - if (str) { - /* - * This is E17's way of telling us it's only pretending - * as a workaround for a bug related to the way java handles - * Window Managers. - * (Only valid after date of this comment) - * -- richlowe 2005-06-22 - */ - XFree(str); - D(3,(" -> Found a fake E17 IPC window, ignoring")); - ipc_win = None; - e17_fake_ipc = 1; - D_RETURN(4, ipc_win); - } - - D(3, - (" -> IPC Window found and verified as 0x%08x. Registering feh as an IPC client.\n", - (int) ipc_win)); - XSelectInput(disp, ipc_win, - StructureNotifyMask | SubstructureNotifyMask); - enl_ipc_send("set clientname " PACKAGE); - enl_ipc_send("set version " VERSION); - enl_ipc_send("set email tom@linuxbrit.co.uk"); - enl_ipc_send("set web http://www.linuxbrit.co.uk"); - enl_ipc_send("set info Feh - be pr0n or be dead"); - } - if (my_ipc_win == None) - { - my_ipc_win = XCreateSimpleWindow(disp, root, -2, -2, 1, 1, 0, 0, 0); - } - D_RETURN(4, ipc_win); + unsigned char *str = NULL; + Atom prop, prop2, ever; + unsigned long num, after; + int format; + Window dummy_win; + int dummy_int; + unsigned int dummy_uint; + + D_ENTER(4); + + D(3, ("Searching for IPC window.\n")); + + /* + * Shortcircuit this entire func + * if we already know it's an e17 fake + */ + if (e17_fake_ipc) + D_RETURN(4, ipc_win) + + prop = XInternAtom(disp, "ENLIGHTENMENT_COMMS", True); + if (prop == None) { + D(3, ("Enlightenment is not running.\n")); + D_RETURN(4, None); + } else { + /* XXX: This will only work with E17 prior to 6/22/2005 */ + ever = XInternAtom(disp, "ENLIGHTENMENT_VERSION", True); + if (ever == None) { + /* This is an E without ENLIGHTENMENT_VERSION */ + D(3, ("E16 IPC Protocol not supported")); + D_RETURN(4, None); + } + } + XGetWindowProperty(disp, root, prop, 0, 14, False, AnyPropertyType, &prop2, &format, &num, &after, &str); + if (str) { + sscanf((char *) str, "%*s %x", (unsigned int *) &ipc_win); + XFree(str); + } + if (ipc_win != None) { + if (!XGetGeometry + (disp, ipc_win, &dummy_win, &dummy_int, &dummy_int, + &dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint)) { + D(3, (" -> IPC Window property is valid, but the window doesn't exist.\n")); + ipc_win = None; + } + str = NULL; + if (ipc_win != None) { + XGetWindowProperty(disp, ipc_win, prop, 0, 14, + False, AnyPropertyType, &prop2, &format, &num, &after, &str); + if (str) { + XFree(str); + } else { + D(3, (" -> IPC Window lacks the proper atom. I can't talk to fake IPC windows....\n")); + ipc_win = None; + } + } + } + if (ipc_win != None) { + + XGetWindowProperty(disp, ipc_win, ever, 0, 14, False, + AnyPropertyType, &prop2, &format, &num, &after, &str); + if (str) { + /* + * This is E17's way of telling us it's only pretending + * as a workaround for a bug related to the way java handles + * Window Managers. + * (Only valid after date of this comment) + * -- richlowe 2005-06-22 + */ + XFree(str); + D(3, (" -> Found a fake E17 IPC window, ignoring")); + ipc_win = None; + e17_fake_ipc = 1; + D_RETURN(4, ipc_win); + } + + D(3, + (" -> IPC Window found and verified as 0x%08x. Registering feh as an IPC client.\n", (int) ipc_win)); + XSelectInput(disp, ipc_win, StructureNotifyMask | SubstructureNotifyMask); + enl_ipc_send("set clientname " PACKAGE); + enl_ipc_send("set version " VERSION); + enl_ipc_send("set email tom@linuxbrit.co.uk"); + enl_ipc_send("set web http://www.linuxbrit.co.uk"); + enl_ipc_send("set info Feh - be pr0n or be dead"); + } + if (my_ipc_win == None) { + my_ipc_win = XCreateSimpleWindow(disp, root, -2, -2, 1, 1, 0, 0, 0); + } + D_RETURN(4, ipc_win); } -void -enl_ipc_send(char *str) +void enl_ipc_send(char *str) { - static char *last_msg = NULL; - char buff[21]; - register unsigned short i; - register unsigned char j; - unsigned short len; - XEvent ev; - - D_ENTER(4); - if (str == NULL) - { - if (last_msg == NULL) - eprintf("eeek"); - str = last_msg; - D(4, ("Resending last message \"%s\" to Enlightenment.\n", str)); - } - else - { - if (last_msg != NULL) - { - free(last_msg); - } - last_msg = estrdup(str); - D(4, ("Sending \"%s\" to Enlightenment.\n", str)); - } - if (ipc_win == None) - { - if ((ipc_win = enl_ipc_get_win()) == None) - { - D(3, - ("Hrm. Enlightenment doesn't seem to be running. No IPC window, no IPC.\n")); - D_RETURN_(4); - } - } - len = strlen(str); - ipc_atom = XInternAtom(disp, "ENL_MSG", False); - if (ipc_atom == None) - { - D(3, ("IPC error: Unable to find/create ENL_MSG atom.\n")); - D_RETURN_(4); - } - for (; XCheckTypedWindowEvent(disp, my_ipc_win, ClientMessage, &ev);); /* Discard any out-of-sync messages */ - ev.xclient.type = ClientMessage; - ev.xclient.serial = 0; - ev.xclient.send_event = True; - ev.xclient.window = ipc_win; - ev.xclient.message_type = ipc_atom; - ev.xclient.format = 8; - - for (i = 0; i < len + 1; i += 12) - { - sprintf(buff, "%8x", (int) my_ipc_win); - for (j = 0; j < 12; j++) - { - buff[8 + j] = str[i + j]; - if (!str[i + j]) - { - break; - } - } - buff[20] = 0; - for (j = 0; j < 20; j++) - { - ev.xclient.data.b[j] = buff[j]; - } - XSendEvent(disp, ipc_win, False, 0, (XEvent *) & ev); - } - D_RETURN_(4); + static char *last_msg = NULL; + char buff[21]; + register unsigned short i; + register unsigned char j; + unsigned short len; + XEvent ev; + + D_ENTER(4); + if (str == NULL) { + if (last_msg == NULL) + eprintf("eeek"); + str = last_msg; + D(4, ("Resending last message \"%s\" to Enlightenment.\n", str)); + } else { + if (last_msg != NULL) { + free(last_msg); + } + last_msg = estrdup(str); + D(4, ("Sending \"%s\" to Enlightenment.\n", str)); + } + if (ipc_win == None) { + if ((ipc_win = enl_ipc_get_win()) == None) { + D(3, ("Hrm. Enlightenment doesn't seem to be running. No IPC window, no IPC.\n")); + D_RETURN_(4); + } + } + len = strlen(str); + ipc_atom = XInternAtom(disp, "ENL_MSG", False); + if (ipc_atom == None) { + D(3, ("IPC error: Unable to find/create ENL_MSG atom.\n")); + D_RETURN_(4); + } + for (; XCheckTypedWindowEvent(disp, my_ipc_win, ClientMessage, &ev);); /* Discard any out-of-sync messages */ + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.window = ipc_win; + ev.xclient.message_type = ipc_atom; + ev.xclient.format = 8; + + for (i = 0; i < len + 1; i += 12) { + sprintf(buff, "%8x", (int) my_ipc_win); + for (j = 0; j < 12; j++) { + buff[8 + j] = str[i + j]; + if (!str[i + j]) { + break; + } + } + buff[20] = 0; + for (j = 0; j < 20; j++) { + ev.xclient.data.b[j] = buff[j]; + } + XSendEvent(disp, ipc_win, False, 0, (XEvent *) & ev); + } + D_RETURN_(4); } -static sighandler_t * -enl_ipc_timeout(int sig) +static sighandler_t *enl_ipc_timeout(int sig) { - timeout = 1; - D_RETURN(4, (sighandler_t *) sig); - sig = 0; + timeout = 1; + D_RETURN(4, (sighandler_t *) sig); + sig = 0; } -char * -enl_wait_for_reply(void) +char *enl_wait_for_reply(void) { - XEvent ev; - static char msg_buffer[20]; - register unsigned char i; - - D_ENTER(4); - - alarm(2); - for (; - !XCheckTypedWindowEvent(disp, my_ipc_win, ClientMessage, &ev) - && !timeout;); - alarm(0); - if (ev.xany.type != ClientMessage) - { - D_RETURN(4, IPC_TIMEOUT); - } - for (i = 0; i < 20; i++) - { - msg_buffer[i] = ev.xclient.data.b[i]; - } - D_RETURN(4, msg_buffer + 8); + XEvent ev; + static char msg_buffer[20]; + register unsigned char i; + + D_ENTER(4); + + alarm(2); + for (; !XCheckTypedWindowEvent(disp, my_ipc_win, ClientMessage, &ev) + && !timeout;); + alarm(0); + if (ev.xany.type != ClientMessage) { + D_RETURN(4, IPC_TIMEOUT); + } + for (i = 0; i < 20; i++) { + msg_buffer[i] = ev.xclient.data.b[i]; + } + D_RETURN(4, msg_buffer + 8); } -char * -enl_ipc_get(const char *msg_data) +char *enl_ipc_get(const char *msg_data) { - static char *message = NULL; - static unsigned short len = 0; - char buff[13], *ret_msg = NULL; - register unsigned char i; - unsigned char blen; - - D_ENTER(4); - - if (msg_data == IPC_TIMEOUT) - { - D_RETURN(4, IPC_TIMEOUT); - } - for (i = 0; i < 12; i++) - { - buff[i] = msg_data[i]; - } - buff[12] = 0; - blen = strlen(buff); - if (message != NULL) - { - len += blen; - message = (char *) erealloc(message, len + 1); - strcat(message, buff); - } - else - { - len = blen; - message = (char *) emalloc(len + 1); - strcpy(message, buff); - } - if (blen < 12) - { - ret_msg = message; - message = NULL; - D(4, ("Received complete reply: \"%s\"\n", ret_msg)); - } - D_RETURN(4, ret_msg); + static char *message = NULL; + static unsigned short len = 0; + char buff[13], *ret_msg = NULL; + register unsigned char i; + unsigned char blen; + + D_ENTER(4); + + if (msg_data == IPC_TIMEOUT) { + D_RETURN(4, IPC_TIMEOUT); + } + for (i = 0; i < 12; i++) { + buff[i] = msg_data[i]; + } + buff[12] = 0; + blen = strlen(buff); + if (message != NULL) { + len += blen; + message = (char *) erealloc(message, len + 1); + strcat(message, buff); + } else { + len = blen; + message = (char *) emalloc(len + 1); + strcpy(message, buff); + } + if (blen < 12) { + ret_msg = message; + message = NULL; + D(4, ("Received complete reply: \"%s\"\n", ret_msg)); + } + D_RETURN(4, ret_msg); } -char * -enl_send_and_wait(char *msg) +char *enl_send_and_wait(char *msg) { - char *reply = IPC_TIMEOUT; - sighandler_t old_alrm; - - D_ENTER(4); - - /* - * Shortcut this func and return IPC_FAKE - * If the IPC Window is the E17 fake - */ - if (e17_fake_ipc) - return IPC_FAKE; - - if (ipc_win == None) - { - /* The IPC window is missing. Wait for it to return or feh to be killed. */ - /* Only called once in the E17 case */ - for (; enl_ipc_get_win() == None;) - { - if (e17_fake_ipc) - return IPC_FAKE; - else - sleep(1); - } - } - old_alrm = (sighandler_t) signal(SIGALRM, (sighandler_t) enl_ipc_timeout); - for (; reply == IPC_TIMEOUT;) - { - timeout = 0; - enl_ipc_send(msg); - for (; !(reply = enl_ipc_get(enl_wait_for_reply()));); - if (reply == IPC_TIMEOUT) - { - /* We timed out. The IPC window must be AWOL. Reset and resend message. */ - D(3, ("IPC timed out. IPC window has gone. Clearing ipc_win.\n")); - XSelectInput(disp, ipc_win, None); - ipc_win = None; - } - } - signal(SIGALRM, old_alrm); - D_RETURN(4, reply); + char *reply = IPC_TIMEOUT; + sighandler_t old_alrm; + + D_ENTER(4); + + /* + * Shortcut this func and return IPC_FAKE + * If the IPC Window is the E17 fake + */ + if (e17_fake_ipc) + return IPC_FAKE; + + if (ipc_win == None) { + /* The IPC window is missing. Wait for it to return or feh to be killed. */ + /* Only called once in the E17 case */ + for (; enl_ipc_get_win() == None;) { + if (e17_fake_ipc) + return IPC_FAKE; + else + sleep(1); + } + } + old_alrm = (sighandler_t) signal(SIGALRM, (sighandler_t) enl_ipc_timeout); + for (; reply == IPC_TIMEOUT;) { + timeout = 0; + enl_ipc_send(msg); + for (; !(reply = enl_ipc_get(enl_wait_for_reply()));); + if (reply == IPC_TIMEOUT) { + /* We timed out. The IPC window must be AWOL. Reset and resend message. */ + D(3, ("IPC timed out. IPC window has gone. Clearing ipc_win.\n")); + XSelectInput(disp, ipc_win, None); + ipc_win = None; + } + } + signal(SIGALRM, old_alrm); + D_RETURN(4, reply); } diff --git a/src/support.h b/src/support.h index a8f81a1..c50f999 100644 --- a/src/support.h +++ b/src/support.h @@ -27,16 +27,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SUPPORT_H #include <X11/Xfuncproto.h> -#include <X11/Intrinsic.h> /* Xlib, Xutil, Xresource, Xfuncproto */ +#include <X11/Intrinsic.h> /* Xlib, Xutil, Xresource, Xfuncproto */ #define IPC_TIMEOUT ((char *) 1) -#define IPC_FAKE ((char *) 2) /* Faked IPC */ +#define IPC_FAKE ((char *) 2) /* Faked IPC */ #define enl_ipc_sync() do { \ char *reply = enl_send_and_wait("nop"); \ if ((reply != IPC_FAKE) && (reply != IPC_TIMEOUT)) \ free(reply); \ - } while (0) + } while (0) extern Window ipc_win; extern Atom ipc_atom; @@ -46,8 +46,7 @@ extern void enl_ipc_send(char *); extern char *enl_wait_for_reply(void); extern char *enl_ipc_get(const char *); extern char *enl_send_and_wait(char *); -extern void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, - int desktop, int set); +extern void feh_wm_set_bg(char *fil, Imlib_Image im, int centered, int scaled, int desktop, int set); extern int feh_wm_get_num_desks(void); extern signed char feh_wm_get_wm_is_e(void); void feh_wm_set_bg_file(char *file, unsigned char bgmode); diff --git a/src/thumbnail.c b/src/thumbnail.c index b4f410d..d317ac7 100644 --- a/src/thumbnail.c +++ b/src/thumbnail.c @@ -40,549 +40,491 @@ static thumbmode_data td; /* TODO Break this up a bit ;) */ /* TODO s/bit/lot */ -void -init_thumbnail_mode(void) +void init_thumbnail_mode(void) { /* moved to thumbnail_data: - Imlib_Image im_main; - Imlib_Image bg_im = NULL; - Imlib_Font fn = NULL; - Imlib_Font title_fn = NULL; - - int w = 800, h = 600; - int bg_w = 0, bg_h = 0; - - int text_area_w, text_area_h; - int max_column_w = 0; - */ - - - Imlib_Image im_temp; - int ww = 0, hh = 0, www, hhh, xxx, yyy; - int x = 0, y = 0; - winwidget winwid = NULL; - Imlib_Image im_thumb = NULL; - unsigned char trans_bg = 0; - int title_area_h = 0; - int tw = 0, th = 0; - int fw_name, fw_size, fw_dim, fh; - int thumbnailcount = 0; - feh_file *file = NULL; - gib_list *l, *last = NULL; - int lines; - int index_image_width, index_image_height; - int x_offset_name = 0, x_offset_dim = 0, x_offset_size = 0; - char *s; - - /* initialize thumbnail mode data */ - td.im_main = NULL; - td.im_bg = NULL; - td.font_main = NULL; - td.font_title = NULL; - - td.w = 640; - td.h = 480; - td.bg_w = 0; - td.bg_h = 0; - td.thumb_tot_h = 0; - td.text_area_w = 0; - td.text_area_h = 0; - - td.vertical = 0; - td.max_column_w = 0; - - D_ENTER(3); - - mode = "thumbnail"; - - td.font_main = gib_imlib_load_font(opt.font); - - if (opt.title_font) - { - int fh, fw; - - td.font_title = gib_imlib_load_font(opt.title_font); - gib_imlib_get_text_size(td.font_title, "W", NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - title_area_h = fh + 4; - } - else - td.font_title = imlib_load_font(DEFAULT_FONT_TITLE); - - if ((!td.font_main) || (!td.font_title)) - eprintf("Error loading fonts"); - - /* Work out how tall the font is */ - gib_imlib_get_text_size(td.font_main, "W", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); - /* For now, allow room for the right number of lines with small gaps */ - td.text_area_h = - ((th + 2) * (opt.index_show_name + opt.index_show_size + - opt.index_show_dim)) + 5; - - /* This includes the text area for index data */ - td.thumb_tot_h = opt.thumb_h + td.text_area_h; - - /* Use bg image dimensions for default size */ - if (opt.bg && opt.bg_file) - { - if (!strcmp(opt.bg_file, "trans")) - trans_bg = 1; - else - { - - D(3, ("Time to apply a background to blend onto\n")); - if (feh_load_image_char(&td.im_bg, opt.bg_file) != 0) - { - td.bg_w = gib_imlib_image_get_width(td.im_bg); - td.bg_h = gib_imlib_image_get_height(td.im_bg); - } - } - } - - /* figure out geometry for the main window and entries */ - feh_thumbnail_calculate_geometry(); - - index_image_width = td.w; - index_image_height = td.h + title_area_h; - td.im_main = imlib_create_image(index_image_width, index_image_height); - gib_imlib_image_set_has_alpha(td.im_main, 1); - - if (!td.im_main) - eprintf("Imlib error creating index image, are you low on RAM?"); - - if (td.im_bg) - gib_imlib_blend_image_onto_image(td.im_main, td.im_bg, - gib_imlib_image_has_alpha(td.im_bg), 0, 0, - td.bg_w, td.bg_h, 0, 0, td.w, td.h, 1, 0, 0); - else if (trans_bg) - { - gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w, td.h + title_area_h, 0, 0, - 0, 0); - gib_imlib_image_set_has_alpha(td.im_main, 1); - } - else - { - /* Colour the background */ - gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w, td.h + title_area_h, 0, 0, - 0, 255); - } - - /* Create title now */ - - if (!opt.title) - s = estrdup(PACKAGE " [thumbnail mode]"); - else - s = estrdup(feh_printf(opt.title, NULL)); - - if (opt.display) - { - winwid = winwidget_create_from_image(td.im_main, s, WIN_TYPE_THUMBNAIL); - winwidget_show(winwid); - } - - /* make sure we have an ~/.thumbnails/normal directory for storing - permanent thumbnails */ - td.cache_thumbnails = feh_thumbnail_setup_thumbnail_dir(); - td.cache_thumbnails = opt.cache_thumbnails; - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - if (last) - { - filelist = feh_file_remove_from_list(filelist, last); - filelist_len--; - last = NULL; - } - D(4, ("About to load image %s\n", file->filename)); - /* if (feh_load_image(&im_temp, file) != 0) */ - if (feh_thumbnail_get_thumbnail(&im_temp, file) != 0) - { - if (opt.verbose) - feh_display_status('.'); - D(4, ("Successfully loaded %s\n", file->filename)); - www = opt.thumb_w; - hhh = opt.thumb_h; - ww = gib_imlib_image_get_width(im_temp); - hh = gib_imlib_image_get_height(im_temp); - thumbnailcount++; - if (gib_imlib_image_has_alpha(im_temp)) - imlib_context_set_blend(1); - else - imlib_context_set_blend(0); - - if (opt.aspect) - { - double ratio = 0.0; - - /* Keep the aspect ratio for the thumbnail */ - ratio = ((double) ww / hh) / ((double) www / hhh); - - if (ratio > 1.0) - hhh = opt.thumb_h / ratio; - else if (ratio != 1.0) - www = opt.thumb_w * ratio; - } - - if ((!opt.stretch) && ((www > ww) || (hhh > hh))) - { - /* Don't make the image larger unless stretch is specified */ - www = ww; - hhh = hh; - } - - im_thumb = - gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, - hhh, 1); - gib_imlib_free_image_and_decache(im_temp); - - if (opt.alpha) - { - DATA8 atab[256]; - - D(3, ("Applying alpha options\n")); - gib_imlib_image_set_has_alpha(im_thumb, 1); - memset(atab, opt.alpha_level, sizeof(atab)); - gib_imlib_apply_color_modifier_to_rectangle(im_thumb, 0, 0, www, - hhh, NULL, NULL, NULL, - atab); - } - - td.text_area_w = opt.thumb_w; - /* Now draw on the info text */ - if (opt.index_show_name) - { - gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw_name, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw_name > td.text_area_w) - td.text_area_w = fw_name; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(td.font_main, create_index_dimension_string(ww, hh), - NULL, &fw_dim, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw_dim > td.text_area_w) - td.text_area_w = fw_dim; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(td.font_main, - create_index_size_string(file->filename), - NULL, &fw_size, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw_size > td.text_area_w) - td.text_area_w = fw_size; - } - if (td.text_area_w > opt.thumb_w) - td.text_area_w += 5; - - /* offsets for centering text */ - x_offset_name = (td.text_area_w - fw_name) / 2; - x_offset_dim = (td.text_area_w - fw_dim) / 2; - x_offset_size = (td.text_area_w - fw_size) / 2; - - if (td.vertical) - { - if (td.text_area_w > td.max_column_w) - td.max_column_w = td.text_area_w; - if (y > td.h - td.thumb_tot_h) - { - y = 0; - x += td.max_column_w; - td.max_column_w = 0; - } - if (x > td.w - td.text_area_w) - break; - } - else - { - if (x > td.w - td.text_area_w) - { - x = 0; - y += td.thumb_tot_h; - } - if (y > td.h - td.thumb_tot_h) - break; - } - - if (opt.aspect) - { - xxx = x + ((opt.thumb_w - www) / 2); - yyy = y + ((opt.thumb_h - hhh) / 2); - } - else - { - /* Ignore the aspect ratio and squash the image in */ - xxx = x; - yyy = y; - } - - /* Draw now */ - gib_imlib_blend_image_onto_image(td.im_main, im_thumb, - gib_imlib_image_has_alpha(im_thumb), - 0, 0, www, hhh, xxx, yyy, www, hhh, - 1, - gib_imlib_image_has_alpha(im_thumb), - 0); - - thumbnails = - gib_list_add_front(thumbnails, - feh_thumbnail_new(file, xxx, yyy, www, hhh)); - - gib_imlib_free_image_and_decache(im_thumb); - - lines = 0; - if (opt.index_show_name) - gib_imlib_text_draw(td.im_main, td.font_main, NULL, x + x_offset_name, - y + opt.thumb_h + (lines++ * (th + 2)) + 2, - file->name, IMLIB_TEXT_TO_RIGHT, 255, 255, - 255, 255); - if (opt.index_show_dim) - gib_imlib_text_draw(td.im_main, td.font_main, NULL, x + x_offset_dim, - y + opt.thumb_h + (lines++ * (th + 2)) + 2, - create_index_dimension_string(ww, hh), - IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); - if (opt.index_show_size) - gib_imlib_text_draw(td.im_main, td.font_main, NULL, x + x_offset_size, - y + opt.thumb_h + (lines++ * (th + 2)) + 2, - create_index_size_string(file->filename), - IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); - - if (td.vertical) - y += td.thumb_tot_h; - else - x += td.text_area_w; - } - else - { - if (opt.verbose) - feh_display_status('x'); - last = l; - } - if (opt.display) - { - winwidget_render_image(winwid, 0, 0); - if (!feh_main_iteration(0)) - exit(0); - } - } - if (opt.verbose) - fprintf(stdout, "\n"); - - if (opt.title_font) - { - int fw, fh, fx, fy; - char *s; - - s = create_index_title_string(thumbnailcount, td.w, td.h); - gib_imlib_get_text_size(td.font_title, s, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - fx = (index_image_width - fw) >> 1; - fy = index_image_height - fh - 2; - gib_imlib_text_draw(td.im_main, td.font_title, NULL, fx, fy, s, IMLIB_TEXT_TO_RIGHT, - 255, 255, 255, 255); - } - - if (opt.output && opt.output_file) - { - char output_buf[1024]; - - if (opt.output_dir) - snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file); - else - strncpy(output_buf, opt.output_file, 1024); - gib_imlib_save_image(td.im_main, output_buf); - if (opt.verbose) - { - int tw, th; - - tw = gib_imlib_image_get_width(td.im_main); - th = gib_imlib_image_get_height(td.im_main); - fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf); - fprintf(stdout, - " - Image is %dx%d pixels and contains %d thumbnails\n", - tw, th, thumbnailcount); - } - } - - if (!opt.display) - gib_imlib_free_image_and_decache(td.im_main); - - free(s); - D_RETURN_(3); -} + Imlib_Image im_main; + Imlib_Image bg_im = NULL; + Imlib_Font fn = NULL; + Imlib_Font title_fn = NULL; + + int w = 800, h = 600; + int bg_w = 0, bg_h = 0; + + int text_area_w, text_area_h; + int max_column_w = 0; + */ + + Imlib_Image im_temp; + int ww = 0, hh = 0, www, hhh, xxx, yyy; + int x = 0, y = 0; + winwidget winwid = NULL; + Imlib_Image im_thumb = NULL; + unsigned char trans_bg = 0; + int title_area_h = 0; + int tw = 0, th = 0; + int fw_name, fw_size, fw_dim, fh; + int thumbnailcount = 0; + feh_file *file = NULL; + gib_list *l, *last = NULL; + int lines; + int index_image_width, index_image_height; + int x_offset_name = 0, x_offset_dim = 0, x_offset_size = 0; + char *s; + + /* initialize thumbnail mode data */ + td.im_main = NULL; + td.im_bg = NULL; + td.font_main = NULL; + td.font_title = NULL; + + td.w = 640; + td.h = 480; + td.bg_w = 0; + td.bg_h = 0; + td.thumb_tot_h = 0; + td.text_area_w = 0; + td.text_area_h = 0; + + td.vertical = 0; + td.max_column_w = 0; + + D_ENTER(3); + + mode = "thumbnail"; + + td.font_main = gib_imlib_load_font(opt.font); + + if (opt.title_font) { + int fh, fw; + + td.font_title = gib_imlib_load_font(opt.title_font); + gib_imlib_get_text_size(td.font_title, "W", NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + title_area_h = fh + 4; + } else + td.font_title = imlib_load_font(DEFAULT_FONT_TITLE); + + if ((!td.font_main) || (!td.font_title)) + eprintf("Error loading fonts"); + + /* Work out how tall the font is */ + gib_imlib_get_text_size(td.font_main, "W", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); + /* For now, allow room for the right number of lines with small gaps */ + td.text_area_h = ((th + 2) * (opt.index_show_name + opt.index_show_size + opt.index_show_dim)) + 5; + + /* This includes the text area for index data */ + td.thumb_tot_h = opt.thumb_h + td.text_area_h; + + /* Use bg image dimensions for default size */ + if (opt.bg && opt.bg_file) { + if (!strcmp(opt.bg_file, "trans")) + trans_bg = 1; + else { + + D(3, ("Time to apply a background to blend onto\n")); + if (feh_load_image_char(&td.im_bg, opt.bg_file) != 0) { + td.bg_w = gib_imlib_image_get_width(td.im_bg); + td.bg_h = gib_imlib_image_get_height(td.im_bg); + } + } + } + + /* figure out geometry for the main window and entries */ + feh_thumbnail_calculate_geometry(); + + index_image_width = td.w; + index_image_height = td.h + title_area_h; + td.im_main = imlib_create_image(index_image_width, index_image_height); + gib_imlib_image_set_has_alpha(td.im_main, 1); + + if (!td.im_main) + eprintf("Imlib error creating index image, are you low on RAM?"); + + if (td.im_bg) + gib_imlib_blend_image_onto_image(td.im_main, td.im_bg, + gib_imlib_image_has_alpha + (td.im_bg), 0, 0, td.bg_w, td.bg_h, 0, 0, td.w, td.h, 1, 0, 0); + else if (trans_bg) { + gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w, td.h + title_area_h, 0, 0, 0, 0); + gib_imlib_image_set_has_alpha(td.im_main, 1); + } else { + /* Colour the background */ + gib_imlib_image_fill_rectangle(td.im_main, 0, 0, td.w, td.h + title_area_h, 0, 0, 0, 255); + } + + /* Create title now */ + + if (!opt.title) + s = estrdup(PACKAGE " [thumbnail mode]"); + else + s = estrdup(feh_printf(opt.title, NULL)); + + if (opt.display) { + winwid = winwidget_create_from_image(td.im_main, s, WIN_TYPE_THUMBNAIL); + winwidget_show(winwid); + } + + /* make sure we have an ~/.thumbnails/normal directory for storing + permanent thumbnails */ + td.cache_thumbnails = feh_thumbnail_setup_thumbnail_dir(); + td.cache_thumbnails = opt.cache_thumbnails; + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + if (last) { + filelist = feh_file_remove_from_list(filelist, last); + filelist_len--; + last = NULL; + } + D(4, ("About to load image %s\n", file->filename)); + /* if (feh_load_image(&im_temp, file) != 0) */ + if (feh_thumbnail_get_thumbnail(&im_temp, file) != 0) { + if (opt.verbose) + feh_display_status('.'); + D(4, ("Successfully loaded %s\n", file->filename)); + www = opt.thumb_w; + hhh = opt.thumb_h; + ww = gib_imlib_image_get_width(im_temp); + hh = gib_imlib_image_get_height(im_temp); + thumbnailcount++; + if (gib_imlib_image_has_alpha(im_temp)) + imlib_context_set_blend(1); + else + imlib_context_set_blend(0); + + if (opt.aspect) { + double ratio = 0.0; + + /* Keep the aspect ratio for the thumbnail */ + ratio = ((double) ww / hh) / ((double) www / hhh); + + if (ratio > 1.0) + hhh = opt.thumb_h / ratio; + else if (ratio != 1.0) + www = opt.thumb_w * ratio; + } + + if ((!opt.stretch) && ((www > ww) || (hhh > hh))) { + /* Don't make the image larger unless stretch is specified */ + www = ww; + hhh = hh; + } + + im_thumb = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, ww, hh, www, hhh, 1); + gib_imlib_free_image_and_decache(im_temp); + + if (opt.alpha) { + DATA8 atab[256]; + + D(3, ("Applying alpha options\n")); + gib_imlib_image_set_has_alpha(im_thumb, 1); + memset(atab, opt.alpha_level, sizeof(atab)); + gib_imlib_apply_color_modifier_to_rectangle + (im_thumb, 0, 0, www, hhh, NULL, NULL, NULL, atab); + } + td.text_area_w = opt.thumb_w; + /* Now draw on the info text */ + if (opt.index_show_name) { + gib_imlib_get_text_size(td.font_main, + file->name, NULL, &fw_name, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw_name > td.text_area_w) + td.text_area_w = fw_name; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(td.font_main, + create_index_dimension_string + (ww, hh), NULL, &fw_dim, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw_dim > td.text_area_w) + td.text_area_w = fw_dim; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(td.font_main, + create_index_size_string + (file->filename), NULL, &fw_size, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw_size > td.text_area_w) + td.text_area_w = fw_size; + } + if (td.text_area_w > opt.thumb_w) + td.text_area_w += 5; + + /* offsets for centering text */ + x_offset_name = (td.text_area_w - fw_name) / 2; + x_offset_dim = (td.text_area_w - fw_dim) / 2; + x_offset_size = (td.text_area_w - fw_size) / 2; + + if (td.vertical) { + if (td.text_area_w > td.max_column_w) + td.max_column_w = td.text_area_w; + if (y > td.h - td.thumb_tot_h) { + y = 0; + x += td.max_column_w; + td.max_column_w = 0; + } + if (x > td.w - td.text_area_w) + break; + } else { + if (x > td.w - td.text_area_w) { + x = 0; + y += td.thumb_tot_h; + } + if (y > td.h - td.thumb_tot_h) + break; + } -static char * -create_index_size_string(char *file) + if (opt.aspect) { + xxx = x + ((opt.thumb_w - www) / 2); + yyy = y + ((opt.thumb_h - hhh) / 2); + } else { + /* Ignore the aspect ratio and squash the image in */ + xxx = x; + yyy = y; + } + + /* Draw now */ + gib_imlib_blend_image_onto_image(td.im_main, + im_thumb, + gib_imlib_image_has_alpha + (im_thumb), 0, 0, + www, hhh, xxx, + yyy, www, hhh, 1, gib_imlib_image_has_alpha(im_thumb), 0); + + thumbnails = gib_list_add_front(thumbnails, feh_thumbnail_new(file, xxx, yyy, www, hhh)); + + gib_imlib_free_image_and_decache(im_thumb); + + lines = 0; + if (opt.index_show_name) + gib_imlib_text_draw(td.im_main, + td.font_main, NULL, + x + x_offset_name, + y + opt.thumb_h + + (lines++ * (th + 2)) + + 2, file->name, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + if (opt.index_show_dim) + gib_imlib_text_draw(td.im_main, + td.font_main, NULL, + x + x_offset_dim, + y + opt.thumb_h + + (lines++ * (th + 2)) + + 2, + create_index_dimension_string + (ww, hh), IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + if (opt.index_show_size) + gib_imlib_text_draw(td.im_main, + td.font_main, NULL, + x + x_offset_size, + y + opt.thumb_h + + (lines++ * (th + 2)) + + 2, + create_index_size_string + (file->filename), IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + + if (td.vertical) + y += td.thumb_tot_h; + else + x += td.text_area_w; + } else { + if (opt.verbose) + feh_display_status('x'); + last = l; + } + if (opt.display) { + winwidget_render_image(winwid, 0, 0); + if (!feh_main_iteration(0)) + exit(0); + } + } + if (opt.verbose) + fprintf(stdout, "\n"); + + if (opt.title_font) { + int fw, fh, fx, fy; + char *s; + + s = create_index_title_string(thumbnailcount, td.w, td.h); + gib_imlib_get_text_size(td.font_title, s, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + fx = (index_image_width - fw) >> 1; + fy = index_image_height - fh - 2; + gib_imlib_text_draw(td.im_main, td.font_title, NULL, fx, + fy, s, IMLIB_TEXT_TO_RIGHT, 255, 255, 255, 255); + } + + if (opt.output && opt.output_file) { + char output_buf[1024]; + + if (opt.output_dir) + snprintf(output_buf, 1024, "%s/%s", opt.output_dir, opt.output_file); + else + strncpy(output_buf, opt.output_file, 1024); + gib_imlib_save_image(td.im_main, output_buf); + if (opt.verbose) { + int tw, th; + + tw = gib_imlib_image_get_width(td.im_main); + th = gib_imlib_image_get_height(td.im_main); + fprintf(stdout, PACKAGE " - File saved as %s\n", output_buf); + fprintf(stdout, + " - Image is %dx%d pixels and contains %d thumbnails\n", tw, th, thumbnailcount); + } + } + + if (!opt.display) + gib_imlib_free_image_and_decache(td.im_main); + + free(s); + D_RETURN_(3); +} + +static char *create_index_size_string(char *file) { - static char str[50]; - int size = 0; - double kbs = 0.0; - struct stat st; - - D_ENTER(4); - if (stat(file, &st)) - kbs = 0.0; - else - { - size = st.st_size; - kbs = (double) size / 1000; - } - - snprintf(str, sizeof(str), "%.2fKb", kbs); - D_RETURN(4, str); + static char str[50]; + int size = 0; + double kbs = 0.0; + struct stat st; + + D_ENTER(4); + if (stat(file, &st)) + kbs = 0.0; + else { + size = st.st_size; + kbs = (double) size / 1000; + } + + snprintf(str, sizeof(str), "%.2fKb", kbs); + D_RETURN(4, str); } -static char * -create_index_dimension_string(int w, int h) +static char *create_index_dimension_string(int w, int h) { - static char str[50]; + static char str[50]; - D_ENTER(4); - snprintf(str, sizeof(str), "%dx%d", w, h); - D_RETURN(4, str); + D_ENTER(4); + snprintf(str, sizeof(str), "%dx%d", w, h); + D_RETURN(4, str); } -static char * -create_index_title_string(int num, int w, int h) +static char *create_index_title_string(int num, int w, int h) { - static char str[50]; + static char str[50]; - D_ENTER(4); - snprintf(str, sizeof(str), - PACKAGE " index - %d thumbnails, %d by %d pixels", num, w, h); - D_RETURN(4, str); + D_ENTER(4); + snprintf(str, sizeof(str), PACKAGE " index - %d thumbnails, %d by %d pixels", num, w, h); + D_RETURN(4, str); } -feh_thumbnail * -feh_thumbnail_new(feh_file * file, int x, int y, int w, int h) +feh_thumbnail *feh_thumbnail_new(feh_file * file, int x, int y, int w, int h) { - feh_thumbnail *thumb; + feh_thumbnail *thumb; - D_ENTER(4); + D_ENTER(4); - thumb = (feh_thumbnail *) emalloc(sizeof(feh_thumbnail)); - thumb->x = x; - thumb->y = y; - thumb->w = w; - thumb->h = h; - thumb->file = file; - thumb->exists = 1; + thumb = (feh_thumbnail *) emalloc(sizeof(feh_thumbnail)); + thumb->x = x; + thumb->y = y; + thumb->w = w; + thumb->h = h; + thumb->file = file; + thumb->exists = 1; - D_RETURN(4, thumb); + D_RETURN(4, thumb); } -feh_file * -feh_thumbnail_get_file_from_coords(int x, int y) +feh_file *feh_thumbnail_get_file_from_coords(int x, int y) { - gib_list *l; - feh_thumbnail *thumb; - - D_ENTER(4); - - for (l = thumbnails; l; l = l->next) - { - thumb = FEH_THUMB(l->data); - if (XY_IN_RECT(x, y, thumb->x, thumb->y, thumb->w, thumb->h)) - { - if (thumb->exists) - { - D_RETURN(4, thumb->file); - } - } - } - D(4, ("No matching %d %d\n", x, y)); - D_RETURN(4, NULL); + gib_list *l; + feh_thumbnail *thumb; + + D_ENTER(4); + + for (l = thumbnails; l; l = l->next) { + thumb = FEH_THUMB(l->data); + if (XY_IN_RECT(x, y, thumb->x, thumb->y, thumb->w, thumb->h)) { + if (thumb->exists) { + D_RETURN(4, thumb->file); + } + } + } + D(4, ("No matching %d %d\n", x, y)); + D_RETURN(4, NULL); } -feh_thumbnail * -feh_thumbnail_get_thumbnail_from_coords(int x, int y) +feh_thumbnail *feh_thumbnail_get_thumbnail_from_coords(int x, int y) { - gib_list *l; - feh_thumbnail *thumb; - - D_ENTER(4); - - for (l = thumbnails; l; l = l->next) - { - thumb = FEH_THUMB(l->data); - if (XY_IN_RECT(x, y, thumb->x, thumb->y, thumb->w, thumb->h)) - { - if (thumb->exists) - { - D_RETURN(4, thumb); - } - } - } - D(4, ("No matching %d %d\n", x, y)); - D_RETURN(4, NULL); + gib_list *l; + feh_thumbnail *thumb; + + D_ENTER(4); + + for (l = thumbnails; l; l = l->next) { + thumb = FEH_THUMB(l->data); + if (XY_IN_RECT(x, y, thumb->x, thumb->y, thumb->w, thumb->h)) { + if (thumb->exists) { + D_RETURN(4, thumb); + } + } + } + D(4, ("No matching %d %d\n", x, y)); + D_RETURN(4, NULL); } -feh_thumbnail * -feh_thumbnail_get_from_file(feh_file * file) +feh_thumbnail *feh_thumbnail_get_from_file(feh_file * file) { - gib_list *l; - feh_thumbnail *thumb; - - D_ENTER(4); - - for (l = thumbnails; l; l = l->next) - { - thumb = FEH_THUMB(l->data); - if (thumb->file == file) - { - if (thumb->exists) - { - D_RETURN(4, thumb); - } - } - } - D(4, ("No match\n")); - D_RETURN(4, NULL); -} + gib_list *l; + feh_thumbnail *thumb; + D_ENTER(4); -void -feh_thumbnail_mark_removed(feh_file * file, int deleted) + for (l = thumbnails; l; l = l->next) { + thumb = FEH_THUMB(l->data); + if (thumb->file == file) { + if (thumb->exists) { + D_RETURN(4, thumb); + } + } + } + D(4, ("No match\n")); + D_RETURN(4, NULL); +} + +void feh_thumbnail_mark_removed(feh_file * file, int deleted) { - feh_thumbnail *thumb; - winwidget w; - - D_ENTER(4); - - thumb = feh_thumbnail_get_from_file(file); - if (thumb) - { - w = winwidget_get_first_window_of_type(WIN_TYPE_THUMBNAIL); - if (w) - { - td.font_main = imlib_load_font(DEFAULT_FONT_TITLE); - if (deleted) - gib_imlib_image_fill_rectangle(w->im, thumb->x, thumb->y, - thumb->w, thumb->h, 255, 0, 0, - 150); - else - gib_imlib_image_fill_rectangle(w->im, thumb->x, thumb->y, - thumb->w, thumb->h, 0, 0, 255, - 150); - if (td.font_main) - { - int tw, th; - - gib_imlib_get_text_size(td.font_main, "X", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); - gib_imlib_text_draw(w->im, td.font_main, NULL, thumb->x + ((thumb->w - tw) / 2), - thumb->y + ((thumb->h - th) / 2), "X", - IMLIB_TEXT_TO_RIGHT, 205, 205, 50, 255); - } - else - weprintf(DEFAULT_FONT_TITLE); - winwidget_render_image(w, 0, 1); - } - thumb->exists = 0; - } - D_RETURN_(4); + feh_thumbnail *thumb; + winwidget w; + + D_ENTER(4); + + thumb = feh_thumbnail_get_from_file(file); + if (thumb) { + w = winwidget_get_first_window_of_type(WIN_TYPE_THUMBNAIL); + if (w) { + td.font_main = imlib_load_font(DEFAULT_FONT_TITLE); + if (deleted) + gib_imlib_image_fill_rectangle(w->im, + thumb->x, thumb->y, thumb->w, thumb->h, 255, 0, 0, 150); + else + gib_imlib_image_fill_rectangle(w->im, + thumb->x, thumb->y, thumb->w, thumb->h, 0, 0, 255, 150); + if (td.font_main) { + int tw, th; + + gib_imlib_get_text_size(td.font_main, "X", NULL, &tw, &th, IMLIB_TEXT_TO_RIGHT); + gib_imlib_text_draw(w->im, td.font_main, + NULL, + thumb->x + + ((thumb->w - tw) / 2), + thumb->y + + ((thumb->h - th) / 2), "X", IMLIB_TEXT_TO_RIGHT, 205, 205, 50, 255); + } else + weprintf(DEFAULT_FONT_TITLE); + winwidget_render_image(w, 0, 1); + } + thumb->exists = 0; + } + D_RETURN_(4); } -void -feh_thumbnail_calculate_geometry(void) +void feh_thumbnail_calculate_geometry(void) { gib_list *l; feh_file *file; @@ -590,237 +532,204 @@ feh_thumbnail_calculate_geometry(void) int x = 0, y = 0; int fw, fh; - if (!opt.limit_w && !opt.limit_h) - { - if (td.im_bg) - { - if (opt.verbose) - fprintf(stdout, - PACKAGE " - No size restriction specified for index.\n" - " You did specify a background however, so the\n" - " index size has defaulted to the size of the image\n"); - opt.limit_w = td.bg_w; - opt.limit_h = td.bg_h; - } - else - { - if (opt.verbose) - fprintf(stdout, - PACKAGE " - No size restriction specified for index.\n" - " Using defaults (width limited to 640)\n"); - opt.limit_w = 640; - } - } - - - /* Here we need to whiz through the files, and look at the filenames and - info in the selected font, work out how much space we need, and - calculate the size of the image we will require */ - - if (opt.limit_w && opt.limit_h) - { - int rec_h = 0; - - td.w = opt.limit_w; - td.h = opt.limit_h; - - /* Work out if this is big enough, and give a warning if not */ - - /* Pretend we are limiting width by that specified, loop through, and - see it we fit in the height specified. If not, continue the loop, - and recommend the final value instead. Carry on and make the index - anyway. */ - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - td.text_area_w = opt.thumb_w; - if (opt.index_show_name) - { - gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(td.font_main, - create_index_dimension_string(1000, 1000), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(td.font_main, - create_index_size_string(file->filename), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (td.text_area_w > opt.thumb_w) - td.text_area_w += 5; - - if ((x > td.w - td.text_area_w)) - { - x = 0; - y += td.thumb_tot_h; - } - - x += td.text_area_w; - } - rec_h = y + td.thumb_tot_h; - - if (td.h < rec_h) - { - weprintf("The image size you specified (%d by %d) is not large\n" - "enough to hold all the thumnails you specified (%d). To fit all\n" - "the thumnails, either decrease their size, choose a smaller font,\n" - "or use a larger image (may I recommend %d by %d?)", - opt.limit_w, opt.limit_h, filelist_len, opt.limit_w, rec_h); - } - } - else if (opt.limit_h) - { - td.vertical = 1; - td.h = opt.limit_h; - /* calc w */ - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - td.text_area_w = opt.thumb_w; - /* Calc width of text */ - if (opt.index_show_name) - { - gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(td.font_main, - create_index_dimension_string(1000, 1000), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(td.font_main, - create_index_size_string(file->filename), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (td.text_area_w > opt.thumb_w) - td.text_area_w += 5; - - if (td.text_area_w > td.max_column_w) - td.max_column_w = td.text_area_w; - - if ((y > td.h - td.thumb_tot_h)) - { - y = 0; - x += td.max_column_w; - td.max_column_w = 0; - } - - y += td.thumb_tot_h; - } - td.w = x + td.text_area_w; - td.max_column_w = 0; - } - else if (opt.limit_w) - { - td.w = opt.limit_w; - /* calc h */ - - for (l = filelist; l; l = l->next) - { - file = FEH_FILE(l->data); - td.text_area_w = opt.thumb_w; - if (opt.index_show_name) - { - gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw, &fh, - IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (opt.index_show_dim) - { - gib_imlib_get_text_size(td.font_main, - create_index_dimension_string(1000, 1000), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - if (opt.index_show_size) - { - gib_imlib_get_text_size(td.font_main, - create_index_size_string(file->filename), - NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); - if (fw > td.text_area_w) - td.text_area_w = fw; - } - - if (td.text_area_w > opt.thumb_w) - td.text_area_w += 5; - - if ((x > td.w - td.text_area_w)) - { - x = 0; - y += td.thumb_tot_h; - } - - x += td.text_area_w; - } - td.h = y + td.thumb_tot_h; - } + if (!opt.limit_w && !opt.limit_h) { + if (td.im_bg) { + if (opt.verbose) + fprintf(stdout, + PACKAGE + " - No size restriction specified for index.\n" + " You did specify a background however, so the\n" + " index size has defaulted to the size of the image\n"); + opt.limit_w = td.bg_w; + opt.limit_h = td.bg_h; + } else { + if (opt.verbose) + fprintf(stdout, + PACKAGE + " - No size restriction specified for index.\n" + " Using defaults (width limited to 640)\n"); + opt.limit_w = 640; + } + } + + /* Here we need to whiz through the files, and look at the filenames and + info in the selected font, work out how much space we need, and + calculate the size of the image we will require */ + + if (opt.limit_w && opt.limit_h) { + int rec_h = 0; + + td.w = opt.limit_w; + td.h = opt.limit_h; + + /* Work out if this is big enough, and give a warning if not */ + + /* Pretend we are limiting width by that specified, loop through, and + see it we fit in the height specified. If not, continue the loop, + and recommend the final value instead. Carry on and make the index + anyway. */ + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + td.text_area_w = opt.thumb_w; + if (opt.index_show_name) { + gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(td.font_main, + create_index_dimension_string + (1000, 1000), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(td.font_main, + create_index_size_string + (file->filename), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (td.text_area_w > opt.thumb_w) + td.text_area_w += 5; + + if ((x > td.w - td.text_area_w)) { + x = 0; + y += td.thumb_tot_h; + } + + x += td.text_area_w; + } + rec_h = y + td.thumb_tot_h; + + if (td.h < rec_h) { + weprintf + ("The image size you specified (%d by %d) is not large\n" + "enough to hold all the thumnails you specified (%d). To fit all\n" + "the thumnails, either decrease their size, choose a smaller font,\n" + "or use a larger image (may I recommend %d by %d?)", + opt.limit_w, opt.limit_h, filelist_len, opt.limit_w, rec_h); + } + } else if (opt.limit_h) { + td.vertical = 1; + td.h = opt.limit_h; + /* calc w */ + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + td.text_area_w = opt.thumb_w; + /* Calc width of text */ + if (opt.index_show_name) { + gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(td.font_main, + create_index_dimension_string + (1000, 1000), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(td.font_main, + create_index_size_string + (file->filename), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (td.text_area_w > opt.thumb_w) + td.text_area_w += 5; + + if (td.text_area_w > td.max_column_w) + td.max_column_w = td.text_area_w; + + if ((y > td.h - td.thumb_tot_h)) { + y = 0; + x += td.max_column_w; + td.max_column_w = 0; + } + + y += td.thumb_tot_h; + } + td.w = x + td.text_area_w; + td.max_column_w = 0; + } else if (opt.limit_w) { + td.w = opt.limit_w; + /* calc h */ + + for (l = filelist; l; l = l->next) { + file = FEH_FILE(l->data); + td.text_area_w = opt.thumb_w; + if (opt.index_show_name) { + gib_imlib_get_text_size(td.font_main, file->name, NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (opt.index_show_dim) { + gib_imlib_get_text_size(td.font_main, + create_index_dimension_string + (1000, 1000), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + if (opt.index_show_size) { + gib_imlib_get_text_size(td.font_main, + create_index_size_string + (file->filename), NULL, &fw, &fh, IMLIB_TEXT_TO_RIGHT); + if (fw > td.text_area_w) + td.text_area_w = fw; + } + + if (td.text_area_w > opt.thumb_w) + td.text_area_w += 5; + + if ((x > td.w - td.text_area_w)) { + x = 0; + y += td.thumb_tot_h; + } + + x += td.text_area_w; + } + td.h = y + td.thumb_tot_h; + } } -int -feh_thumbnail_get_thumbnail(Imlib_Image *image, feh_file *file) +int feh_thumbnail_get_thumbnail(Imlib_Image * image, feh_file * file) { int status = 0; char *thumb_file = NULL, *uri = NULL; if (!file || !file->filename) - return(0); + return (0); - if (td.cache_thumbnails) - { + if (td.cache_thumbnails) { uri = feh_thumbnail_get_name_uri(file->filename); thumb_file = feh_thumbnail_get_name(uri); status = feh_thumbnail_get_generated(image, file, thumb_file, uri); if (!status) status = feh_thumbnail_generate(image, file, thumb_file, uri); - - printf("uri is %s, thumb_file is %s\n", uri, thumb_file); + + printf("uri is %s, thumb_file is %s\n", uri, thumb_file); free(uri); free(thumb_file); - } - else + } else status = feh_load_image(image, file); return status; } -char* -feh_thumbnail_get_name(char *uri) +char *feh_thumbnail_get_name(char *uri) { char *home = NULL, *thumb_file = NULL, *md5_name = NULL; /* FIXME: make sure original file isn't under ~/.thumbnails */ - - md5_name = feh_thumbnail_get_name_md5(uri); home = getenv("HOME"); - if (home) - { + if (home) { thumb_file = estrjoin("/", home, ".thumbnails/normal", md5_name, NULL); } @@ -829,21 +738,18 @@ feh_thumbnail_get_name(char *uri) return thumb_file; } -char* -feh_thumbnail_get_name_uri(char *name) +char *feh_thumbnail_get_name_uri(char *name) { char *cwd, *uri = NULL; /* FIXME: what happends with http, https, and ftp? MTime etc */ if ((strncmp(name, "http://", 7) != 0) && - (strncmp(name, "https://", 8) != 0) && - (strncmp(name, "ftp://", 6) != 0) && - (strncmp(name, "file://", 7) != 0)) - { + (strncmp(name, "https://", 8) != 0) && (strncmp(name, "ftp://", 6) != 0) + && (strncmp(name, "file://", 7) != 0)) { /* make sure it's an absoulte path */ /* FIXME: add support for ~, need to investigate if it's expanded - somewhere else before adding (unecessary) code */ + somewhere else before adding (unecessary) code */ if (name[0] != '/') { cwd = getcwd(NULL, 0); uri = estrjoin("/", "file:/", cwd, name, NULL); @@ -851,15 +757,13 @@ feh_thumbnail_get_name_uri(char *name) } else { uri = estrjoin(NULL, "file://", name, NULL); } - } - else + } else uri = estrdup(name); - + return uri; } -char* -feh_thumbnail_get_name_md5(char *uri) +char *feh_thumbnail_get_name_md5(char *uri) { int i; char *pos, *md5_name; @@ -872,9 +776,8 @@ feh_thumbnail_get_name_md5(char *uri) md5_finish(&pms, digest); /* print the md5 as hex to a string */ - md5_name = emalloc(32 + 4 + 1 * sizeof(char)); /* md5 + .png + '\0' */ - for (i = 0, pos = md5_name; i < 16; i++, pos += 2) - { + md5_name = emalloc(32 + 4 + 1 * sizeof(char)); /* md5 + .png + '\0' */ + for (i = 0, pos = md5_name; i < 16; i++, pos += 2) { sprintf(pos, "%02x", digest[i]); } sprintf(pos, ".png"); @@ -882,23 +785,20 @@ feh_thumbnail_get_name_md5(char *uri) return md5_name; } -int -feh_thumbnail_generate(Imlib_Image *image, feh_file *file, char *thumb_file, char *uri) +int feh_thumbnail_generate(Imlib_Image * image, feh_file * file, char *thumb_file, char *uri) { int w, h, thumb_w, thumb_h; char *c_mtime; Imlib_Image im_temp; struct stat sb; - if (feh_load_image(&im_temp, file) != 0) - { + if (feh_load_image(&im_temp, file) != 0) { w = gib_imlib_image_get_width(im_temp); h = gib_imlib_image_get_height(im_temp); thumb_w = 128; thumb_h = 128; - if ((w > 128) || (h > 128)) - { + if ((w > 128) || (h > 128)) { double ratio = (double) w / h; if (ratio > 1.0) thumb_h = 128 / ratio; @@ -906,78 +806,68 @@ feh_thumbnail_generate(Imlib_Image *image, feh_file *file, char *thumb_file, cha thumb_w = 128 * ratio; } - *image = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, w, h, - thumb_w, thumb_h, 1); + *image = gib_imlib_create_cropped_scaled_image(im_temp, 0, 0, w, h, thumb_w, thumb_h, 1); - if (!stat(file->filename, &sb)) - { - char c_mtime[256]; + if (!stat(file->filename, &sb)) { + char c_mtime[256]; sprintf(c_mtime, "%d", sb.st_mtime); - feh_png_write_png(*image, thumb_file, - "Thumb::URI", uri, "Thumb::MTime", c_mtime); + feh_png_write_png(*image, thumb_file, "Thumb::URI", uri, "Thumb::MTime", c_mtime); } gib_imlib_free_image_and_decache(im_temp); - return(1); + return (1); } - return(0); + return (0); } -int -feh_thumbnail_get_generated(Imlib_Image *image, feh_file *file, char *thumb_file, char *uri) +int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file, char *thumb_file, char *uri) { struct stat sb; char *c_mtime; time_t mtime = 0; gib_hash *hash; - if (!stat(file->filename, &sb)) - { + if (!stat(file->filename, &sb)) { hash = feh_png_read_comments(thumb_file); - if (hash != NULL) - { - c_mtime = (char*) gib_hash_get(hash, "Thumb::MTime"); + if (hash != NULL) { + c_mtime = (char *) gib_hash_get(hash, "Thumb::MTime"); if (c_mtime != NULL) - mtime = (time_t) strtol(c_mtime, NULL,10); + mtime = (time_t) strtol(c_mtime, NULL, 10); gib_hash_free_and_data(hash); } /* FIXME: should we bother about Thumb::URI? */ - if (mtime == sb.st_mtime) - { - feh_load_image_char(image, thumb_file); + if (mtime == sb.st_mtime) { + feh_load_image_char(image, thumb_file); - return(1); + return (1); } } - return(0); + return (0); } -int -feh_thumbnail_setup_thumbnail_dir(void) +int feh_thumbnail_setup_thumbnail_dir(void) { int status = 0; struct stat sb; char *dir, *dir_thumbnails, *home; home = getenv("HOME"); - if (home != NULL) - { + if (home != NULL) { dir = estrjoin("/", home, ".thumbnails/normal", NULL); if (!stat(dir, &sb)) { if (S_ISDIR(sb.st_mode)) - status = 1; + status = 1; else weprintf("%s should be a directory", dir); } else { dir_thumbnails = estrjoin("/", home, ".thumbnails", NULL); - if (stat(dir_thumbnails, &sb) != 0) - { + if (stat(dir_thumbnails, &sb) != 0) { if (mkdir(dir_thumbnails, 0700) == -1) weprintf("unable to create %s directory", dir_thumbnails); } diff --git a/src/thumbnail.h b/src/thumbnail.h index bc986de..e096693 100644 --- a/src/thumbnail.h +++ b/src/thumbnail.h @@ -26,45 +26,40 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef THIMBNAIL_H #define THIMBNAIL_H - #include "feh.h" #include "filelist.h" #include "winwidget.h" #define FEH_THUMB(l) ((feh_thumbnail *) l) -typedef struct thumbnail -{ - int x; - int y; - int w; - int h; - feh_file *file; - unsigned char exists; - struct feh_thumbnail *next; -} -feh_thumbnail; - -typedef struct thumbmode_data -{ +typedef struct thumbnail { + int x; + int y; + int w; + int h; + feh_file *file; + unsigned char exists; + struct feh_thumbnail *next; +} feh_thumbnail; + +typedef struct thumbmode_data { /* FIXME: text_area_h not really needed, remove? */ - Imlib_Image im_main; /* base image which all thumbnails are rendered on */ - Imlib_Image im_bg; /* background for the thumbnails */ + Imlib_Image im_main; /* base image which all thumbnails are rendered on */ + Imlib_Image im_bg; /* background for the thumbnails */ - Imlib_Font font_main; /* font used for file info */ - Imlib_Font font_title; /* font used for title */ + Imlib_Font font_main; /* font used for file info */ + Imlib_Font font_title; /* font used for title */ - int w, h, bg_w, bg_h; /* dimensions of the window and bg image */ + int w, h, bg_w, bg_h; /* dimensions of the window and bg image */ - int thumb_tot_h; /* total space needed for a thumbnail including description */ - int text_area_w, text_area_h; /* space needed for thumbnail description */ + int thumb_tot_h; /* total space needed for a thumbnail including description */ + int text_area_w, text_area_h; /* space needed for thumbnail description */ - int max_column_w; /* FIXME: description */ - int vertical; /* FIXME: vertical in what way? */ - int cache_thumbnails; /* use cached thumbnails from ~/.thumbnails/normal */ -} -thumbmode_data; + int max_column_w; /* FIXME: description */ + int vertical; /* FIXME: vertical in what way? */ + int cache_thumbnails; /* use cached thumbnails from ~/.thumbnails/normal */ +} thumbmode_data; feh_thumbnail *feh_thumbnail_new(feh_file * fil, int x, int y, int w, int h); feh_file *feh_thumbnail_get_file_from_coords(int x, int y); @@ -74,9 +69,9 @@ void feh_thumbnail_mark_removed(feh_file * file, int deleted); void feh_thumbnail_calculate_geometry(void); -int feh_thumbnail_get_thumbnail(Imlib_Image *image, feh_file *file); -int feh_thumbnail_generate(Imlib_Image *image, feh_file *file, char *thumb_file, char *uri); -int feh_thumbnail_get_generated(Imlib_Image *image, feh_file *file, char *thumb_file, char *uri); +int feh_thumbnail_get_thumbnail(Imlib_Image * image, feh_file * file); +int feh_thumbnail_generate(Imlib_Image * image, feh_file * file, char *thumb_file, char *uri); +int feh_thumbnail_get_generated(Imlib_Image * image, feh_file * file, char *thumb_file, char *uri); char *feh_thumbnail_get_name(char *uri); char *feh_thumbnail_get_name_uri(char *name); char *feh_thumbnail_get_name_md5(char *uri); diff --git a/src/timers.c b/src/timers.c index 5db92f0..710d2ab 100644 --- a/src/timers.c +++ b/src/timers.c @@ -29,144 +29,131 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. fehtimer first_timer = NULL; -void -feh_handle_timer(void) +void feh_handle_timer(void) { - fehtimer ft; - - D_ENTER(4); - if (!first_timer) - { - D(3,("No timer to handle, returning\n")); - D_RETURN_(4); - } - ft = first_timer; - first_timer = first_timer->next; - D(3,("Executing timer function now\n")); - (*(ft->func)) (ft->data); - D(3,("Freeing the timer\n")); - if (ft && ft->name) - free(ft->name); - if (ft) - free(ft); - D_RETURN_(4); + fehtimer ft; + + D_ENTER(4); + if (!first_timer) { + D(3, ("No timer to handle, returning\n")); + D_RETURN_(4); + } + ft = first_timer; + first_timer = first_timer->next; + D(3, ("Executing timer function now\n")); + (*(ft->func)) (ft->data); + D(3, ("Freeing the timer\n")); + if (ft && ft->name) + free(ft->name); + if (ft) + free(ft); + D_RETURN_(4); } -double -feh_get_time(void) +double feh_get_time(void) { - struct timeval timev; + struct timeval timev; - D_ENTER(4); - gettimeofday(&timev, NULL); - D_RETURN(4,(double) timev.tv_sec + (((double) timev.tv_usec) / 1000000)); + D_ENTER(4); + gettimeofday(&timev, NULL); + D_RETURN(4, (double) timev.tv_sec + (((double) timev.tv_usec) / 1000000)); } -void -feh_remove_timer(char *name) +void feh_remove_timer(char *name) { - fehtimer ft, ptr, pptr; - - D_ENTER(4); - D(3,("removing %s\n", name)); - pptr = NULL; - ptr = first_timer; - while (ptr) - { - D(3,("Stepping through event list\n")); - ft = ptr; - if (!strcmp(ft->name, name)) - { - D(3,("Found it. Removing\n")); - if (pptr) - pptr->next = ft->next; - else - first_timer = ft->next; - if (ft->next) - ft->next->in += ft->in; - if (ft->name) - free(ft->name); - if (ft) - free(ft); - D_RETURN_(4); - } - pptr = ptr; - ptr = ptr->next; - } - D_RETURN_(4); + fehtimer ft, ptr, pptr; + + D_ENTER(4); + D(3, ("removing %s\n", name)); + pptr = NULL; + ptr = first_timer; + while (ptr) { + D(3, ("Stepping through event list\n")); + ft = ptr; + if (!strcmp(ft->name, name)) { + D(3, ("Found it. Removing\n")); + if (pptr) + pptr->next = ft->next; + else + first_timer = ft->next; + if (ft->next) + ft->next->in += ft->in; + if (ft->name) + free(ft->name); + if (ft) + free(ft); + D_RETURN_(4); + } + pptr = ptr; + ptr = ptr->next; + } + D_RETURN_(4); } -void -feh_add_timer(void (*func) (void *data), void *data, double in, char *name) +void feh_add_timer(void (*func) (void *data), void *data, double in, char *name) { - fehtimer ft, ptr, pptr; - double tally; - - D_ENTER(4); - D(3,("adding timer %s for %f seconds time\n", name, in)); - feh_remove_timer(name); - ft = malloc(sizeof(_fehtimer)); - ft->next = NULL; - ft->func = func; - ft->data = data; - ft->name = estrdup(name); - ft->just_added = 1; - ft->in = in; - D(3,("ft->in = %f\n", ft->in)); - tally = 0.0; - if (!first_timer) - { - D(3,("No first timer\n")); - first_timer = ft; - } - else - { - D(3,("There is a first timer\n")); - pptr = NULL; - ptr = first_timer; - tally = 0.0; - while (ptr) - { - tally += ptr->in; - if (tally > in) - { - tally -= ptr->in; - ft->next = ptr; - if (pptr) - pptr->next = ft; - else - first_timer = ft; - ft->in -= tally; - if (ft->next) - ft->next->in -= ft->in; - D_RETURN_(4); - } - pptr = ptr; - ptr = ptr->next; - } - if (pptr) - pptr->next = ft; - else - first_timer = ft; - ft->in -= tally; - } - D(3,("ft->in = %f\n", ft->in)); - D_RETURN_(4); + fehtimer ft, ptr, pptr; + double tally; + + D_ENTER(4); + D(3, ("adding timer %s for %f seconds time\n", name, in)); + feh_remove_timer(name); + ft = malloc(sizeof(_fehtimer)); + ft->next = NULL; + ft->func = func; + ft->data = data; + ft->name = estrdup(name); + ft->just_added = 1; + ft->in = in; + D(3, ("ft->in = %f\n", ft->in)); + tally = 0.0; + if (!first_timer) { + D(3, ("No first timer\n")); + first_timer = ft; + } else { + D(3, ("There is a first timer\n")); + pptr = NULL; + ptr = first_timer; + tally = 0.0; + while (ptr) { + tally += ptr->in; + if (tally > in) { + tally -= ptr->in; + ft->next = ptr; + if (pptr) + pptr->next = ft; + else + first_timer = ft; + ft->in -= tally; + if (ft->next) + ft->next->in -= ft->in; + D_RETURN_(4); + } + pptr = ptr; + ptr = ptr->next; + } + if (pptr) + pptr->next = ft; + else + first_timer = ft; + ft->in -= tally; + } + D(3, ("ft->in = %f\n", ft->in)); + D_RETURN_(4); } -void -feh_add_unique_timer(void (*func) (void *data), void *data, double in) +void feh_add_unique_timer(void (*func) (void *data), void *data, double in) { - static long i = 0; - char evname[20]; - - D_ENTER(4); - snprintf(evname, sizeof(evname), "T_%ld", i); - D(4,("adding timer with unique name %s\n", evname)); - feh_add_timer(func, data, in, evname); - i++; - /* Mega paranoia ;) */ - if (i > 1000000) - i = 0; - D_RETURN_(4); + static long i = 0; + char evname[20]; + + D_ENTER(4); + snprintf(evname, sizeof(evname), "T_%ld", i); + D(4, ("adding timer with unique name %s\n", evname)); + feh_add_timer(func, data, in, evname); + i++; + /* Mega paranoia ;) */ + if (i > 1000000) + i = 0; + D_RETURN_(4); } diff --git a/src/timers.h b/src/timers.h index 5cce160..a4243ca 100644 --- a/src/timers.h +++ b/src/timers.h @@ -26,22 +26,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef TIMERS_H #define TIMERS_H -struct __fehtimer -{ - char *name; - void (*func) (void *data); - void *data; - double in; - char just_added; - fehtimer next; +struct __fehtimer { + char *name; + void (*func) (void *data); + void *data; + double in; + char just_added; + fehtimer next; }; void feh_handle_timer(void); double feh_get_time(void); void feh_remove_timer(char *name); -void feh_add_timer(void (*func) (void *data), void *data, double in, - - char *name); +void feh_add_timer(void (*func) (void *data), void *data, double in, char *name); void feh_add_unique_timer(void (*func) (void *data), void *data, double in); extern fehtimer first_timer; diff --git a/src/transupp.c b/src/transupp.c index 7b6d7ee..162cc3f 100644 --- a/src/transupp.c +++ b/src/transupp.c @@ -31,11 +31,9 @@ #define JFWRITE(file,buf,sizeofbuf) \ ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) - #include "jpeglib.h" #include "transupp.h" /* My own external interface */ - #if TRANSFORMS_SUPPORTED /* @@ -75,404 +73,397 @@ * dimensions and ignore the source's. */ - -LOCAL(void) -do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays) +LOCAL(void) do_flip_h(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays) /* Horizontal flip; done in-place, so no separate dest array is required */ { - JDIMENSION MCU_cols, comp_width, blk_x, blk_y; - int ci, k, offset_y; - JBLOCKARRAY buffer; - JCOEFPTR ptr1, ptr2; - JCOEF temp1, temp2; - jpeg_component_info *compptr; - - /* Horizontal mirroring of DCT blocks is accomplished by swapping - * pairs of blocks in-place. Within a DCT block, we perform horizontal - * mirroring by changing the signs of odd-numbered columns. - * Partial iMCUs at the right edge are left untouched. - */ - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - for (blk_y = 0; blk_y < compptr->height_in_blocks; - blk_y += compptr->v_samp_factor) { - buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y, - (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { - ptr1 = buffer[offset_y][blk_x]; - ptr2 = buffer[offset_y][comp_width - blk_x - 1]; - /* this unrolled loop doesn't need to know which row it's on... */ - for (k = 0; k < DCTSIZE2; k += 2) { - temp1 = *ptr1; /* swap even column */ - temp2 = *ptr2; - *ptr1++ = temp2; - *ptr2++ = temp1; - temp1 = *ptr1; /* swap odd column with sign change */ - temp2 = *ptr2; - *ptr1++ = -temp2; - *ptr2++ = -temp1; - } + JDIMENSION MCU_cols, comp_width, blk_x, blk_y; + int ci, k, offset_y; + JBLOCKARRAY buffer; + JCOEFPTR ptr1, ptr2; + JCOEF temp1, temp2; + jpeg_component_info *compptr; + + /* Horizontal mirroring of DCT blocks is accomplished by swapping + * pairs of blocks in-place. Within a DCT block, we perform horizontal + * mirroring by changing the signs of odd-numbered columns. + * Partial iMCUs at the right edge are left untouched. + */ + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + for (blk_y = 0; blk_y < compptr->height_in_blocks; blk_y += compptr->v_samp_factor) { + buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], + blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) { + ptr1 = buffer[offset_y][blk_x]; + ptr2 = buffer[offset_y][comp_width - blk_x - 1]; + /* this unrolled loop doesn't need to know which row it's on... */ + for (k = 0; k < DCTSIZE2; k += 2) { + temp1 = *ptr1; /* swap even column */ + temp2 = *ptr2; + *ptr1++ = temp2; + *ptr2++ = temp1; + temp1 = *ptr1; /* swap odd column with sign change */ + temp2 = *ptr2; + *ptr1++ = -temp2; + *ptr2++ = -temp1; + } + } + } + } } - } - } - } } - LOCAL(void) -do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jvirt_barray_ptr *dst_coef_arrays) +do_flip_v(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) /* Vertical flip */ { - JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JBLOCKROW src_row_ptr, dst_row_ptr; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* We output into a separate array because we can't touch different - * rows of the source virtual array simultaneously. Otherwise, this - * is a pretty straightforward analog of horizontal flip. - * Within a DCT block, vertical mirroring is done by changing the signs - * of odd-numbered rows. - * Partial iMCUs at the bottom edge are copied verbatim. - */ - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; - dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, TRUE); - if (dst_blk_y < comp_height) { - /* Row is within the mirrorable area. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], - comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, FALSE); - } else { - /* Bottom-edge blocks will be copied verbatim. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, FALSE); - } - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - if (dst_blk_y < comp_height) { - /* Row is within the mirrorable area. */ - dst_row_ptr = dst_buffer[offset_y]; - src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; - for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; - dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[dst_blk_x]; - for (i = 0; i < DCTSIZE; i += 2) { - /* copy even row */ - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = *src_ptr++; - /* copy odd row with sign change */ - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = - *src_ptr++; - } - } - } else { - /* Just copy row verbatim. */ - jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y], - compptr->width_in_blocks); + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* We output into a separate array because we can't touch different + * rows of the source virtual array simultaneously. Otherwise, this + * is a pretty straightforward analog of horizontal flip. + * Within a DCT block, vertical mirroring is done by changing the signs + * of odd-numbered rows. + * Partial iMCUs at the bottom edge are copied verbatim. + */ + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], + dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); + if (dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, + src_coef_arrays[ci], + comp_height - dst_blk_y - + (JDIMENSION) compptr->v_samp_factor, (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge blocks will be copied verbatim. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, + src_coef_arrays[ci], dst_blk_y, (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + if (dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; + for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[dst_blk_x]; + for (i = 0; i < DCTSIZE; i += 2) { + /* copy even row */ + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = *src_ptr++; + /* copy odd row with sign change */ + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = -*src_ptr++; + } + } + } else { + /* Just copy row verbatim. */ + jcopy_block_row(src_buffer + [offset_y], dst_buffer[offset_y], compptr->width_in_blocks); + } + } + } } - } - } - } } - LOCAL(void) -do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jvirt_barray_ptr *dst_coef_arrays) +do_transpose(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) /* Transpose source into destination */ { - JDIMENSION dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* Transposing pixels within a block just requires transposing the - * DCT coefficients. - * Partial iMCUs at the edges require no special treatment; we simply - * process all the available DCT blocks for every component. - */ - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; - dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; - dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, - (JDIMENSION) compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - } + JDIMENSION dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Transposing pixels within a block just requires transposing the + * DCT coefficients. + * Partial iMCUs at the edges require no special treatment; we simply + * process all the available DCT blocks for every component. + */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], + dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; + dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) + compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y]; + dst_ptr = dst_buffer[offset_y] + [dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + } + } + } + } } - } - } - } } - LOCAL(void) -do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jvirt_barray_ptr *dst_coef_arrays) +do_rot_90(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) /* 90 degree rotation is equivalent to * 1. Transposing the image; * 2. Horizontal mirroring. * These two steps are merged into a single processing routine. */ { - JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* Because of the horizontal mirror step, we can't process partial iMCUs - * at the (output) right edge properly. They just get transposed and - * not mirrored. - */ - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; - dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; - dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, - (JDIMENSION) compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; - if (dst_blk_x < comp_width) { - /* Block is within the mirrorable area. */ - dst_ptr = dst_buffer[offset_y] - [comp_width - dst_blk_x - offset_x - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - i++; - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; - } - } else { - /* Edge blocks are transposed but not mirrored. */ - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - } - } + JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Because of the horizontal mirror step, we can't process partial iMCUs + * at the (output) right edge properly. They just get transposed and + * not mirrored. + */ + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], + dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; + dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) + compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y]; + if (dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + dst_ptr = dst_buffer[offset_y] + [comp_width - dst_blk_x - offset_x - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + i++; + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = -src_ptr[i * DCTSIZE + j]; + } + } else { + /* Edge blocks are transposed but not mirrored. */ + dst_ptr = dst_buffer[offset_y] + [dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + } + } + } + } + } } - } - } - } } - LOCAL(void) -do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jvirt_barray_ptr *dst_coef_arrays) +do_rot_270(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) /* 270 degree rotation is equivalent to * 1. Horizontal mirroring; * 2. Transposing the image. * These two steps are merged into a single processing routine. */ { - JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - /* Because of the horizontal mirror step, we can't process partial iMCUs - * at the (output) bottom edge properly. They just get transposed and - * not mirrored. - */ - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; - dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; - dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, - (JDIMENSION) compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; - if (dst_blk_y < comp_height) { - /* Block is within the mirrorable area. */ - src_ptr = src_buffer[offset_x] - [comp_height - dst_blk_y - offset_y - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - j++; - dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; + JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + /* Because of the horizontal mirror step, we can't process partial iMCUs + * at the (output) bottom edge properly. They just get transposed and + * not mirrored. + */ + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], + dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; + dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) + compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + dst_ptr = dst_buffer[offset_y] + [dst_blk_x + offset_x]; + if (dst_blk_y < comp_height) { + /* Block is within the mirrorable area. */ + src_ptr = src_buffer[offset_x] + [comp_height - dst_blk_y - offset_y - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + j++; + dst_ptr[j * DCTSIZE + i] + = -src_ptr[i * DCTSIZE + j]; + } + } + } else { + /* Edge blocks are transposed but not mirrored. */ + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + } + } + } + } } - } - } else { - /* Edge blocks are transposed but not mirrored. */ - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - } - } } - } - } - } } - LOCAL(void) -do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jvirt_barray_ptr *dst_coef_arrays) +do_rot_180(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) /* 180 degree rotation is equivalent to * 1. Vertical mirroring; * 2. Horizontal mirroring. * These two steps are merged into a single processing routine. */ { - JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JBLOCKROW src_row_ptr, dst_row_ptr; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; - dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, TRUE); - if (dst_blk_y < comp_height) { - /* Row is within the vertically mirrorable area. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], - comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, FALSE); - } else { - /* Bottom-edge rows are only mirrored horizontally. */ - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, FALSE); - } - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - if (dst_blk_y < comp_height) { - /* Row is within the mirrorable area. */ - dst_row_ptr = dst_buffer[offset_y]; - src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; - /* Process the blocks that can be mirrored both ways. */ - for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; - for (i = 0; i < DCTSIZE; i += 2) { - /* For even row, negate every odd column. */ - for (j = 0; j < DCTSIZE; j += 2) { - *dst_ptr++ = *src_ptr++; - *dst_ptr++ = - *src_ptr++; - } - /* For odd row, negate every even column. */ - for (j = 0; j < DCTSIZE; j += 2) { - *dst_ptr++ = - *src_ptr++; - *dst_ptr++ = *src_ptr++; - } - } - } - /* Any remaining right-edge blocks are only mirrored vertically. */ - for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[dst_blk_x]; - for (i = 0; i < DCTSIZE; i += 2) { - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = *src_ptr++; - for (j = 0; j < DCTSIZE; j++) - *dst_ptr++ = - *src_ptr++; - } - } - } else { - /* Remaining rows are just mirrored horizontally. */ - dst_row_ptr = dst_buffer[offset_y]; - src_row_ptr = src_buffer[offset_y]; - /* Process the blocks that can be mirrored. */ - for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; - for (i = 0; i < DCTSIZE2; i += 2) { - *dst_ptr++ = *src_ptr++; - *dst_ptr++ = - *src_ptr++; - } - } - /* Any remaining right-edge blocks are only copied. */ - for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { - dst_ptr = dst_row_ptr[dst_blk_x]; - src_ptr = src_row_ptr[dst_blk_x]; - for (i = 0; i < DCTSIZE2; i++) - *dst_ptr++ = *src_ptr++; - } + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JBLOCKROW src_row_ptr, dst_row_ptr; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], + dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); + if (dst_blk_y < comp_height) { + /* Row is within the vertically mirrorable area. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, + src_coef_arrays[ci], + comp_height - dst_blk_y - + (JDIMENSION) compptr->v_samp_factor, (JDIMENSION) compptr->v_samp_factor, FALSE); + } else { + /* Bottom-edge rows are only mirrored horizontally. */ + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, + src_coef_arrays[ci], dst_blk_y, (JDIMENSION) compptr->v_samp_factor, FALSE); + } + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + if (dst_blk_y < comp_height) { + /* Row is within the mirrorable area. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1]; + /* Process the blocks that can be mirrored both ways. */ + for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; + for (i = 0; i < DCTSIZE; i += 2) { + /* For even row, negate every odd column. */ + for (j = 0; j < DCTSIZE; j += 2) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = -*src_ptr++; + } + /* For odd row, negate every even column. */ + for (j = 0; j < DCTSIZE; j += 2) { + *dst_ptr++ = -*src_ptr++; + *dst_ptr++ = *src_ptr++; + } + } + } + /* Any remaining right-edge blocks are only mirrored vertically. */ + for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[dst_blk_x]; + for (i = 0; i < DCTSIZE; i += 2) { + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = *src_ptr++; + for (j = 0; j < DCTSIZE; j++) + *dst_ptr++ = -*src_ptr++; + } + } + } else { + /* Remaining rows are just mirrored horizontally. */ + dst_row_ptr = dst_buffer[offset_y]; + src_row_ptr = src_buffer[offset_y]; + /* Process the blocks that can be mirrored. */ + for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[comp_width - dst_blk_x - 1]; + for (i = 0; i < DCTSIZE2; i += 2) { + *dst_ptr++ = *src_ptr++; + *dst_ptr++ = -*src_ptr++; + } + } + /* Any remaining right-edge blocks are only copied. */ + for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) { + dst_ptr = dst_row_ptr[dst_blk_x]; + src_ptr = src_row_ptr[dst_blk_x]; + for (i = 0; i < DCTSIZE2; i++) + *dst_ptr++ = *src_ptr++; + } + } + } + } } - } - } - } } - LOCAL(void) -do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jvirt_barray_ptr *dst_coef_arrays) +do_transverse(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, + jvirt_barray_ptr * src_coef_arrays, jvirt_barray_ptr * dst_coef_arrays) /* Transverse transpose is equivalent to * 1. 180 degree rotation; * 2. Transposition; @@ -483,91 +474,101 @@ do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, * These steps are merged into a single processing routine. */ { - JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; - int ci, i, j, offset_x, offset_y; - JBLOCKARRAY src_buffer, dst_buffer; - JCOEFPTR src_ptr, dst_ptr; - jpeg_component_info *compptr; - - MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); - MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); - - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - comp_width = MCU_cols * compptr->h_samp_factor; - comp_height = MCU_rows * compptr->v_samp_factor; - for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; - dst_blk_y += compptr->v_samp_factor) { - dst_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y, - (JDIMENSION) compptr->v_samp_factor, TRUE); - for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { - for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks; - dst_blk_x += compptr->h_samp_factor) { - src_buffer = (*srcinfo->mem->access_virt_barray) - ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, - (JDIMENSION) compptr->h_samp_factor, FALSE); - for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { - if (dst_blk_y < comp_height) { - src_ptr = src_buffer[offset_x] - [comp_height - dst_blk_y - offset_y - 1]; - if (dst_blk_x < comp_width) { - /* Block is within the mirrorable area. */ - dst_ptr = dst_buffer[offset_y] - [comp_width - dst_blk_x - offset_x - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - j++; - dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; - } - i++; - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; - j++; - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - } - } - } else { - /* Right-edge blocks are mirrored in y only */ - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) { - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - j++; - dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; - } + JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y; + int ci, i, j, offset_x, offset_y; + JBLOCKARRAY src_buffer, dst_buffer; + JCOEFPTR src_ptr, dst_ptr; + jpeg_component_info *compptr; + + MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE); + MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE); + + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + comp_width = MCU_cols * compptr->h_samp_factor; + comp_height = MCU_rows * compptr->v_samp_factor; + for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks; dst_blk_y += compptr->v_samp_factor) { + dst_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, dst_coef_arrays[ci], + dst_blk_y, (JDIMENSION) compptr->v_samp_factor, TRUE); + for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) { + for (dst_blk_x = 0; + dst_blk_x < compptr->width_in_blocks; dst_blk_x += compptr->h_samp_factor) { + src_buffer = (*srcinfo->mem->access_virt_barray) + ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x, (JDIMENSION) + compptr->h_samp_factor, FALSE); + for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) { + if (dst_blk_y < comp_height) { + src_ptr = src_buffer[offset_x] + [comp_height - dst_blk_y - offset_y - 1]; + if (dst_blk_x < comp_width) { + /* Block is within the mirrorable area. */ + dst_ptr = dst_buffer[offset_y] + [comp_width - dst_blk_x - offset_x - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + j++; + dst_ptr[j * DCTSIZE + i] + = -src_ptr[i * DCTSIZE + j]; + } + i++; + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j * DCTSIZE + i] + = -src_ptr[i * DCTSIZE + j]; + j++; + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + } + } + } else { + /* Right-edge blocks are mirrored in y only */ + dst_ptr = dst_buffer[offset_y] + [dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) { + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + j++; + dst_ptr[j * DCTSIZE + i] + = -src_ptr[i * DCTSIZE + j]; + } + } + } + } else { + src_ptr = src_buffer[offset_x] + [dst_blk_y + offset_y]; + if (dst_blk_x < comp_width) { + /* Bottom-edge blocks are mirrored in x only */ + dst_ptr = dst_buffer[offset_y] + [comp_width - dst_blk_x - offset_x - 1]; + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + i++; + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = -src_ptr[i * DCTSIZE + j]; + } + } else { + /* At lower right corner, just transpose, no mirroring */ + dst_ptr = dst_buffer[offset_y] + [dst_blk_x + offset_x]; + for (i = 0; i < DCTSIZE; i++) + for (j = 0; j < DCTSIZE; j++) + dst_ptr[j * DCTSIZE + i] + = src_ptr[i * DCTSIZE + j]; + } + } + } + } + } } - } - } else { - src_ptr = src_buffer[offset_x][dst_blk_y + offset_y]; - if (dst_blk_x < comp_width) { - /* Bottom-edge blocks are mirrored in x only */ - dst_ptr = dst_buffer[offset_y] - [comp_width - dst_blk_x - offset_x - 1]; - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - i++; - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j]; - } - } else { - /* At lower right corner, just transpose, no mirroring */ - dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x]; - for (i = 0; i < DCTSIZE; i++) - for (j = 0; j < DCTSIZE; j++) - dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j]; - } - } - } } - } - } - } } - /* Request any required workspace. * * We allocate the workspace virtual arrays from the source decompression @@ -578,255 +579,260 @@ do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, * the source's virtual arrays). */ -GLOBAL(void) -jtransform_request_workspace (j_decompress_ptr srcinfo, - jpeg_transform_info *info) +GLOBAL(void) jtransform_request_workspace(j_decompress_ptr srcinfo, jpeg_transform_info * info) { - jvirt_barray_ptr *coef_arrays = NULL; - jpeg_component_info *compptr; - int ci; - - if (info->force_grayscale && - srcinfo->jpeg_color_space == JCS_YCbCr && - srcinfo->num_components == 3) { - /* We'll only process the first component */ - info->num_components = 1; - } else { - /* Process all the components */ - info->num_components = srcinfo->num_components; - } - - switch (info->transform) { - case JXFORM_NONE: - case JXFORM_FLIP_H: - /* Don't need a workspace array */ - break; - case JXFORM_FLIP_V: - case JXFORM_ROT_180: - /* Need workspace arrays having same dimensions as source image. - * Note that we allocate arrays padded out to the next iMCU boundary, - * so that transform routines need not worry about missing edge blocks. - */ - coef_arrays = (jvirt_barray_ptr *) - (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, - SIZEOF(jvirt_barray_ptr) * info->num_components); - for (ci = 0; ci < info->num_components; ci++) { - compptr = srcinfo->comp_info + ci; - coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) - ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, - (JDIMENSION) jround_up((long) compptr->width_in_blocks, - (long) compptr->h_samp_factor), - (JDIMENSION) jround_up((long) compptr->height_in_blocks, - (long) compptr->v_samp_factor), - (JDIMENSION) compptr->v_samp_factor); - } - break; - case JXFORM_TRANSPOSE: - case JXFORM_TRANSVERSE: - case JXFORM_ROT_90: - case JXFORM_ROT_270: - /* Need workspace arrays having transposed dimensions. - * Note that we allocate arrays padded out to the next iMCU boundary, - * so that transform routines need not worry about missing edge blocks. - */ - coef_arrays = (jvirt_barray_ptr *) - (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, - SIZEOF(jvirt_barray_ptr) * info->num_components); - for (ci = 0; ci < info->num_components; ci++) { - compptr = srcinfo->comp_info + ci; - coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) - ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, - (JDIMENSION) jround_up((long) compptr->height_in_blocks, - (long) compptr->v_samp_factor), - (JDIMENSION) jround_up((long) compptr->width_in_blocks, - (long) compptr->h_samp_factor), - (JDIMENSION) compptr->h_samp_factor); - } - break; - } - info->workspace_coef_arrays = coef_arrays; -} + jvirt_barray_ptr *coef_arrays = NULL; + jpeg_component_info *compptr; + int ci; + + if (info->force_grayscale && srcinfo->jpeg_color_space == JCS_YCbCr && srcinfo->num_components == 3) { + /* We'll only process the first component */ + info->num_components = 1; + } else { + /* Process all the components */ + info->num_components = srcinfo->num_components; + } + switch (info->transform) { + case JXFORM_NONE: + case JXFORM_FLIP_H: + /* Don't need a workspace array */ + break; + case JXFORM_FLIP_V: + case JXFORM_ROT_180: + /* Need workspace arrays having same dimensions as source image. + * Note that we allocate arrays padded out to the next iMCU boundary, + * so that transform routines need not worry about missing edge blocks. + */ + coef_arrays = (jvirt_barray_ptr *) + (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, SIZEOF(jvirt_barray_ptr) + * info->num_components); + for (ci = 0; ci < info->num_components; ci++) { + compptr = srcinfo->comp_info + ci; + coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) + ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, (JDIMENSION) jround_up((long) + compptr->width_in_blocks, + (long) + compptr->h_samp_factor), + (JDIMENSION) jround_up((long) + compptr->height_in_blocks, (long) + compptr->v_samp_factor), (JDIMENSION) compptr->v_samp_factor); + } + break; + case JXFORM_TRANSPOSE: + case JXFORM_TRANSVERSE: + case JXFORM_ROT_90: + case JXFORM_ROT_270: + /* Need workspace arrays having transposed dimensions. + * Note that we allocate arrays padded out to the next iMCU boundary, + * so that transform routines need not worry about missing edge blocks. + */ + coef_arrays = (jvirt_barray_ptr *) + (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, SIZEOF(jvirt_barray_ptr) + * info->num_components); + for (ci = 0; ci < info->num_components; ci++) { + compptr = srcinfo->comp_info + ci; + coef_arrays[ci] = (*srcinfo->mem->request_virt_barray) + ((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE, (JDIMENSION) jround_up((long) + compptr->height_in_blocks, + (long) + compptr->v_samp_factor), + (JDIMENSION) jround_up((long) + compptr->width_in_blocks, (long) + compptr->h_samp_factor), (JDIMENSION) compptr->h_samp_factor); + } + break; + } + info->workspace_coef_arrays = coef_arrays; +} /* Transpose destination image parameters */ -LOCAL(void) -transpose_critical_parameters (j_compress_ptr dstinfo) +LOCAL(void) transpose_critical_parameters(j_compress_ptr dstinfo) { - int tblno, i, j, ci, itemp; - jpeg_component_info *compptr; - JQUANT_TBL *qtblptr; - JDIMENSION dtemp; - UINT16 qtemp; - - /* Transpose basic image dimensions */ - dtemp = dstinfo->image_width; - dstinfo->image_width = dstinfo->image_height; - dstinfo->image_height = dtemp; - - /* Transpose sampling factors */ - for (ci = 0; ci < dstinfo->num_components; ci++) { - compptr = dstinfo->comp_info + ci; - itemp = compptr->h_samp_factor; - compptr->h_samp_factor = compptr->v_samp_factor; - compptr->v_samp_factor = itemp; - } - - /* Transpose quantization tables */ - for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { - qtblptr = dstinfo->quant_tbl_ptrs[tblno]; - if (qtblptr != NULL) { - for (i = 0; i < DCTSIZE; i++) { - for (j = 0; j < i; j++) { - qtemp = qtblptr->quantval[i*DCTSIZE+j]; - qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i]; - qtblptr->quantval[j*DCTSIZE+i] = qtemp; + int tblno, i, j, ci, itemp; + jpeg_component_info *compptr; + JQUANT_TBL *qtblptr; + JDIMENSION dtemp; + UINT16 qtemp; + + /* Transpose basic image dimensions */ + dtemp = dstinfo->image_width; + dstinfo->image_width = dstinfo->image_height; + dstinfo->image_height = dtemp; + + /* Transpose sampling factors */ + for (ci = 0; ci < dstinfo->num_components; ci++) { + compptr = dstinfo->comp_info + ci; + itemp = compptr->h_samp_factor; + compptr->h_samp_factor = compptr->v_samp_factor; + compptr->v_samp_factor = itemp; } - } - } - } -} + /* Transpose quantization tables */ + for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { + qtblptr = dstinfo->quant_tbl_ptrs[tblno]; + if (qtblptr != NULL) { + for (i = 0; i < DCTSIZE; i++) { + for (j = 0; j < i; j++) { + qtemp = qtblptr->quantval[i * DCTSIZE + j]; + qtblptr->quantval[i * DCTSIZE + j] = qtblptr->quantval[j * DCTSIZE + i]; + qtblptr->quantval[j * DCTSIZE + i] = qtemp; + } + } + } + } +} /* Trim off any partial iMCUs on the indicated destination edge */ -LOCAL(void) -trim_right_edge (j_compress_ptr dstinfo) +LOCAL(void) trim_right_edge(j_compress_ptr dstinfo) { - int ci, max_h_samp_factor; - JDIMENSION MCU_cols; - - /* We have to compute max_h_samp_factor ourselves, - * because it hasn't been set yet in the destination - * (and we don't want to use the source's value). - */ - max_h_samp_factor = 1; - for (ci = 0; ci < dstinfo->num_components; ci++) { - int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; - max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); - } - MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); - if (MCU_cols > 0) /* can't trim to 0 pixels */ - dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); + int ci, max_h_samp_factor; + JDIMENSION MCU_cols; + + /* We have to compute max_h_samp_factor ourselves, + * because it hasn't been set yet in the destination + * (and we don't want to use the source's value). + */ + max_h_samp_factor = 1; + for (ci = 0; ci < dstinfo->num_components; ci++) { + int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor; + max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor); + } + MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE); + if (MCU_cols > 0) /* can't trim to 0 pixels */ + dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE); } -LOCAL(void) -trim_bottom_edge (j_compress_ptr dstinfo) +LOCAL(void) trim_bottom_edge(j_compress_ptr dstinfo) { - int ci, max_v_samp_factor; - JDIMENSION MCU_rows; - - /* We have to compute max_v_samp_factor ourselves, - * because it hasn't been set yet in the destination - * (and we don't want to use the source's value). - */ - max_v_samp_factor = 1; - for (ci = 0; ci < dstinfo->num_components; ci++) { - int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; - max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); - } - MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); - if (MCU_rows > 0) /* can't trim to 0 pixels */ - dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); + int ci, max_v_samp_factor; + JDIMENSION MCU_rows; + + /* We have to compute max_v_samp_factor ourselves, + * because it hasn't been set yet in the destination + * (and we don't want to use the source's value). + */ + max_v_samp_factor = 1; + for (ci = 0; ci < dstinfo->num_components; ci++) { + int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor; + max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor); + } + MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE); + if (MCU_rows > 0) /* can't trim to 0 pixels */ + dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE); } -LOCAL(void) -set_exif_orientation (JOCTET FAR * data, unsigned int length, - unsigned char new_orient) +LOCAL(void) set_exif_orientation(JOCTET FAR * data, unsigned int length, unsigned char new_orient) { - boolean is_motorola; /* Flag for byte order */ - unsigned int number_of_tags, tagnum; - unsigned int firstoffset, offset; - - if (length < 12) return; /* Length of an IFD entry */ - - /* Discover byte order */ - if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) - is_motorola = FALSE; - else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) - is_motorola = TRUE; - else - return; - - /* Check Tag Mark */ - if (is_motorola) { - if (GETJOCTET(data[2]) != 0) return; - if (GETJOCTET(data[3]) != 0x2A) return; - } else { - if (GETJOCTET(data[3]) != 0) return; - if (GETJOCTET(data[2]) != 0x2A) return; - } - - /* Get first IFD offset (offset to IFD0) */ - if (is_motorola) { - if (GETJOCTET(data[4]) != 0) return; - if (GETJOCTET(data[5]) != 0) return; - firstoffset = GETJOCTET(data[6]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[7]); - } else { - if (GETJOCTET(data[7]) != 0) return; - if (GETJOCTET(data[6]) != 0) return; - firstoffset = GETJOCTET(data[5]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[4]); - } - if (firstoffset > length - 2) return; /* check end of data segment */ - - /* Get the number of directory entries contained in this IFD */ - if (is_motorola) { - number_of_tags = GETJOCTET(data[firstoffset]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset+1]); - } else { - number_of_tags = GETJOCTET(data[firstoffset+1]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset]); - } - if (number_of_tags == 0) return; - firstoffset += 2; - - /* Search for Orientation offset Tag in IFD0 */ - for (;;) { - if (firstoffset > length - 12) return; /* check end of data segment */ - /* Get Tag number */ - if (is_motorola) { - tagnum = GETJOCTET(data[firstoffset]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset+1]); - } else { - tagnum = GETJOCTET(data[firstoffset+1]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset]); - } - if (tagnum == 0x0112) break; /* found Orientation Tag */ - if (--number_of_tags == 0) return; - firstoffset += 12; - } - - if (is_motorola) { - data[firstoffset+2] = 0; /* Format = unsigned short (2 octets) */ - data[firstoffset+3] = 3; - data[firstoffset+4] = 0; /* Number Of Components = 1 */ - data[firstoffset+5] = 0; - data[firstoffset+6] = 0; - data[firstoffset+7] = 1; - data[firstoffset+8] = 0; - data[firstoffset+9] = (unsigned char) new_orient; - data[firstoffset+10] = 0; - data[firstoffset+11] = 0; - } else { - data[firstoffset+2] = 3; /* Format = unsigned short (2 octets) */ - data[firstoffset+3] = 0; - data[firstoffset+4] = 1; /* Number Of Components = 1 */ - data[firstoffset+5] = 0; - data[firstoffset+6] = 0; - data[firstoffset+7] = 0; - data[firstoffset+8] = (unsigned char) new_orient; - data[firstoffset+9] = 0; - data[firstoffset+10] = 0; - data[firstoffset+11] = 0; - } + boolean is_motorola; /* Flag for byte order */ + unsigned int number_of_tags, tagnum; + unsigned int firstoffset, offset; + + if (length < 12) + return; /* Length of an IFD entry */ + + /* Discover byte order */ + if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) + is_motorola = FALSE; + else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) + is_motorola = TRUE; + else + return; + + /* Check Tag Mark */ + if (is_motorola) { + if (GETJOCTET(data[2]) != 0) + return; + if (GETJOCTET(data[3]) != 0x2A) + return; + } else { + if (GETJOCTET(data[3]) != 0) + return; + if (GETJOCTET(data[2]) != 0x2A) + return; + } + + /* Get first IFD offset (offset to IFD0) */ + if (is_motorola) { + if (GETJOCTET(data[4]) != 0) + return; + if (GETJOCTET(data[5]) != 0) + return; + firstoffset = GETJOCTET(data[6]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[7]); + } else { + if (GETJOCTET(data[7]) != 0) + return; + if (GETJOCTET(data[6]) != 0) + return; + firstoffset = GETJOCTET(data[5]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[4]); + } + if (firstoffset > length - 2) + return; /* check end of data segment */ + + /* Get the number of directory entries contained in this IFD */ + if (is_motorola) { + number_of_tags = GETJOCTET(data[firstoffset]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset + 1]); + } else { + number_of_tags = GETJOCTET(data[firstoffset + 1]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset]); + } + if (number_of_tags == 0) + return; + firstoffset += 2; + + /* Search for Orientation offset Tag in IFD0 */ + for (;;) { + if (firstoffset > length - 12) + return; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = GETJOCTET(data[firstoffset]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset + 1]); + } else { + tagnum = GETJOCTET(data[firstoffset + 1]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset]); + } + if (tagnum == 0x0112) + break; /* found Orientation Tag */ + if (--number_of_tags == 0) + return; + firstoffset += 12; + } + + if (is_motorola) { + data[firstoffset + 2] = 0; /* Format = unsigned short (2 octets) */ + data[firstoffset + 3] = 3; + data[firstoffset + 4] = 0; /* Number Of Components = 1 */ + data[firstoffset + 5] = 0; + data[firstoffset + 6] = 0; + data[firstoffset + 7] = 1; + data[firstoffset + 8] = 0; + data[firstoffset + 9] = (unsigned char) new_orient; + data[firstoffset + 10] = 0; + data[firstoffset + 11] = 0; + } else { + data[firstoffset + 2] = 3; /* Format = unsigned short (2 octets) */ + data[firstoffset + 3] = 0; + data[firstoffset + 4] = 1; /* Number Of Components = 1 */ + data[firstoffset + 5] = 0; + data[firstoffset + 6] = 0; + data[firstoffset + 7] = 0; + data[firstoffset + 8] = (unsigned char) new_orient; + data[firstoffset + 9] = 0; + data[firstoffset + 10] = 0; + data[firstoffset + 11] = 0; + } } /* Adjust Exif image parameters. @@ -834,158 +840,176 @@ set_exif_orientation (JOCTET FAR * data, unsigned int length, * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible. */ -LOCAL(void) -adjust_exif_parameters (JOCTET FAR * data, unsigned int length, - JDIMENSION new_width, JDIMENSION new_height) +LOCAL(void) adjust_exif_parameters(JOCTET FAR * data, unsigned int length, JDIMENSION new_width, JDIMENSION new_height) { - boolean is_motorola; /* Flag for byte order */ - unsigned int number_of_tags, tagnum; - unsigned int firstoffset, offset; - unsigned int new_orient; - JDIMENSION new_value; - - if (length < 12) return; /* Length of an IFD entry */ - - /* Discover byte order */ - if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) - is_motorola = FALSE; - else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) - is_motorola = TRUE; - else - return; - - /* Check Tag Mark */ - if (is_motorola) { - if (GETJOCTET(data[2]) != 0) return; - if (GETJOCTET(data[3]) != 0x2A) return; - } else { - if (GETJOCTET(data[3]) != 0) return; - if (GETJOCTET(data[2]) != 0x2A) return; - } - - /* Get first IFD offset (offset to IFD0) */ - if (is_motorola) { - if (GETJOCTET(data[4]) != 0) return; - if (GETJOCTET(data[5]) != 0) return; - firstoffset = GETJOCTET(data[6]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[7]); - } else { - if (GETJOCTET(data[7]) != 0) return; - if (GETJOCTET(data[6]) != 0) return; - firstoffset = GETJOCTET(data[5]); - firstoffset <<= 8; - firstoffset += GETJOCTET(data[4]); - } - if (firstoffset > length - 2) return; /* check end of data segment */ - - /* Get the number of directory entries contained in this IFD */ - if (is_motorola) { - number_of_tags = GETJOCTET(data[firstoffset]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset+1]); - } else { - number_of_tags = GETJOCTET(data[firstoffset+1]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[firstoffset]); - } - if (number_of_tags == 0) return; - firstoffset += 2; - - /* Search for ExifSubIFD offset Tag in IFD0 */ - for (;;) { - if (firstoffset > length - 12) return; /* check end of data segment */ - /* Get Tag number */ - if (is_motorola) { - tagnum = GETJOCTET(data[firstoffset]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset+1]); - } else { - tagnum = GETJOCTET(data[firstoffset+1]); - tagnum <<= 8; - tagnum += GETJOCTET(data[firstoffset]); - } - if (tagnum == 0x8769) break; /* found ExifSubIFD offset Tag */ - if (--number_of_tags == 0) return; - firstoffset += 12; - } - - /* Get the ExifSubIFD offset */ - if (is_motorola) { - if (GETJOCTET(data[firstoffset+8]) != 0) return; - if (GETJOCTET(data[firstoffset+9]) != 0) return; - offset = GETJOCTET(data[firstoffset+10]); - offset <<= 8; - offset += GETJOCTET(data[firstoffset+11]); - } else { - if (GETJOCTET(data[firstoffset+11]) != 0) return; - if (GETJOCTET(data[firstoffset+10]) != 0) return; - offset = GETJOCTET(data[firstoffset+9]); - offset <<= 8; - offset += GETJOCTET(data[firstoffset+8]); - } - if (offset > length - 2) return; /* check end of data segment */ - - /* Get the number of directory entries contained in this SubIFD */ - if (is_motorola) { - number_of_tags = GETJOCTET(data[offset]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[offset+1]); - } else { - number_of_tags = GETJOCTET(data[offset+1]); - number_of_tags <<= 8; - number_of_tags += GETJOCTET(data[offset]); - } - if (number_of_tags < 2) return; - offset += 2; - - /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ - do { - if (offset > length - 12) return; /* check end of data segment */ - /* Get Tag number */ - if (is_motorola) { - tagnum = GETJOCTET(data[offset]); - tagnum <<= 8; - tagnum += GETJOCTET(data[offset+1]); - } else { - tagnum = GETJOCTET(data[offset+1]); - tagnum <<= 8; - tagnum += GETJOCTET(data[offset]); - } - if (tagnum == 0xA002 || tagnum == 0xA003) { - if (tagnum == 0xA002) { - new_value = new_width; /* ExifImageWidth Tag */ - } else { - new_value = new_height; /* ExifImageHeight Tag */ - } - if (is_motorola) { - data[offset+2] = 0; /* Format = unsigned long (4 octets) */ - data[offset+3] = 4; - data[offset+4] = 0; /* Number Of Components = 1 */ - data[offset+5] = 0; - data[offset+6] = 0; - data[offset+7] = 1; - data[offset+8] = 0; - data[offset+9] = 0; - data[offset+10] = (JOCTET)((new_value >> 8) & 0xFF); - data[offset+11] = (JOCTET)(new_value & 0xFF); - } else { - data[offset+2] = 4; /* Format = unsigned long (4 octets) */ - data[offset+3] = 0; - data[offset+4] = 1; /* Number Of Components = 1 */ - data[offset+5] = 0; - data[offset+6] = 0; - data[offset+7] = 0; - data[offset+8] = (JOCTET)(new_value & 0xFF); - data[offset+9] = (JOCTET)((new_value >> 8) & 0xFF); - data[offset+10] = 0; - data[offset+11] = 0; - } - } - offset += 12; - } while (--number_of_tags); -} + boolean is_motorola; /* Flag for byte order */ + unsigned int number_of_tags, tagnum; + unsigned int firstoffset, offset; + unsigned int new_orient; + JDIMENSION new_value; + + if (length < 12) + return; /* Length of an IFD entry */ + + /* Discover byte order */ + if (GETJOCTET(data[0]) == 0x49 && GETJOCTET(data[1]) == 0x49) + is_motorola = FALSE; + else if (GETJOCTET(data[0]) == 0x4D && GETJOCTET(data[1]) == 0x4D) + is_motorola = TRUE; + else + return; + + /* Check Tag Mark */ + if (is_motorola) { + if (GETJOCTET(data[2]) != 0) + return; + if (GETJOCTET(data[3]) != 0x2A) + return; + } else { + if (GETJOCTET(data[3]) != 0) + return; + if (GETJOCTET(data[2]) != 0x2A) + return; + } + /* Get first IFD offset (offset to IFD0) */ + if (is_motorola) { + if (GETJOCTET(data[4]) != 0) + return; + if (GETJOCTET(data[5]) != 0) + return; + firstoffset = GETJOCTET(data[6]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[7]); + } else { + if (GETJOCTET(data[7]) != 0) + return; + if (GETJOCTET(data[6]) != 0) + return; + firstoffset = GETJOCTET(data[5]); + firstoffset <<= 8; + firstoffset += GETJOCTET(data[4]); + } + if (firstoffset > length - 2) + return; /* check end of data segment */ + + /* Get the number of directory entries contained in this IFD */ + if (is_motorola) { + number_of_tags = GETJOCTET(data[firstoffset]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset + 1]); + } else { + number_of_tags = GETJOCTET(data[firstoffset + 1]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[firstoffset]); + } + if (number_of_tags == 0) + return; + firstoffset += 2; + + /* Search for ExifSubIFD offset Tag in IFD0 */ + for (;;) { + if (firstoffset > length - 12) + return; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = GETJOCTET(data[firstoffset]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset + 1]); + } else { + tagnum = GETJOCTET(data[firstoffset + 1]); + tagnum <<= 8; + tagnum += GETJOCTET(data[firstoffset]); + } + if (tagnum == 0x8769) + break; /* found ExifSubIFD offset Tag */ + if (--number_of_tags == 0) + return; + firstoffset += 12; + } + + /* Get the ExifSubIFD offset */ + if (is_motorola) { + if (GETJOCTET(data[firstoffset + 8]) != 0) + return; + if (GETJOCTET(data[firstoffset + 9]) != 0) + return; + offset = GETJOCTET(data[firstoffset + 10]); + offset <<= 8; + offset += GETJOCTET(data[firstoffset + 11]); + } else { + if (GETJOCTET(data[firstoffset + 11]) != 0) + return; + if (GETJOCTET(data[firstoffset + 10]) != 0) + return; + offset = GETJOCTET(data[firstoffset + 9]); + offset <<= 8; + offset += GETJOCTET(data[firstoffset + 8]); + } + if (offset > length - 2) + return; /* check end of data segment */ + + /* Get the number of directory entries contained in this SubIFD */ + if (is_motorola) { + number_of_tags = GETJOCTET(data[offset]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[offset + 1]); + } else { + number_of_tags = GETJOCTET(data[offset + 1]); + number_of_tags <<= 8; + number_of_tags += GETJOCTET(data[offset]); + } + if (number_of_tags < 2) + return; + offset += 2; + + /* Search for ExifImageWidth and ExifImageHeight Tags in this SubIFD */ + do { + if (offset > length - 12) + return; /* check end of data segment */ + /* Get Tag number */ + if (is_motorola) { + tagnum = GETJOCTET(data[offset]); + tagnum <<= 8; + tagnum += GETJOCTET(data[offset + 1]); + } else { + tagnum = GETJOCTET(data[offset + 1]); + tagnum <<= 8; + tagnum += GETJOCTET(data[offset]); + } + if (tagnum == 0xA002 || tagnum == 0xA003) { + if (tagnum == 0xA002) { + new_value = new_width; /* ExifImageWidth Tag */ + } else { + new_value = new_height; /* ExifImageHeight Tag */ + } + if (is_motorola) { + data[offset + 2] = 0; /* Format = unsigned long (4 octets) */ + data[offset + 3] = 4; + data[offset + 4] = 0; /* Number Of Components = 1 */ + data[offset + 5] = 0; + data[offset + 6] = 0; + data[offset + 7] = 1; + data[offset + 8] = 0; + data[offset + 9] = 0; + data[offset + 10] = (JOCTET) ((new_value >> 8) & 0xFF); + data[offset + 11] = (JOCTET) (new_value & 0xFF); + } else { + data[offset + 2] = 4; /* Format = unsigned long (4 octets) */ + data[offset + 3] = 0; + data[offset + 4] = 1; /* Number Of Components = 1 */ + data[offset + 5] = 0; + data[offset + 6] = 0; + data[offset + 7] = 0; + data[offset + 8] = (JOCTET) (new_value & 0xFF); + data[offset + 9] = (JOCTET) ((new_value >> 8) & 0xFF); + data[offset + 10] = 0; + data[offset + 11] = 0; + } + } + offset += 12; + } while (--number_of_tags); +} /* Adjust output image parameters as needed. * @@ -999,117 +1023,110 @@ adjust_exif_parameters (JOCTET FAR * data, unsigned int length, */ GLOBAL(jvirt_barray_ptr *) -jtransform_adjust_parameters (j_decompress_ptr srcinfo, - j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jpeg_transform_info *info) + jtransform_adjust_parameters(j_decompress_ptr srcinfo, + j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info) { - jpeg_saved_marker_ptr marker; - /* If force-to-grayscale is requested, adjust destination parameters */ - if (info->force_grayscale) { - /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed - * properly. Among other things, the target h_samp_factor & v_samp_factor - * will get set to 1, which typically won't match the source. - * In fact we do this even if the source is already grayscale; that - * provides an easy way of coercing a grayscale JPEG with funny sampling - * factors to the customary 1,1. (Some decoders fail on other factors.) - */ - if ((dstinfo->jpeg_color_space == JCS_YCbCr && - dstinfo->num_components == 3) || - (dstinfo->jpeg_color_space == JCS_GRAYSCALE && - dstinfo->num_components == 1)) { - /* We have to preserve the source's quantization table number. */ - int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; - jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); - dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; - } else { - /* Sorry, can't do it */ - ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); - } - } - - /* Correct the destination's image dimensions etc if necessary */ - switch (info->transform) { - case JXFORM_NONE: - /* Nothing to do */ - break; - case JXFORM_FLIP_H: - if (info->trim) - trim_right_edge(dstinfo); - break; - case JXFORM_FLIP_V: - if (info->trim) - trim_bottom_edge(dstinfo); - break; - case JXFORM_TRANSPOSE: - transpose_critical_parameters(dstinfo); - /* transpose does NOT have to trim anything */ - break; - case JXFORM_TRANSVERSE: - transpose_critical_parameters(dstinfo); - if (info->trim) { - trim_right_edge(dstinfo); - trim_bottom_edge(dstinfo); - } - break; - case JXFORM_ROT_90: - transpose_critical_parameters(dstinfo); - if (info->trim) - trim_right_edge(dstinfo); - break; - case JXFORM_ROT_180: - if (info->trim) { - trim_right_edge(dstinfo); - trim_bottom_edge(dstinfo); - } - break; - case JXFORM_ROT_270: - transpose_critical_parameters(dstinfo); - if (info->trim) - trim_bottom_edge(dstinfo); - break; - } - - for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { - if (marker->marker != JPEG_APP0+1) - continue; - /* Adjust Exif properties */ - if (marker->marker == JPEG_APP0+1 && - marker->data_length >= 6 && - GETJOCTET(marker->data[0]) == 0x45 && - GETJOCTET(marker->data[1]) == 0x78 && - GETJOCTET(marker->data[2]) == 0x69 && - GETJOCTET(marker->data[3]) == 0x66 && - GETJOCTET(marker->data[4]) == 0 && - GETJOCTET(marker->data[5]) == 0) { - /* Suppress output of JFIF marker */ - dstinfo->write_JFIF_header = FALSE; - /* Adjust Exif image parameters */ - if (dstinfo->image_width != srcinfo->image_width || - dstinfo->image_height != srcinfo->image_height) - /* Align data segment to start of TIFF structure for parsing */ - adjust_exif_parameters(marker->data + 6, - marker->data_length - 6, - dstinfo->image_width, dstinfo->image_height); - /* I'm honestly not sure what the right thing to do is here.. The - * existing orientation tag may be incorrect, so making a change based - * on the previous value seems like the wrong thing to do. For now, I'm - * going to assume that the user is always "fixing" the orientation, - * i.e. putting the image the "right way up". In this case, we want to - * set the orientation to "top left". - */ - set_exif_orientation(marker->data + 6, - marker->data_length - 6, - 1); - } - } - - /* Return the appropriate output data set */ - if (info->workspace_coef_arrays != NULL) - return info->workspace_coef_arrays; - return src_coef_arrays; -} + jpeg_saved_marker_ptr marker; + /* If force-to-grayscale is requested, adjust destination parameters */ + if (info->force_grayscale) { + /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed + * properly. Among other things, the target h_samp_factor & v_samp_factor + * will get set to 1, which typically won't match the source. + * In fact we do this even if the source is already grayscale; that + * provides an easy way of coercing a grayscale JPEG with funny sampling + * factors to the customary 1,1. (Some decoders fail on other factors.) + */ + if ((dstinfo->jpeg_color_space == JCS_YCbCr && + dstinfo->num_components == 3) || + (dstinfo->jpeg_color_space == JCS_GRAYSCALE && dstinfo->num_components == 1)) { + /* We have to preserve the source's quantization table number. */ + int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no; + jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE); + dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no; + } else { + /* Sorry, can't do it */ + ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL); + } + } + /* Correct the destination's image dimensions etc if necessary */ + switch (info->transform) { + case JXFORM_NONE: + /* Nothing to do */ + break; + case JXFORM_FLIP_H: + if (info->trim) + trim_right_edge(dstinfo); + break; + case JXFORM_FLIP_V: + if (info->trim) + trim_bottom_edge(dstinfo); + break; + case JXFORM_TRANSPOSE: + transpose_critical_parameters(dstinfo); + /* transpose does NOT have to trim anything */ + break; + case JXFORM_TRANSVERSE: + transpose_critical_parameters(dstinfo); + if (info->trim) { + trim_right_edge(dstinfo); + trim_bottom_edge(dstinfo); + } + break; + case JXFORM_ROT_90: + transpose_critical_parameters(dstinfo); + if (info->trim) + trim_right_edge(dstinfo); + break; + case JXFORM_ROT_180: + if (info->trim) { + trim_right_edge(dstinfo); + trim_bottom_edge(dstinfo); + } + break; + case JXFORM_ROT_270: + transpose_critical_parameters(dstinfo); + if (info->trim) + trim_bottom_edge(dstinfo); + break; + } + + for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker->marker != JPEG_APP0 + 1) + continue; + /* Adjust Exif properties */ + if (marker->marker == JPEG_APP0 + 1 && + marker->data_length >= 6 && + GETJOCTET(marker->data[0]) == 0x45 && + GETJOCTET(marker->data[1]) == 0x78 && + GETJOCTET(marker->data[2]) == 0x69 && + GETJOCTET(marker->data[3]) == 0x66 && + GETJOCTET(marker->data[4]) == 0 && GETJOCTET(marker->data[5]) == 0) { + /* Suppress output of JFIF marker */ + dstinfo->write_JFIF_header = FALSE; + /* Adjust Exif image parameters */ + if (dstinfo->image_width != srcinfo->image_width || + dstinfo->image_height != srcinfo->image_height) + /* Align data segment to start of TIFF structure for parsing */ + adjust_exif_parameters(marker->data + 6, + marker->data_length - 6, + dstinfo->image_width, dstinfo->image_height); + /* I'm honestly not sure what the right thing to do is here.. The + * existing orientation tag may be incorrect, so making a change based + * on the previous value seems like the wrong thing to do. For now, I'm + * going to assume that the user is always "fixing" the orientation, + * i.e. putting the image the "right way up". In this case, we want to + * set the orientation to "top left". + */ + set_exif_orientation(marker->data + 6, marker->data_length - 6, 1); + } + } + + /* Return the appropriate output data set */ + if (info->workspace_coef_arrays != NULL) + return info->workspace_coef_arrays; + return src_coef_arrays; +} /* Execute the actual transformation, if any. * @@ -1121,63 +1138,62 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo, */ GLOBAL(void) -jtransform_execute_transformation (j_decompress_ptr srcinfo, - j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jpeg_transform_info *info) + + + jtransform_execute_transformation(j_decompress_ptr srcinfo, + j_compress_ptr dstinfo, + jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info) { - jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; - - switch (info->transform) { - case JXFORM_NONE: - break; - case JXFORM_FLIP_H: - do_flip_h(srcinfo, dstinfo, src_coef_arrays); - break; - case JXFORM_FLIP_V: - do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_TRANSPOSE: - do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_TRANSVERSE: - do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_ROT_90: - do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_ROT_180: - do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - case JXFORM_ROT_270: - do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); - break; - } + jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays; + + switch (info->transform) { + case JXFORM_NONE: + break; + case JXFORM_FLIP_H: + do_flip_h(srcinfo, dstinfo, src_coef_arrays); + break; + case JXFORM_FLIP_V: + do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSPOSE: + do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_TRANSVERSE: + do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_90: + do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_180: + do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + case JXFORM_ROT_270: + do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays); + break; + } } -#endif /* TRANSFORMS_SUPPORTED */ - +#endif /* TRANSFORMS_SUPPORTED */ /* Setup decompression object to save desired markers in memory. * This must be called before jpeg_read_header() to have the desired effect. */ -GLOBAL(void) -jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) +GLOBAL(void) jcopy_markers_setup(j_decompress_ptr srcinfo, JCOPY_OPTION option) { #ifdef SAVE_MARKERS_SUPPORTED - int m; - - /* Save comments except under NONE option */ - if (option != JCOPYOPT_NONE) { - jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); - } - /* Save all types of APPn markers iff ALL option */ - if (option == JCOPYOPT_ALL) { - for (m = 0; m < 16; m++) - jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); - } -#endif /* SAVE_MARKERS_SUPPORTED */ + int m; + + /* Save comments except under NONE option */ + if (option != JCOPYOPT_NONE) { + jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); + } + /* Save all types of APPn markers iff ALL option */ + if (option == JCOPYOPT_ALL) { + for (m = 0; m < 16; m++) + jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); + } +#endif /* SAVE_MARKERS_SUPPORTED */ } /* Copy markers saved in the given source object to the destination object. @@ -1187,47 +1203,42 @@ jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option) * JFIF APP0 or Adobe APP14 markers if selected. */ -GLOBAL(void) -jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - JCOPY_OPTION option) +GLOBAL(void) jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, JCOPY_OPTION option) { - jpeg_saved_marker_ptr marker; - - /* In the current implementation, we don't actually need to examine the - * option flag here; we just copy everything that got saved. - * But to avoid confusion, we do not output JFIF and Adobe APP14 markers - * if the encoder library already wrote one. - */ - for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { - if (dstinfo->write_JFIF_header && - marker->marker == JPEG_APP0 && - marker->data_length >= 5 && - GETJOCTET(marker->data[0]) == 0x4A && - GETJOCTET(marker->data[1]) == 0x46 && - GETJOCTET(marker->data[2]) == 0x49 && - GETJOCTET(marker->data[3]) == 0x46 && - GETJOCTET(marker->data[4]) == 0) - continue; /* reject duplicate JFIF */ - if (dstinfo->write_Adobe_marker && - marker->marker == JPEG_APP0+14 && - marker->data_length >= 5 && - GETJOCTET(marker->data[0]) == 0x41 && - GETJOCTET(marker->data[1]) == 0x64 && - GETJOCTET(marker->data[2]) == 0x6F && - GETJOCTET(marker->data[3]) == 0x62 && - GETJOCTET(marker->data[4]) == 0x65) - continue; /* reject duplicate Adobe */ + jpeg_saved_marker_ptr marker; + + /* In the current implementation, we don't actually need to examine the + * option flag here; we just copy everything that got saved. + * But to avoid confusion, we do not output JFIF and Adobe APP14 markers + * if the encoder library already wrote one. + */ + for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { + if (dstinfo->write_JFIF_header + && marker->marker == JPEG_APP0 + && marker->data_length >= 5 + && GETJOCTET(marker->data[0]) == 0x4A + && GETJOCTET(marker->data[1]) == 0x46 + && GETJOCTET(marker->data[2]) == 0x49 + && GETJOCTET(marker->data[3]) == 0x46 && GETJOCTET(marker->data[4]) == 0) + continue; /* reject duplicate JFIF */ + if (dstinfo->write_Adobe_marker && + marker->marker == JPEG_APP0 + 14 && + marker->data_length >= 5 && + GETJOCTET(marker->data[0]) == 0x41 && + GETJOCTET(marker->data[1]) == 0x64 && + GETJOCTET(marker->data[2]) == 0x6F && + GETJOCTET(marker->data[3]) == 0x62 && GETJOCTET(marker->data[4]) == 0x65) + continue; /* reject duplicate Adobe */ #ifdef NEED_FAR_POINTERS - /* We could use jpeg_write_marker if the data weren't FAR... */ - { - unsigned int i; - jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); - for (i = 0; i < marker->data_length; i++) - jpeg_write_m_byte(dstinfo, marker->data[i]); - } + /* We could use jpeg_write_marker if the data weren't FAR... */ + { + unsigned int i; + jpeg_write_m_header(dstinfo, marker->marker, marker->data_length); + for (i = 0; i < marker->data_length; i++) + jpeg_write_m_byte(dstinfo, marker->data[i]); + } #else - jpeg_write_marker(dstinfo, marker->marker, - marker->data, marker->data_length); + jpeg_write_marker(dstinfo, marker->marker, marker->data, marker->data_length); #endif - } + } } diff --git a/src/transupp.h b/src/transupp.h index 5c2d32a..056a282 100644 --- a/src/transupp.h +++ b/src/transupp.h @@ -19,7 +19,7 @@ /* If you happen not to want the image transform support, disable it here */ #ifndef TRANSFORMS_SUPPORTED -#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ +#define TRANSFORMS_SUPPORTED 1 /* 0 disables transform code */ #endif /* Short forms of external names for systems with brain-damaged linkers. */ @@ -30,8 +30,7 @@ #define jtransform_execute_transformation jTrExec #define jcopy_markers_setup jCMrkSetup #define jcopy_markers_execute jCMrkExec -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - +#endif /* NEED_SHORT_EXTERNAL_NAMES */ /* * Codes for supported types of image transformations. @@ -84,35 +83,28 @@ typedef enum { */ typedef struct { - /* Options: set by caller */ - JXFORM_CODE transform; /* image transform operator */ - boolean trim; /* if TRUE, trim partial MCUs as needed */ - boolean force_grayscale; /* if TRUE, convert color image to grayscale */ - - /* Internal workspace: caller should not touch these */ - int num_components; /* # of components in workspace */ - jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */ + /* Options: set by caller */ + JXFORM_CODE transform; /* image transform operator */ + boolean trim; /* if TRUE, trim partial MCUs as needed */ + boolean force_grayscale; /* if TRUE, convert color image to grayscale */ + + /* Internal workspace: caller should not touch these */ + int num_components; /* # of components in workspace */ + jvirt_barray_ptr *workspace_coef_arrays; /* workspace for transformations */ } jpeg_transform_info; - #if TRANSFORMS_SUPPORTED /* Request any required workspace */ -EXTERN(void) jtransform_request_workspace - JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info)); +EXTERN(void) jtransform_request_workspace JPP((j_decompress_ptr srcinfo, jpeg_transform_info * info)); /* Adjust output image parameters */ EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters - JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jpeg_transform_info *info)); +JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info)); /* Execute the actual transformation, if any */ EXTERN(void) jtransform_execute_transformation - JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - jvirt_barray_ptr *src_coef_arrays, - jpeg_transform_info *info)); - -#endif /* TRANSFORMS_SUPPORTED */ +JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, jvirt_barray_ptr * src_coef_arrays, jpeg_transform_info * info)); +#endif /* TRANSFORMS_SUPPORTED */ /* * Support for copying optional markers from source to destination file. @@ -127,9 +119,7 @@ typedef enum { #define JCOPYOPT_DEFAULT JCOPYOPT_COMMENTS /* recommended default */ /* Setup decompression object to save desired markers in memory */ -EXTERN(void) jcopy_markers_setup - JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); +EXTERN(void) +jcopy_markers_setup JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option)); /* Copy markers saved in the given source object to the destination object */ -EXTERN(void) jcopy_markers_execute - JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, - JCOPY_OPTION option)); +EXTERN(void) jcopy_markers_execute JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo, JCOPY_OPTION option)); diff --git a/src/utils.c b/src/utils.c index 7183b66..b74bc8c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -31,218 +31,207 @@ static char *feh_user_name = NULL; static char *feh_tmp_dir = NULL; /* eprintf: print error message and exit */ -void -eprintf(char *fmt, ...) +void eprintf(char *fmt, ...) { - va_list args; + va_list args; - fflush(stdout); - fprintf(stderr, "%s ERROR: ", PACKAGE); + fflush(stdout); + fprintf(stderr, "%s ERROR: ", PACKAGE); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); - if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') - fprintf(stderr, " %s", strerror(errno)); - fprintf(stderr, "\n"); - exit(2); + if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') + fprintf(stderr, " %s", strerror(errno)); + fprintf(stderr, "\n"); + exit(2); } /* weprintf: print warning message and continue */ -void -weprintf(char *fmt, ...) +void weprintf(char *fmt, ...) { - va_list args; + va_list args; - fflush(stdout); - fprintf(stderr, "%s WARNING: ", PACKAGE); + fflush(stdout); + fprintf(stderr, "%s WARNING: ", PACKAGE); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); - if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') - fprintf(stderr, " %s", strerror(errno)); - fprintf(stderr, "\n"); + if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') + fprintf(stderr, " %s", strerror(errno)); + fprintf(stderr, "\n"); } /* estrdup: duplicate a string, report if error */ -char * -_estrdup(char *s) +char *_estrdup(char *s) { - char *t; + char *t; - if (!s) - return NULL; + if (!s) + return NULL; - t = (char *) malloc(strlen(s) + 1); - if (t == NULL) - eprintf("estrdup(\"%.20s\") failed:", s); - strcpy(t, s); - return t; + t = (char *) malloc(strlen(s) + 1); + if (t == NULL) + eprintf("estrdup(\"%.20s\") failed:", s); + strcpy(t, s); + return t; } /* emalloc: malloc and report if error */ -void * -_emalloc(size_t n) +void *_emalloc(size_t n) { - void *p; + void *p; - p = malloc(n); - if (p == NULL) - eprintf("malloc of %u bytes failed:", n); - return p; + p = malloc(n); + if (p == NULL) + eprintf("malloc of %u bytes failed:", n); + return p; } /* erealloc: realloc and report if error */ -void * -_erealloc(void *ptr, size_t n) +void *_erealloc(void *ptr, size_t n) { - void *p; + void *p; - p = realloc(ptr, n); - if (p == NULL) - eprintf("realloc of %p by %u bytes failed:", ptr, n); - return p; + p = realloc(ptr, n); + if (p == NULL) + eprintf("realloc of %p by %u bytes failed:", ptr, n); + return p; } -char * -estrjoin(const char *separator, ...) +char *estrjoin(const char *separator, ...) { - char *string, *s; - va_list args; - int len; - int separator_len; - - if (separator == NULL) - separator = ""; - - separator_len = strlen(separator); - va_start(args, separator); - s = va_arg(args, char *); - - if (s) - { - len = strlen(s); - s = va_arg(args, char *); - - while (s) - { - len += separator_len + strlen(s); - s = va_arg(args, char *); - } - va_end(args); - string = malloc(sizeof(char) * (len + 1)); - - *string = 0; - va_start(args, separator); - s = va_arg(args, char *); - - strcat(string, s); - s = va_arg(args, char *); - - while (s) - { - strcat(string, separator); - strcat(string, s); - s = va_arg(args, char *); - } - } - else - string = estrdup(""); - va_end(args); - - return string; + char *string, *s; + va_list args; + int len; + int separator_len; + + if (separator == NULL) + separator = ""; + + separator_len = strlen(separator); + va_start(args, separator); + s = va_arg(args, char *); + + if (s) { + len = strlen(s); + s = va_arg(args, char *); + + while (s) { + len += separator_len + strlen(s); + s = va_arg(args, char *); + } + va_end(args); + string = malloc(sizeof(char) * (len + 1)); + + *string = 0; + va_start(args, separator); + s = va_arg(args, char *); + + strcat(string, s); + s = va_arg(args, char *); + + while (s) { + strcat(string, separator); + strcat(string, s); + s = va_arg(args, char *); + } + } else + string = estrdup(""); + va_end(args); + + return string; } -char * -stroflen(char c, int l) +char *stroflen(char c, int l) { - static char buf[1024]; - int i = 0; - - buf[0] = '\0'; - while (l--) - buf[i++] = c; - buf[i] = '\0'; - return buf; + static char buf[1024]; + int i = 0; + + buf[0] = '\0'; + while (l--) + buf[i++] = c; + buf[i] = '\0'; + return buf; } /* free the result please */ char *feh_unique_filename(char *path, char *basename) { - char *tmpname; - char num[10]; - char cppid[10]; - static long int i = 1; - struct stat st; - pid_t ppid; - - D_ENTER(4); - /* Massive paranoia ;) */ - if (i > 999998) - i = 1; - - ppid = getpid(); - snprintf(cppid, sizeof(cppid), "%06ld", (long)ppid); - - /* make sure file doesn't exist */ - do - { - snprintf(num, sizeof(num), "%06ld", i++); - tmpname = - estrjoin("", path, "feh_", cppid, "_", num, "_", - basename, NULL); - } - while (stat(tmpname, &st) == 0); - D_RETURN(4, tmpname); + char *tmpname; + char num[10]; + char cppid[10]; + static long int i = 1; + struct stat st; + pid_t ppid; + + D_ENTER(4); + /* Massive paranoia ;) */ + if (i > 999998) + i = 1; + + ppid = getpid(); + snprintf(cppid, sizeof(cppid), "%06ld", (long) ppid); + + /* make sure file doesn't exist */ + do { + snprintf(num, sizeof(num), "%06ld", i++); + tmpname = estrjoin("", path, "feh_", cppid, "_", num, "_", basename, NULL); + } + while (stat(tmpname, &st) == 0); + D_RETURN(4, tmpname); } /* reads file into a string, but limits o 4095 chars and ensures a \0 */ -char *ereadfile(char *path) { - char buffer[4096]; - FILE *fp; - int count; - - fp = fopen(path, "r"); - if (!fp) - return NULL; - - count = fread(buffer, sizeof(char), sizeof(buffer) - 1, fp); - if (buffer[count - 1] == '\n') - buffer[count - 1] = '\0'; - else - buffer[count] = '\0'; - - fclose(fp); - - return estrdup(buffer); -} +char *ereadfile(char *path) +{ + char buffer[4096]; + FILE *fp; + int count; + + fp = fopen(path, "r"); + if (!fp) + return NULL; + + count = fread(buffer, sizeof(char), sizeof(buffer) - 1, fp); + if (buffer[count - 1] == '\n') + buffer[count - 1] = '\0'; + else + buffer[count] = '\0'; -char *feh_get_tmp_dir(void) { - char *tmp; - if (feh_tmp_dir) - return feh_tmp_dir; - tmp = getenv("TMPDIR"); - if (!tmp) - tmp = getenv("TMP"); - if (!tmp) - tmp = getenv("TEMP"); - if (!tmp) - tmp = "/tmp"; - feh_tmp_dir = estrdup(tmp); - return feh_tmp_dir; + fclose(fp); + + return estrdup(buffer); } -char *feh_get_user_name(void) { - struct passwd *pw = NULL; +char *feh_get_tmp_dir(void) +{ + char *tmp; + if (feh_tmp_dir) + return feh_tmp_dir; + tmp = getenv("TMPDIR"); + if (!tmp) + tmp = getenv("TMP"); + if (!tmp) + tmp = getenv("TEMP"); + if (!tmp) + tmp = "/tmp"; + feh_tmp_dir = estrdup(tmp); + return feh_tmp_dir; +} - if (feh_user_name) - return feh_user_name; - setpwent (); - pw = getpwuid (getuid ()); - endpwent (); - feh_user_name = estrdup(pw->pw_name); - return feh_user_name; +char *feh_get_user_name(void) +{ + struct passwd *pw = NULL; + + if (feh_user_name) + return feh_user_name; + setpwent(); + pw = getpwuid(getuid()); + endpwent(); + feh_user_name = estrdup(pw->pw_name); + return feh_user_name; } diff --git a/src/utils.h b/src/utils.h index 221319c..d0d7665 100644 --- a/src/utils.h +++ b/src/utils.h @@ -74,7 +74,7 @@ char *feh_get_user_name(void); (a) = ____newstr;\ }\ } - + #define ESTRTRUNC(string,chars) \ {\ int ____len;\ @@ -86,5 +86,4 @@ char *feh_get_user_name(void); }\ } - #endif diff --git a/src/winwidget.c b/src/winwidget.c index c494123..dd0adbb 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -32,1068 +32,994 @@ static void winwidget_unregister(winwidget win); static void winwidget_register(winwidget win); static winwidget winwidget_allocate(void); -static char bm_no_data[] = { 0,0,0,0, 0,0,0,0 }; -int window_num = 0; /* For window list */ -winwidget *windows = NULL; /* List of windows to loop though */ +static char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static winwidget -winwidget_allocate(void) +int window_num = 0; /* For window list */ +winwidget *windows = NULL; /* List of windows to loop though */ + +static winwidget winwidget_allocate(void) { - winwidget ret = NULL; - - D_ENTER(4); - ret = emalloc(sizeof(_winwidget)); - - ret->win = 0; - ret->w = 0; - ret->h = 0; - ret->full_screen = 0; - ret->im_w = 0; - ret->im_h = 0; - ret->im_angle = 0; - ret->bg_pmap = 0; - ret->bg_pmap_cache = 0; - ret->im = NULL; - ret->name = NULL; - ret->file = NULL; - ret->type = WIN_TYPE_UNSET; - ret->visible = 0; - ret->caption_entry = 0; - - /* Zoom stuff */ - ret->mode = MODE_NORMAL; - - ret->gc = None; - - /* New stuff */ - ret->im_x = 0; - ret->im_y = 0; - ret->zoom = 1.0; - - ret->click_offset_x = 0; - ret->click_offset_y = 0; - ret->im_click_offset_x = 0; - ret->im_click_offset_y = 0; - ret->has_rotated = 0; - - D_RETURN(4, ret); + winwidget ret = NULL; + + D_ENTER(4); + ret = emalloc(sizeof(_winwidget)); + + ret->win = 0; + ret->w = 0; + ret->h = 0; + ret->full_screen = 0; + ret->im_w = 0; + ret->im_h = 0; + ret->im_angle = 0; + ret->bg_pmap = 0; + ret->bg_pmap_cache = 0; + ret->im = NULL; + ret->name = NULL; + ret->file = NULL; + ret->type = WIN_TYPE_UNSET; + ret->visible = 0; + ret->caption_entry = 0; + + /* Zoom stuff */ + ret->mode = MODE_NORMAL; + + ret->gc = None; + + /* New stuff */ + ret->im_x = 0; + ret->im_y = 0; + ret->zoom = 1.0; + + ret->click_offset_x = 0; + ret->click_offset_y = 0; + ret->im_click_offset_x = 0; + ret->im_click_offset_y = 0; + ret->has_rotated = 0; + + D_RETURN(4, ret); } -winwidget -winwidget_create_from_image(Imlib_Image im, - char *name, - char type) +winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type) { - winwidget ret = NULL; + winwidget ret = NULL; - D_ENTER(4); + D_ENTER(4); - if (im == NULL) - D_RETURN(4, NULL); + if (im == NULL) + D_RETURN(4, NULL); - ret = winwidget_allocate(); - ret->type = type; + ret = winwidget_allocate(); + ret->type = type; - ret->im = im; - ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); - ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); + ret->im = im; + ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); + ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); - if (name) - ret->name = estrdup(name); - else - ret->name = estrdup(PACKAGE); + if (name) + ret->name = estrdup(name); + else + ret->name = estrdup(PACKAGE); - if (opt.full_screen) - ret->full_screen = True; - winwidget_create_window(ret, ret->w, ret->h); - winwidget_render_image(ret, 1, 1); + if (opt.full_screen) + ret->full_screen = True; + winwidget_create_window(ret, ret->w, ret->h); + winwidget_render_image(ret, 1, 1); - D_RETURN(4, ret); + D_RETURN(4, ret); } -winwidget -winwidget_create_from_file(gib_list * list, - char *name, - char type) +winwidget winwidget_create_from_file(gib_list * list, char *name, char type) { - winwidget ret = NULL; - feh_file *file = FEH_FILE(list->data); - - D_ENTER(4); - - if (!file || !file->filename) - D_RETURN(4, NULL); - - ret = winwidget_allocate(); - ret->file = list; - ret->type = type; - if (name) - ret->name = estrdup(name); - else - ret->name = estrdup(file->filename); - - if (winwidget_loadimage(ret, file) == 0) { - winwidget_destroy(ret); - D_RETURN(4, NULL); - } - - if (!ret->win) { - ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); - ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); - D(3, - ("image is %dx%d pixels, format %s\n", ret->w, ret->h, - gib_imlib_image_format(ret->im))); - if (opt.full_screen) - ret->full_screen = True; - winwidget_create_window(ret, ret->w, ret->h); - winwidget_render_image(ret, 1, 1); - } - - D_RETURN(4, ret); + winwidget ret = NULL; + feh_file *file = FEH_FILE(list->data); + + D_ENTER(4); + + if (!file || !file->filename) + D_RETURN(4, NULL); + + ret = winwidget_allocate(); + ret->file = list; + ret->type = type; + if (name) + ret->name = estrdup(name); + else + ret->name = estrdup(file->filename); + + if (winwidget_loadimage(ret, file) == 0) { + winwidget_destroy(ret); + D_RETURN(4, NULL); + } + + if (!ret->win) { + ret->w = ret->im_w = gib_imlib_image_get_width(ret->im); + ret->h = ret->im_h = gib_imlib_image_get_height(ret->im); + D(3, ("image is %dx%d pixels, format %s\n", ret->w, ret->h, gib_imlib_image_format(ret->im))); + if (opt.full_screen) + ret->full_screen = True; + winwidget_create_window(ret, ret->w, ret->h); + winwidget_render_image(ret, 1, 1); + } + + D_RETURN(4, ret); } -void -winwidget_create_window(winwidget ret, - int w, - int h) +void winwidget_create_window(winwidget ret, int w, int h) { - XSetWindowAttributes attr; - XEvent ev; - XClassHint *xch; - MWMHints mwmhints; - Atom prop = None; - int x = 0; - int y = 0; + XSetWindowAttributes attr; + XEvent ev; + XClassHint *xch; + MWMHints mwmhints; + Atom prop = None; + int x = 0; + int y = 0; - D_ENTER(4); + D_ENTER(4); - if (ret->full_screen) { - w = scr->width; - h = scr->height; + if (ret->full_screen) { + w = scr->width; + h = scr->height; #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - w = xinerama_screens[xinerama_screen].width; - h = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - } else if (opt.geom_flags) { - if (opt.geom_flags & WidthValue) { - w = opt.geom_w; - } - if (opt.geom_flags & HeightValue) { - h = opt.geom_h; - } - if (opt.geom_flags & XValue) { - if (opt.geom_flags & XNegative) { - x = scr->width - opt.geom_x; - } else { - x = opt.geom_x; - } - } - if (opt.geom_flags & YValue) { - if (opt.geom_flags & YNegative) { - y = scr->height - opt.geom_y; - } else { - y = opt.geom_y; - } - } - } else if (opt.screen_clip) { - if (w > scr->width) - w = scr->width; - if (h > scr->height) - h = scr->height; + if (opt.xinerama && xinerama_screens) { + w = xinerama_screens[xinerama_screen].width; + h = xinerama_screens[xinerama_screen].height; + } +#endif /* HAVE_LIBXINERAMA */ + } else if (opt.geom_flags) { + if (opt.geom_flags & WidthValue) { + w = opt.geom_w; + } + if (opt.geom_flags & HeightValue) { + h = opt.geom_h; + } + if (opt.geom_flags & XValue) { + if (opt.geom_flags & XNegative) { + x = scr->width - opt.geom_x; + } else { + x = opt.geom_x; + } + } + if (opt.geom_flags & YValue) { + if (opt.geom_flags & YNegative) { + y = scr->height - opt.geom_y; + } else { + y = opt.geom_y; + } + } + } else if (opt.screen_clip) { + if (w > scr->width) + w = scr->width; + if (h > scr->height) + h = scr->height; #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - if (w > xinerama_screens[xinerama_screen].width) - w = xinerama_screens[xinerama_screen].width; - if (h > xinerama_screens[xinerama_screen].height) - h = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - } - - ret->x = x; - ret->y = y; - ret->w = w; - ret->h = h; - ret->visible = False; - - attr.backing_store = NotUseful; - attr.override_redirect = False; - attr.colormap = cm; - attr.border_pixel = 0; - attr.background_pixel = 0; - attr.save_under = False; - attr.event_mask = - StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | EnterWindowMask | LeaveWindowMask | KeyPressMask | - KeyReleaseMask | ButtonMotionMask | ExposureMask | FocusChangeMask | - PropertyChangeMask | VisibilityChangeMask; - - if (opt.borderless || ret->full_screen) { - prop = XInternAtom(disp, "_MOTIF_WM_HINTS", True); - if (prop == None) { - weprintf("Window Manager does not support MWM hints. " - "To get a borderless window I have to bypass your wm."); - attr.override_redirect = True; - mwmhints.flags = 0; - } else { - mwmhints.flags = MWM_HINTS_DECORATIONS; - mwmhints.decorations = 0; - } - } else - mwmhints.flags = 0; - - ret->win = - XCreateWindow(disp, DefaultRootWindow(disp), x, y, w, h, 0, depth, - InputOutput, vis, - CWOverrideRedirect | CWSaveUnder | CWBackingStore | - CWColormap | CWBackPixel | CWBorderPixel | CWEventMask, - &attr); - - if (mwmhints.flags) { - XChangeProperty(disp, ret->win, prop, prop, 32, PropModeReplace, - (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS); - } - if (ret->full_screen) { - Atom prop_fs = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False); - Atom prop_state = XInternAtom(disp, "_NET_WM_STATE", False); - - memset(&ev, 0, sizeof(ev)); - ev.xclient.type = ClientMessage; - ev.xclient.message_type = prop_state; - ev.xclient.display = disp; - ev.xclient.window = ret->win; - ev.xclient.format = 32; - ev.xclient.data.l[0] = (ret->full_screen ? 1 : 0); - ev.xclient.data.l[1] = prop_fs; - - XChangeProperty(disp, ret->win, prop_state, XA_ATOM, 32, - PropModeReplace, &prop_fs, 1); - } - - XSetWMProtocols(disp, ret->win, &wmDeleteWindow, 1); - winwidget_update_title(ret); - xch = XAllocClassHint(); - xch->res_name = "feh"; - xch->res_class = "feh"; - XSetClassHint(disp, ret->win, xch); - XFree(xch); - - /* Size hints */ - if (ret->full_screen || opt.geom_flags) { - XSizeHints xsz; - - xsz.flags = USPosition; - xsz.x = x; - xsz.y = y; - XSetWMNormalHints(disp, ret->win, &xsz); - XMoveWindow(disp, ret->win, x, y); - } - if (ret->full_screen && opt.hide_pointer) { - Cursor no_ptr; - XColor black, dummy; - Pixmap bm_no; - bm_no = XCreateBitmapFromData(disp, ret->win, bm_no_data, 8, 8); - XAllocNamedColor(disp, DefaultColormapOfScreen(DefaultScreenOfDisplay(disp)), "black", &black, &dummy); - - no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); - XDefineCursor(disp, ret->win, no_ptr); - } - - /* set the icon name property */ - XSetIconName(disp, ret->win, "feh"); - /* set the command hint */ - XSetCommand(disp, ret->win, cmdargv, cmdargc); - - winwidget_register(ret); - D_RETURN_(4); + if (opt.xinerama && xinerama_screens) { + if (w > xinerama_screens[xinerama_screen].width) + w = xinerama_screens[xinerama_screen].width; + if (h > xinerama_screens[xinerama_screen].height) + h = xinerama_screens[xinerama_screen].height; + } +#endif /* HAVE_LIBXINERAMA */ + } + + ret->x = x; + ret->y = y; + ret->w = w; + ret->h = h; + ret->visible = False; + + attr.backing_store = NotUseful; + attr.override_redirect = False; + attr.colormap = cm; + attr.border_pixel = 0; + attr.background_pixel = 0; + attr.save_under = False; + attr.event_mask = + StructureNotifyMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | EnterWindowMask | LeaveWindowMask | + KeyPressMask | KeyReleaseMask | ButtonMotionMask | ExposureMask + | FocusChangeMask | PropertyChangeMask | VisibilityChangeMask; + + if (opt.borderless || ret->full_screen) { + prop = XInternAtom(disp, "_MOTIF_WM_HINTS", True); + if (prop == None) { + weprintf + ("Window Manager does not support MWM hints. " + "To get a borderless window I have to bypass your wm."); + attr.override_redirect = True; + mwmhints.flags = 0; + } else { + mwmhints.flags = MWM_HINTS_DECORATIONS; + mwmhints.decorations = 0; + } + } else + mwmhints.flags = 0; + + ret->win = + XCreateWindow(disp, DefaultRootWindow(disp), x, y, w, h, 0, + depth, InputOutput, vis, + CWOverrideRedirect | CWSaveUnder | CWBackingStore + | CWColormap | CWBackPixel | CWBorderPixel | CWEventMask, &attr); + + if (mwmhints.flags) { + XChangeProperty(disp, ret->win, prop, prop, 32, + PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS); + } + if (ret->full_screen) { + Atom prop_fs = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False); + Atom prop_state = XInternAtom(disp, "_NET_WM_STATE", False); + + memset(&ev, 0, sizeof(ev)); + ev.xclient.type = ClientMessage; + ev.xclient.message_type = prop_state; + ev.xclient.display = disp; + ev.xclient.window = ret->win; + ev.xclient.format = 32; + ev.xclient.data.l[0] = (ret->full_screen ? 1 : 0); + ev.xclient.data.l[1] = prop_fs; + + XChangeProperty(disp, ret->win, prop_state, XA_ATOM, 32, PropModeReplace, &prop_fs, 1); + } + + XSetWMProtocols(disp, ret->win, &wmDeleteWindow, 1); + winwidget_update_title(ret); + xch = XAllocClassHint(); + xch->res_name = "feh"; + xch->res_class = "feh"; + XSetClassHint(disp, ret->win, xch); + XFree(xch); + + /* Size hints */ + if (ret->full_screen || opt.geom_flags) { + XSizeHints xsz; + + xsz.flags = USPosition; + xsz.x = x; + xsz.y = y; + XSetWMNormalHints(disp, ret->win, &xsz); + XMoveWindow(disp, ret->win, x, y); + } + if (ret->full_screen && opt.hide_pointer) { + Cursor no_ptr; + XColor black, dummy; + Pixmap bm_no; + bm_no = XCreateBitmapFromData(disp, ret->win, bm_no_data, 8, 8); + XAllocNamedColor(disp, DefaultColormapOfScreen(DefaultScreenOfDisplay(disp)), "black", &black, &dummy); + + no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); + XDefineCursor(disp, ret->win, no_ptr); + } + + /* set the icon name property */ + XSetIconName(disp, ret->win, "feh"); + /* set the command hint */ + XSetCommand(disp, ret->win, cmdargv, cmdargc); + + winwidget_register(ret); + D_RETURN_(4); } -void -winwidget_update_title(winwidget ret) +void winwidget_update_title(winwidget ret) { - char *name; - - D_ENTER(4); - D(4, ("winwid->name = %s\n", ret->name)); - name = ret->name ? ret->name : "feh"; - XStoreName(disp, ret->win, name); - XSetIconName(disp, ret->win, name); - /* XFlush(disp); */ - D_RETURN_(4); + char *name; + + D_ENTER(4); + D(4, ("winwid->name = %s\n", ret->name)); + name = ret->name ? ret->name : "feh"; + XStoreName(disp, ret->win, name); + XSetIconName(disp, ret->win, name); + /* XFlush(disp); */ + D_RETURN_(4); } -void -winwidget_setup_pixmaps(winwidget winwid) +void winwidget_setup_pixmaps(winwidget winwid) { - D_ENTER(4); - - if (winwid->full_screen) { - if (!(winwid->bg_pmap)) { - if (winwid->gc == None) { - XGCValues gcval; - - gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); - winwid->gc = XCreateGC(disp, winwid->win, GCForeground, &gcval); - } - winwid->bg_pmap = - XCreatePixmap(disp, winwid->win, scr->width, scr->height, depth); - } - XFillRectangle(disp, winwid->bg_pmap, winwid->gc, 0, 0, scr->width, - scr->height); - } else { - if (!winwid->bg_pmap || winwid->had_resize) { - D(4, ("recreating background pixmap (%dx%d)\n", winwid->w, winwid->h)); - if (winwid->bg_pmap) - XFreePixmap(disp, winwid->bg_pmap); - - if (winwid->w == 0) - winwid->w = 1; - if (winwid->h == 0) - winwid->h = 1; - winwid->bg_pmap = - XCreatePixmap(disp, winwid->win, winwid->w, winwid->h, depth); - winwid->had_resize = 0; - } - } - D_RETURN_(4); + D_ENTER(4); + + if (winwid->full_screen) { + if (!(winwid->bg_pmap)) { + if (winwid->gc == None) { + XGCValues gcval; + + gcval.foreground = BlackPixel(disp, DefaultScreen(disp)); + winwid->gc = XCreateGC(disp, winwid->win, GCForeground, &gcval); + } + winwid->bg_pmap = XCreatePixmap(disp, winwid->win, scr->width, scr->height, depth); + } + XFillRectangle(disp, winwid->bg_pmap, winwid->gc, 0, 0, scr->width, scr->height); + } else { + if (!winwid->bg_pmap || winwid->had_resize) { + D(4, ("recreating background pixmap (%dx%d)\n", winwid->w, winwid->h)); + if (winwid->bg_pmap) + XFreePixmap(disp, winwid->bg_pmap); + + if (winwid->w == 0) + winwid->w = 1; + if (winwid->h == 0) + winwid->h = 1; + winwid->bg_pmap = XCreatePixmap(disp, winwid->win, winwid->w, winwid->h, depth); + winwid->had_resize = 0; + } + } + D_RETURN_(4); } -void -winwidget_render_image(winwidget winwid, - int resize, - int alias) +void winwidget_render_image(winwidget winwid, int resize, int alias) { - int sx, sy, sw, sh, dx, dy, dw, dh; - int calc_w, calc_h; - - D_ENTER(4); - - if (!winwid->full_screen && resize) { - winwidget_resize(winwid, winwid->im_w, winwid->im_h); - winwidget_reset_image(winwid); - } - - /* bounds checks for panning */ - if (winwid->im_x > winwid->w) - winwid->im_x = winwid->w; - if (winwid->im_y > winwid->h) - winwid->im_y = winwid->h; - - winwidget_setup_pixmaps(winwid); - - if (!winwid->full_screen - && ((gib_imlib_image_has_alpha(winwid->im)) || (opt.geom_flags) - || (winwid->im_x || winwid->im_y) || (winwid->zoom != 1.0) - || (winwid->w > winwid->im_w || winwid->h > winwid->im_h) - || (winwid->has_rotated))) - feh_draw_checks(winwid); - - if (!winwid->full_screen && opt.scale_down - && ((winwid->w < winwid->im_w) || (winwid->h < winwid->im_h))) { - D(2, ("scaling down image\n")); - - feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, - winwid->w, winwid->h); - winwidget_resize(winwid, winwid->im_w * winwid->zoom, - winwid->im_h * winwid->zoom); - } - - if (resize && (winwid->full_screen || opt.geom_flags)) { - int smaller; /* Is the image smaller than screen? */ - int max_w, max_h; - - if (winwid->full_screen) { - max_w = scr->width; - max_h = scr->height; + int sx, sy, sw, sh, dx, dy, dw, dh; + int calc_w, calc_h; + + D_ENTER(4); + + if (!winwid->full_screen && resize) { + winwidget_resize(winwid, winwid->im_w, winwid->im_h); + winwidget_reset_image(winwid); + } + + /* bounds checks for panning */ + if (winwid->im_x > winwid->w) + winwid->im_x = winwid->w; + if (winwid->im_y > winwid->h) + winwid->im_y = winwid->h; + + winwidget_setup_pixmaps(winwid); + + if (!winwid->full_screen && ((gib_imlib_image_has_alpha(winwid->im)) || (opt.geom_flags) + || (winwid->im_x || winwid->im_y) || (winwid->zoom != 1.0) + || (winwid->w > winwid->im_w || winwid->h > winwid->im_h) + || (winwid->has_rotated))) + feh_draw_checks(winwid); + + if (!winwid->full_screen && opt.scale_down && ((winwid->w < winwid->im_w) + || (winwid->h < winwid->im_h))) { + D(2, ("scaling down image\n")); + + feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, winwid->w, winwid->h); + winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom); + } + + if (resize && (winwid->full_screen || opt.geom_flags)) { + int smaller; /* Is the image smaller than screen? */ + int max_w, max_h; + + if (winwid->full_screen) { + max_w = scr->width; + max_h = scr->height; #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - max_w = xinerama_screens[xinerama_screen].width; - max_h = xinerama_screens[xinerama_screen].height; - } -#endif /* HAVE_LIBXINERAMA */ - } else { - if (opt.geom_flags & WidthValue) { - max_w = opt.geom_w; - } - if (opt.geom_flags & HeightValue) { - max_h = opt.geom_h; - } - } - - D(4, ("Calculating for fullscreen/fixed geom render\n")); - smaller = ((winwid->im_w < max_w) && (winwid->im_h < max_h)); - - if (!smaller || opt.auto_zoom) { - double ratio = 0.0; - - /* Image is larger than the screen (so wants shrinking), or it's - smaller but wants expanding to fill it */ - ratio = - feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, - max_w, max_h); - - /* contributed by Jens Laas <jens.laas@data.slu.se> - * What it does: - * zooms images by a fixed amount but never larger than the screen. - * - * Why: - * This is nice if you got a collection of images where some - * are small and can stand a small zoom. Large images are unaffected. - * - * When does it work, and how? - * You have to be in fullscreen mode _and_ have auto-zoom turned on. - * "feh -FZ --zoom 130 imagefile" will do the trick. - * -zoom percent - the new switch. - * 100 = orignal size, - * 130 is 30% larger. - */ - if (opt.default_zoom) { - double old_zoom = winwid->zoom; - - winwid->zoom = 0.01 * opt.default_zoom; - if ((winwid->im_h * winwid->zoom) > max_h) - winwid->zoom = old_zoom; - if ((winwid->im_w * winwid->zoom) > max_w) - winwid->zoom = old_zoom; - - winwid->im_x = ((int) (max_w - (winwid->im_w * winwid->zoom))) >> 1; - winwid->im_y = ((int) (max_h - (winwid->im_h * winwid->zoom))) >> 1; - } else { - if (ratio > 1.0) { - /* height is the factor */ - winwid->im_x = 0; - winwid->im_y = ((int) (max_h - (winwid->im_h * winwid->zoom))) >> 1; - } else { - /* width is the factor */ - winwid->im_x = ((int) (max_w - (winwid->im_w * winwid->zoom))) >> 1; - winwid->im_y = 0; - } - } - } else { - /* my modification to jens hack, allow --zoom without auto-zoom mode */ - if(opt.default_zoom) { - winwid->zoom = 0.01 * opt.default_zoom; - } else { - winwid->zoom = 1.0; - } - /* Just center the image in the window */ - winwid->im_x = (int)(max_w - (winwid->im_w * winwid->zoom)) >> 1; - winwid->im_y = (int)(max_h - (winwid->im_h * winwid->zoom)) >> 1; - } - } - - /* Now we ensure only to render the area we're looking at */ - dx = winwid->im_x; - dy = winwid->im_y; - if (dx < 0) - dx = 0; - if (dy < 0) - dy = 0; - - if (winwid->im_x < 0) - sx = 0 - (winwid->im_x / winwid->zoom); - else - sx = 0; - - if (winwid->im_y < 0) - sy = 0 - (winwid->im_y / winwid->zoom); - else - sy = 0; - - calc_w = winwid->im_w * winwid->zoom; - calc_h = winwid->im_h * winwid->zoom; - dw = (winwid->w - winwid->im_x); - dh = (winwid->h - winwid->im_y); - if (calc_w < dw) - dw = calc_w; - if (calc_h < dh) - dh = calc_h; - if (dw > winwid->w) - dw = winwid->w; - if (dh > winwid->h) - dh = winwid->h; - - sw = dw / winwid->zoom; - sh = dh / winwid->zoom; - - D(5, - ("sx: %d sy: %d sw: %d sh: %d dx: %d dy: %d dw: %d dh: %d zoom: %f\n", sx, - sy, sw, sh, dx, dy, dw, dh, winwid->zoom)); - - D(5, ("winwidget_render(): winwid->im_angle = %f\n", winwid->im_angle)); - if (winwid->has_rotated) - gib_imlib_render_image_part_on_drawable_at_size_with_rotation(winwid-> - bg_pmap, - winwid->im, - sx, sy, sw, - sh, dx, dy, - dw, dh, - winwid-> - im_angle, 1, - 1, alias); - else - gib_imlib_render_image_part_on_drawable_at_size(winwid->bg_pmap, - winwid->im, sx, sy, sw, - sh, dx, dy, dw, dh, 1, - gib_imlib_image_has_alpha - (winwid->im), alias); - if (opt.caption_path) { - /* cache bg pixmap. during caption entry, multiple redraws are done - * because the caption overlay changes - the image doesn't though, so re- - * rendering that is a waste of time */ - if (winwid->caption_entry) { - GC gc; - if (winwid->bg_pmap_cache) - XFreePixmap(disp, winwid->bg_pmap_cache); - winwid->bg_pmap_cache = XCreatePixmap(disp, - winwid->win, - winwid->w, - winwid->h, - depth); - gc = XCreateGC(disp, winwid->win, 0, NULL); - XCopyArea(disp, winwid->bg_pmap, winwid->bg_pmap_cache, gc, 0, 0, winwid->w, winwid->h, 0, 0); - XFreeGC(disp, gc); - } - feh_draw_caption(winwid); - } - - if (opt.draw_filename) - feh_draw_filename(winwid); - if (opt.draw_actions) - feh_draw_actions(winwid); - if ((opt.mode == MODE_ZOOM) && !alias) - feh_draw_zoom(winwid); - XSetWindowBackgroundPixmap(disp, winwid->win, winwid->bg_pmap); - XClearWindow(disp, winwid->win); - D_RETURN_(4); + if (opt.xinerama && xinerama_screens) { + max_w = xinerama_screens[xinerama_screen].width; + max_h = xinerama_screens[xinerama_screen].height; + } +#endif /* HAVE_LIBXINERAMA */ + } else { + if (opt.geom_flags & WidthValue) { + max_w = opt.geom_w; + } + if (opt.geom_flags & HeightValue) { + max_h = opt.geom_h; + } + } + + D(4, ("Calculating for fullscreen/fixed geom render\n")); + smaller = ((winwid->im_w < max_w) + && (winwid->im_h < max_h)); + + if (!smaller || opt.auto_zoom) { + double ratio = 0.0; + + /* Image is larger than the screen (so wants shrinking), or it's + smaller but wants expanding to fill it */ + ratio = feh_calc_needed_zoom(&(winwid->zoom), winwid->im_w, winwid->im_h, max_w, max_h); + + /* contributed by Jens Laas <jens.laas@data.slu.se> + * What it does: + * zooms images by a fixed amount but never larger than the screen. + * + * Why: + * This is nice if you got a collection of images where some + * are small and can stand a small zoom. Large images are unaffected. + * + * When does it work, and how? + * You have to be in fullscreen mode _and_ have auto-zoom turned on. + * "feh -FZ --zoom 130 imagefile" will do the trick. + * -zoom percent - the new switch. + * 100 = orignal size, + * 130 is 30% larger. + */ + if (opt.default_zoom) { + double old_zoom = winwid->zoom; + + winwid->zoom = 0.01 * opt.default_zoom; + if ((winwid->im_h * winwid->zoom) > max_h) + winwid->zoom = old_zoom; + if ((winwid->im_w * winwid->zoom) > max_w) + winwid->zoom = old_zoom; + + winwid->im_x = ((int) + (max_w - (winwid->im_w * winwid->zoom))) >> 1; + winwid->im_y = ((int) + (max_h - (winwid->im_h * winwid->zoom))) >> 1; + } else { + if (ratio > 1.0) { + /* height is the factor */ + winwid->im_x = 0; + winwid->im_y = ((int) + (max_h - (winwid->im_h * winwid->zoom))) >> 1; + } else { + /* width is the factor */ + winwid->im_x = ((int) + (max_w - (winwid->im_w * winwid->zoom))) >> 1; + winwid->im_y = 0; + } + } + } else { + /* my modification to jens hack, allow --zoom without auto-zoom mode */ + if (opt.default_zoom) { + winwid->zoom = 0.01 * opt.default_zoom; + } else { + winwid->zoom = 1.0; + } + /* Just center the image in the window */ + winwid->im_x = (int) (max_w - (winwid->im_w * winwid->zoom)) >> 1; + winwid->im_y = (int) (max_h - (winwid->im_h * winwid->zoom)) >> 1; + } + } + + /* Now we ensure only to render the area we're looking at */ + dx = winwid->im_x; + dy = winwid->im_y; + if (dx < 0) + dx = 0; + if (dy < 0) + dy = 0; + + if (winwid->im_x < 0) + sx = 0 - (winwid->im_x / winwid->zoom); + else + sx = 0; + + if (winwid->im_y < 0) + sy = 0 - (winwid->im_y / winwid->zoom); + else + sy = 0; + + calc_w = winwid->im_w * winwid->zoom; + calc_h = winwid->im_h * winwid->zoom; + dw = (winwid->w - winwid->im_x); + dh = (winwid->h - winwid->im_y); + if (calc_w < dw) + dw = calc_w; + if (calc_h < dh) + dh = calc_h; + if (dw > winwid->w) + dw = winwid->w; + if (dh > winwid->h) + dh = winwid->h; + + sw = dw / winwid->zoom; + sh = dh / winwid->zoom; + + D(5, + ("sx: %d sy: %d sw: %d sh: %d dx: %d dy: %d dw: %d dh: %d zoom: %f\n", + sx, sy, sw, sh, dx, dy, dw, dh, winwid->zoom)); + + D(5, ("winwidget_render(): winwid->im_angle = %f\n", winwid->im_angle)); + if (winwid->has_rotated) + gib_imlib_render_image_part_on_drawable_at_size_with_rotation + (winwid->bg_pmap, winwid->im, sx, sy, sw, sh, dx, dy, dw, dh, winwid->im_angle, 1, 1, alias); + else + gib_imlib_render_image_part_on_drawable_at_size(winwid->bg_pmap, + winwid->im, + sx, sy, sw, + sh, dx, dy, + dw, dh, 1, + gib_imlib_image_has_alpha(winwid->im), alias); + if (opt.caption_path) { + /* cache bg pixmap. during caption entry, multiple redraws are done + * because the caption overlay changes - the image doesn't though, so re- + * rendering that is a waste of time */ + if (winwid->caption_entry) { + GC gc; + if (winwid->bg_pmap_cache) + XFreePixmap(disp, winwid->bg_pmap_cache); + winwid->bg_pmap_cache = XCreatePixmap(disp, winwid->win, winwid->w, winwid->h, depth); + gc = XCreateGC(disp, winwid->win, 0, NULL); + XCopyArea(disp, winwid->bg_pmap, winwid->bg_pmap_cache, gc, 0, 0, winwid->w, winwid->h, 0, 0); + XFreeGC(disp, gc); + } + feh_draw_caption(winwid); + } + + if (opt.draw_filename) + feh_draw_filename(winwid); + if (opt.draw_actions) + feh_draw_actions(winwid); + if ((opt.mode == MODE_ZOOM) && !alias) + feh_draw_zoom(winwid); + XSetWindowBackgroundPixmap(disp, winwid->win, winwid->bg_pmap); + XClearWindow(disp, winwid->win); + D_RETURN_(4); } -void winwidget_render_image_cached(winwidget winwid) { - static GC gc = None; - - if (gc == None) { - gc = XCreateGC(disp, winwid->win, 0, NULL); - } - XCopyArea(disp, winwid->bg_pmap_cache, winwid->bg_pmap, gc, 0, 0, winwid->w, winwid->h, 0, 0); - - if (opt.caption_path) - feh_draw_caption(winwid); - if (opt.draw_filename) - feh_draw_filename(winwid); - if (opt.draw_actions) - feh_draw_actions(winwid); - XSetWindowBackgroundPixmap(disp, winwid->win, winwid->bg_pmap); - XClearWindow(disp, winwid->win); +void winwidget_render_image_cached(winwidget winwid) +{ + static GC gc = None; + + if (gc == None) { + gc = XCreateGC(disp, winwid->win, 0, NULL); + } + XCopyArea(disp, winwid->bg_pmap_cache, winwid->bg_pmap, gc, 0, 0, winwid->w, winwid->h, 0, 0); + + if (opt.caption_path) + feh_draw_caption(winwid); + if (opt.draw_filename) + feh_draw_filename(winwid); + if (opt.draw_actions) + feh_draw_actions(winwid); + XSetWindowBackgroundPixmap(disp, winwid->win, winwid->bg_pmap); + XClearWindow(disp, winwid->win); } -double -feh_calc_needed_zoom(double *zoom, - int orig_w, - int orig_h, - int dest_w, - int dest_h) +double feh_calc_needed_zoom(double *zoom, int orig_w, int orig_h, int dest_w, int dest_h) { - double ratio = 0.0; + double ratio = 0.0; - D_ENTER(4); + D_ENTER(4); - ratio = ((double) orig_w / orig_h) / ((double) dest_w / dest_h); + ratio = ((double) orig_w / orig_h) / ((double) dest_w / dest_h); - if (ratio > 1.0) - *zoom = ((double) dest_w / orig_w); - else - *zoom = ((double) dest_h / orig_h); + if (ratio > 1.0) + *zoom = ((double) dest_w / orig_w); + else + *zoom = ((double) dest_h / orig_h); - D_RETURN(4, ratio); + D_RETURN(4, ratio); } -Pixmap -feh_create_checks(void) +Pixmap feh_create_checks(void) { - static Pixmap checks_pmap = None; - Imlib_Image checks = NULL; - - D_ENTER(4); - if (checks_pmap == None) { - int onoff, x, y; - - checks = imlib_create_image(16, 16); - - if (!checks) - eprintf - ("Unable to create a teeny weeny imlib image. I detect problems"); - - if (strncmp(opt.image_bg, "white", 5) == 0) - gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 255, 255, 255, 255); - else if (strncmp(opt.image_bg, "black", 5) == 0) - gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 0, 0, 0, 255); - else { - for (y = 0; y < 16; y += 8) { - onoff = (y / 8) & 0x1; - for (x = 0; x < 16; x += 8) { - if (onoff) - gib_imlib_image_fill_rectangle(checks, x, y, 8, 8, 144, 144, 144, - 255); - else - gib_imlib_image_fill_rectangle(checks, x, y, 8, 8, 100, 100, 100, - 255); - onoff++; - if (onoff == 2) - onoff = 0; - } - } - } - - checks_pmap = XCreatePixmap(disp, root, 16, 16, depth); - gib_imlib_render_image_on_drawable(checks_pmap, checks, 0, 0, 1, 0, 0); - gib_imlib_free_image_and_decache(checks); - } - D_RETURN(4, checks_pmap); + static Pixmap checks_pmap = None; + Imlib_Image checks = NULL; + + D_ENTER(4); + if (checks_pmap == None) { + int onoff, x, y; + + checks = imlib_create_image(16, 16); + + if (!checks) + eprintf("Unable to create a teeny weeny imlib image. I detect problems"); + + if (strncmp(opt.image_bg, "white", 5) == 0) + gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 255, 255, 255, 255); + else if (strncmp(opt.image_bg, "black", 5) == 0) + gib_imlib_image_fill_rectangle(checks, 0, 0, 16, 16, 0, 0, 0, 255); + else { + for (y = 0; y < 16; y += 8) { + onoff = (y / 8) & 0x1; + for (x = 0; x < 16; x += 8) { + if (onoff) + gib_imlib_image_fill_rectangle(checks, x, y, 8, 8, 144, 144, 144, 255); + else + gib_imlib_image_fill_rectangle(checks, x, y, 8, 8, 100, 100, 100, 255); + onoff++; + if (onoff == 2) + onoff = 0; + } + } + } + + checks_pmap = XCreatePixmap(disp, root, 16, 16, depth); + gib_imlib_render_image_on_drawable(checks_pmap, checks, 0, 0, 1, 0, 0); + gib_imlib_free_image_and_decache(checks); + } + D_RETURN(4, checks_pmap); } -void -winwidget_clear_background(winwidget w) +void winwidget_clear_background(winwidget w) { - D_ENTER(4); - XSetWindowBackgroundPixmap(disp, w->win, feh_create_checks()); - /* XClearWindow(disp, w->win); */ - D_RETURN_(4); + D_ENTER(4); + XSetWindowBackgroundPixmap(disp, w->win, feh_create_checks()); + /* XClearWindow(disp, w->win); */ + D_RETURN_(4); } -void -feh_draw_checks(winwidget win) +void feh_draw_checks(winwidget win) { - static GC gc = None; - XGCValues gcval; - - D_ENTER(4); - if (gc == None) { - gcval.tile = feh_create_checks(); - gcval.fill_style = FillTiled; - gc = XCreateGC(disp, win->win, GCTile | GCFillStyle, &gcval); - } - XFillRectangle(disp, win->bg_pmap, gc, 0, 0, win->w, win->h); - D_RETURN_(4); + static GC gc = None; + XGCValues gcval; + + D_ENTER(4); + if (gc == None) { + gcval.tile = feh_create_checks(); + gcval.fill_style = FillTiled; + gc = XCreateGC(disp, win->win, GCTile | GCFillStyle, &gcval); + } + XFillRectangle(disp, win->bg_pmap, gc, 0, 0, win->w, win->h); + D_RETURN_(4); } -void -winwidget_destroy_xwin(winwidget winwid) +void winwidget_destroy_xwin(winwidget winwid) { - D_ENTER(4); - if (winwid->win) { - winwidget_unregister(winwid); - XDestroyWindow(disp, winwid->win); - } - if (winwid->bg_pmap) { - XFreePixmap(disp, winwid->bg_pmap); - winwid->bg_pmap = None; - } - D_RETURN_(4); + D_ENTER(4); + if (winwid->win) { + winwidget_unregister(winwid); + XDestroyWindow(disp, winwid->win); + } + if (winwid->bg_pmap) { + XFreePixmap(disp, winwid->bg_pmap); + winwid->bg_pmap = None; + } + D_RETURN_(4); } -void -winwidget_destroy(winwidget winwid) +void winwidget_destroy(winwidget winwid) { - D_ENTER(4); - winwidget_destroy_xwin(winwid); - if (winwid->name) - free(winwid->name); - if ((winwid->type == WIN_TYPE_ABOUT) && winwid->file) { - feh_file_free(FEH_FILE(winwid->file->data)); - free(winwid->file); - } - if (winwid->gc) - XFreeGC(disp, winwid->gc); - if (winwid->im) - gib_imlib_free_image_and_decache(winwid->im); - free(winwid); - D_RETURN_(4); + D_ENTER(4); + winwidget_destroy_xwin(winwid); + if (winwid->name) + free(winwid->name); + if ((winwid->type == WIN_TYPE_ABOUT) && winwid->file) { + feh_file_free(FEH_FILE(winwid->file->data)); + free(winwid->file); + } + if (winwid->gc) + XFreeGC(disp, winwid->gc); + if (winwid->im) + gib_imlib_free_image_and_decache(winwid->im); + free(winwid); + D_RETURN_(4); } -void -winwidget_destroy_all(void) +void winwidget_destroy_all(void) { - int i; + int i; - D_ENTER(4); - /* Have to DESCEND the list here, 'cos of the way _unregister works */ - for (i = window_num - 1; i >= 0; i--) - winwidget_destroy(windows[i]); - D_RETURN_(4); + D_ENTER(4); + /* Have to DESCEND the list here, 'cos of the way _unregister works */ + for (i = window_num - 1; i >= 0; i--) + winwidget_destroy(windows[i]); + D_RETURN_(4); } -void -winwidget_rerender_all(int resize, - int alias) +void winwidget_rerender_all(int resize, int alias) { - int i; + int i; - D_ENTER(4); - /* Have to DESCEND the list here, 'cos of the way _unregister works */ - for (i = window_num - 1; i >= 0; i--) - winwidget_render_image(windows[i], resize, alias); - D_RETURN_(4); + D_ENTER(4); + /* Have to DESCEND the list here, 'cos of the way _unregister works */ + for (i = window_num - 1; i >= 0; i--) + winwidget_render_image(windows[i], resize, alias); + D_RETURN_(4); } -winwidget -winwidget_get_first_window_of_type(unsigned int type) +winwidget winwidget_get_first_window_of_type(unsigned int type) { - int i; + int i; - D_ENTER(4); - for (i = 0; i < window_num; i++) - if (windows[i]->type == type) - D_RETURN(4, windows[i]); - D_RETURN(4, NULL); + D_ENTER(4); + for (i = 0; i < window_num; i++) + if (windows[i]->type == type) + D_RETURN(4, windows[i]); + D_RETURN(4, NULL); } -int -winwidget_loadimage(winwidget winwid, - feh_file * file) +int winwidget_loadimage(winwidget winwid, feh_file * file) { - D_ENTER(4); - D(4, ("filename %s\n", file->filename)); - D_RETURN(4, feh_load_image(&(winwid->im), file)); + D_ENTER(4); + D(4, ("filename %s\n", file->filename)); + D_RETURN(4, feh_load_image(&(winwid->im), file)); } -void -winwidget_show(winwidget winwid) +void winwidget_show(winwidget winwid) { - XEvent ev; - - D_ENTER(4); - - /* feh_debug_print_winwid(winwid); */ - if (!winwid->visible) { - XMapWindow(disp, winwid->win); - if (opt.full_screen) - XMoveWindow(disp, winwid->win, 0, 0); - /* wait for the window to map */ - D(4, ("Waiting for window to map\n")); - XMaskEvent(disp, StructureNotifyMask, &ev); - D(4, ("Window mapped\n")); - winwid->visible = 1; - } - D_RETURN_(4); + XEvent ev; + + D_ENTER(4); + + /* feh_debug_print_winwid(winwid); */ + if (!winwid->visible) { + XMapWindow(disp, winwid->win); + if (opt.full_screen) + XMoveWindow(disp, winwid->win, 0, 0); + /* wait for the window to map */ + D(4, ("Waiting for window to map\n")); + XMaskEvent(disp, StructureNotifyMask, &ev); + D(4, ("Window mapped\n")); + winwid->visible = 1; + } + D_RETURN_(4); } -int -winwidget_count(void) +int winwidget_count(void) { - D_ENTER(4); - D_RETURN(4, window_num); + D_ENTER(4); + D_RETURN(4, window_num); } -void -winwidget_move(winwidget winwid, - int x, - int y) +void winwidget_move(winwidget winwid, int x, int y) { - D_ENTER(4); - if (winwid && ((winwid->x != x) || (winwid->y != y))) { - winwid->x = x; - winwid->y = y; - winwid->x = (x > scr->width) ? scr->width : x; - winwid->y = (y > scr->height) ? scr->height : y; - XMoveWindow(disp, winwid->win, winwid->x, winwid->y); - XFlush(disp); - } else { - D(4, ("No move actually needed\n")); - } - D_RETURN_(4); + D_ENTER(4); + if (winwid && ((winwid->x != x) || (winwid->y != y))) { + winwid->x = x; + winwid->y = y; + winwid->x = (x > scr->width) ? scr->width : x; + winwid->y = (y > scr->height) ? scr->height : y; + XMoveWindow(disp, winwid->win, winwid->x, winwid->y); + XFlush(disp); + } else { + D(4, ("No move actually needed\n")); + } + D_RETURN_(4); } -void -winwidget_resize(winwidget winwid, - int w, - int h) +void winwidget_resize(winwidget winwid, int w, int h) { - Window ignored_window; - XWindowAttributes attributes; - int tc_x, tc_y; - - D_ENTER(4); - if (opt.geom_flags) { - winwid->had_resize = 1; - return; - } - if (winwid && ((winwid->w != w) || (winwid->h != h))) { - D(4, ("Really doing a resize\n")); - /* winwidget_clear_background(winwid); */ - if (opt.screen_clip) { - winwid->w = (w > scr->width) ? scr->width : w; - winwid->h = (h > scr->height) ? scr->height : h; - } - /* XResizeWindow(disp, winwid->win, winwid->w, winwid->h); */ - XGetWindowAttributes(disp, winwid->win, &attributes); - XTranslateCoordinates(disp, winwid->win, attributes.root, - -attributes.border_width - attributes.x, - -attributes.border_width - attributes.y, - &tc_x, &tc_y, &ignored_window); - winwid->x = tc_x; - winwid->y = tc_y; - XMoveResizeWindow(disp, winwid->win, tc_x, tc_y, winwid->w, winwid->h); - - winwid->had_resize = 1; - XFlush(disp); + Window ignored_window; + XWindowAttributes attributes; + int tc_x, tc_y; + + D_ENTER(4); + if (opt.geom_flags) { + winwid->had_resize = 1; + return; + } + if (winwid && ((winwid->w != w) || (winwid->h != h))) { + D(4, ("Really doing a resize\n")); + /* winwidget_clear_background(winwid); */ + if (opt.screen_clip) { + winwid->w = (w > scr->width) ? scr->width : w; + winwid->h = (h > scr->height) ? scr->height : h; + } + /* XResizeWindow(disp, winwid->win, winwid->w, winwid->h); */ + XGetWindowAttributes(disp, winwid->win, &attributes); + XTranslateCoordinates(disp, winwid->win, attributes.root, + -attributes.border_width - + attributes.x, + -attributes.border_width - attributes.y, &tc_x, &tc_y, &ignored_window); + winwid->x = tc_x; + winwid->y = tc_y; + XMoveResizeWindow(disp, winwid->win, tc_x, tc_y, winwid->w, winwid->h); + + winwid->had_resize = 1; + XFlush(disp); #ifdef HAVE_LIBXINERAMA - if (opt.xinerama && xinerama_screens) { - int i; - - for (i = 0; i < num_xinerama_screens; i++) { - xinerama_screen = 0; - if (XY_IN_RECT(winwid->x, winwid->y, - xinerama_screens[i].x_org, xinerama_screens[i].y_org, - xinerama_screens[i].width, xinerama_screens[i].height)) { - xinerama_screen = i; - break; - } - - } - } -#endif /* HAVE_LIBXINERAMA */ - - } else { - D(4, ("No resize actually needed\n")); - } - - D_RETURN_(4); + if (opt.xinerama && xinerama_screens) { + int i; + + for (i = 0; i < num_xinerama_screens; i++) { + xinerama_screen = 0; + if (XY_IN_RECT(winwid->x, winwid->y, + xinerama_screens[i].x_org, + xinerama_screens[i].y_org, + xinerama_screens[i].width, xinerama_screens[i].height)) { + xinerama_screen = i; + break; + } + + } + } +#endif /* HAVE_LIBXINERAMA */ + + } else { + D(4, ("No resize actually needed\n")); + } + + D_RETURN_(4); } -void -winwidget_hide(winwidget winwid) +void winwidget_hide(winwidget winwid) { - D_ENTER(4); - XUnmapWindow(disp, winwid->win); - winwid->visible = 0; - D_RETURN_(4); + D_ENTER(4); + XUnmapWindow(disp, winwid->win); + winwid->visible = 0; + D_RETURN_(4); } -static void -winwidget_register(winwidget win) +static void winwidget_register(winwidget win) { - D_ENTER(4); - D(5, ("window %p\n", win)); - window_num++; - if (windows) - windows = erealloc(windows, window_num * sizeof(winwidget)); - else - windows = emalloc(window_num * sizeof(winwidget)); - windows[window_num - 1] = win; - - XSaveContext(disp, win->win, xid_context, (XPointer) win); - D_RETURN_(4); + D_ENTER(4); + D(5, ("window %p\n", win)); + window_num++; + if (windows) + windows = erealloc(windows, window_num * sizeof(winwidget)); + else + windows = emalloc(window_num * sizeof(winwidget)); + windows[window_num - 1] = win; + + XSaveContext(disp, win->win, xid_context, (XPointer) win); + D_RETURN_(4); } -static void -winwidget_unregister(winwidget win) +static void winwidget_unregister(winwidget win) { - int i, j; - - D_ENTER(4); - for (i = 0; i < window_num; i++) { - if (windows[i] == win) { - for (j = i; j < window_num - 1; j++) - windows[j] = windows[j + 1]; - window_num--; - if (window_num > 0) - windows = erealloc(windows, window_num * sizeof(winwidget)); - else { - free(windows); - windows = NULL; - } - } - } - XDeleteContext(disp, win->win, xid_context); - D_RETURN_(4); + int i, j; + + D_ENTER(4); + for (i = 0; i < window_num; i++) { + if (windows[i] == win) { + for (j = i; j < window_num - 1; j++) + windows[j] = windows[j + 1]; + window_num--; + if (window_num > 0) + windows = erealloc(windows, window_num * sizeof(winwidget)); + else { + free(windows); + windows = NULL; + } + } + } + XDeleteContext(disp, win->win, xid_context); + D_RETURN_(4); } -winwidget -winwidget_get_from_window(Window win) +winwidget winwidget_get_from_window(Window win) { - winwidget ret = NULL; + winwidget ret = NULL; - D_ENTER(4); - if (XFindContext(disp, win, xid_context, (XPointer *) & ret) != XCNOENT) - D_RETURN(4, ret); - D_RETURN(4, NULL); + D_ENTER(4); + if (XFindContext(disp, win, xid_context, (XPointer *) & ret) != XCNOENT) + D_RETURN(4, ret); + D_RETURN(4, NULL); } -void -winwidget_rename(winwidget winwid, - char *newname) +void winwidget_rename(winwidget winwid, char *newname) { - D_ENTER(4); - if (winwid->name) - free(winwid->name); - winwid->name = estrdup(newname); - winwidget_update_title(winwid); - D_RETURN_(4); + D_ENTER(4); + if (winwid->name) + free(winwid->name); + winwid->name = estrdup(newname); + winwidget_update_title(winwid); + D_RETURN_(4); } -void -winwidget_free_image(winwidget w) +void winwidget_free_image(winwidget w) { - D_ENTER(4); - if (w->im) - gib_imlib_free_image_and_decache(w->im); - w->im = NULL; - w->im_w = 0; - w->im_h = 0; - D_RETURN_(4); + D_ENTER(4); + if (w->im) + gib_imlib_free_image_and_decache(w->im); + w->im = NULL; + w->im_w = 0; + w->im_h = 0; + D_RETURN_(4); } -void -feh_debug_print_winwid(winwidget w) +void feh_debug_print_winwid(winwidget w) { - printf("winwid_debug:\n" "winwid = %p\n" "win = %ld\n" "w = %d\n" "h = %d\n" - "im_w = %d\n" "im_h = %d\n" "im_angle = %f\n" "type = %d\n" - "had_resize = %d\n" "im = %p\n" "GC = %p\n" "pixmap = %ld\n" - "name = %s\n" "file = %p\n" "mode = %d\n" "im_x = %d\n" "im_y = %d\n" - "zoom = %f\n" "click_offset_x = %d\n" "click_offset_y = %d\n" - "im_click_offset_x = %d\n" "im_click_offset_y = %d\n" - "has_rotated = %d\n", w, w->win, w->w, w->h, w->im_w, w->im_h, - w->im_angle, w->type, w->had_resize, w->im, w->gc, w->bg_pmap, - w->name, w->file, w->mode, w->im_x, w->im_y, w->zoom, - w->click_offset_x, w->click_offset_y, w->im_click_offset_x, - w->im_click_offset_y, w->has_rotated); + printf("winwid_debug:\n" "winwid = %p\n" "win = %ld\n" "w = %d\n" + "h = %d\n" "im_w = %d\n" "im_h = %d\n" "im_angle = %f\n" + "type = %d\n" "had_resize = %d\n" "im = %p\n" "GC = %p\n" + "pixmap = %ld\n" "name = %s\n" "file = %p\n" "mode = %d\n" + "im_x = %d\n" "im_y = %d\n" "zoom = %f\n" + "click_offset_x = %d\n" "click_offset_y = %d\n" + "im_click_offset_x = %d\n" "im_click_offset_y = %d\n" + "has_rotated = %d\n", w, w->win, w->w, w->h, w->im_w, + w->im_h, w->im_angle, w->type, w->had_resize, w->im, w->gc, + w->bg_pmap, w->name, w->file, w->mode, w->im_x, w->im_y, + w->zoom, w->click_offset_x, w->click_offset_y, + w->im_click_offset_x, w->im_click_offset_y, w->has_rotated); } -void -winwidget_reset_image(winwidget winwid) +void winwidget_reset_image(winwidget winwid) { - D_ENTER(4); - winwid->zoom = 1.0; - winwid->im_x = 0; - winwid->im_y = 0; - winwid->im_angle = 0.0; - winwid->has_rotated = 0; - D_RETURN_(4); + D_ENTER(4); + winwid->zoom = 1.0; + winwid->im_x = 0; + winwid->im_y = 0; + winwid->im_angle = 0.0; + winwid->has_rotated = 0; + D_RETURN_(4); } -void -winwidget_sanitise_offsets(winwidget winwid) +void winwidget_sanitise_offsets(winwidget winwid) { - int far_left, far_top; - int min_x, max_x, max_y, min_y; - - D_ENTER(4); - - far_left = winwid->w - (winwid->im_w * winwid->zoom); - far_top = winwid->h - (winwid->im_h * winwid->zoom); - - if ((winwid->im_w * winwid->zoom) > winwid->w) { - min_x = far_left; - max_x = 0; - } else { - min_x = 0; - max_x = far_left; - } - if ((winwid->im_h * winwid->zoom) > winwid->h) { - min_y = far_top; - max_y = 0; - } else { - min_y = 0; - max_y = far_top; - } - if (winwid->im_x > max_x) - winwid->im_x = max_x; - if (winwid->im_x < min_x) - winwid->im_x = min_x; - if (winwid->im_y > max_y) - winwid->im_y = max_y; - if (winwid->im_y < min_y) - winwid->im_y = min_y; - - D_RETURN_(4); + int far_left, far_top; + int min_x, max_x, max_y, min_y; + + D_ENTER(4); + + far_left = winwid->w - (winwid->im_w * winwid->zoom); + far_top = winwid->h - (winwid->im_h * winwid->zoom); + + if ((winwid->im_w * winwid->zoom) > winwid->w) { + min_x = far_left; + max_x = 0; + } else { + min_x = 0; + max_x = far_left; + } + if ((winwid->im_h * winwid->zoom) > winwid->h) { + min_y = far_top; + max_y = 0; + } else { + min_y = 0; + max_y = far_top; + } + if (winwid->im_x > max_x) + winwid->im_x = max_x; + if (winwid->im_x < min_x) + winwid->im_x = min_x; + if (winwid->im_y > max_y) + winwid->im_y = max_y; + if (winwid->im_y < min_y) + winwid->im_y = min_y; + + D_RETURN_(4); } - -void -winwidget_size_to_image(winwidget winwid) +void winwidget_size_to_image(winwidget winwid) { - D_ENTER(4); - winwidget_resize(winwid, winwid->im_w * winwid->zoom, - winwid->im_h * winwid->zoom); - winwid->im_x = winwid->im_y = 0; - winwidget_render_image(winwid, 0, 1); - D_RETURN_(4); + D_ENTER(4); + winwidget_resize(winwid, winwid->im_w * winwid->zoom, winwid->im_h * winwid->zoom); + winwid->im_x = winwid->im_y = 0; + winwidget_render_image(winwid, 0, 1); + D_RETURN_(4); } -int winwidget_get_width(winwidget winwid) { - int rect[4]; - D_ENTER(4); - winwidget_get_geometry(winwid, rect); - D_RETURN(4, rect[2]); +int winwidget_get_width(winwidget winwid) +{ + int rect[4]; + D_ENTER(4); + winwidget_get_geometry(winwid, rect); + D_RETURN(4, rect[2]); } -int winwidget_get_height(winwidget winwid) { - int rect[4]; - D_ENTER(4); - winwidget_get_geometry(winwid, rect); - D_RETURN(4, rect[3]); +int winwidget_get_height(winwidget winwid) +{ + int rect[4]; + D_ENTER(4); + winwidget_get_geometry(winwid, rect); + D_RETURN(4, rect[3]); } -void winwidget_get_geometry(winwidget winwid, int *rect) { - int bw, bp; - Window child; - D_ENTER(4); - if (!rect) - return; - - XGetGeometry(disp, winwid->win, &root, - &(rect[0]), &(rect[1]), &(rect[2]), &(rect[3]), &bw, &bp); - - XTranslateCoordinates(disp, winwid->win, root, - 0, 0, &(rect[0]), &(rect[1]), &child); - - /* update the window geometry (in case it's inaccurate) */ - winwid->x = rect[0]; - winwid->y = rect[1]; - winwid->w = rect[2]; - winwid->h = rect[3]; - D_RETURN_(4); +void winwidget_get_geometry(winwidget winwid, int *rect) +{ + int bw, bp; + Window child; + D_ENTER(4); + if (!rect) + return; + + XGetGeometry(disp, winwid->win, &root, &(rect[0]), &(rect[1]), &(rect[2]), &(rect[3]), &bw, &bp); + + XTranslateCoordinates(disp, winwid->win, root, 0, 0, &(rect[0]), &(rect[1]), &child); + + /* update the window geometry (in case it's inaccurate) */ + winwid->x = rect[0]; + winwid->y = rect[1]; + winwid->w = rect[2]; + winwid->h = rect[3]; + D_RETURN_(4); } -void winwidget_show_menu(winwidget winwid) { - int x, y, b; - unsigned int c; - Window r; - - XQueryPointer(disp, winwid->win, &r, &r, &x, &y, &b, &b, &c); - if (winwid->type == WIN_TYPE_ABOUT) - { - if (!menu_about_win) - feh_menu_init_about_win(); - feh_menu_show_at_xy(menu_about_win, winwid, x, y); - } - else if (winwid->type == WIN_TYPE_SINGLE) - { - if (!menu_single_win) - feh_menu_init_single_win(); - feh_menu_show_at_xy(menu_single_win, winwid, x, y); - } - else if (winwid->type == WIN_TYPE_THUMBNAIL) - { - if (!menu_thumbnail_win) - feh_menu_init_thumbnail_win(); - feh_menu_show_at_xy(menu_thumbnail_win, winwid, x, y); - } - else if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) - { - if (!menu_single_win) - feh_menu_init_thumbnail_viewer(); - feh_menu_show_at_xy(menu_thumbnail_viewer, winwid, x, y); - } - else - { - if (!menu_main) - feh_menu_init_main(); - feh_menu_show_at_xy(menu_main, winwid, x, y); - } +void winwidget_show_menu(winwidget winwid) +{ + int x, y, b; + unsigned int c; + Window r; + + XQueryPointer(disp, winwid->win, &r, &r, &x, &y, &b, &b, &c); + if (winwid->type == WIN_TYPE_ABOUT) { + if (!menu_about_win) + feh_menu_init_about_win(); + feh_menu_show_at_xy(menu_about_win, winwid, x, y); + } else if (winwid->type == WIN_TYPE_SINGLE) { + if (!menu_single_win) + feh_menu_init_single_win(); + feh_menu_show_at_xy(menu_single_win, winwid, x, y); + } else if (winwid->type == WIN_TYPE_THUMBNAIL) { + if (!menu_thumbnail_win) + feh_menu_init_thumbnail_win(); + feh_menu_show_at_xy(menu_thumbnail_win, winwid, x, y); + } else if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) { + if (!menu_single_win) + feh_menu_init_thumbnail_viewer(); + feh_menu_show_at_xy(menu_thumbnail_viewer, winwid, x, y); + } else { + if (!menu_main) + feh_menu_init_main(); + feh_menu_show_at_xy(menu_main, winwid, x, y); + } } diff --git a/src/winwidget.h b/src/winwidget.h index de08ec9..47ebfcc 100644 --- a/src/winwidget.h +++ b/src/winwidget.h @@ -59,58 +59,55 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PROP_MWM_HINTS_ELEMENTS 5 /* Motif window hints */ -typedef struct _mwmhints -{ - CARD32 flags; - CARD32 functions; - CARD32 decorations; - INT32 input_mode; - CARD32 status; -} -MWMHints; - -enum win_type -{ - WIN_TYPE_UNSET, WIN_TYPE_SLIDESHOW, WIN_TYPE_SINGLE, WIN_TYPE_ABOUT, - WIN_TYPE_THUMBNAIL, WIN_TYPE_THUMBNAIL_VIEWER +typedef struct _mwmhints { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 input_mode; + CARD32 status; +} MWMHints; + +enum win_type { + WIN_TYPE_UNSET, WIN_TYPE_SLIDESHOW, WIN_TYPE_SINGLE, + WIN_TYPE_ABOUT, + WIN_TYPE_THUMBNAIL, WIN_TYPE_THUMBNAIL_VIEWER }; -struct __winwidget -{ - Window win; - int x; - int y; - int w; - int h; - int im_w; - int im_h; - double im_angle; - enum win_type type; - unsigned char had_resize, full_screen; - Imlib_Image im; - GC gc; - Pixmap bg_pmap; - Pixmap bg_pmap_cache; - char *name; - gib_list *file; - unsigned char visible; - - /* Stuff for zooming */ - unsigned char mode; - - unsigned char caption_entry; /* are we in caption entry mode? */ - - /* New stuff */ - int im_x; /* image offset from window top left */ - int im_y; /* image offset from window top left */ - double zoom; /* From 0 (not visible) to 100 (actual size) - all the way up to INT_MAX (ouch) */ - int click_offset_x; - int click_offset_y; - int im_click_offset_x; - int im_click_offset_y; - - unsigned char has_rotated; +struct __winwidget { + Window win; + int x; + int y; + int w; + int h; + int im_w; + int im_h; + double im_angle; + enum win_type type; + unsigned char had_resize, full_screen; + Imlib_Image im; + GC gc; + Pixmap bg_pmap; + Pixmap bg_pmap_cache; + char *name; + gib_list *file; + unsigned char visible; + + /* Stuff for zooming */ + unsigned char mode; + + unsigned char caption_entry; /* are we in caption entry mode? */ + + /* New stuff */ + int im_x; /* image offset from window top left */ + int im_y; /* image offset from window top left */ + double zoom; /* From 0 (not visible) to 100 (actual size) + all the way up to INT_MAX (ouch) */ + int click_offset_x; + int click_offset_y; + int im_click_offset_x; + int im_click_offset_y; + + unsigned char has_rotated; }; int winwidget_loadimage(winwidget winwid, feh_file * filename); @@ -133,18 +130,14 @@ void winwidget_get_geometry(winwidget winwid, int *rect); int winwidget_get_width(winwidget winwid); int winwidget_get_height(winwidget winwid); winwidget winwidget_get_from_window(Window win); -winwidget winwidget_create_from_file(gib_list * filename, char *name, - - char type); +winwidget winwidget_create_from_file(gib_list * filename, char *name, char type); winwidget winwidget_create_from_image(Imlib_Image im, char *name, char type); void winwidget_rename(winwidget winwid, char *newname); void winwidget_destroy(winwidget winwid); void winwidget_create_window(winwidget ret, int w, int h); void winwidget_clear_background(winwidget w); Pixmap feh_create_checks(void); -double feh_calc_needed_zoom(double *zoom, int orig_w, int orig_h, int dest_w, - - int dest_h); +double feh_calc_needed_zoom(double *zoom, int orig_w, int orig_h, int dest_w, int dest_h); void feh_debug_print_winwid(winwidget winwid); winwidget winwidget_get_first_window_of_type(unsigned int type); void winwidget_reset_image(winwidget winwid); @@ -152,7 +145,7 @@ void winwidget_sanitise_offsets(winwidget winwid); void winwidget_size_to_image(winwidget winwid); void winwidget_render_image_cached(winwidget winwid); -extern int window_num; /* For window list */ -extern winwidget *windows; /* List of windows to loop though */ +extern int window_num; /* For window list */ +extern winwidget *windows; /* List of windows to loop though */ #endif |