w3m

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/w3m.git/
Log | Files | Refs | README

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 }