diff --git a/ChangeLog b/ChangeLog index 546dfb1..255d8d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3553,3 +3553,10 @@ Wed May 3 21:04:37 PDT 2000 Michael Jennings another menuitem is selected. ------------------------------------------------------------------------------- +Thu May 4 00:32:45 PDT 2000 Michael Jennings + + Added new shade/tint routines, including some done in MMX assembly, by + Willem Monsuwe . Thanks Willem! These should prove + to be faster than the old stuff, probably by quite a bit. + +------------------------------------------------------------------------------- diff --git a/acconfig.h b/acconfig.h index 394e595..130fd33 100644 --- a/acconfig.h +++ b/acconfig.h @@ -331,6 +331,7 @@ #undef CONFIG_BUFF #undef PKGDATADIR #undef HAVE_LIBIMLIB2 +#undef HAVE_MMX /* Leave that blank line there!! Autoheader needs it. diff --git a/configure.in b/configure.in index 929b392..4e32aec 100644 --- a/configure.in +++ b/configure.in @@ -111,7 +111,7 @@ AC_CHECK_SIZEOF(int, 4) AC_CHECK_SIZEOF(long, 4) AC_CHECK_SIZEOF(void *, 4) AC_CHECK_SIZEOF(long long, 8) -dnl AC_C_BIGENDIAN +AC_C_BIGENDIAN AC_C_CONST AC_C_INLINE @@ -322,6 +322,23 @@ AC_ARG_ENABLE(trans, fi, AC_MSG_RESULT(yes) AC_DEFINE(PIXMAP_OFFSET) ) + +AC_MSG_CHECKING(for MMX support) +HAVE_MMX="" +AC_ARG_ENABLE(mmx, [ --enable-mmx enable MMX assembly routines], + test x$enableval = xyes && HAVE_MMX="yes" + , + if test x$build_os = xlinux-gnu; then + grep mmx /proc/cpuinfo >/dev/null 2>&1 && HAVE_MMX="yes" + fi + ) +if test -n "$HAVE_MMX"; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MMX) +else + AC_MSG_RESULT(no) +fi + AC_MSG_CHECKING(for utmp support) AC_ARG_ENABLE(utmp, [ --enable-utmp compile with utmp support], diff --git a/src/Makefile.am b/src/Makefile.am index e504a40..feb66f1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,7 @@ # $Id$ lib_LTLIBRARIES = libEterm.la +bin_PROGRAMS = Eterm libEterm_la_SOURCES = actions.c actions.h buttons.c buttons.h command.c \ command.h debug.h draw.c draw.h e.c e.h eterm_utmp.h \ @@ -9,15 +10,13 @@ libEterm_la_SOURCES = actions.c actions.h buttons.c buttons.h command.c \ options.c options.h pixmap.c pixmap.h profile.h screen.c \ screen.h scrollbar.c scrollbar.h startup.c startup.h \ system.c system.h term.c term.h timer.c timer.h utmp.c \ - windows.c windows.h - + windows.c windows.h mmx_cmod.S libEterm_la_DEPENDENCIES = $(top_builddir)/libmej/libmej.la feature.h libEterm_la_LDFLAGS = -release $(VERSION) -bin_PROGRAMS = Eterm Eterm_SOURCES = main.c Eterm_DEPENDENCIES = libEterm.la Eterm_LDFLAGS = -rpath $(libdir):$(pkglibdir) +Eterm_LDADD = libEterm.la $(top_builddir)/libmej/libmej.la -L$(libdir) -L$(prefix)/lib $(X_LIBS) $(GRLIBS) $(LIBS) INCLUDES = -I. -I$(top_srcdir) -I$(top_srcdir)/libmej -I.. -I$(includedir) -I$(prefix)/include $(X_CFLAGS) -LDADD = libEterm.la $(top_builddir)/libmej/libmej.la -L$(libdir) -L$(prefix)/lib $(X_LIBS) $(GRLIBS) $(LIBS) diff --git a/src/events.c b/src/events.c index 4b75fd7..a8f90ce 100644 --- a/src/events.c +++ b/src/events.c @@ -484,8 +484,6 @@ handle_focus_out(event_t * ev) unsigned char handle_configure_notify(event_t * ev) { - XEvent xevent; - D_EVENTS(("handle_configure_notify(ev [%8p] on window 0x%08x)\n", ev, ev->xany.window)); REQUIRE_RVAL(XEVENT_IS_MYWIN(ev, &primary_data), 0); diff --git a/src/mmx_cmod.S b/src/mmx_cmod.S new file mode 100644 index 0000000..f875062 --- /dev/null +++ b/src/mmx_cmod.S @@ -0,0 +1,482 @@ +/* + * Copyright (C) 1997-2000, Michael Jennings + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies of the Software, its documentation and marketing & publicity + * materials, and acknowledgment shall be given in the documentation, materials + * and software packages that this Software was used. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +/* MMX routines for tinting XImages written by Willem Monsuwe */ + +/* Function calling conventions: + * shade_ximage_xx(void *data, int bpl, int w, int h, int rm, int gm, int bm); + */ + +#ifdef HAVE_MMX + +#define data 8(%ebp) +#define bpl 12(%ebp) +#define w 16(%ebp) +#define h 20(%ebp) +#define rm 24(%ebp) +#define gm 28(%ebp) +#define bm 32(%ebp) + +.global shade_ximage_15_mmx + .type shade_ximage_15_mmx,@function +.global shade_ximage_16_mmx + .type shade_ximage_16_mmx,@function +.global shade_ximage_32_mmx + .type shade_ximage_32_mmx,@function + +.bss +.text +.align 8 + +#define ENTER \ + pushl %ebp ;\ + movl %esp, %ebp ;\ + pushl %ebx ;\ + pushl %ecx ;\ + pushl %edx ;\ + pushl %edi ;\ + pushl %esi ;\ + movl data, %esi ;\ + movl w, %ebx ;\ + movl h, %edx + +#define LEAVE \ +4: ;\ + emms ;\ + popl %esi ;\ + popl %edi ;\ + popl %edx ;\ + popl %ecx ;\ + popl %ebx ;\ + movl %ebp, %esp ;\ + popl %ebp ;\ + ret + + +shade_ximage_15_mmx: + ENTER + + leal -6(%esi, %ebx, 2), %esi + negl %ebx + jz 5f + + /* Setup multipliers */ + movd rm, %mm5 + movd gm, %mm6 + movd bm, %mm7 + punpcklwd %mm5, %mm5 /* 00 00 00 00 rm rm rm rm */ + punpcklwd %mm6, %mm6 /* 00 00 00 00 gm gm gm gm */ + punpcklwd %mm7, %mm7 /* 00 00 00 00 bm bm bm bm */ + punpckldq %mm5, %mm5 /* rm rm rm rm rm rm rm rm */ + punpckldq %mm6, %mm6 /* gm gm gm gm gm gm gm gm */ + punpckldq %mm7, %mm7 /* bm bm bm bm bm bm bm bm */ + + cmpl $256, rm + jg shade_ximage_15_mmx_saturate + cmpl $256, gm + jg shade_ximage_15_mmx_saturate + cmpl $256, bm + jg shade_ximage_15_mmx_saturate + +1: movl %ebx, %ecx + addl $3, %ecx + jns 3f +2: + movq (%esi, %ecx, 2), %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $10, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $11, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $3, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* 00 0r */ + pmulhw %mm6, %mm1 /* 00 0g */ + pmulhw %mm7, %mm2 /* 00 0b */ + + psllw $10, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movq %mm0, (%esi, %ecx, 2) + + addl $4, %ecx + js 2b + jz 4f +3: + movw (%esi, %ecx, 2), %ax + movd %eax, %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $10, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $11, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $3, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* 00 0r */ + pmulhw %mm6, %mm1 /* 00 0g */ + pmulhw %mm7, %mm2 /* 00 0b */ + + psllw $10, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movd %mm0, %eax + movw %ax, (%esi, %ecx, 2) + + incl %ecx + cmpl $2, %ecx + jng 3b +4: + addl bpl, %esi + decl %edx + jnz 1b +5: + LEAVE + + +shade_ximage_15_mmx_saturate: + + pcmpeqw %mm3, %mm3 + psllw $5, %mm3 /* ff e0 ff e0 ff e0 ff e0 */ + +1: movl %ebx, %ecx + addl $3, %ecx + jns 3f +2: + movq (%esi, %ecx, 2), %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $10, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $11, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $3, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* xx xr */ + pmulhw %mm6, %mm1 /* xx xg */ + pmulhw %mm7, %mm2 /* xx xb */ + + /* Saturate upper */ + paddusw %mm3, %mm0 /* ff er */ + paddusw %mm3, %mm1 /* ff eg */ + paddusw %mm3, %mm2 /* ff eb */ + + psubw %mm3, %mm1 /* 00 0g */ + psubw %mm3, %mm2 /* 00 0b */ + + psllw $10, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movq %mm0, (%esi, %ecx, 2) + + addl $4, %ecx + js 2b + jz 4f +3: + movw (%esi, %ecx, 2), %ax + movd %eax, %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $10, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $11, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $3, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* xx xr */ + pmulhw %mm6, %mm1 /* xx xg */ + pmulhw %mm7, %mm2 /* xx xb */ + + /* Saturate upper */ + paddusw %mm3, %mm0 /* ff er */ + paddusw %mm3, %mm1 /* ff eg */ + paddusw %mm3, %mm2 /* ff eb */ + + psubw %mm3, %mm1 /* 00 0g */ + psubw %mm3, %mm2 /* 00 0b */ + + psllw $10, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movd %mm0, %eax + movw %ax, (%esi, %ecx, 2) + + incl %ecx + cmpl $2, %ecx + jng 3b +4: + addl bpl, %esi + decl %edx + jnz 1b +5: + LEAVE + + +shade_ximage_16_mmx: + ENTER + + leal -6(%esi, %ebx, 2), %esi + negl %ebx + jz 5f + + /* Setup multipliers */ + movd rm, %mm5 + movd gm, %mm6 + movd bm, %mm7 + punpcklwd %mm5, %mm5 /* 00 00 00 00 rm rm rm rm */ + punpcklwd %mm6, %mm6 /* 00 00 00 00 gm gm gm gm */ + punpcklwd %mm7, %mm7 /* 00 00 00 00 bm bm bm bm */ + punpckldq %mm5, %mm5 /* rm rm rm rm rm rm rm rm */ + punpckldq %mm6, %mm6 /* gm gm gm gm gm gm gm gm */ + punpckldq %mm7, %mm7 /* bm bm bm bm bm bm bm bm */ + + cmpl $256, rm + jg shade_ximage_16_mmx_saturate + cmpl $256, gm + jg shade_ximage_16_mmx_saturate + cmpl $256, bm + jg shade_ximage_16_mmx_saturate + +1: movl %ebx, %ecx + addl $3, %ecx + jns 3f +2: + movq (%esi, %ecx, 2), %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $11, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $10, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $2, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* 00 0r */ + pmulhw %mm6, %mm1 /* 00 0g */ + pmulhw %mm7, %mm2 /* 00 0b */ + + psllw $11, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movq %mm0, (%esi, %ecx, 2) + + addl $4, %ecx + js 2b + jz 4f +3: + movw (%esi, %ecx, 2), %ax + movd %eax, %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $11, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $10, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $2, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* 00 0r */ + pmulhw %mm6, %mm1 /* 00 0g */ + pmulhw %mm7, %mm2 /* 00 0b */ + + psllw $11, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movd %mm0, %eax + movw %ax, (%esi, %ecx, 2) + + incl %ecx + cmpl $2, %ecx + jng 3b +4: + addl bpl, %esi + decl %edx + jnz 1b +5: + LEAVE + + +shade_ximage_16_mmx_saturate: + + pcmpeqw %mm3, %mm3 + movq %mm3, %mm4 + psllw $5, %mm3 /* ff e0 ff e0 ff e0 ff e0 */ + psllw $6, %mm4 /* ff c0 ff c0 ff c0 ff c0 */ + +1: movl %ebx, %ecx + addl $3, %ecx + jns 3f +2: + movq (%esi, %ecx, 2), %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $11, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $10, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $2, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* xx xr */ + pmulhw %mm6, %mm1 /* xx xg */ + pmulhw %mm7, %mm2 /* xx xb */ + + /* Saturate upper */ + paddusw %mm3, %mm0 /* ff er */ + paddusw %mm4, %mm1 /* ff cg */ + paddusw %mm3, %mm2 /* ff eb */ + + psubw %mm4, %mm1 /* 00 0g */ + psubw %mm3, %mm2 /* 00 0b */ + + psllw $11, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movq %mm0, (%esi, %ecx, 2) + + addl $4, %ecx + js 2b + jz 4f +3: + movw (%esi, %ecx, 2), %ax + movd %eax, %mm0 + + movq %mm0, %mm1 /* rg gb */ + movq %mm0, %mm2 /* rg gb */ + psrlw $5, %mm1 /* 0r rg */ + psrlw $11, %mm0 /* 00 0r */ + psllw $11, %mm2 /* b0 00 */ + psllw $10, %mm1 /* g0 00 */ + psllw $8, %mm0 /* 0r 00 */ + psrlw $2, %mm1 /* 0g 00 */ + psrlw $3, %mm2 /* 0b 00 */ + + pmulhw %mm5, %mm0 /* xx xr */ + pmulhw %mm6, %mm1 /* xx xg */ + pmulhw %mm7, %mm2 /* xx xb */ + + /* Saturate upper */ + paddusw %mm3, %mm0 /* ff er */ + paddusw %mm4, %mm1 /* ff cg */ + paddusw %mm3, %mm2 /* ff eb */ + + psubw %mm4, %mm1 /* 00 0g */ + psubw %mm3, %mm2 /* 00 0b */ + + psllw $11, %mm0 /* r0 00 */ + psllw $5, %mm1 /* 0g g0 */ + por %mm2, %mm0 /* r0 0b */ + por %mm1, %mm0 /* rg gb */ + + movd %mm0, %eax + movw %ax, (%esi, %ecx, 2) + + incl %ecx + cmpl $2, %ecx + jng 3b +4: + addl bpl, %esi + decl %edx + jnz 1b +5: + LEAVE + + +shade_ximage_32_mmx: + ENTER + + leal (%esi, %ebx, 4), %esi + negl %ebx + jz 3f + + movd rm, %mm4 + movd gm, %mm5 + movd bm, %mm6 + psllq $32, %mm4 + psllq $16, %mm5 + por %mm6, %mm4 + por %mm5, %mm4 + + pcmpeqw %mm6, %mm6 + psllw $15, %mm6 /* 80 00 80 00 80 00 80 00 */ + movq %mm6, %mm5 + pmulhw %mm4, %mm5 /* Get correction factor */ +1: + movl %ebx, %ecx +2: + movd (%esi, %ecx, 4), %mm1 /* 00 rr gg bb */ + pxor %mm0, %mm0 + punpcklbw %mm1, %mm0 /* 00 00 rr 00 gg 00 bb 00 */ + pxor %mm6, %mm0 /* Flip sign */ + + pmulhw %mm4, %mm0 /* 00 00 xx rr xx gg xx bb */ + psubw %mm5, %mm0 /* Correct range */ + packuswb %mm0, %mm0 /* 00 rr gg bb 00 rr gg bb */ + + movd %mm0, (%esi, %ecx, 4) + + incl %ecx + jnz 2b + + addl bpl, %esi + decl %edx + jnz 1b +3: + LEAVE + +#endif /* HAVE_MMX */ diff --git a/src/pixmap.c b/src/pixmap.c index 8d109e1..c56170d 100644 --- a/src/pixmap.c +++ b/src/pixmap.c @@ -53,6 +53,11 @@ static const char cvs_ident[] = "$Id$"; #include "term.h" #include "windows.h" +/* Assembler routines */ +extern void shade_ximage_15_mmx(void *data, int bpl, int w, int h, int rm, int gm, int bm); +extern void shade_ximage_16_mmx(void *data, int bpl, int w, int h, int rm, int gm, int bm); +extern void shade_ximage_32_mmx(void *data, int bpl, int w, int h, int rm, int gm, int bm); + #ifdef PIXMAP_SUPPORT static Imlib_Border bord_none = { 0, 0, 0, 0 }; static colormod_t cmod_none = { 256, 256, 256 }; @@ -1302,21 +1307,236 @@ need_colormod(register imlib_t *iml) } } +/* New optimized routines for tinting XImages written by Willem Monsuwe */ + +#ifndef HAVE_MMX +/* RGB 15 */ +static void +shade_ximage_15(void *data, int bpl, int w, int h, int rm, int gm, int bm) +{ + unsigned char *ptr; + int x, y; + + ptr = data + (w * sizeof(DATA16)); + if ((rm <= 256) && (gm <= 256) && (bm <= 256)) { + /* No saturation */ + for (y = h; --y >= 0; ) { + for (x = -w; x < 0; x++) { + int r, g, b; + b = ((DATA16 *)ptr)[x]; + r = (b & 0x7c00) * rm; + g = (b & 0x3e0) * gm; + b = (b & 0x1f) * bm; + ((DATA16 *)ptr)[x] = ((r >> 8) & 0x7c00) + | ((g >> 8) & 0x3e0) + | ((b >> 8) & 0x1f); + } + ptr += bpl; + } + } else { + for (y = h; --y >= 0; ) { + for (x = -w; x < 0; x++) { + int r, g, b; + b = ((DATA16 *)ptr)[x]; + r = (b & 0x7c00) * rm; + g = (b & 0x3e0) * gm; + b = (b & 0x1f) * bm; + r |= (!(r >> 15) - 1); + g |= (!(g >> 10) - 1); + b |= (!(b >> 5) - 1); + ((DATA16 *)ptr)[x] = ((r >> 8) & 0x7c00) + | ((g >> 8) & 0x3e0) + | ((b >> 8) & 0x1f); + } + ptr += bpl; + } + } +} + +/* RGB 16 */ +static void +shade_ximage_16(void *data, int bpl, int w, int h, int rm, int gm, int bm) +{ + unsigned char *ptr; + int x, y; + + ptr = data + (w * sizeof(DATA16)); + if ((rm <= 256) && (gm <= 256) && (bm <= 256)) { + /* No saturation */ + for (y = h; --y >= 0; ) { + for (x = -w; x < 0; x++) { + int r, g, b; + b = ((DATA16 *)ptr)[x]; + r = (b & 0xf800) * rm; + g = (b & 0x7e0) * gm; + b = (b & 0x1f) * bm; + ((DATA16 *)ptr)[x] = ((r >> 8) & 0xf800) + | ((g >> 8) & 0x7e0) + | ((b >> 8) & 0x1f); + } + ptr += bpl; + } + } else { + for (y = h; --y >= 0; ) { + for (x = -w; x < 0; x++) { + int r, g, b; + b = ((DATA16 *)ptr)[x]; + r = (b & 0xf800) * rm; + g = (b & 0x7e0) * gm; + b = (b & 0x1f) * bm; + r |= (!(r >> 16) - 1); + g |= (!(g >> 11) - 1); + b |= (!(b >> 5) - 1); + ((DATA16 *)ptr)[x] = ((r >> 8) & 0xf800) + | ((g >> 8) & 0x7e0) + | ((b >> 8) & 0x1f); + } + ptr += bpl; + } + } +} + +/* RGB 32 */ +static void +shade_ximage_32(void *data, int bpl, int w, int h, int rm, int gm, int bm) +{ + unsigned char *ptr; + int x, y; + + ptr = data + (w * 4); + if ((rm <= 256) && (gm <= 256) && (bm <= 256)) { + /* No saturation */ + for (y = h; --y >= 0; ) { + for (x = -(w * 4); x < 0; x += 4) { + int r, g, b; +# ifdef WORDS_BIGENDIAN + r = (ptr[x + 1] * rm) >> 8; + g = (ptr[x + 2] * gm) >> 8; + b = (ptr[x + 3] * bm) >> 8; + ptr[x + 1] = r; + ptr[x + 2] = g; + ptr[x + 3] = b; +# else + r = (ptr[x + 2] * rm) >> 8; + g = (ptr[x + 1] * gm) >> 8; + b = (ptr[x + 0] * bm) >> 8; + ptr[x + 2] = r; + ptr[x + 1] = g; + ptr[x + 0] = b; +# endif + } + ptr += bpl; + } + } else { + for (y = h; --y >= 0; ) { + for (x = -(w * 4); x < 0; x += 4) { + int r, g, b; +# ifdef WORDS_BIGENDIAN + r = (ptr[x + 1] * rm) >> 8; + g = (ptr[x + 2] * gm) >> 8; + b = (ptr[x + 3] * bm) >> 8; +# else + r = (ptr[x + 2] * rm) >> 8; + g = (ptr[x + 1] * gm) >> 8; + b = (ptr[x + 0] * bm) >> 8; +# endif + r |= (!(r >> 8) - 1); + g |= (!(g >> 8) - 1); + b |= (!(b >> 8) - 1); +# ifdef WORDS_BIGENDIAN + ptr[x + 1] = r; + ptr[x + 2] = g; + ptr[x + 3] = b; +# else + ptr[x + 2] = r; + ptr[x + 1] = g; + ptr[x + 0] = b; +# endif + } + ptr += bpl; + } + } +} +#endif + +/* RGB 24 */ +static void +shade_ximage_24(void *data, int bpl, int w, int h, int rm, int gm, int bm) +{ + unsigned char *ptr; + int x, y; + + ptr = data + (w * 3); + if ((rm <= 256) && (gm <= 256) && (bm <= 256)) { + /* No saturation */ + for (y = h; --y >= 0; ) { + for (x = -(w * 3); x < 0; x += 3) { + int r, g, b; +# ifdef WORDS_BIGENDIAN + r = (ptr[x + 0] * rm) >> 8; + g = (ptr[x + 1] * gm) >> 8; + b = (ptr[x + 2] * bm) >> 8; + ptr[x + 0] = r; + ptr[x + 1] = g; + ptr[x + 2] = b; +# else + r = (ptr[x + 0] * rm) >> 8; + g = (ptr[x + 1] * gm) >> 8; + b = (ptr[x + 2] * bm) >> 8; + ptr[x + 0] = r; + ptr[x + 1] = g; + ptr[x + 2] = b; +# endif + } + ptr += bpl; + } + } else { + for (y = h; --y >= 0; ) { + for (x = -(w * 3); x < 0; x += 3) { + int r, g, b; +# ifdef WORDS_BIGENDIAN + r = (ptr[x + 0] * rm) >> 8; + g = (ptr[x + 1] * gm) >> 8; + b = (ptr[x + 2] * bm) >> 8; +# else + r = (ptr[x + 2] * rm) >> 8; + g = (ptr[x + 1] * gm) >> 8; + b = (ptr[x + 0] * bm) >> 8; +# endif + r |= (!(r >> 8) - 1); + g |= (!(g >> 8) - 1); + b |= (!(b >> 8) - 1); +# ifdef WORDS_BIGENDIAN + ptr[x + 0] = r; + ptr[x + 1] = g; + ptr[x + 2] = b; +# else + ptr[x + 2] = r; + ptr[x + 1] = g; + ptr[x + 0] = b; +# endif + } + ptr += bpl; + } + } +} + void colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h) { XImage *ximg; - register unsigned long v, i; - unsigned long x, y; + register unsigned long i; #if 0 + register unsigned long v; + unsigned long x, y; int r, g, b; + register int br, bg, bb; + register unsigned int mr, mg, mb; #endif unsigned short rm, gm, bm, shade; Imlib_Color ctab[256]; int real_depth = 0; - register int br, bg, bb; - register unsigned int mr, mg, mb; D_PIXMAP(("colormod_trans(p == 0x%08x, gc, w == %hu, h == %hu) called.\n", p, w, h)); @@ -1365,7 +1585,7 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h XWindowAttributes xattr; XGetWindowAttributes(Xdisplay, desktop_window, &xattr); - if ((xattr.visual->red_mask == 0x7c00) && (xattr.visual->green_mask == 0x3e0) && (xattr.visual->blue_mask == 0x1f)) { + if ((xattr.visual->green_mask == 0x3e0)) { real_depth = 15; } } @@ -1394,48 +1614,49 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h #endif } else { D_PIXMAP(("Rendering high-depth image, depth == %d\n", real_depth)); + /* Swap rm and bm for bgr */ + { + XWindowAttributes xattr; + XGetWindowAttributes(Xdisplay, desktop_window, &xattr); + if (xattr.visual->blue_mask > xattr.visual->red_mask) { + unsigned short tmp; + tmp = rm; + rm = bm; + bm = tmp; + } + } /* Determine bitshift and bitmask values */ switch (real_depth) { case 15: - br = 7; - bg = 2; - bb = 3; - mr = mg = mb = 0xf8; +#ifdef HAVE_MMX + shade_ximage_15_mmx(ximg->data, ximg->bytes_per_line, w, h, rm, gm, bm); +#else + shade_ximage_15(ximg->data, ximg->bytes_per_line, w, h, rm, gm, bm); +#endif break; case 16: - br = 8; - bg = bb = 3; - mr = mb = 0xf8; - mg = 0xfc; +#ifdef HAVE_MMX + shade_ximage_16_mmx(ximg->data, ximg->bytes_per_line, w, h, rm, gm, bm); +#else + shade_ximage_16(ximg->data, ximg->bytes_per_line, w, h, rm, gm, bm); +#endif break; case 24: + if (ximg->bits_per_pixel != 32) { + shade_ximage_24(ximg->data, ximg->bytes_per_line, w, h, rm, gm, bm); + break; + } case 32: - br = 16; - bg = 8; - bb = 0; - mr = mg = mb = 0xff; +#ifdef HAVE_MMX + shade_ximage_32_mmx(ximg->data, ximg->bytes_per_line, w, h, rm, gm, bm); +#else + shade_ximage_32(ximg->data, ximg->bytes_per_line, w, h, rm, gm, bm); +#endif break; default: print_warning("Bit depth of %d is unsupported for tinting/shading.", real_depth); return; } - - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - register unsigned int rn, gn, bn; - - v = XGetPixel(ximg, x, y); - rn = ((((v >> br) & mr) * rm) >> 8); - gn = ((((v >> bg) & mg) * gm) >> 8); - bn = ((((v << bb) & mb) * bm) >> 8); - if (!((rn & ~mr & 0xfff0) || (gn & ~mg & 0xfff0) || (bn & ~mb & 0xfff0))) { - v = ((rn & mr) << br) | ((gn & mg) << bg) | ((bn & mb) >> bb); - } else { - v = WhitePixel(Xdisplay, Xscreen); - } - XPutPixel(ximg, x, y, v); - } - } } XPutImage(Xdisplay, p, gc, ximg, 0, 0, 0, 0, w, h); XDestroyImage(ximg);