No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

302 líneas
9.0 KiB

  1. /*
  2. * view image viewer for libcaca
  3. * Copyright (c) 2003 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  21. * 02111-1307 USA
  22. */
  23. #include "config.h"
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <malloc.h>
  27. #define X_DISPLAY_MISSING 1
  28. #include <Imlib2.h>
  29. #include "caca.h"
  30. Imlib_Image image = NULL;
  31. char *pixels = NULL;
  32. struct caca_bitmap *bitmap = NULL;
  33. int x, y, w, h;
  34. int dithering = 1;
  35. const enum caca_dithering dithering_list[] =
  36. { CACA_DITHER_NONE, CACA_DITHER_ORDERED, CACA_DITHER_RANDOM };
  37. static void load_image(const char *);
  38. int main(int argc, char **argv)
  39. {
  40. int quit = 0, update = 1, help = 0, reload = 0;
  41. int i, zoom = 0;
  42. char **list = NULL;
  43. int current = 0, items = 0, opts = 1;
  44. /* Initialise libcaca */
  45. if(caca_init())
  46. {
  47. fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]);
  48. return 1;
  49. }
  50. /* Load items into playlist */
  51. for(i = 1; i < argc; i++)
  52. {
  53. /* Skip options except after `--' */
  54. if(opts && argv[i][0] == '-')
  55. {
  56. if(argv[i][1] == '-' && argv[i][2] == '\0')
  57. opts = 0;
  58. continue;
  59. }
  60. /* Add argv[i] to the list */
  61. if(items)
  62. list = realloc(list, (items + 1) * sizeof(char *));
  63. else
  64. list = malloc(sizeof(char *));
  65. list[items] = argv[i];
  66. items++;
  67. reload = 1;
  68. }
  69. /* Go ! */
  70. while(!quit)
  71. {
  72. int ww = caca_get_width();
  73. int wh = caca_get_height();
  74. int event;
  75. while((event = caca_get_event()))
  76. {
  77. switch(event)
  78. {
  79. case CACA_EVENT_KEY_PRESS | 'n':
  80. case CACA_EVENT_KEY_PRESS | 'N':
  81. if(items) current = (current + 1) % items;
  82. reload = 1;
  83. break;
  84. case CACA_EVENT_KEY_PRESS | 'p':
  85. case CACA_EVENT_KEY_PRESS | 'P':
  86. if(items) current = (items + current - 1) % items;
  87. reload = 1;
  88. break;
  89. case CACA_EVENT_KEY_PRESS | 'd':
  90. case CACA_EVENT_KEY_PRESS | 'D':
  91. dithering = (dithering + 1) % 3;
  92. update = 1;
  93. break;
  94. case CACA_EVENT_KEY_PRESS | '+':
  95. zoom++;
  96. if(zoom > 48) zoom = 48; else update = 1;
  97. break;
  98. case CACA_EVENT_KEY_PRESS | '-':
  99. zoom--;
  100. if(zoom < -48) zoom = -48; else update = 1;
  101. break;
  102. case CACA_EVENT_KEY_PRESS | 'x':
  103. case CACA_EVENT_KEY_PRESS | 'X':
  104. zoom = 0;
  105. update = 1;
  106. break;
  107. case CACA_EVENT_KEY_PRESS | 'k':
  108. case CACA_EVENT_KEY_PRESS | 'K':
  109. case CACA_EVENT_KEY_PRESS | CACA_KEY_UP:
  110. if(zoom > 0) y -= 1 + h / (2 + zoom) / 8;
  111. update = 1;
  112. break;
  113. case CACA_EVENT_KEY_PRESS | 'j':
  114. case CACA_EVENT_KEY_PRESS | 'J':
  115. case CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN:
  116. if(zoom > 0) y += 1 + h / (2 + zoom) / 8;
  117. update = 1;
  118. break;
  119. case CACA_EVENT_KEY_PRESS | 'h':
  120. case CACA_EVENT_KEY_PRESS | 'H':
  121. case CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT:
  122. if(zoom > 0) x -= 1 + w / (2 + zoom) / 8;
  123. update = 1;
  124. break;
  125. case CACA_EVENT_KEY_PRESS | 'l':
  126. case CACA_EVENT_KEY_PRESS | 'L':
  127. case CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT:
  128. if(zoom > 0) x += 1 + w / (2 + zoom) / 8;
  129. update = 1;
  130. break;
  131. case CACA_EVENT_KEY_PRESS | '?':
  132. help = !help;
  133. update = 1;
  134. break;
  135. case CACA_EVENT_KEY_PRESS | 'q':
  136. case CACA_EVENT_KEY_PRESS | 'Q':
  137. quit = 1;
  138. break;
  139. }
  140. }
  141. if(items && reload)
  142. {
  143. char *buffer = malloc(ww + 1);
  144. /* Reset image-specific runtime variables */
  145. zoom = 0;
  146. snprintf(buffer, ww, " Loading `%s'... ", list[current]);
  147. buffer[ww] = '\0';
  148. caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
  149. caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
  150. caca_refresh();
  151. load_image(list[current]);
  152. reload = 0;
  153. update = 1;
  154. free(buffer);
  155. }
  156. if(update)
  157. {
  158. caca_clear();
  159. caca_set_dithering(dithering_list[dithering]);
  160. caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
  161. if(!items)
  162. caca_printf(ww / 2 - 5, wh / 2, " No image. ");
  163. else if(!image)
  164. {
  165. char *buffer = malloc(ww + 1);
  166. snprintf(buffer, ww, " Error loading `%s'. ", list[current]);
  167. buffer[ww] = '\0';
  168. caca_putstr((ww - strlen(buffer)) / 2, wh / 2, buffer);
  169. free(buffer);
  170. }
  171. else if(zoom < 0)
  172. {
  173. int xo = (ww - 1) / 2;
  174. int yo = (wh - 1) / 2;
  175. int xn = (ww - 1) / (2 - zoom);
  176. int yn = (wh - 1) / (2 - zoom);
  177. caca_draw_bitmap(xo - xn, yo - yn, xo + xn, yo + yn,
  178. bitmap, pixels);
  179. }
  180. else if(zoom > 0)
  181. {
  182. struct caca_bitmap *newbitmap;
  183. int xn = w / (2 + zoom);
  184. int yn = h / (2 + zoom);
  185. if(x < xn) x = xn;
  186. if(y < yn) y = yn;
  187. if(xn + x > w) x = w - xn;
  188. if(yn + y > h) y = h - yn;
  189. newbitmap = caca_create_bitmap(32, 2 * xn, 2 * yn, 4 * w,
  190. 0x00ff0000, 0x0000ff00, 0x000000ff);
  191. caca_draw_bitmap(0, 0, ww - 1, wh - 1, newbitmap,
  192. pixels + 4 * (x - xn) + 4 * w * (y - yn));
  193. caca_free_bitmap(newbitmap);
  194. }
  195. else
  196. {
  197. caca_draw_bitmap(0, 0, ww - 1, wh - 1, bitmap, pixels);
  198. }
  199. caca_set_color(CACA_COLOR_WHITE, CACA_COLOR_BLUE);
  200. caca_draw_line(0, 0, ww - 1, 0, ' ');
  201. caca_draw_line(0, wh - 1, ww - 1, wh - 1, '-');
  202. caca_putstr(0, 0, "q:Quit +/-/x:Zoom h/j/k/l: Move "
  203. "d:Dithering ?:Help");
  204. caca_printf(3, wh - 1, "cacaview %s", VERSION);
  205. caca_printf(ww - 14, wh - 1,
  206. "(zoom: %s%i)", zoom > 0 ? "+" : "", zoom);
  207. if(help)
  208. {
  209. caca_putstr(2, 2, " +: zoom in ");
  210. caca_putstr(2, 3, " -: zoom out ");
  211. caca_putstr(2, 4, " x: reset zoom ");
  212. caca_putstr(2, 5, " ------------------- ");
  213. caca_putstr(2, 6, " hjkl: move view ");
  214. caca_putstr(2, 7, " arrows: move view ");
  215. caca_putstr(2, 8, " ------------------- ");
  216. caca_putstr(2, 9, " d: dithering method ");
  217. caca_putstr(2, 10, " ------------------- ");
  218. caca_putstr(2, 11, " ?: help ");
  219. caca_putstr(2, 12, " q: quit ");
  220. help = 0;
  221. }
  222. caca_refresh();
  223. update = 0;
  224. }
  225. }
  226. if(bitmap)
  227. caca_free_bitmap(bitmap);
  228. if(image)
  229. imlib_free_image();
  230. /* Clean up */
  231. caca_end();
  232. return 0;
  233. }
  234. static void load_image(const char *name)
  235. {
  236. /* Empty previous data */
  237. if(image)
  238. imlib_free_image();
  239. if(bitmap)
  240. caca_free_bitmap(bitmap);
  241. image = NULL;
  242. bitmap = NULL;
  243. /* Load the new image */
  244. image = imlib_load_image(name);
  245. if(!image)
  246. {
  247. return;
  248. }
  249. imlib_context_set_image(image);
  250. pixels = (char *)imlib_image_get_data_for_reading_only();
  251. w = imlib_image_get_width();
  252. h = imlib_image_get_height();
  253. x = w / 2;
  254. y = h / 2;
  255. /* Create the libcaca bitmap */
  256. bitmap = caca_create_bitmap(32, w, h, 4 * w,
  257. 0x00ff0000, 0x0000ff00, 0x000000ff);
  258. if(!bitmap)
  259. {
  260. imlib_free_image();
  261. image = NULL;
  262. }
  263. }