4 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
26 static struct images all_images
= TAILQ_HEAD_INITIALIZER(all_images
);
27 static u_int all_images_count
;
30 image_free(struct image
*im
)
32 struct screen
*s
= im
->s
;
34 TAILQ_REMOVE(&all_images
, im
, all_entry
);
37 TAILQ_REMOVE(&s
->images
, im
, entry
);
44 image_free_all(struct screen
*s
)
46 struct image
*im
, *im1
;
47 int redraw
= !TAILQ_EMPTY(&s
->images
);
49 TAILQ_FOREACH_SAFE(im
, &s
->images
, entry
, im1
)
54 /* Create text placeholder for an image. */
56 image_fallback(char **ret
, u_int sx
, u_int sy
)
59 u_int py
, size
, lsize
;
61 /* Allocate first line. */
62 lsize
= xasprintf(&label
, "SIXEL IMAGE (%ux%u)\r\n", sx
, sy
) + 1;
68 /* Remaining lines. Every placeholder line has \r\n at the end. */
69 size
+= (sx
+ 2) * (sy
- 1) + 1;
70 *ret
= buf
= xmalloc(size
);
72 /* Render first line. */
74 memcpy(buf
, label
, lsize
);
77 memcpy(buf
, label
, lsize
- 3);
79 memset(buf
, '+', sx
- lsize
+ 3);
80 buf
+= sx
- lsize
+ 3;
81 snprintf(buf
, 3, "\r\n");
85 /* Remaining lines. */
86 for (py
= 1; py
< sy
; py
++) {
89 snprintf(buf
, 3, "\r\n");
97 image_store(struct screen
*s
, struct sixel_image
*si
)
101 im
= xcalloc(1, sizeof *im
);
107 sixel_size_in_cells(si
, &im
->sx
, &im
->sy
);
109 image_fallback(&im
->fallback
, im
->sx
, im
->sy
);
111 TAILQ_INSERT_TAIL(&s
->images
, im
, entry
);
113 TAILQ_INSERT_TAIL(&all_images
, im
, all_entry
);
114 if (++all_images_count
== 10/*XXX*/)
115 image_free(TAILQ_FIRST(&all_images
));
121 image_check_line(struct screen
*s
, u_int py
, u_int ny
)
123 struct image
*im
, *im1
;
126 TAILQ_FOREACH_SAFE(im
, &s
->images
, entry
, im1
) {
127 if (py
+ ny
> im
->py
&& py
< im
->py
+ im
->sy
) {
136 image_check_area(struct screen
*s
, u_int px
, u_int py
, u_int nx
, u_int ny
)
138 struct image
*im
, *im1
;
141 TAILQ_FOREACH_SAFE(im
, &s
->images
, entry
, im1
) {
142 if (py
+ ny
<= im
->py
|| py
>= im
->py
+ im
->sy
)
144 if (px
+ nx
<= im
->px
|| px
>= im
->px
+ im
->sx
)
153 image_scroll_up(struct screen
*s
, u_int lines
)
155 struct image
*im
, *im1
;
158 struct sixel_image
*new;
160 TAILQ_FOREACH_SAFE(im
, &s
->images
, entry
, im1
) {
161 if (im
->py
>= lines
) {
166 if (im
->py
+ im
->sy
<= lines
) {
172 sy
= (im
->py
+ im
->sy
) - lines
;
174 new = sixel_scale(im
->data
, 0, 0, 0, im
->sy
- sy
, sx
, sy
, 1);
175 sixel_free(im
->data
);
179 sixel_size_in_cells(im
->data
, &im
->sx
, &im
->sy
);
182 image_fallback(&im
->fallback
, im
->sx
, im
->sy
);