/** * Callback when canvas recieves an expose event. The icon is entirely * redrawn for every expose event instead of checking and redrawing * just the dirty regions. Since the icon is so small, the gain * probably isn't worth the extra overhead. */ gboolean on_canvas_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer unused_udata) { GdkRectangle panel, rect, bar; (void) unused_udata; /* just draw once for all expose events */ if (event->count) return FALSE; /* setup image column */ panel.x = ICON_INSET; panel.y = ICON_INSET; panel.height = (widget->allocation.height - ICON_INSET2) / 3; panel.width = XPM_WIDTH; /* draw connection icon */ center_image(&rect, &panel, con_pixbuf); gdk_draw_pixbuf(canvas->window, NULL, con_pixbuf, 0, 0, rect.x, rect.y, rect.width, rect.height, GDK_RGB_DITHER_NONE, 0, 0); panel.y += panel.height; /* paint download icon */ center_image(&rect, &panel, down_pixbuf); gdk_draw_pixbuf(canvas->window, NULL, down_pixbuf, 0, 0, rect.x, rect.y, rect.width, rect.height, GDK_RGB_DITHER_NONE, 0, 0); panel.y += panel.height; /* paint upload icon */ center_image(&rect, &panel, up_pixbuf); gdk_draw_pixbuf(canvas->window, NULL, up_pixbuf, 0, 0, rect.x, rect.y, rect.width, rect.height, GDK_RGB_DITHER_NONE, 0, 0); /* setup bar column */ panel.x = XPM_WIDTH + ICON_INSET; panel.y = ICON_INSET; panel.width = (ICON_WIDTH - ICON_INSET2) - XPM_WIDTH; panel.height = (widget->allocation.height - ICON_INSET2); /* draw bar panel */ gtk_paint_box(widget->style, widget->window, GTK_STATE_INSENSITIVE, GTK_SHADOW_OUT, NULL, widget, NULL, panel.x, panel.y, panel.width, panel.height); panel.height /= 3; rect.x = panel.x + ICON_INSET2; rect.y = panel.y + ICON_INSET2; rect.width = panel.width - ICON_INSET4; rect.height = panel.height - ICON_INSET4; bar.x = rect.x + ICON_INSET; bar.y = rect.y + ICON_INSET; bar.width = rect.width - ICON_INSET2; bar.height = rect.height - ICON_INSET2; /* paint connection bar */ gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, rect.x, rect.y, rect.width, rect.height); gdk_draw_rectangle(widget->window, widget->style->black_gc, TRUE, bar.x, bar.y, bar.width, bar.height); bar.width = get_width(&bar, leaf_cnt + norm_cnt + ultra_cnt, con_max); gdk_draw_rectangle(widget->window, widget->style->white_gc, TRUE, bar.x, bar.y, bar.width, bar.height); panel.y += panel.height; rect.y += panel.height; bar.y += panel.height; bar.width = rect.width - ICON_INSET2; /* paint download bar */ gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, rect.x, rect.y, rect.width, rect.height); gdk_draw_rectangle(widget->window, widget->style->black_gc, TRUE, bar.x, bar.y, bar.width, bar.height); bar.width = get_width(&bar, down_cnt, down_max); gdk_draw_rectangle(widget->window, widget->style->white_gc, TRUE, bar.x, bar.y, bar.width, bar.height); panel.y += panel.height; rect.y += panel.height; bar.y += panel.height; bar.width = rect.width - ICON_INSET2; /* paint upload bar */ gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, rect.x, rect.y, rect.width, rect.height); gdk_draw_rectangle(widget->window, widget->style->black_gc, TRUE, bar.x, bar.y, bar.width, bar.height); bar.width = get_width(&bar, up_cnt, up_max); gdk_draw_rectangle(widget->window, widget->style->white_gc, TRUE, bar.x, bar.y, bar.width, bar.height); /* paint border */ gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, widget, NULL, 0, 0, -1, -1); return FALSE; }
int main(int argc, char **argv) { int c, image_index, image_count, incr, i; SDL_Event event; DispContext dc_s, *dc = &dc_s; const SDL_VideoInfo *vi; for(;;) { c = getopt(argc, argv, "h"); if (c == -1) break; switch(c) { case 'h': show_help: help(); break; default: exit(1); } } if (optind >= argc) goto show_help; if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { fprintf(stderr, "Could not init SDL\n"); exit(1); } memset(dc, 0, sizeof(*dc)); vi = SDL_GetVideoInfo(); dc->screen_w = vi->current_w; dc->screen_h = vi->current_h; dc->is_full_screen = 0; image_count = argc - optind; image_index = 0; if (load_image(dc, argv[optind + image_index]) < 0) exit(1); dc->background_type = BG_TILED; { int w, h; if (image_count > 1 || (dc->img_w < 256 || dc->img_h < 256)) { w = DEFAULT_W; h = DEFAULT_H; } else { w = clamp_int(dc->img_w, 32, dc->screen_w); h = clamp_int(dc->img_h, 32, dc->screen_h); } open_window(dc, w, h, 0); set_caption(dc, argv + optind, image_index, image_count); } center_image(dc); draw_image(dc); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); for(;;) { if (!SDL_WaitEvent(&event)) continue; switch(event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_ESCAPE: case SDLK_q: goto done; case SDLK_SPACE: /* next image */ case SDLK_n: incr = 1; goto prev_next; case SDLK_p: /* previous image */ incr = -1; prev_next: if (image_count > 1) { for(i = 0; i < image_count; i++) { image_index += incr; if (image_index < 0) image_index = image_count - 1; else if (image_index >= image_count) image_index = 0; if (load_image(dc, argv[optind + image_index]) == 0) break; } if (i == image_count) exit(1); set_caption(dc, argv + optind, image_index, image_count); center_image(dc); draw_image(dc); } break; case SDLK_LEFT: pan_image(dc, 32, 0); break; case SDLK_RIGHT: pan_image(dc, -32, 0); break; case SDLK_UP: pan_image(dc, 0, 32); break; case SDLK_DOWN: pan_image(dc, 0, -32); break; case SDLK_c: center_image(dc); draw_image(dc); break; case SDLK_b: dc->background_type ^= 1; draw_image(dc); break; case SDLK_f: dc->is_full_screen ^= 1; if (dc->is_full_screen) { /* save old windows size */ dc->win_w = dc->screen->w; dc->win_h = dc->screen->h; open_window(dc, dc->screen_w, dc->screen_h, 1); } else { open_window(dc, dc->win_w, dc->win_h, 0); } center_image(dc); draw_image(dc); break; default: break; } break; case SDL_VIDEORESIZE: { open_window(dc, event.resize.w, event.resize.h, 0); center_image(dc); draw_image(dc); } break; case SDL_QUIT: goto done; case SDL_MOUSEMOTION: if (event.motion.state) { pan_image(dc, event.motion.xrel, event.motion.yrel); } break; case SDL_USEREVENT: if (dc->frame_count > 1) { /* show next frame */ if (dc->frame_index == (dc->frame_count - 1)) { if (dc->loop_count == 0 || dc->loop_counter < (dc->loop_count - 1)) { dc->frame_index = 0; dc->loop_counter++; } else { break; } } else { dc->frame_index++; } draw_image(dc); restart_frame_timer(dc); } break; default: break; } } done: SDL_FreeSurface(dc->screen); return 0; }