… | |
… | |
175 | # endif |
175 | # endif |
176 | |
176 | |
177 | return false; |
177 | return false; |
178 | } |
178 | } |
179 | |
179 | |
180 | bool bgPixmap_t::need_client_side_rendering () |
|
|
181 | { |
|
|
182 | # ifdef HAVE_AFTERIMAGE |
|
|
183 | if (original_asim) |
|
|
184 | return true; |
|
|
185 | # endif |
|
|
186 | return false; |
|
|
187 | } |
|
|
188 | |
|
|
189 | # ifdef BG_IMAGE_FROM_FILE |
180 | # ifdef BG_IMAGE_FROM_FILE |
190 | static inline bool |
181 | static inline bool |
191 | check_set_scale_value (int geom_flags, int flag, unsigned int &scale, unsigned int new_value) |
182 | check_set_scale_value (int geom_flags, int flag, unsigned int &scale, unsigned int new_value) |
192 | { |
183 | { |
193 | if (geom_flags & flag) |
184 | if (geom_flags & flag) |
… | |
… | |
262 | int x = 0, y = 0; |
253 | int x = 0, y = 0; |
263 | unsigned int w = 0, h = 0; |
254 | unsigned int w = 0, h = 0; |
264 | unsigned int n; |
255 | unsigned int n; |
265 | unsigned long new_flags = (flags & (~geometryFlags)); |
256 | unsigned long new_flags = (flags & (~geometryFlags)); |
266 | const char *ops; |
257 | const char *ops; |
267 | # define MAXLEN_GEOM 256 /* could be longer than regular geometry string */ |
|
|
268 | |
258 | |
269 | if (geom == NULL) |
259 | if (geom == NULL) |
270 | return false; |
260 | return false; |
271 | |
261 | |
272 | char str[MAXLEN_GEOM]; |
262 | char str[256]; |
273 | |
263 | |
274 | ops = strchr (geom, ':'); |
264 | ops = strchr (geom, ':'); |
275 | if (ops == NULL) |
265 | if (ops == NULL) |
276 | n = strlen (geom); |
266 | n = strlen (geom); |
277 | else |
267 | else |
278 | n = ops - geom; |
268 | n = ops - geom; |
279 | |
269 | |
280 | if (n >= MAXLEN_GEOM) |
270 | if (n >= sizeof (str)) |
281 | return false; |
271 | return false; |
282 | |
272 | |
283 | memcpy (str, geom, n); |
273 | memcpy (str, geom, n); |
284 | str[n] = '\0'; |
274 | str[n] = '\0'; |
285 | rxvt_strtrim (str); |
275 | rxvt_strtrim (str); |
… | |
… | |
307 | geom_flags |= WidthValue|HeightValue|XValue|YValue; |
297 | geom_flags |= WidthValue|HeightValue|XValue|YValue; |
308 | } |
298 | } |
309 | |
299 | |
310 | if (ops) |
300 | if (ops) |
311 | { |
301 | { |
312 | while (*ops) |
302 | char **arr = rxvt_strsplit (':', ops + 1); |
313 | { |
|
|
314 | while (*ops == ':' || isspace(*ops)) ++ops; |
|
|
315 | |
303 | |
316 | # define CHECK_GEOM_OPS(op_str) (strncasecmp (ops, (op_str), sizeof (op_str) - 1) == 0) |
304 | for (int i = 0; arr[i]; i++) |
317 | if (CHECK_GEOM_OPS ("tile")) |
305 | { |
|
|
306 | if (!strcasecmp (arr[i], "tile")) |
318 | { |
307 | { |
319 | w = h = noScale; |
308 | w = h = noScale; |
320 | geom_flags |= WidthValue|HeightValue; |
309 | geom_flags |= WidthValue|HeightValue; |
321 | } |
310 | } |
322 | else if (CHECK_GEOM_OPS ("propscale")) |
311 | else if (!strcasecmp (arr[i], "propscale")) |
323 | { |
312 | { |
324 | new_flags |= propScale; |
313 | new_flags |= propScale; |
325 | } |
314 | } |
326 | else if (CHECK_GEOM_OPS ("hscale")) |
315 | else if (!strcasecmp (arr[i], "hscale")) |
327 | { |
316 | { |
328 | if (w == 0) w = windowScale; |
317 | if (w == 0) w = windowScale; |
329 | |
318 | |
330 | h = noScale; |
319 | h = noScale; |
331 | geom_flags |= WidthValue|HeightValue; |
320 | geom_flags |= WidthValue|HeightValue; |
332 | } |
321 | } |
333 | else if (CHECK_GEOM_OPS ("vscale")) |
322 | else if (!strcasecmp (arr[i], "vscale")) |
334 | { |
323 | { |
335 | if (h == 0) h = windowScale; |
324 | if (h == 0) h = windowScale; |
336 | |
325 | |
337 | w = noScale; |
326 | w = noScale; |
338 | geom_flags |= WidthValue|HeightValue; |
327 | geom_flags |= WidthValue|HeightValue; |
339 | } |
328 | } |
340 | else if (CHECK_GEOM_OPS ("scale")) |
329 | else if (!strcasecmp (arr[i], "scale")) |
341 | { |
330 | { |
342 | if (h == 0) h = windowScale; |
331 | if (h == 0) h = windowScale; |
343 | if (w == 0) w = windowScale; |
332 | if (w == 0) w = windowScale; |
344 | |
333 | |
345 | geom_flags |= WidthValue|HeightValue; |
334 | geom_flags |= WidthValue|HeightValue; |
346 | } |
335 | } |
347 | else if (CHECK_GEOM_OPS ("auto")) |
336 | else if (!strcasecmp (arr[i], "auto")) |
348 | { |
337 | { |
349 | w = h = windowScale; |
338 | w = h = windowScale; |
350 | x = y = centerAlign; |
339 | x = y = centerAlign; |
351 | geom_flags |= WidthValue|HeightValue|XValue|YValue; |
340 | geom_flags |= WidthValue|HeightValue|XValue|YValue; |
352 | } |
341 | } |
353 | else if (CHECK_GEOM_OPS ("root")) |
342 | else if (!strcasecmp (arr[i], "root")) |
354 | { |
343 | { |
355 | new_flags |= rootAlign; |
344 | new_flags |= rootAlign; |
356 | w = h = noScale; |
345 | w = h = noScale; |
357 | geom_flags |= WidthValue|HeightValue; |
346 | geom_flags |= WidthValue|HeightValue; |
358 | } |
347 | } |
359 | # undef CHECK_GEOM_OPS |
|
|
360 | |
|
|
361 | while (*ops != ':' && *ops != '\0') ++ops; |
|
|
362 | } /* done parsing ops */ |
348 | } /* done parsing ops */ |
|
|
349 | |
|
|
350 | rxvt_free_strsplit (arr); |
363 | } |
351 | } |
364 | |
352 | |
365 | if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) changed = true; |
353 | if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) changed = true; |
366 | if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) changed = true; |
354 | if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) changed = true; |
367 | if (check_set_align_value (geom_flags, XValue, h_align, x)) changed = true; |
355 | if (check_set_align_value (geom_flags, XValue, h_align, x)) changed = true; |
… | |
… | |
606 | GC gc; |
594 | GC gc; |
607 | |
595 | |
608 | /* create Pixmap */ |
596 | /* create Pixmap */ |
609 | if (pixmap == None |
597 | if (pixmap == None |
610 | || pmap_width != new_pmap_width |
598 | || pmap_width != new_pmap_width |
611 | || pmap_height != new_pmap_height |
599 | || pmap_height != new_pmap_height) |
612 | || pmap_depth != target->depth) |
|
|
613 | { |
600 | { |
614 | if (pixmap) |
601 | if (pixmap) |
615 | XFreePixmap (target->dpy, pixmap); |
602 | XFreePixmap (target->dpy, pixmap); |
616 | pixmap = XCreatePixmap (target->dpy, target->vt, new_pmap_width, new_pmap_height, target->depth); |
603 | pixmap = XCreatePixmap (target->dpy, target->vt, new_pmap_width, new_pmap_height, target->depth); |
617 | pmap_width = new_pmap_width; |
604 | pmap_width = new_pmap_width; |
618 | pmap_height = new_pmap_height; |
605 | pmap_height = new_pmap_height; |
619 | pmap_depth = target->depth; |
|
|
620 | } |
606 | } |
621 | /* fill with background color (if result's not completely overlapping it) */ |
607 | /* fill with background color (if result's not completely overlapping it) */ |
622 | gcv.foreground = target->pix_colors[Color_bg]; |
608 | gcv.foreground = target->pix_colors[Color_bg]; |
623 | gc = XCreateGC (target->dpy, target->vt, GCForeground, &gcv); |
609 | gc = XCreateGC (target->dpy, target->vt, GCForeground, &gcv); |
624 | |
610 | |
… | |
… | |
708 | { |
694 | { |
709 | free (data); |
695 | free (data); |
710 | return false; |
696 | return false; |
711 | } |
697 | } |
712 | |
698 | |
713 | ximage->byte_order = byteorder.big_endian () ? MSBFirst : LSBFirst; |
699 | ximage->byte_order = byteorder::big_endian () ? MSBFirst : LSBFirst; |
714 | |
700 | |
715 | rowstride = gdk_pixbuf_get_rowstride (pixbuf); |
701 | rowstride = gdk_pixbuf_get_rowstride (pixbuf); |
716 | channels = gdk_pixbuf_get_n_channels (pixbuf); |
702 | channels = gdk_pixbuf_get_n_channels (pixbuf); |
717 | row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; |
703 | row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; |
718 | line = data; |
704 | line = data; |
… | |
… | |
815 | } |
801 | } |
816 | } |
802 | } |
817 | |
803 | |
818 | if (pixmap == None |
804 | if (pixmap == None |
819 | || pmap_width != new_pmap_width |
805 | || pmap_width != new_pmap_width |
820 | || pmap_height != new_pmap_height |
806 | || pmap_height != new_pmap_height) |
821 | || pmap_depth != target->depth) |
|
|
822 | { |
807 | { |
823 | if (pixmap) |
808 | if (pixmap) |
824 | XFreePixmap (target->dpy, pixmap); |
809 | XFreePixmap (target->dpy, pixmap); |
825 | pixmap = XCreatePixmap (target->dpy, target->vt, new_pmap_width, new_pmap_height, target->depth); |
810 | pixmap = XCreatePixmap (target->dpy, target->vt, new_pmap_width, new_pmap_height, target->depth); |
826 | pmap_width = new_pmap_width; |
811 | pmap_width = new_pmap_width; |
827 | pmap_height = new_pmap_height; |
812 | pmap_height = new_pmap_height; |
828 | pmap_depth = target->depth; |
|
|
829 | } |
813 | } |
830 | |
814 | |
831 | gcv.foreground = target->pix_colors[Color_bg]; |
815 | gcv.foreground = target->pix_colors[Color_bg]; |
832 | gc = XCreateGC (target->dpy, target->vt, GCForeground, &gcv); |
816 | gc = XCreateGC (target->dpy, target->vt, GCForeground, &gcv); |
833 | |
817 | |
… | |
… | |
940 | if (image) |
924 | if (image) |
941 | { |
925 | { |
942 | if (original_asim) |
926 | if (original_asim) |
943 | safe_asimage_destroy (original_asim); |
927 | safe_asimage_destroy (original_asim); |
944 | original_asim = image; |
928 | original_asim = image; |
|
|
929 | flags |= CLIENT_RENDER; |
945 | have_image = true; |
930 | have_image = true; |
946 | return true; |
931 | return true; |
947 | } |
932 | } |
948 | # endif |
933 | # endif |
949 | |
934 | |
… | |
… | |
1021 | bool has_shade = shade != 100; |
1006 | bool has_shade = shade != 100; |
1022 | |
1007 | |
1023 | if (tint) |
1008 | if (tint) |
1024 | { |
1009 | { |
1025 | tint->get (c); |
1010 | tint->get (c); |
1026 | # define IS_COMPONENT_WHOLESOME(cmp) ((cmp) <= 0x00ff || (cmp) >= 0xff00) |
|
|
1027 | if (!has_shade |
1011 | if (!has_shade |
1028 | && IS_COMPONENT_WHOLESOME (c.r) |
1012 | && (c.r <= 0x00ff || c.r >= 0xff00) |
1029 | && IS_COMPONENT_WHOLESOME (c.g) |
1013 | && (c.g <= 0x00ff || c.g >= 0xff00) |
1030 | && IS_COMPONENT_WHOLESOME (c.b)) |
1014 | && (c.b <= 0x00ff || c.b >= 0xff00)) |
1031 | flags |= bgPixmap_t::tintWholesome; |
1015 | flags |= bgPixmap_t::tintWholesome; |
1032 | # undef IS_COMPONENT_WHOLESOME |
|
|
1033 | } |
1016 | } |
1034 | |
1017 | |
1035 | if (has_shade || tint) |
1018 | if (has_shade || tint) |
1036 | flags |= bgPixmap_t::tintNeeded; |
1019 | flags |= bgPixmap_t::tintNeeded; |
1037 | |
1020 | |
… | |
… | |
1044 | if (!(flags & tintSet) || tint != new_tint) |
1027 | if (!(flags & tintSet) || tint != new_tint) |
1045 | { |
1028 | { |
1046 | unsigned long new_flags = compute_tint_shade_flags (&new_tint, shade); |
1029 | unsigned long new_flags = compute_tint_shade_flags (&new_tint, shade); |
1047 | tint = new_tint; |
1030 | tint = new_tint; |
1048 | flags = (flags & ~tintFlags) | new_flags | tintSet; |
1031 | flags = (flags & ~tintFlags) | new_flags | tintSet; |
1049 | return true; |
|
|
1050 | } |
|
|
1051 | |
|
|
1052 | return false; |
|
|
1053 | } |
|
|
1054 | |
|
|
1055 | bool |
|
|
1056 | bgPixmap_t::unset_tint () |
|
|
1057 | { |
|
|
1058 | unsigned long new_flags = compute_tint_shade_flags (NULL, shade); |
|
|
1059 | |
|
|
1060 | if (new_flags != (flags & tintFlags)) |
|
|
1061 | { |
|
|
1062 | flags = (flags & ~tintFlags) | new_flags; |
|
|
1063 | return true; |
1032 | return true; |
1064 | } |
1033 | } |
1065 | |
1034 | |
1066 | return false; |
1035 | return false; |
1067 | } |
1036 | } |
… | |
… | |
1377 | { |
1346 | { |
1378 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
1347 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
1379 | result |= transpPmapTiled; |
1348 | result |= transpPmapTiled; |
1380 | XFreeGC (dpy, gc); |
1349 | XFreeGC (dpy, gc); |
1381 | |
1350 | |
1382 | if (!need_client_side_rendering ()) |
1351 | if (!(flags & CLIENT_RENDER)) |
1383 | { |
1352 | { |
1384 | if ((flags & blurNeeded) |
1353 | if ((flags & blurNeeded) |
1385 | && (flags & HAS_RENDER_CONV)) |
1354 | && (flags & HAS_RENDER_CONV)) |
1386 | { |
1355 | { |
1387 | if (blur_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) |
1356 | if (blur_pixmap (tiled_root_pmap, target->visual, window_width, window_height)) |
… | |
… | |
1399 | XFreePixmap (dpy, pixmap); |
1368 | XFreePixmap (dpy, pixmap); |
1400 | |
1369 | |
1401 | pixmap = tiled_root_pmap; |
1370 | pixmap = tiled_root_pmap; |
1402 | pmap_width = window_width; |
1371 | pmap_width = window_width; |
1403 | pmap_height = window_height; |
1372 | pmap_height = window_height; |
1404 | pmap_depth = target->depth; |
|
|
1405 | } |
1373 | } |
1406 | else |
1374 | else |
1407 | XFreePixmap (dpy, tiled_root_pmap); |
1375 | XFreePixmap (dpy, tiled_root_pmap); |
1408 | |
1376 | |
1409 | if (recoded_root_pmap != root_pixmap) |
1377 | if (recoded_root_pmap != root_pixmap) |
… | |
… | |
1594 | uint32_t mask_r, mask_g, mask_b; |
1562 | uint32_t mask_r, mask_g, mask_b; |
1595 | uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; |
1563 | uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; |
1596 | rgba low; |
1564 | rgba low; |
1597 | rgba high; |
1565 | rgba high; |
1598 | int i; |
1566 | int i; |
1599 | int host_byte_order = byteorder.big_endian () ? MSBFirst : LSBFirst; |
1567 | int host_byte_order = byteorder::big_endian () ? MSBFirst : LSBFirst; |
1600 | |
1568 | |
1601 | if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; |
1569 | if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; |
1602 | |
1570 | |
1603 | /* for convenience */ |
1571 | /* for convenience */ |
1604 | mask_r = visual->red_mask; |
1572 | mask_r = visual->red_mask; |