… | |
… | |
71 | |
71 | |
72 | // since we require rgb24/argb32 formats from xrender we assume |
72 | // since we require rgb24/argb32 formats from xrender we assume |
73 | // that both 24 and 32 bpp MUST be supported by any screen that supports xrender |
73 | // that both 24 and 32 bpp MUST be supported by any screen that supports xrender |
74 | int depth = gdk_pixbuf_get_has_alpha (pb) ? 32 : 24; |
74 | int depth = gdk_pixbuf_get_has_alpha (pb) ? 32 : 24; |
75 | |
75 | |
|
|
76 | int byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; |
|
|
77 | |
76 | XImage xi; |
78 | XImage xi; |
77 | |
79 | |
78 | xi.width = width; |
80 | xi.width = width; |
79 | xi.height = height; |
81 | xi.height = height; |
80 | xi.xoffset = 0; |
82 | xi.xoffset = 0; |
81 | xi.format = ZPixmap; |
83 | xi.format = ZPixmap; |
82 | xi.byte_order = MSBFirst; // maybe go for host byte order, because servers are usually local? |
84 | xi.byte_order = ImageByteOrder (dpy); |
83 | xi.bitmap_unit = 32; |
85 | xi.bitmap_unit = 0; //XY only, unused |
84 | xi.bitmap_bit_order = MSBFirst; |
86 | xi.bitmap_bit_order = 0; //XY only, unused |
85 | xi.bitmap_pad = BitmapPad (dpy); |
87 | xi.bitmap_pad = BitmapPad (dpy); |
86 | xi.depth = depth; |
88 | xi.depth = depth; |
87 | xi.bytes_per_line = 0; |
89 | xi.bytes_per_line = 0; |
88 | xi.bits_per_pixel = 32; |
90 | xi.bits_per_pixel = 32; //Z only |
89 | xi.red_mask = 0x00ff0000; |
91 | xi.red_mask = 0x00000000; //Z only, unused |
90 | xi.green_mask = 0x0000ff00; |
92 | xi.green_mask = 0x00000000; //Z only, unused |
91 | xi.blue_mask = 0x000000ff; |
93 | xi.blue_mask = 0x00000000; //Z only, unused |
|
|
94 | xi.obdata = 0; // probably unused |
|
|
95 | |
|
|
96 | bool byte_order_mismatch = byte_order != xi.byte_order; |
92 | |
97 | |
93 | if (!XInitImage (&xi)) |
98 | if (!XInitImage (&xi)) |
94 | rxvt_fatal ("unable to initialise ximage, please report.\n"); |
99 | rxvt_fatal ("unable to initialise ximage, please report.\n"); |
95 | |
100 | |
96 | if (height > INT_MAX / xi.bytes_per_line) |
101 | if (height > INT_MAX / xi.bytes_per_line) |
… | |
… | |
104 | unsigned char *row = gdk_pixbuf_get_pixels (pb); |
109 | unsigned char *row = gdk_pixbuf_get_pixels (pb); |
105 | char *line = xi.data; |
110 | char *line = xi.data; |
106 | |
111 | |
107 | for (int y = 0; y < height; y++) |
112 | for (int y = 0; y < height; y++) |
108 | { |
113 | { |
109 | unsigned char r, g, b, a; |
|
|
110 | unsigned char *data = row; |
114 | unsigned char *src = row; |
|
|
115 | uint32_t *dst = (uint32_t *)line; |
111 | |
116 | |
112 | if (depth == 24) |
117 | if (depth == 24) |
113 | for (int x = 0; x < width; x++) |
118 | for (int x = 0; x < width; x++) |
114 | { |
119 | { |
115 | asm volatile("nop"); |
120 | uint8_t r = *src++; |
116 | r = *data++; |
121 | uint8_t g = *src++; |
117 | g = *data++; |
122 | uint8_t b = *src++; |
118 | b = *data++; |
123 | |
|
|
124 | uint32_t v = (r << 16) | (g << 8) | b; |
|
|
125 | |
|
|
126 | if (ecb_big_endian () ? !byte_order_mismatch : byte_order_mismatch) |
|
|
127 | v = ecb_bswap32 (v); |
|
|
128 | |
119 | *line++ = 0; |
129 | *dst++ = v; |
120 | *line++ = r; |
|
|
121 | *line++ = g; |
|
|
122 | *line++ = b; |
|
|
123 | asm volatile("nop"); |
|
|
124 | } |
130 | } |
125 | else |
131 | else |
126 | for (int x = 0; x < width; x++) |
132 | for (int x = 0; x < width; x++) |
127 | { |
133 | { |
128 | uint32_t v = *(uint32_t *)data; data += 4; |
134 | uint32_t v = *(uint32_t *)src; src += 4; |
129 | v = ecb_big_endian () ? ecb_rotr32 (v, 8) : ecb_rotl32 (v, 8); |
135 | |
130 | *(uint32_t *)line = x; line += 4; |
136 | if (ecb_little_endian ()) |
|
|
137 | v = ecb_bswap32 (v); |
|
|
138 | |
|
|
139 | v = ecb_rotr32 (v, 8); |
|
|
140 | |
|
|
141 | if (byte_order_mismatch) |
|
|
142 | v = ecb_bswap32 (v); |
|
|
143 | |
|
|
144 | *dst++ = v; |
131 | } |
145 | } |
132 | |
146 | |
133 | row += rowstride; |
147 | row += rowstride; |
|
|
148 | line += xi.bytes_per_line; |
134 | } |
149 | } |
135 | |
150 | |
136 | rxvt_img *img = new rxvt_img (s, XRenderFindStandardFormat (dpy, depth == 24 ? PictStandardRGB24 : PictStandardARGB32), 0, 0, width, height); |
151 | rxvt_img *img = new rxvt_img (s, XRenderFindStandardFormat (dpy, depth == 24 ? PictStandardRGB24 : PictStandardARGB32), 0, 0, width, height); |
137 | img->alloc (); |
152 | img->alloc (); |
138 | |
153 | |