w3mimgdisplay.c (7185B)
1 /* $Id$ */ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <ctype.h> 5 #include <string.h> 6 #include <sys/types.h> 7 #include <unistd.h> 8 #include "config.h" 9 #include "w3mimg/w3mimg.h" 10 11 w3mimg_op *w_op; 12 static char *background = NULL; 13 static int offset_x = 0, offset_y = 0; 14 static int defined_bg = 0, defined_x = 0, defined_y = 0, defined_test = 0; 15 static int defined_debug = 0; 16 static char *defined_size = NULL; 17 18 #define MAX_IMAGE 1000 19 static W3MImage *imageBuf = NULL; 20 static int maxImage = 0, maxAnim = 100, clearMargin = 0; 21 22 static void GetOption(int argc, char **argv); 23 static void DrawImage(char *buf, int redraw); 24 static void TermImage(void); 25 static void ClearImage(char *buf); 26 27 int 28 main(int argc, char **argv) 29 { 30 int len; 31 char buf[1024 + 128]; 32 #ifdef W3MIMGDISPLAY_SETUID 33 uid_t runner_uid = getuid(); 34 uid_t owner_uid = geteuid(); 35 36 /* swap real and effective */ 37 setreuid(owner_uid, runner_uid); 38 #endif 39 GetOption(argc, argv); 40 if (!defined_debug) 41 freopen(DEV_NULL_PATH, "w", stderr); 42 43 #ifdef W3MIMGDISPLAY_SETUID 44 /* 45 * back real and effective 46 * run w3mimg_open() in setuid privileges 47 */ 48 setreuid(runner_uid, owner_uid); 49 #endif 50 w_op = w3mimg_open(); 51 #ifdef W3MIMGDISPLAY_SETUID 52 /* make sure drop privileges now */ 53 setreuid(runner_uid, runner_uid); 54 #endif 55 if (w_op == NULL) 56 exit(1); 57 if (defined_x) 58 w_op->offset_x = offset_x; 59 if (defined_y) 60 w_op->offset_y = offset_y; 61 62 w_op->max_anim = maxAnim; 63 w_op->clear_margin = clearMargin; 64 65 if (defined_test) { 66 printf("%d %d\n", w_op->width - w_op->offset_x, 67 w_op->height - w_op->offset_y); 68 w_op->close(w_op); 69 exit(0); 70 } 71 72 if (defined_size) { 73 if (w_op->init(w_op)) { 74 W3MImage img; 75 int w, h; 76 if (w_op->get_image_size(w_op, &img, defined_size, &w, &h)) 77 printf("%d %d\n", w, h); 78 } 79 w_op->close(w_op); 80 exit(0); 81 } 82 83 w_op->set_background(w_op, background); 84 85 while (fgets(buf, sizeof(buf), stdin) != NULL) { 86 if (!(isdigit(buf[0]) && buf[1] == ';')) { 87 fputc('\n', stdout); 88 fflush(stdout); 89 continue; 90 } 91 len = strlen(buf); 92 if (buf[len - 1] == '\n') { 93 buf[--len] = '\0'; 94 if (buf[len - 1] == '\r') 95 buf[--len] = '\0'; 96 } 97 /* 98 * w3mimg protocol 99 * 0 1 2 .... 100 * +--+--+--+--+ ...... +--+--+ 101 * |op|; |args |\n| 102 * +--+--+--+--+ .......+--+--+ 103 * 104 * args is separeted by ';' 105 * op args 106 * 0; params draw image 107 * 1; params redraw image 108 * 2; -none- terminate drawing 109 * 3; -none- sync drawing 110 * 4; -none- nop, sync communication 111 * response '\n' 112 * 5; path get size of image, 113 * response "<width> <height>\n" 114 * 6; params(6) clear image 115 * 116 * params 117 * <n>;<x>;<y>;<w>;<h>;<sx>;<sy>;<sw>;<sh>;<path> 118 * params(6) 119 * <x>;<y>;<w>;<h> 120 * 121 */ 122 switch (buf[0]) { 123 case '0': 124 DrawImage(&buf[2], 0); 125 break; 126 case '1': 127 DrawImage(&buf[2], 1); 128 break; 129 case '2': 130 TermImage(); 131 break; 132 case '3': 133 w_op->sync(w_op); 134 break; 135 case '4': 136 fputs("\n", stdout); 137 fflush(stdout); 138 break; 139 case '5': 140 if (w_op->init(w_op)) { 141 W3MImage img; 142 int w, h; 143 if (w_op->get_image_size(w_op, &img, &buf[2], &w, &h)) { 144 fprintf(stdout, "%d %d\n", w, h); 145 fflush(stdout); 146 } 147 else { 148 fprintf(stdout, "\n"); 149 fflush(stdout); 150 } 151 } 152 else { 153 fprintf(stdout, "\n"); 154 fflush(stdout); 155 } 156 break; 157 case '6': 158 ClearImage(&buf[2]); 159 break; 160 } 161 } 162 TermImage(); 163 w_op->close(w_op); 164 exit(0); 165 } 166 167 static void 168 GetOption(int argc, char **argv) 169 { 170 int i; 171 172 for (i = 1; i < argc; i++) { 173 if (!strcmp("-bg", argv[i])) { 174 if (++i >= argc) 175 exit(1); 176 background = argv[i]; 177 defined_bg = 1; 178 } 179 else if (!strcmp("-x", argv[i])) { 180 if (++i >= argc) 181 exit(1); 182 offset_x = atoi(argv[i]); 183 defined_x = 1; 184 } 185 else if (!strcmp("-y", argv[i])) { 186 if (++i >= argc) 187 exit(1); 188 offset_y = atoi(argv[i]); 189 defined_y = 1; 190 } 191 else if (!strcmp("-test", argv[i])) { 192 defined_test = 1; 193 } 194 else if (!strcmp("-anim", argv[i])) { 195 if (++i >= argc) 196 exit(1); 197 maxAnim = atoi(argv[i]); 198 } 199 else if (!strcmp("-margin", argv[i])) { 200 if (++i >= argc) 201 exit(1); 202 clearMargin = atoi(argv[i]); 203 if (clearMargin < 0) 204 clearMargin = 0; 205 } 206 else if (!strcmp("-size", argv[i])) { 207 if (++i >= argc) 208 exit(1); 209 defined_size = argv[i]; 210 } 211 else if (!strcmp("-debug", argv[i])) { 212 defined_debug = 1; 213 } 214 else { 215 exit(1); 216 } 217 } 218 } 219 220 void 221 DrawImage(char *buf, int redraw) 222 { 223 char *p = buf; 224 int n = 0, x = 0, y = 0, w = 0, h = 0, sx = 0, sy = 0, sw = 0, sh = 0; 225 226 if (!p) 227 return; 228 for (; isdigit(*p); p++) 229 n = 10 * n + (*p - '0'); 230 if (*(p++) != ';') 231 return; 232 for (; isdigit(*p); p++) 233 x = 10 * x + (*p - '0'); 234 if (*(p++) != ';') 235 return; 236 for (; isdigit(*p); p++) 237 y = 10 * y + (*p - '0'); 238 if (*(p++) != ';') 239 return; 240 for (; isdigit(*p); p++) 241 w = 10 * w + (*p - '0'); 242 if (*(p++) != ';') 243 return; 244 for (; isdigit(*p); p++) 245 h = 10 * h + (*p - '0'); 246 if (*(p++) != ';') 247 return; 248 for (; isdigit(*p); p++) 249 sx = 10 * sx + (*p - '0'); 250 if (*(p++) != ';') 251 return; 252 for (; isdigit(*p); p++) 253 sy = 10 * sy + (*p - '0'); 254 if (*(p++) != ';') 255 return; 256 for (; isdigit(*p); p++) 257 sw = 10 * sw + (*p - '0'); 258 if (*(p++) != ';') 259 return; 260 for (; isdigit(*p); p++) 261 sh = 10 * sh + (*p - '0'); 262 if (*(p++) != ';') 263 return; 264 265 n--; 266 if (n < 0 || n >= MAX_IMAGE) 267 return; 268 if (redraw) { 269 if (!w_op->active(w_op) || n >= maxImage || !imageBuf[n].pixmap) 270 return; 271 goto draw_image; 272 } 273 w_op->init(w_op); 274 275 if (n >= maxImage) { 276 int i = maxImage; 277 maxImage = i ? (i * 2) : 2; 278 if (maxImage > MAX_IMAGE) 279 maxImage = MAX_IMAGE; 280 else if (n >= maxImage) 281 maxImage = n + 1; 282 imageBuf = (W3MImage *) realloc((void *)imageBuf, 283 sizeof(W3MImage) * maxImage); 284 for (; i < maxImage; i++) 285 imageBuf[i].pixmap = NULL; 286 } 287 if (imageBuf[n].pixmap) { 288 w_op->free_image(w_op, &imageBuf[n]); 289 imageBuf[n].pixmap = NULL; 290 } 291 292 if (w_op->load_image(w_op, &imageBuf[n], p, w, h) == 0) 293 imageBuf[n].pixmap = NULL; 294 295 draw_image: 296 if (imageBuf[n].pixmap) 297 w_op->show_image(w_op, &imageBuf[n], sx, sy, sw, sh, x, y); 298 } 299 300 void 301 TermImage(void) 302 { 303 w_op->finish(w_op); 304 if (imageBuf) { 305 int i; 306 for (i = 0; i < maxImage; i++) { 307 w_op->free_image(w_op, &imageBuf[i]); 308 } 309 free(imageBuf); 310 imageBuf = NULL; 311 } 312 maxImage = 0; 313 } 314 315 void 316 ClearImage(char *buf) 317 { 318 char *p = buf; 319 int x = 0, y = 0, w = 0, h = 0; 320 321 if (!p) 322 return; 323 for (; isdigit(*p); p++) 324 x = 10 * x + (*p - '0'); 325 if (*(p++) != ';') 326 return; 327 for (; isdigit(*p); p++) 328 y = 10 * y + (*p - '0'); 329 if (*(p++) != ';') 330 return; 331 for (; isdigit(*p); p++) 332 w = 10 * w + (*p - '0'); 333 if (*(p++) != ';') 334 return; 335 for (; isdigit(*p); p++) 336 h = 10 * h + (*p - '0'); 337 338 w_op->clear(w_op, 339 x + offset_x - w_op->clear_margin, 340 y + offset_y - w_op->clear_margin, 341 w + w_op->clear_margin * 2, h + w_op->clear_margin * 2); 342 }