char * rxvt_wcstombs (const wchar_t *str, int len) { if (len < 0) len = wcslen (str); mbstate mbs; char *r = (char *)rxvt_malloc (len * MB_CUR_MAX + 1); char *dst = r; while (len--) { ssize_t l = wcrtomb (dst, *str++, mbs); if (l < 0) { *dst++ = '?'; wcrtomb (0, 0, mbs); // reset undefined state } else dst += l; } *dst++ = 0; return (char *)rxvt_realloc (r, dst - r); }
/* EXTPROTO */ char* rxvt_wcstombs (const wchar_t* str, int len) { mbstate_t mbs; char* r; char* dst; if (len < 0) len = wcslen (str); memset (&mbs, 0, sizeof (mbs)); r = (char *)rxvt_malloc (len * MB_CUR_MAX + 1); dst = r; while (len--) { int l = wcrtomb (dst, *str++, &mbs); if (l < 0) *dst++ = '?'; else dst += l; } *dst++ = 0; return r; }
/* INTPROTO */ void kstate_add_xlat(char *str) { K_XLAT *xlat; u_int *pval_tmp; char *sval; int i; if (str == NULL) return; /* add a new xlat table in state */ if (pStateNow->num_xlat == 0) { pStateNow->xlat = rxvt_malloc(sizeof(K_XLAT)); } else /* prefer contiguous data, realloc */ pStateNow->xlat = rxvt_realloc (pStateNow->xlat, (pStateNow->num_xlat + 1) * sizeof(K_XLAT)); xlat = &pStateNow->xlat[pStateNow->num_xlat]; /* parse str and derive first, last, values */ xlat->first = (u_int) atoi(strtok(str, "-")); xlat->last = (u_int) atoi(strtok(NULL, ":")); i = 0; pval_tmp = calloc(MAX_VAL, sizeof(K_XLAT)); while ((sval = strtok(NULL, ",")) != NULL) pval_tmp[i++] = (u_int) (atoi(sval)); xlat->pval = calloc(i, sizeof(K_XLAT)); if (xlat->pval != NULL) MEMCPY(xlat->pval, pval_tmp, i * sizeof(u_int)); free(pval_tmp); pStateNow->num_xlat++; }
wchar_t * rxvt_mbstowcs (const char *str, int len) { if (len < 0) len = strlen (str); wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)); if ((ssize_t)mbstowcs (r, str, len + 1) < 0) *r = 0; return r; }
/* EXTPROTO */ wchar_t* rxvt_mbstowcs (const char* str) { wchar_t* r; int len = STRLEN (str); r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)); if (mbstowcs (r, str, len + 1) < 0) *r = 0; return r; }
/* INTPROTO */ void rxvt_Gr_NewWindow(rxvt_t *r, int nargs, int args[]) { int x, y; unsigned int w, h; Window win; grwin_t *grwin; Cursor cursor; if (nargs != 4) { rxvt_print_error("NewWindow: 4 args needed, got %d\n", nargs); return; } x = args[0] * TermWin_TotalWidth() / GRX_SCALE; y = args[1] * TermWin_TotalHeight() / GRX_SCALE; w = args[2] * TermWin_TotalWidth() / GRX_SCALE; h = args[3] * TermWin_TotalHeight() / GRX_SCALE; win = XCreateSimpleWindow(r->Xdisplay, r->TermWin.vt, x, y, w, h, 0, r->PixColors[Color_fg], r->PixColors[Color_bg]); cursor = XCreateFontCursor(r->Xdisplay, XC_crosshair); XDefineCursor(r->Xdisplay, win, cursor); XMapWindow(r->Xdisplay, win); XSelectInput(r->Xdisplay, win, ExposureMask); grwin = (grwin_t *) rxvt_malloc(sizeof(grwin_t)); grwin->win = win; grwin->x = x; grwin->y = y; grwin->w = w; grwin->h = h; grwin->screen = 0; grwin->prev = NULL; grwin->next = r->h->gr_root; if (grwin->next) grwin->next->prev = grwin; r->h->gr_root = grwin; grwin->graphics = NULL; r->h->graphics_up++; rxvt_tt_printf(r, "\033W%ld\n", (long)grwin->win); }
char * rxvt_wcstoutf8 (const wchar_t *str, int len) { if (len < 0) len = wcslen (str); char *r = (char *)rxvt_malloc (len * 4 + 1); char *p = r; while (len--) { unicode_t w = *str++ & UNICODE_MASK; if (w < 0x000080) *p++ = w; else if (w < 0x000800) *p++ = 0xc0 | ( w >> 6), *p++ = 0x80 | ( w & 0x3f); else if (w < 0x010000) *p++ = 0xe0 | ( w >> 12), *p++ = 0x80 | ((w >> 6) & 0x3f), *p++ = 0x80 | ( w & 0x3f); else if (w < 0x110000)
/* EXTPROTO */ char* rxvt_wcstoutf8 (const wchar_t* str) { char* r; char* p; int len; len = wcslen (str); r = (char *)rxvt_malloc (len * 4 + 1); p = r; while (len--) { unicode_t w = *str++ & UNICODE_MASK; if (w < 0x000080) *p++ = w; else if (w < 0x000800) { *p++ = 0xc0 | ( w >> 6); *p++ = 0x80 | ( w & 0x3f); } else if (w < 0x010000) {
/* EXTPROTO */ int rxvt_scale_pixmap(rxvt_t *r, int page, const char *geom) { int flags, changed = 0; int x = 0, y = 0; unsigned int w = 0, h = 0; unsigned int n; char *p, *str; bgPixmap_t *bgpixmap = &(PVTS(r, page)->bg); #define MAXLEN_GEOM sizeof("[1000x1000+1000+1000]") if (geom == NULL) return 0; str = rxvt_malloc(MAXLEN_GEOM + 1); if (!STRCMP(geom, "?")) { sprintf(str, "[%dx%d+%d+%d]", /* can't presume snprintf() ! */ min(bgpixmap->w, 9999), min(bgpixmap->h, 9999), min(bgpixmap->x, 9999), min(bgpixmap->y, 9999)); rxvt_xterm_seq(r, page, XTerm_title, str, CHAR_ST); rxvt_free(str); return 0; } if ((p = STRCHR(geom, ';')) == NULL) p = STRCHR(geom, '\0'); n = (p - geom); if (n <= MAXLEN_GEOM) { STRNCPY(str, geom, n); str[n] = '\0'; flags = XParseGeometry(str, &x, &y, &w, &h); if (!flags) { flags |= WidthValue; w = 0; } /* default is tile */ if (flags & WidthValue) { if (!(flags & XValue)) x = 50; if (!(flags & HeightValue)) h = w; if (w && !h) { w = (bgpixmap->w * w) / 100; h = bgpixmap->h; } else if (h && !w) { w = bgpixmap->w; h = (bgpixmap->h * h) / 100; } if (w > 1000) w = 1000; if (h > 1000) h = 1000; if (bgpixmap->w != (short)w) { bgpixmap->w = (short)w; changed++; } if (bgpixmap->h != (short)h) { bgpixmap->h = (short)h; changed++; } } if (!(flags & YValue)) { if (flags & XNegative) flags |= YNegative; y = x; } if (!(flags & WidthValue) && geom[0] != '=') { x += bgpixmap->x; y += bgpixmap->y; } else { if (flags & XNegative) x += 100; if (flags & YNegative) y += 100; } MIN_IT(x, 100); MIN_IT(y, 100); MAX_IT(x, 0); MAX_IT(y, 0); if (bgpixmap->x != x) { bgpixmap->x = x; changed++; } if (bgpixmap->y != y) { bgpixmap->y = y; changed++; } } rxvt_free(str); return changed; }
long PngReadFileToPixmap (Display* display, Window window, GC gc, char* filename, Pixmap* pixmap, long* w, long* h) { int red_mask, green_mask, blue_mask; int red_shift, green_shift, blue_shift; int start_shift, msb_flag; unsigned int start_mask, udat; XWindowAttributes win_attr; FILE* ifile; long display_depth; png_byte sig[8]; png_infop info_ptr; png_structp png_ptr; png_uint_32 png_width; png_uint_32 png_height; int png_depth; int png_color_type; png_uint_32 png_row_bytes; png_uint_32 png_channels; long rwidth; long rheight; long components; unsigned char* buf; png_byte** png_row_ptrs; long vwidth; long vheight; long stretched; XImage* image; Visual* visual; Pixmap pix; int i; char* data1; unsigned char r,g,b; long ptr = 0; long ptr2 = 0; long j; red_mask = green_mask = blue_mask = 0; red_shift = green_shift = blue_shift = 0; ifile = fopen(filename,"r"); if (ifile == NULL){ return -1; } display_depth = XDefaultDepth(display,XDefaultScreen(display)); fread(sig, 1, 8, ifile); if (png_sig_cmp(sig, 0, 8)){ fclose(ifile); return -1; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); if (png_ptr == NULL){ fclose(ifile); return -1; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL){ png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(ifile); return -1; } png_init_io(png_ptr, ifile); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &png_width, &png_height, &png_depth, &png_color_type, NULL, NULL, NULL); if (png_depth == 16){ png_set_strip_16(png_ptr); } png_row_bytes = png_get_rowbytes(png_ptr, info_ptr); png_channels = png_get_channels(png_ptr, info_ptr); if (png_depth < 8){ if (png_color_type == PNG_COLOR_TYPE_GRAY ){ png_set_expand_gray_1_2_4_to_8(png_ptr); png_row_bytes = png_width; }else{ png_set_expand(png_ptr); png_row_bytes = png_width; png_row_bytes = png_width * 3; png_channels = 3; } } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)){ png_set_expand(png_ptr); png_row_bytes = png_width; } if (png_color_type == PNG_COLOR_TYPE_GRAY || png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA){ png_set_gray_to_rgb(png_ptr); png_row_bytes = png_width; } if (png_color_type == PNG_COLOR_TYPE_PALETTE){ png_set_palette_to_rgb(png_ptr); png_row_bytes = png_width * 3; png_channels = 3; } rwidth = png_width; rheight = png_height; components = png_channels; /* possible integer overflow? */ assert ((int) png_row_bytes > 0); assert ((int) png_height > 0); assert (((int)png_row_bytes) * ((int)png_height) * sizeof(png_byte) > 0); buf = rxvt_malloc(png_row_bytes * png_height * sizeof(png_byte)); if (buf == NULL){ rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(ifile); return -1; } /* possible integer overflow? */ assert ((int) png_height > 0); assert (sizeof(png_bytep) * ((int)png_height) > 0); png_row_ptrs = rxvt_malloc (sizeof(png_bytep)*png_height); if (png_row_ptrs == NULL){ rxvt_msg (DBG_ERROR, DBG_IMAGES, "png read error: out of memory..\n"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(ifile); return -1; } for(i = 0; i < (int)png_height; i++){ png_row_ptrs[i] = (png_byte*)(buf + i * png_row_bytes); } png_read_image(png_ptr, png_row_ptrs); png_read_end(png_ptr,NULL); rxvt_free(png_row_ptrs); vwidth = *w; vheight = *h; stretched =0; if (*w == 0 || *h == 0){ *w = rwidth; *h = rheight; }else{ if ((long)((double)rwidth * vheight/vwidth) < rheight){ *w = (long)((double)vheight * rwidth/rheight); }else{ *h = (long)((double)vwidth * rheight/rwidth); } stretched = 1; } vwidth = *w; vheight = *h; image = 0; visual = XDefaultVisual(display,XDefaultScreen(display)); if (display_depth >16){ image = XCreateImage(display,visual, display_depth, ZPixmap,0,0,vwidth,vheight,32,0); }else if (display_depth >8){ image = XCreateImage(display,visual, display_depth, ZPixmap,0,0,vwidth,vheight,16,0); }else{ image = XCreateImage(display,visual, display_depth, ZPixmap,0,0,vwidth,vheight,8,0); } msb_flag = (ImageByteOrder(display) == MSBFirst)?1:0; if (XGetWindowAttributes(display, RootWindow(display, DefaultScreen(display)), &win_attr) == 0) { fclose(ifile); return -1; } if ((win_attr.depth == 24) || (win_attr.depth == 16)) { unsigned int n; if (win_attr.depth == 24) { start_shift = 24; start_mask = 0x80000000; }else{ start_shift = 8; start_mask = 0x8000; } red_mask = win_attr.visual->red_mask; red_shift = start_shift; n = start_mask; while (!(n & red_mask)) { n >>= 1; red_shift--; } green_mask = win_attr.visual->green_mask; green_shift = start_shift; n = start_mask; while (!(n & green_mask)) { n >>= 1; green_shift--; } blue_mask = win_attr.visual->blue_mask; blue_shift = start_shift; n = start_mask; while (!(n & blue_mask)) { n >>= 1; blue_shift--; } }
green_shift--; } blue_mask = win_attr.visual->blue_mask; blue_shift = start_shift; n = start_mask; while (!(n & blue_mask)) { n >>= 1; blue_shift--; } } /* possible integer overflow? */ assert ((int) image->bytes_per_line > 0); assert ((int) vheight > 0); assert (((int)image->bytes_per_line) * ((int)vheight) > 0); data1 = rxvt_malloc(image->bytes_per_line * vheight); if (image->bits_per_pixel ==32){ if (components == 3 || components == 4){ for(i=0; i<vheight; i++){ for(j=0; j<vwidth; j++){ if (stretched != 0){ ptr = (long)((double)i*rheight/vheight)*rwidth + (long)((double)j*rwidth/vwidth); ptr *= 3; } r = buf[ptr++]; g = buf[ptr++]; b = buf[ptr++]; if (components == 4){ ptr++; }