Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2021
- 70 participants
- 697 discussions
16 Apr '21
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/user32/rawinput.c | 27 +++++++++------------------
1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c
index ba11a121bc5..da3824b10ee 100644
--- a/dlls/user32/rawinput.c
+++ b/dlls/user32/rawinput.c
@@ -44,7 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
struct device
{
- WCHAR *path;
+ SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
HANDLE file;
RID_DEVICE_INFO info;
PHIDP_PREPARSED_DATA data;
@@ -94,7 +94,6 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
struct device *device;
HANDLE file;
- WCHAR *path;
DWORD size;
SetupDiGetDeviceInterfaceDetailW(set, iface, NULL, 0, &size, NULL);
@@ -113,20 +112,12 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
TRACE("Found HID device %s.\n", debugstr_w(detail->DevicePath));
- if (!(path = heap_strdupW(detail->DevicePath)))
- {
- ERR("Failed to allocate memory.\n");
- heap_free(detail);
- return NULL;
- }
- heap_free(detail);
-
- file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE,
+ file = CreateFileW(detail->DevicePath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if (file == INVALID_HANDLE_VALUE)
{
- ERR("Failed to open device file %s, error %u.\n", debugstr_w(path), GetLastError());
- heap_free(path);
+ ERR("Failed to open device file %s, error %u.\n", debugstr_w(detail->DevicePath), GetLastError());
+ heap_free(detail);
return NULL;
}
@@ -135,12 +126,12 @@ static struct device *add_device(HDEVINFO set, SP_DEVICE_INTERFACE_DATA *iface)
{
ERR("Failed to allocate memory.\n");
CloseHandle(file);
- heap_free(path);
+ heap_free(detail);
return NULL;
}
device = &rawinput_devices[rawinput_devices_count++];
- device->path = path;
+ device->detail = detail;
device->file = file;
device->info.cbSize = sizeof(RID_DEVICE_INFO);
@@ -171,7 +162,7 @@ static void find_devices(void)
for (idx = 0; idx < rawinput_devices_count; ++idx)
{
CloseHandle(rawinput_devices[idx].file);
- heap_free(rawinput_devices[idx].path);
+ heap_free(rawinput_devices[idx].detail);
}
rawinput_devices_count = 0;
@@ -681,8 +672,8 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE handle, UINT command, void *data, UINT
}
else
{
- *data_size = lstrlenW(device->path) + 1;
- to_copy = device->path;
+ *data_size = lstrlenW(device->detail->DevicePath) + 1;
+ to_copy = device->detail->DevicePath;
}
to_copy_bytes = *data_size * sizeof(WCHAR);
break;
--
2.31.0
2
5
[PATCH v3 1/2] gdi32: Move the loop through each clipped rectangle to the primitive blend funcs.
by Gabriel Ivăncescu 16 Apr '21
by Gabriel Ivăncescu 16 Apr '21
16 Apr '21
This is to prepare so we don't recalculate the lookup cache map for color
tables on every clipped rect (which is expensive).
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
This is a no-op patch, it's needed for next patch.
dlls/gdi32/dibdrv/bitblt.c | 14 +-
dlls/gdi32/dibdrv/dibdrv.h | 18 +--
dlls/gdi32/dibdrv/primitives.c | 284 +++++++++++++++++++--------------
3 files changed, 177 insertions(+), 139 deletions(-)
diff --git a/dlls/gdi32/dibdrv/bitblt.c b/dlls/gdi32/dibdrv/bitblt.c
index 8f67535..045c969 100644
--- a/dlls/gdi32/dibdrv/bitblt.c
+++ b/dlls/gdi32/dibdrv/bitblt.c
@@ -584,17 +584,15 @@ static void mask_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src,
static DWORD blend_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src, const RECT *src_rect,
HRGN clip, BLENDFUNCTION blend )
{
- POINT origin;
struct clipped_rects clipped_rects;
- int i;
+ POINT offset;
if (!get_clipped_rects( dst, dst_rect, clip, &clipped_rects )) return ERROR_SUCCESS;
- for (i = 0; i < clipped_rects.count; i++)
- {
- origin.x = src_rect->left + clipped_rects.rects[i].left - dst_rect->left;
- origin.y = src_rect->top + clipped_rects.rects[i].top - dst_rect->top;
- dst->funcs->blend_rect( dst, &clipped_rects.rects[i], src, &origin, blend );
- }
+
+ offset.x = src_rect->left - dst_rect->left;
+ offset.y = src_rect->top - dst_rect->top;
+ dst->funcs->blend_rect( dst, src, &offset, &clipped_rects, blend );
+
free_clipped_rects( &clipped_rects );
return ERROR_SUCCESS;
}
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index 88b4c62..7db825c 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -165,6 +165,13 @@ static inline dibdrv_physdev *get_dibdrv_pdev( PHYSDEV dev )
return (dibdrv_physdev *)dev;
}
+struct clipped_rects
+{
+ RECT *rects;
+ int count;
+ RECT buffer[32];
+};
+
struct line_params
{
int err_start, err_add_1, err_add_2, bias;
@@ -189,8 +196,8 @@ typedef struct primitive_funcs
const dib_info *brush, const rop_mask_bits *bits);
void (* copy_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, int rop2, int overlap);
- void (* blend_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
- const POINT *origin, BLENDFUNCTION blend);
+ void (* blend_rect)(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend);
BOOL (* gradient_rect)(const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode);
void (* mask_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, int rop2);
@@ -240,13 +247,6 @@ typedef struct
DWORD octant;
} bres_params;
-struct clipped_rects
-{
- RECT *rects;
- int count;
- RECT buffer[32];
-};
-
extern void get_rop_codes(INT rop, struct rop_codes *codes) DECLSPEC_HIDDEN;
extern void reset_dash_origin(dibdrv_physdev *pdev) DECLSPEC_HIDDEN;
extern void init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c
index 01a1c7c..0a5f7e5 100644
--- a/dlls/gdi32/dibdrv/primitives.c
+++ b/dlls/gdi32/dibdrv/primitives.c
@@ -4651,199 +4651,239 @@ static inline DWORD blend_rgb( BYTE dst_r, BYTE dst_g, BYTE dst_b, DWORD src, BL
blend_color( dst_r, src >> 16, blend.SourceConstantAlpha ) << 16);
}
-static void blend_rect_8888(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_8888(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- if (blend.AlphaFormat & AC_SRC_ALPHA)
+ for (i = 0; i < clipped_rects->count; i++)
{
- if (blend.SourceConstantAlpha == 255)
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb( dst_ptr[x], src_ptr[x] );
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
+
+ if (blend.AlphaFormat & AC_SRC_ALPHA)
+ {
+ if (blend.SourceConstantAlpha == 255)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb( dst_ptr[x], src_ptr[x] );
+ else
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
+ }
+ else if (src->compression == BI_RGB)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
else
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
- }
- else if (src->compression == BI_RGB)
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
- else
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb_no_src_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb_no_src_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
+ }
}
-static void blend_rect_32(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_32(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- if (dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
+ for (i = 0; i < clipped_rects->count; i++)
{
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
+
+ if (dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( dst_ptr[x] >> dst->red_shift,
- dst_ptr[x] >> dst->green_shift,
- dst_ptr[x] >> dst->blue_shift,
- src_ptr[x], blend );
- dst_ptr[x] = ((( val & 0xff) << dst->blue_shift) |
- (((val >> 8) & 0xff) << dst->green_shift) |
- (((val >> 16) & 0xff) << dst->red_shift));
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( dst_ptr[x] >> dst->red_shift,
+ dst_ptr[x] >> dst->green_shift,
+ dst_ptr[x] >> dst->blue_shift,
+ src_ptr[x], blend );
+ dst_ptr[x] = ((( val & 0xff) << dst->blue_shift) |
+ (((val >> 8) & 0xff) << dst->green_shift) |
+ (((val >> 16) & 0xff) << dst->red_shift));
+ }
}
}
- }
- else
- {
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ else
{
- for (x = 0; x < rc->right - rc->left; x++)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
- get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
- get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
- src_ptr[x], blend );
- dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
+ get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
+ get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
+ src_ptr[x], blend );
+ dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ }
}
}
}
}
-static void blend_rect_24(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_24(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_24( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < clipped_rects->count; i++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_24( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
- src_ptr[x], blend );
- dst_ptr[x * 3] = val;
- dst_ptr[x * 3 + 1] = val >> 8;
- dst_ptr[x * 3 + 2] = val >> 16;
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
+ src_ptr[x], blend );
+ dst_ptr[x * 3] = val;
+ dst_ptr[x * 3 + 1] = val >> 8;
+ dst_ptr[x * 3 + 2] = val >> 16;
+ }
}
}
}
-static void blend_rect_555(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_555(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
+ for (i = 0; i < clipped_rects->count; i++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
- ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
- ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
- src_ptr[x], blend );
- dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
+ ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
+ ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
+ src_ptr[x], blend );
+ dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
+ }
}
}
}
-static void blend_rect_16(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_16(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
+ for (i = 0; i < clipped_rects->count; i++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
- get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
- get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
- src_ptr[x], blend );
- dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
+ get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
+ get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
+ src_ptr[x], blend );
+ dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ }
}
}
}
-static void blend_rect_8(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_8(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_8( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < clipped_rects->count; i++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_8( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- RGBQUAD rgb = color_table[dst_ptr[x]];
- DWORD val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
- dst_ptr[x] = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ RGBQUAD rgb = color_table[dst_ptr[x]];
+ DWORD val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
+ dst_ptr[x] = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ }
}
}
}
-static void blend_rect_4(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_4(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_4( dst, rc->left, rc->top );
- int i, x, y;
+ int i, j, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < clipped_rects->count; i++)
{
- for (i = 0, x = (dst->rect.left + rc->left) & 1; i < rc->right - rc->left; i++, x++)
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_4( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
- RGBQUAD rgb = color_table[val];
- val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
- val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
- if (x & 1)
- dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
- else
- dst_ptr[x / 2] = (val << 4) | (dst_ptr[x / 2] & 0x0f);
+ for (j = 0, x = (dst->rect.left + rc->left) & 1; j < rc->right - rc->left; j++, x++)
+ {
+ DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
+ RGBQUAD rgb = color_table[val];
+ val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[j], blend );
+ val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ if (x & 1)
+ dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
+ else
+ dst_ptr[x / 2] = (val << 4) | (dst_ptr[x / 2] & 0x0f);
+ }
}
}
}
-static void blend_rect_1(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_1(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_1( dst, rc->left, rc->top );
- int i, x, y;
+ int i, j, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < clipped_rects->count; i++)
{
- for (i = 0, x = (dst->rect.left + rc->left) & 7; i < rc->right - rc->left; i++, x++)
+ const RECT *rc = &clipped_rects->rects[i];
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_1( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- DWORD val = (dst_ptr[x / 8] & pixel_masks_1[x % 8]) ? 1 : 0;
- RGBQUAD rgb = color_table[val];
- val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
- val = rgb_to_pixel_colortable(dst, val >> 16, val >> 8, val) ? 0xff : 0;
- dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
+ for (j = 0, x = (dst->rect.left + rc->left) & 7; j < rc->right - rc->left; j++, x++)
+ {
+ DWORD val = (dst_ptr[x / 8] & pixel_masks_1[x % 8]) ? 1 : 0;
+ RGBQUAD rgb = color_table[val];
+ val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[j], blend );
+ val = rgb_to_pixel_colortable(dst, val >> 16, val >> 8, val) ? 0xff : 0;
+ dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
+ }
}
}
}
-static void blend_rect_null(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rect_null(const dib_info *dst, const dib_info *src, const POINT *offset,
+ const struct clipped_rects *clipped_rects, BLENDFUNCTION blend)
{
}
--
2.30.0
2
3
[PATCH 1/2] mfplay: Raise MFP_EVENT_TYPE_ERROR events on pipeline errors.
by Nikolay Sivov 16 Apr '21
by Nikolay Sivov 16 Apr '21
16 Apr '21
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/mfplay/player.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c
index b098d880461..e57db8e107d 100644
--- a/dlls/mfplay/player.c
+++ b/dlls/mfplay/player.c
@@ -1571,6 +1571,12 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba
break;
+ case MEError:
+
+ media_event_create(player, MFP_EVENT_TYPE_ERROR, event_status, NULL, &event);
+
+ break;
+
default:
;
}
--
2.30.2
1
1
[PATCH v3] msxml3: Don't unlink the XML declaration when saving document.
by Dmitry Timoshkov 16 Apr '21
by Dmitry Timoshkov 16 Apr '21
16 Apr '21
v3:
Treat standalone == -1 and standalone == -2 same way when saving XML.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/msxml3/domdoc.c | 7 ++-----
dlls/msxml3/tests/domdoc.c | 30 ++++++++++++++++++++++++++++--
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 80c32e9ba99..19674d6713a 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -2534,7 +2534,6 @@ static HRESULT WINAPI domdoc_save(
{
domdoc *This = impl_from_IXMLDOMDocument3( iface );
xmlSaveCtxtPtr ctx = NULL;
- xmlNodePtr xmldecl;
HRESULT ret = S_OK;
TRACE("(%p)->(%s)\n", This, debugstr_variant(&destination));
@@ -2567,7 +2566,7 @@ static HRESULT WINAPI domdoc_save(
ret = IUnknown_QueryInterface(pUnk, &IID_IStream, (void**)&stream);
if(ret == S_OK)
{
- int options = get_doc(This)->standalone == -1 ? XML_SAVE_NO_DECL : 0;
+ int options = get_doc(This)->standalone < 0 ? XML_SAVE_NO_DECL : 0;
ctx = xmlSaveToIO(domdoc_stream_save_writecallback,
domdoc_stream_save_closecallback, stream, NULL, options);
@@ -2583,7 +2582,7 @@ static HRESULT WINAPI domdoc_save(
case VT_BSTR:
case VT_BSTR | VT_BYREF:
{
- int options = get_doc(This)->standalone == -1 ? XML_SAVE_NO_DECL : 0;
+ int options = get_doc(This)->standalone < 0 ? XML_SAVE_NO_DECL : 0;
/* save with file path */
HANDLE handle = CreateFileW( (V_VT(&destination) & VT_BYREF)? *V_BSTRREF(&destination) : V_BSTR(&destination),
@@ -2610,9 +2609,7 @@ static HRESULT WINAPI domdoc_save(
return S_FALSE;
}
- xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
- xmldoc_link_xmldecl(get_doc(This), xmldecl);
/* will release resources through close callback */
xmlSaveClose(ctx);
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 5bc2fe1d5c3..85ea26699ee 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -8524,6 +8524,7 @@ static void test_createProcessingInstruction(void)
{
static const WCHAR xml1[] = L"<?xml version=\"1.0\"?>\r\n<test/>\r\n";
static const char xml2[] = "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\r\n<test/>\r\n";
+ static const char xml2_wine[] = "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n<test/>\n";
IXMLDOMProcessingInstruction *pi;
IXMLDOMDocument *doc;
IXMLDOMNode *node;
@@ -8533,6 +8534,8 @@ static void test_createProcessingInstruction(void)
VARIANT var;
HRESULT hr;
IStream *stream;
+ LARGE_INTEGER off;
+ VARIANT_BOOL b;
HGLOBAL global;
char *p;
@@ -8582,9 +8585,32 @@ todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
p = GlobalLock(global);
p[GlobalSize(global)] = 0;
-todo_wine
- ok(!strcmp(p, xml2), "got %s\n", wine_dbgstr_a(p));
+ ok(!strcmp(p, xml2) || !strcmp(p, xml2_wine), "got %s\n", wine_dbgstr_a(p));
+ GlobalUnlock(global);
+
+ /* Verify the result after load+save */
+ off.QuadPart = 0;
+ hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXMLDOMDocument_load(doc, var, &b);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(b == VARIANT_TRUE, "got %d\n", b);
+
+ off.QuadPart = 0;
+ hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXMLDOMDocument_save(doc, var);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = GetHGlobalFromStream(stream, &global);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ p = GlobalLock(global);
+ p[GlobalSize(global)] = 0;
+ ok(!strcmp(p, xml2) || !strcmp(p, xml2_wine), "got %s\n", wine_dbgstr_a(p));
GlobalUnlock(global);
+
IStream_Release(stream);
IXMLDOMDocument_Release(doc);
--
2.30.2
2
2
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/wldap32/control.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wldap32/control.c b/dlls/wldap32/control.c
index 42098fc814a..b012648797c 100644
--- a/dlls/wldap32/control.c
+++ b/dlls/wldap32/control.c
@@ -152,7 +152,7 @@ ULONG CDECL ldap_create_sort_controlW( WLDAP32_LDAP *ld, LDAPSortKeyW **sortkey,
if (!ld || !sortkey || !control) return WLDAP32_LDAP_PARAM_ERROR;
- if (sortkey && !(sortkeyU = sortkeyarrayWtoU( sortkey ))) return WLDAP32_LDAP_NO_MEMORY;
+ if (!(sortkeyU = sortkeyarrayWtoU( sortkey ))) return WLDAP32_LDAP_NO_MEMORY;
ret = map_error( ldap_funcs->ldap_create_sort_control( ld->ld, sortkeyU, critical, &controlU ) );
if (ret == WLDAP32_LDAP_SUCCESS)
--
2.23.0
1
0
[PATCH v4 2/2] gdi32: Use a lazy-init lookup cache when converting RGB values to colour table indices.
by Huw Davies 16 Apr '21
by Huw Davies 16 Apr '21
16 Apr '21
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/gdi32/dibdrv/primitives.c | 57 ++++++++++++++++++++++++++--------
1 file changed, 44 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c
index 31a9259e5f2..e4b18a6656d 100644
--- a/dlls/gdi32/dibdrv/primitives.c
+++ b/dlls/gdi32/dibdrv/primitives.c
@@ -3503,16 +3503,40 @@ static inline BOOL color_tables_match(const dib_info *d1, const dib_info *d2)
return !memcmp(d1->color_table, d2->color_table, (1 << d1->bit_count) * sizeof(d1->color_table[0]));
}
-static inline DWORD rgb_lookup_colortable(const dib_info *dst, BYTE r, BYTE g, BYTE b)
+/*
+ * To translate an RGB value into a colour table index Windows uses the 5 msbs of each component.
+ * We thus create a lookup table with 32^3 entries.
+ */
+struct rgb_lookup_colortable_ctx
+{
+ const dib_info *dib;
+ BYTE map[32 * 32 * 32];
+ BYTE valid[32 * 32 * 32 / 8];
+};
+
+static void rgb_lookup_colortable_init(const dib_info *dib, struct rgb_lookup_colortable_ctx *ctx)
{
- /* Windows reduces precision to 5 bits, probably in order to build some sort of lookup cache */
- return rgb_to_pixel_colortable( dst, (r & ~7) + 4, (g & ~7) + 4, (b & ~7) + 4 );
+ ctx->dib = dib;
+ memset(ctx->valid, 0, sizeof(ctx->valid));
+}
+
+static inline BYTE rgb_lookup_colortable(struct rgb_lookup_colortable_ctx *ctx, DWORD r, DWORD g, DWORD b)
+{
+ DWORD pos = ((r & 0xf8) >> 3) | ((g & 0xf8) << 2) | ((b & 0xf8) << 7);
+
+ if (!(ctx->valid[pos / 8] & pixel_masks_1[pos & 7]))
+ {
+ ctx->valid[pos / 8] |= pixel_masks_1[pos & 7];
+ ctx->map[pos] = rgb_to_pixel_colortable(ctx->dib, (r & 0xf8) | 4, (g & 0xf8) | 4, (b & 0xf8) | 4);
+ }
+ return ctx->map[pos];
}
static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rect, BOOL dither)
{
BYTE *dst_start = get_pixel_ptr_8(dst, 0, 0), *dst_pixel;
INT x, y, pad_size = ((dst->width + 3) & ~3) - (src_rect->right - src_rect->left);
+ struct rgb_lookup_colortable_ctx lookup_ctx;
DWORD src_val;
switch(src->bit_count)
@@ -3521,6 +3545,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
{
DWORD *src_start = get_pixel_ptr_32(src, src_rect->left, src_rect->top), *src_pixel;
+ rgb_lookup_colortable_init(dst, &lookup_ctx);
if(src->funcs == &funcs_8888)
{
for(y = src_rect->top; y < src_rect->bottom; y++)
@@ -3530,7 +3555,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
for(x = src_rect->left; x < src_rect->right; x++)
{
src_val = *src_pixel++;
- *dst_pixel++ = rgb_lookup_colortable(dst, src_val >> 16, src_val >> 8, src_val );
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx, src_val >> 16, src_val >> 8, src_val );
}
if(pad_size) memset(dst_pixel, 0, pad_size);
dst_start += dst->stride;
@@ -3546,7 +3571,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
for(x = src_rect->left; x < src_rect->right; x++)
{
src_val = *src_pixel++;
- *dst_pixel++ = rgb_lookup_colortable(dst,
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx,
src_val >> src->red_shift,
src_val >> src->green_shift,
src_val >> src->blue_shift );
@@ -3565,7 +3590,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
for(x = src_rect->left; x < src_rect->right; x++)
{
src_val = *src_pixel++;
- *dst_pixel++ = rgb_lookup_colortable(dst,
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx,
get_field(src_val, src->red_shift, src->red_len),
get_field(src_val, src->green_shift, src->green_len),
get_field(src_val, src->blue_shift, src->blue_len));
@@ -3582,13 +3607,14 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
{
BYTE *src_start = get_pixel_ptr_24(src, src_rect->left, src_rect->top), *src_pixel;
+ rgb_lookup_colortable_init(dst, &lookup_ctx);
for(y = src_rect->top; y < src_rect->bottom; y++)
{
dst_pixel = dst_start;
src_pixel = src_start;
for(x = src_rect->left; x < src_rect->right; x++, src_pixel += 3)
{
- *dst_pixel++ = rgb_lookup_colortable(dst, src_pixel[2], src_pixel[1], src_pixel[0] );
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx, src_pixel[2], src_pixel[1], src_pixel[0] );
}
if(pad_size) memset(dst_pixel, 0, pad_size);
dst_start += dst->stride;
@@ -3600,6 +3626,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
case 16:
{
WORD *src_start = get_pixel_ptr_16(src, src_rect->left, src_rect->top), *src_pixel;
+ rgb_lookup_colortable_init(dst, &lookup_ctx);
if(src->funcs == &funcs_555)
{
for(y = src_rect->top; y < src_rect->bottom; y++)
@@ -3609,7 +3636,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
for(x = src_rect->left; x < src_rect->right; x++)
{
src_val = *src_pixel++;
- *dst_pixel++ = rgb_lookup_colortable(dst,
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx,
((src_val >> 7) & 0xf8) | ((src_val >> 12) & 0x07),
((src_val >> 2) & 0xf8) | ((src_val >> 7) & 0x07),
((src_val << 3) & 0xf8) | ((src_val >> 2) & 0x07) );
@@ -3628,7 +3655,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
for(x = src_rect->left; x < src_rect->right; x++)
{
src_val = *src_pixel++;
- *dst_pixel++ = rgb_lookup_colortable(dst,
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx,
(((src_val >> src->red_shift) << 3) & 0xf8) |
(((src_val >> src->red_shift) >> 2) & 0x07),
(((src_val >> src->green_shift) << 3) & 0xf8) |
@@ -3650,7 +3677,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
for(x = src_rect->left; x < src_rect->right; x++)
{
src_val = *src_pixel++;
- *dst_pixel++ = rgb_lookup_colortable(dst,
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx,
(((src_val >> src->red_shift) << 3) & 0xf8) |
(((src_val >> src->red_shift) >> 2) & 0x07),
(((src_val >> src->green_shift) << 2) & 0xfc) |
@@ -3672,7 +3699,7 @@ static void convert_to_8(dib_info *dst, const dib_info *src, const RECT *src_rec
for(x = src_rect->left; x < src_rect->right; x++)
{
src_val = *src_pixel++;
- *dst_pixel++ = rgb_lookup_colortable(dst,
+ *dst_pixel++ = rgb_lookup_colortable(&lookup_ctx,
get_field(src_val, src->red_shift, src->red_len),
get_field(src_val, src->green_shift, src->green_len),
get_field(src_val, src->blue_shift, src->blue_len));
@@ -4802,8 +4829,10 @@ static void blend_rects_8(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
+ struct rgb_lookup_colortable_ctx lookup_ctx;
int i, x, y;
+ rgb_lookup_colortable_init( dst, &lookup_ctx );
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
@@ -4815,7 +4844,7 @@ static void blend_rects_8(const dib_info *dst, int num, const RECT *rc,
{
RGBQUAD rgb = color_table[dst_ptr[x]];
DWORD val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
- dst_ptr[x] = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ dst_ptr[x] = rgb_lookup_colortable( &lookup_ctx, val >> 16, val >> 8, val );
}
}
}
@@ -4825,8 +4854,10 @@ static void blend_rects_4(const dib_info *dst, int num, const RECT *rc,
const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
+ struct rgb_lookup_colortable_ctx lookup_ctx;
int i, j, x, y;
+ rgb_lookup_colortable_init( dst, &lookup_ctx );
for (i = 0; i < num; i++, rc++)
{
DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
@@ -4839,7 +4870,7 @@ static void blend_rects_4(const dib_info *dst, int num, const RECT *rc,
DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
RGBQUAD rgb = color_table[val];
val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[j], blend );
- val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ val = rgb_lookup_colortable( &lookup_ctx, val >> 16, val >> 8, val );
if (x & 1)
dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
else
--
2.23.0
1
0
[PATCH v4 1/2] gdi32: Move the loop through each clipped rectangle to the primitive blend funcs.
by Huw Davies 16 Apr '21
by Huw Davies 16 Apr '21
16 Apr '21
From: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
This is to prepare so we don't recalculate the lookup cache map for color
tables on every clipped rect (which is expensive).
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/gdi32/dibdrv/bitblt.c | 14 +-
dlls/gdi32/dibdrv/dibdrv.h | 4 +-
dlls/gdi32/dibdrv/primitives.c | 294 ++++++++++++++++++---------------
3 files changed, 171 insertions(+), 141 deletions(-)
diff --git a/dlls/gdi32/dibdrv/bitblt.c b/dlls/gdi32/dibdrv/bitblt.c
index 8f675354716..d2f59965b02 100644
--- a/dlls/gdi32/dibdrv/bitblt.c
+++ b/dlls/gdi32/dibdrv/bitblt.c
@@ -584,17 +584,15 @@ static void mask_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src,
static DWORD blend_rect( dib_info *dst, const RECT *dst_rect, const dib_info *src, const RECT *src_rect,
HRGN clip, BLENDFUNCTION blend )
{
- POINT origin;
+ POINT offset;
struct clipped_rects clipped_rects;
- int i;
if (!get_clipped_rects( dst, dst_rect, clip, &clipped_rects )) return ERROR_SUCCESS;
- for (i = 0; i < clipped_rects.count; i++)
- {
- origin.x = src_rect->left + clipped_rects.rects[i].left - dst_rect->left;
- origin.y = src_rect->top + clipped_rects.rects[i].top - dst_rect->top;
- dst->funcs->blend_rect( dst, &clipped_rects.rects[i], src, &origin, blend );
- }
+
+ offset.x = src_rect->left - dst_rect->left;
+ offset.y = src_rect->top - dst_rect->top;
+ dst->funcs->blend_rects( dst, clipped_rects.count, clipped_rects.rects, src, &offset, blend );
+
free_clipped_rects( &clipped_rects );
return ERROR_SUCCESS;
}
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index 88b4c62d023..d3a35b96c75 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -189,8 +189,8 @@ typedef struct primitive_funcs
const dib_info *brush, const rop_mask_bits *bits);
void (* copy_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, int rop2, int overlap);
- void (* blend_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
- const POINT *origin, BLENDFUNCTION blend);
+ void (* blend_rects)(const dib_info *dst, int num, const RECT *rc, const dib_info *src,
+ const POINT *offset, BLENDFUNCTION blend);
BOOL (* gradient_rect)(const dib_info *dib, const RECT *rc, const TRIVERTEX *v, int mode);
void (* mask_rect)(const dib_info *dst, const RECT *rc, const dib_info *src,
const POINT *origin, int rop2);
diff --git a/dlls/gdi32/dibdrv/primitives.c b/dlls/gdi32/dibdrv/primitives.c
index 01a1c7c1d83..31a9259e5f2 100644
--- a/dlls/gdi32/dibdrv/primitives.c
+++ b/dlls/gdi32/dibdrv/primitives.c
@@ -4651,199 +4651,231 @@ static inline DWORD blend_rgb( BYTE dst_r, BYTE dst_g, BYTE dst_b, DWORD src, BL
blend_color( dst_r, src >> 16, blend.SourceConstantAlpha ) << 16);
}
-static void blend_rect_8888(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_8888(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- if (blend.AlphaFormat & AC_SRC_ALPHA)
+ for (i = 0; i < num; i++, rc++)
{
- if (blend.SourceConstantAlpha == 255)
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb( dst_ptr[x], src_ptr[x] );
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
+
+ if (blend.AlphaFormat & AC_SRC_ALPHA)
+ {
+ if (blend.SourceConstantAlpha == 255)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb( dst_ptr[x], src_ptr[x] );
+ else
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
+ }
+ else if (src->compression == BI_RGB)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
else
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
- }
- else if (src->compression == BI_RGB)
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb_constant_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
- else
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
- for (x = 0; x < rc->right - rc->left; x++)
- dst_ptr[x] = blend_argb_no_src_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ for (x = 0; x < rc->right - rc->left; x++)
+ dst_ptr[x] = blend_argb_no_src_alpha( dst_ptr[x], src_ptr[x], blend.SourceConstantAlpha );
+ }
}
-static void blend_rect_32(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_32(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- if (dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
+ for (i = 0; i < num; i++, rc++)
{
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ DWORD *dst_ptr = get_pixel_ptr_32( dst, rc->left, rc->top );
+
+ if (dst->red_len == 8 && dst->green_len == 8 && dst->blue_len == 8)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( dst_ptr[x] >> dst->red_shift,
- dst_ptr[x] >> dst->green_shift,
- dst_ptr[x] >> dst->blue_shift,
- src_ptr[x], blend );
- dst_ptr[x] = ((( val & 0xff) << dst->blue_shift) |
- (((val >> 8) & 0xff) << dst->green_shift) |
- (((val >> 16) & 0xff) << dst->red_shift));
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( dst_ptr[x] >> dst->red_shift,
+ dst_ptr[x] >> dst->green_shift,
+ dst_ptr[x] >> dst->blue_shift,
+ src_ptr[x], blend );
+ dst_ptr[x] = ((( val & 0xff) << dst->blue_shift) |
+ (((val >> 8) & 0xff) << dst->green_shift) |
+ (((val >> 16) & 0xff) << dst->red_shift));
+ }
}
}
- }
- else
- {
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
+ else
{
- for (x = 0; x < rc->right - rc->left; x++)
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 4, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
- get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
- get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
- src_ptr[x], blend );
- dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
+ get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
+ get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
+ src_ptr[x], blend );
+ dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ }
}
}
}
}
-static void blend_rect_24(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_24(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_24( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < num; i++, rc++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_24( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
- src_ptr[x], blend );
- dst_ptr[x * 3] = val;
- dst_ptr[x * 3 + 1] = val >> 8;
- dst_ptr[x * 3 + 2] = val >> 16;
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( dst_ptr[x * 3 + 2], dst_ptr[x * 3 + 1], dst_ptr[x * 3],
+ src_ptr[x], blend );
+ dst_ptr[x * 3] = val;
+ dst_ptr[x * 3 + 1] = val >> 8;
+ dst_ptr[x * 3 + 2] = val >> 16;
+ }
}
}
}
-static void blend_rect_555(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_555(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
+ for (i = 0; i < num; i++, rc++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
- ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
- ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
- src_ptr[x], blend );
- dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( ((dst_ptr[x] >> 7) & 0xf8) | ((dst_ptr[x] >> 12) & 0x07),
+ ((dst_ptr[x] >> 2) & 0xf8) | ((dst_ptr[x] >> 7) & 0x07),
+ ((dst_ptr[x] << 3) & 0xf8) | ((dst_ptr[x] >> 2) & 0x07),
+ src_ptr[x], blend );
+ dst_ptr[x] = ((val >> 9) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 3) & 0x001f);
+ }
}
}
}
-static void blend_rect_16(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_16(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
+ for (i = 0; i < num; i++, rc++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ WORD *dst_ptr = get_pixel_ptr_16( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride / 2, src_ptr += src->stride / 4)
{
- DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
- get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
- get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
- src_ptr[x], blend );
- dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ DWORD val = blend_rgb( get_field( dst_ptr[x], dst->red_shift, dst->red_len ),
+ get_field( dst_ptr[x], dst->green_shift, dst->green_len ),
+ get_field( dst_ptr[x], dst->blue_shift, dst->blue_len ),
+ src_ptr[x], blend );
+ dst_ptr[x] = rgb_to_pixel_masks( dst, val >> 16, val >> 8, val );
+ }
}
}
}
-static void blend_rect_8(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_8(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_8( dst, rc->left, rc->top );
- int x, y;
+ int i, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < num; i++, rc++)
{
- for (x = 0; x < rc->right - rc->left; x++)
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_8( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- RGBQUAD rgb = color_table[dst_ptr[x]];
- DWORD val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
- dst_ptr[x] = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ for (x = 0; x < rc->right - rc->left; x++)
+ {
+ RGBQUAD rgb = color_table[dst_ptr[x]];
+ DWORD val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[x], blend );
+ dst_ptr[x] = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ }
}
}
}
-static void blend_rect_4(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_4(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_4( dst, rc->left, rc->top );
- int i, x, y;
+ int i, j, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < num; i++, rc++)
{
- for (i = 0, x = (dst->rect.left + rc->left) & 1; i < rc->right - rc->left; i++, x++)
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_4( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
- RGBQUAD rgb = color_table[val];
- val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
- val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
- if (x & 1)
- dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
- else
- dst_ptr[x / 2] = (val << 4) | (dst_ptr[x / 2] & 0x0f);
+ for (j = 0, x = (dst->rect.left + rc->left) & 1; j < rc->right - rc->left; j++, x++)
+ {
+ DWORD val = ((x & 1) ? dst_ptr[x / 2] : (dst_ptr[x / 2] >> 4)) & 0x0f;
+ RGBQUAD rgb = color_table[val];
+ val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[j], blend );
+ val = rgb_lookup_colortable( dst, val >> 16, val >> 8, val );
+ if (x & 1)
+ dst_ptr[x / 2] = val | (dst_ptr[x / 2] & 0xf0);
+ else
+ dst_ptr[x / 2] = (val << 4) | (dst_ptr[x / 2] & 0x0f);
+ }
}
}
}
-static void blend_rect_1(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_1(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
const RGBQUAD *color_table = get_dib_color_table( dst );
- DWORD *src_ptr = get_pixel_ptr_32( src, origin->x, origin->y );
- BYTE *dst_ptr = get_pixel_ptr_1( dst, rc->left, rc->top );
- int i, x, y;
+ int i, j, x, y;
- for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
+ for (i = 0; i < num; i++, rc++)
{
- for (i = 0, x = (dst->rect.left + rc->left) & 7; i < rc->right - rc->left; i++, x++)
+ DWORD *src_ptr = get_pixel_ptr_32( src, rc->left + offset->x, rc->top + offset->y );
+ BYTE *dst_ptr = get_pixel_ptr_1( dst, rc->left, rc->top );
+
+ for (y = rc->top; y < rc->bottom; y++, dst_ptr += dst->stride, src_ptr += src->stride / 4)
{
- DWORD val = (dst_ptr[x / 8] & pixel_masks_1[x % 8]) ? 1 : 0;
- RGBQUAD rgb = color_table[val];
- val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[i], blend );
- val = rgb_to_pixel_colortable(dst, val >> 16, val >> 8, val) ? 0xff : 0;
- dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
+ for (j = 0, x = (dst->rect.left + rc->left) & 7; j < rc->right - rc->left; j++, x++)
+ {
+ DWORD val = (dst_ptr[x / 8] & pixel_masks_1[x % 8]) ? 1 : 0;
+ RGBQUAD rgb = color_table[val];
+ val = blend_rgb( rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, src_ptr[j], blend );
+ val = rgb_to_pixel_colortable(dst, val >> 16, val >> 8, val) ? 0xff : 0;
+ dst_ptr[x / 8] = (dst_ptr[x / 8] & ~pixel_masks_1[x % 8]) | (val & pixel_masks_1[x % 8]);
+ }
}
}
}
-static void blend_rect_null(const dib_info *dst, const RECT *rc,
- const dib_info *src, const POINT *origin, BLENDFUNCTION blend)
+static void blend_rects_null(const dib_info *dst, int num, const RECT *rc,
+ const dib_info *src, const POINT *offset, BLENDFUNCTION blend)
{
}
@@ -7373,7 +7405,7 @@ const primitive_funcs funcs_8888 =
solid_line_32,
pattern_rects_32,
copy_rect_32,
- blend_rect_8888,
+ blend_rects_8888,
gradient_rect_8888,
mask_rect_32,
draw_glyph_8888,
@@ -7394,7 +7426,7 @@ const primitive_funcs funcs_32 =
solid_line_32,
pattern_rects_32,
copy_rect_32,
- blend_rect_32,
+ blend_rects_32,
gradient_rect_32,
mask_rect_32,
draw_glyph_32,
@@ -7415,7 +7447,7 @@ const primitive_funcs funcs_24 =
solid_line_24,
pattern_rects_24,
copy_rect_24,
- blend_rect_24,
+ blend_rects_24,
gradient_rect_24,
mask_rect_24,
draw_glyph_24,
@@ -7436,7 +7468,7 @@ const primitive_funcs funcs_555 =
solid_line_16,
pattern_rects_16,
copy_rect_16,
- blend_rect_555,
+ blend_rects_555,
gradient_rect_555,
mask_rect_16,
draw_glyph_555,
@@ -7457,7 +7489,7 @@ const primitive_funcs funcs_16 =
solid_line_16,
pattern_rects_16,
copy_rect_16,
- blend_rect_16,
+ blend_rects_16,
gradient_rect_16,
mask_rect_16,
draw_glyph_16,
@@ -7478,7 +7510,7 @@ const primitive_funcs funcs_8 =
solid_line_8,
pattern_rects_8,
copy_rect_8,
- blend_rect_8,
+ blend_rects_8,
gradient_rect_8,
mask_rect_8,
draw_glyph_8,
@@ -7499,7 +7531,7 @@ const primitive_funcs funcs_4 =
solid_line_4,
pattern_rects_4,
copy_rect_4,
- blend_rect_4,
+ blend_rects_4,
gradient_rect_4,
mask_rect_4,
draw_glyph_4,
@@ -7520,7 +7552,7 @@ const primitive_funcs funcs_1 =
solid_line_1,
pattern_rects_1,
copy_rect_1,
- blend_rect_1,
+ blend_rects_1,
gradient_rect_1,
mask_rect_null,
draw_glyph_1,
@@ -7541,7 +7573,7 @@ const primitive_funcs funcs_null =
solid_line_null,
pattern_rects_null,
copy_rect_null,
- blend_rect_null,
+ blend_rects_null,
gradient_rect_null,
mask_rect_null,
draw_glyph_null,
--
2.23.0
1
0
[PATCH 1/2] reg/tests: Only pass a newly created HKEY if it is used in later tests
by Hugh McMaster 16 Apr '21
by Hugh McMaster 16 Apr '21
16 Apr '21
Signed-off-by: Hugh McMaster <hugh.mcmaster(a)outlook.com>
---
programs/reg/tests/add.c | 13 +++++++++----
programs/reg/tests/delete.c | 8 +++-----
programs/reg/tests/export.c | 9 +++------
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/programs/reg/tests/add.c b/programs/reg/tests/add.c
index 8357e9ad0bc..e62caeade01 100644
--- a/programs/reg/tests/add.c
+++ b/programs/reg/tests/add.c
@@ -126,10 +126,16 @@ void verify_key_nonexist_(const char *file, unsigned line, HKEY key_base, const
void add_key_(const char *file, unsigned line, const HKEY hkey, const char *path, HKEY *subkey)
{
LONG err;
+ HKEY new_key;
err = RegCreateKeyExA(hkey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
- KEY_READ|KEY_WRITE, NULL, subkey, NULL);
+ KEY_READ|KEY_WRITE, NULL, &new_key, NULL);
lok(err == ERROR_SUCCESS, "RegCreateKeyExA failed: %d\n", err);
+
+ if (subkey)
+ *subkey = new_key;
+ else
+ RegCloseKey(new_key);
}
void delete_key_(const char *file, unsigned line, const HKEY hkey, const char *path)
@@ -315,7 +321,7 @@ static void test_key_formats(void)
static void test_add(void)
{
- HKEY hkey, hsubkey;
+ HKEY hkey;
DWORD r, dword;
run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
@@ -324,8 +330,7 @@ static void test_add(void)
open_key(HKEY_CURRENT_USER, KEY_BASE, KEY_WRITE, &hkey);
/* Test whether overwriting a registry key modifies existing keys and values */
- add_key(hkey, "Subkey", &hsubkey);
- close_key(hsubkey);
+ add_key(hkey, "Subkey", NULL);
add_value(hkey, "Test1", REG_SZ, "Value1", 7);
dword = 0x123;
add_value(hkey, "Test2", REG_DWORD, &dword, sizeof(dword));
diff --git a/programs/reg/tests/delete.c b/programs/reg/tests/delete.c
index 77d95d013c9..575c393d2b3 100644
--- a/programs/reg/tests/delete.c
+++ b/programs/reg/tests/delete.c
@@ -21,7 +21,7 @@
static void test_delete(void)
{
- HKEY hkey, hsubkey;
+ HKEY hkey;
DWORD r;
const DWORD deadbeef = 0xdeadbeef;
@@ -75,8 +75,7 @@ static void test_delete(void)
add_value(hkey, "bar", REG_DWORD, &deadbeef, sizeof(deadbeef));
add_value(hkey, NULL, REG_DWORD, &deadbeef, sizeof(deadbeef));
- add_key(hkey, "subkey", &hsubkey);
- close_key(hsubkey);
+ add_key(hkey, "subkey", NULL);
run_reg_exe("reg delete HKCU\\" KEY_BASE " /v bar /f", &r);
ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
@@ -92,8 +91,7 @@ static void test_delete(void)
verify_key(hkey, "subkey");
/* Test forward and back slashes */
- add_key(hkey, "https://winehq.org", &hsubkey);
- close_key(hsubkey);
+ add_key(hkey, "https://winehq.org", NULL);
add_value(hkey, "count/up", REG_SZ, "one/two/three", 14);
add_value(hkey, "\\foo\\bar", REG_SZ, "", 1);
diff --git a/programs/reg/tests/export.c b/programs/reg/tests/export.c
index 4e5ac4c71d9..daf42f66e3e 100644
--- a/programs/reg/tests/export.c
+++ b/programs/reg/tests/export.c
@@ -291,10 +291,8 @@ static void test_export(void)
/* Test the export order of registry keys */
add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
- add_key(hkey, "Subkey2", &subkey);
- close_key(subkey);
- add_key(hkey, "Subkey1", &subkey);
- close_key(subkey);
+ add_key(hkey, "Subkey2", NULL);
+ add_key(hkey, "Subkey1", NULL);
run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg /y", &r);
ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
@@ -405,8 +403,7 @@ static void test_export(void)
/* Test registry export with forward and back slashes */
add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
- add_key(hkey, "https://winehq.org", &subkey);
- close_key(subkey);
+ add_key(hkey, "https://winehq.org", NULL);
add_value(hkey, "count/up", REG_SZ, "one/two/three", 14);
add_value(hkey, "\\foo\\bar", REG_SZ, "", 1);
close_key(hkey);
--
2.31.0
1
1
16 Apr '21
Signed-off-by: Jan Sikorski <jsikorski(a)codeweavers.com>
---
dlls/d3d11/tests/d3d11.c | 89 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index c499aa5f75b..f0da87bc0bd 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -17157,6 +17157,94 @@ static void test_shader_stage_input_output_matching(void)
release_test_context(&test_context);
}
+static void test_unbound_streams(void)
+{
+ struct d3d11_test_context test_context;
+ ID3D11DeviceContext *context;
+ ID3D11PixelShader *ps;
+ ID3D11Device *device;
+ HRESULT hr;
+
+ static const DWORD vs_code[] =
+ {
+#if 0
+ struct vs_ps
+ {
+ float4 position : SV_POSITION;
+ float4 color : COLOR0;
+ };
+
+ vs_ps vs_main(float4 position : POSITION, float4 color : COLOR0)
+ {
+ vs_ps result;
+ result.position = position;
+ result.color = color;
+ result.color.w = 1.0;
+ return result;
+ }
+#endif
+ 0x43425844, 0x4a9efaec, 0xe2c6cdf5, 0x15dd28a7, 0xae68e320, 0x00000001, 0x00000154, 0x00000003,
+ 0x0000002c, 0x0000007c, 0x000000d0, 0x4e475349, 0x00000048, 0x00000002, 0x00000008, 0x00000038,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000001, 0x0000070f, 0x49534f50, 0x4e4f4954, 0x4c4f4300, 0xab00524f, 0x4e47534f,
+ 0x0000004c, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
+ 0x0000000f, 0x00000044, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x505f5653,
+ 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052, 0x52444853, 0x0000007c, 0x00010040, 0x0000001f,
+ 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x04000067, 0x001020f2,
+ 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000001, 0x05000036, 0x001020f2, 0x00000000,
+ 0x00101e46, 0x00000000, 0x05000036, 0x00102072, 0x00000001, 0x00101246, 0x00000001, 0x05000036,
+ 0x00102082, 0x00000001, 0x00004001, 0x3f800000, 0x0100003e,
+ };
+
+ static const DWORD ps_code[] =
+ {
+#if 0
+ float4 ps_main(vs_ps input) : SV_TARGET
+ {
+ return input.color;
+ }
+#endif
+ 0x43425844, 0xe2087fa6, 0xa35fbd95, 0x8e585b3f, 0x67890f54, 0x00000001, 0x000000f4, 0x00000003,
+ 0x0000002c, 0x00000080, 0x000000b4, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x00000044, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000001, 0x00000f0f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4f4c4f43, 0xabab0052,
+ 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040,
+ 0x0000000e, 0x03001062, 0x001010f2, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
+ 0x001020f2, 0x00000000, 0x00101e46, 0x00000001, 0x0100003e,
+ };
+
+ static const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ static const D3D11_INPUT_ELEMENT_DESC layout_desc[] =
+ {
+ {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ };
+
+ if (!init_test_context(&test_context, NULL))
+ return;
+
+ device = test_context.device;
+ context = test_context.immediate_context;
+
+ hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps);
+ ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
+
+ hr = ID3D11Device_CreateInputLayout(device, layout_desc, ARRAY_SIZE(layout_desc),
+ vs_code, sizeof(vs_code), &test_context.input_layout);
+ ok(SUCCEEDED(hr), "Failed to create input layout, hr %#x.\n", hr);
+
+ ID3D11DeviceContext_PSSetShader(context, ps, NULL, 0);
+ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white);
+ draw_quad_vs(&test_context, vs_code, sizeof(vs_code));
+ check_texture_color(test_context.backbuffer, 0xff000000, 1);
+
+ ID3D11PixelShader_Release(ps);
+ ID3D11InputLayout_Release(test_context.input_layout);
+ release_test_context(&test_context);
+}
+
static void test_shader_interstage_interface(void)
{
struct d3d11_test_context test_context;
@@ -32520,6 +32608,7 @@ START_TEST(d3d11)
queue_test(test_deferred_context_state);
queue_test(test_deferred_context_swap_state);
queue_test(test_deferred_context_rendering);
+ queue_test(test_unbound_streams);
run_queued_tests();
}
--
2.31.0
2
7
[PATCH 5/5] wldap32: Move support for page functions to the Unix library.
by Hans Leidekker 16 Apr '21
by Hans Leidekker 16 Apr '21
16 Apr '21
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/wldap32/ber.c | 2 +-
dlls/wldap32/page.c | 281 +++++++++++----------------------
dlls/wldap32/winldap_private.h | 76 +++++++++
3 files changed, 169 insertions(+), 190 deletions(-)
diff --git a/dlls/wldap32/ber.c b/dlls/wldap32/ber.c
index ae5e9292e04..c6dca7153a2 100644
--- a/dlls/wldap32/ber.c
+++ b/dlls/wldap32/ber.c
@@ -413,7 +413,7 @@ int WINAPIV WLDAP32_ber_printf( WLDAP32_BerElement *ber, char *fmt, ... )
* berelement must have been allocated with ber_init. This function
* can be called multiple times to decode data.
*/
-int WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *ber, char *fmt, ... )
+ULONG WINAPIV WLDAP32_ber_scanf( WLDAP32_BerElement *ber, char *fmt, ... )
{
__ms_va_list list;
int ret = 0;
diff --git a/dlls/wldap32/page.c b/dlls/wldap32/page.c
index 07f29be0d50..5364280f271 100644
--- a/dlls/wldap32/page.c
+++ b/dlls/wldap32/page.c
@@ -18,31 +18,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
#include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-#ifndef LDAP_MAXINT
-#define LDAP_MAXINT 2147483647
-#endif
-
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
-#include "winldap_private.h"
-#include "wldap32.h"
#include "wine/debug.h"
+#include "wine/heap.h"
+#include "winldap_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#ifdef HAVE_LDAP
-static struct berval null_cookieU = { 0, NULL };
+#define LDAP_MAXINT (2^31)
+
static struct WLDAP32_berval null_cookieW = { 0, NULL };
-#endif
/***********************************************************************
* ldap_create_page_controlA (WLDAP32.@)
@@ -50,84 +39,73 @@ static struct WLDAP32_berval null_cookieW = { 0, NULL };
* See ldap_create_page_controlW.
*/
ULONG CDECL ldap_create_page_controlA( WLDAP32_LDAP *ld, ULONG pagesize,
- struct WLDAP32_berval *cookie, UCHAR critical, PLDAPControlA *control )
+ struct WLDAP32_berval *cookie, UCHAR critical, LDAPControlA **control )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
LDAPControlW *controlW = NULL;
- TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie,
- critical, control );
+ TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie, critical, control );
- if (!ld || !control || pagesize > LDAP_MAXINT)
- return WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld || !control || pagesize > LDAP_MAXINT) return WLDAP32_LDAP_PARAM_ERROR;
ret = ldap_create_page_controlW( ld, pagesize, cookie, critical, &controlW );
- if (ret == LDAP_SUCCESS)
+ if (ret == WLDAP32_LDAP_SUCCESS)
{
*control = controlWtoA( controlW );
ldap_control_freeW( controlW );
}
-
-#endif
return ret;
}
-#ifdef HAVE_LDAP
-
/* create a page control by hand */
-static ULONG create_page_control( ULONG pagesize, struct berval *cookie,
- UCHAR critical, PLDAPControlW *control )
+static ULONG create_page_control( ULONG pagesize, struct WLDAP32_berval *cookie, UCHAR critical, LDAPControlW **control )
{
LDAPControlW *ctrl;
- BerElement *ber;
- ber_tag_t tag;
- struct berval *berval;
- INT ret, len;
+ WLDAP32_BerElement *ber;
+ struct WLDAP32_berval *berval, *vec[2];
+ int ret, len;
char *val;
- ber = ber_alloc_t( LBER_USE_DER );
- if (!ber) return WLDAP32_LDAP_NO_MEMORY;
+ if (!(ber = WLDAP32_ber_alloc_t( WLDAP32_LBER_USE_DER ))) return WLDAP32_LDAP_NO_MEMORY;
+ vec[1] = NULL;
if (cookie)
- tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, cookie );
+ vec[0] = cookie;
else
- tag = ber_printf( ber, "{iO}", (ber_int_t)pagesize, &null_cookieU );
+ vec[0] = &null_cookieW;
+ len = WLDAP32_ber_printf( ber, (char *)"{iV}", pagesize, vec );
- ret = ber_flatten( ber, &berval );
- ber_free( ber, 1 );
+ ret = WLDAP32_ber_flatten( ber, &berval );
+ WLDAP32_ber_free( ber, 1 );
- if (tag == LBER_ERROR)
- return WLDAP32_LDAP_ENCODING_ERROR;
-
- if (ret == -1)
- return WLDAP32_LDAP_NO_MEMORY;
+ if (len == WLDAP32_LBER_ERROR) return WLDAP32_LDAP_ENCODING_ERROR;
+ if (ret == -1) return WLDAP32_LDAP_NO_MEMORY;
/* copy the berval so it can be properly freed by the caller */
if (!(val = heap_alloc( berval->bv_len ))) return WLDAP32_LDAP_NO_MEMORY;
len = berval->bv_len;
memcpy( val, berval->bv_val, len );
- ber_bvfree( berval );
+ WLDAP32_ber_bvfree( berval );
- if (!(ctrl = heap_alloc( sizeof(LDAPControlW) )))
+ if (!(ctrl = heap_alloc( sizeof(*ctrl) )))
{
heap_free( val );
return WLDAP32_LDAP_NO_MEMORY;
}
-
- ctrl->ldctl_oid = strAtoW( LDAP_PAGED_RESULT_OID_STRING );
+ if (!(ctrl->ldctl_oid = strAtoW( LDAP_PAGED_RESULT_OID_STRING )))
+ {
+ heap_free( ctrl );
+ return WLDAP32_LDAP_NO_MEMORY;
+ }
ctrl->ldctl_value.bv_len = len;
ctrl->ldctl_value.bv_val = val;
- ctrl->ldctl_iscritical = critical;
+ ctrl->ldctl_iscritical = critical;
*control = ctrl;
-
return WLDAP32_LDAP_SUCCESS;
}
-#endif /* HAVE_LDAP */
-
/***********************************************************************
* ldap_create_page_controlW (WLDAP32.@)
*
@@ -146,31 +124,16 @@ static ULONG create_page_control( ULONG pagesize, struct berval *cookie,
* Success: LDAP_SUCCESS
* Failure: An LDAP error code.
*/
-ULONG CDECL ldap_create_page_controlW( WLDAP32_LDAP *ld, ULONG pagesize,
- struct WLDAP32_berval *cookie, UCHAR critical, PLDAPControlW *control )
+ULONG CDECL ldap_create_page_controlW( WLDAP32_LDAP *ld, ULONG pagesize, struct WLDAP32_berval *cookie,
+ UCHAR critical, LDAPControlW **control )
{
-#ifdef HAVE_LDAP
- struct berval *cookieU = NULL;
- ULONG ret;
+ TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie, critical, control );
- TRACE( "(%p, 0x%08x, %p, 0x%02x, %p)\n", ld, pagesize, cookie,
- critical, control );
-
- if (!ld || !control || pagesize > LDAP_MAXINT)
- return WLDAP32_LDAP_PARAM_ERROR;
-
- if (cookie && !(cookieU = bervalWtoU( cookie ))) return WLDAP32_LDAP_NO_MEMORY;
- ret = create_page_control( pagesize, cookieU, critical, control );
- heap_free( cookieU );
- return ret;
-
-#else
- return WLDAP32_LDAP_NOT_SUPPORTED;
-#endif
+ if (!ld || !control || pagesize > LDAP_MAXINT) return WLDAP32_LDAP_PARAM_ERROR;
+ return create_page_control( pagesize, cookie, critical, control );
}
-ULONG CDECL ldap_get_next_page( WLDAP32_LDAP *ld, PLDAPSearch search, ULONG pagesize,
- ULONG *message )
+ULONG CDECL ldap_get_next_page( WLDAP32_LDAP *ld, LDAPSearch *search, ULONG pagesize, ULONG *message )
{
FIXME( "(%p, %p, 0x%08x, %p)\n", ld, search, pagesize, message );
@@ -178,18 +141,16 @@ ULONG CDECL ldap_get_next_page( WLDAP32_LDAP *ld, PLDAPSearch search, ULONG page
return WLDAP32_LDAP_NOT_SUPPORTED;
}
-ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, PLDAPSearch search,
- struct l_timeval *timeout, ULONG pagesize, ULONG *count,
- WLDAP32_LDAPMessage **results )
+ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, LDAPSearch *search, struct l_timeval *timeout, ULONG pagesize,
+ ULONG *count, WLDAP32_LDAPMessage **results )
{
-#ifdef HAVE_LDAP
ULONG ret;
- TRACE( "(%p, %p, %p, %u, %p, %p)\n", ld, search, timeout,
- pagesize, count, results );
+ TRACE( "(%p, %p, %p, %u, %p, %p)\n", ld, search, timeout, pagesize, count, results );
+
if (!ld || !search || !count || !results) return ~0u;
- if (search->cookie && search->cookie->bv_len == 0)
+ if (search->cookie && !search->cookie->bv_len)
{
/* end of paged results */
*count = 0;
@@ -207,22 +168,16 @@ ULONG CDECL ldap_get_next_page_s( WLDAP32_LDAP *ld, PLDAPSearch search,
ret = ldap_create_page_controlW( ld, pagesize, search->cookie, 1, &search->serverctrls[0] );
if (ret != WLDAP32_LDAP_SUCCESS) return ret;
- ret = ldap_search_ext_sW( ld, search->dn, search->scope,
- search->filter, search->attrs, search->attrsonly,
+ ret = ldap_search_ext_sW( ld, search->dn, search->scope, search->filter, search->attrs, search->attrsonly,
search->serverctrls, search->clientctrls,
search->timeout.tv_sec ? &search->timeout : NULL, search->sizelimit, results );
if (ret != WLDAP32_LDAP_SUCCESS) return ret;
return ldap_get_paged_count( ld, search, count, *results );
-
-#endif
- return WLDAP32_LDAP_NOT_SUPPORTED;
}
-ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, PLDAPSearch search,
- ULONG *count, WLDAP32_LDAPMessage *results )
+ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, LDAPSearch *search, ULONG *count, WLDAP32_LDAPMessage *results )
{
-#ifdef HAVE_LDAP
ULONG ret;
LDAPControlW **server_ctrls = NULL;
@@ -249,99 +204,68 @@ ULONG CDECL ldap_get_paged_count( WLDAP32_LDAP *ld, PLDAPSearch search,
TRACE("new search->cookie: %s, count %u\n", debugstr_an(search->cookie->bv_val, search->cookie->bv_len), *count);
ldap_controls_freeW( server_ctrls );
-
return ret;
-
-#endif
- return WLDAP32_LDAP_NOT_SUPPORTED;
}
/***********************************************************************
* ldap_parse_page_controlA (WLDAP32.@)
*/
-ULONG CDECL ldap_parse_page_controlA( WLDAP32_LDAP *ld, PLDAPControlA *ctrls,
- ULONG *count, struct WLDAP32_berval **cookie )
+ULONG CDECL ldap_parse_page_controlA( WLDAP32_LDAP *ld, LDAPControlA **ctrls, ULONG *count,
+ struct WLDAP32_berval **cookie )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
LDAPControlW **ctrlsW = NULL;
TRACE( "(%p, %p, %p, %p)\n", ld, ctrls, count, cookie );
- if (!ld || !ctrls || !count || !cookie)
- return WLDAP32_LDAP_PARAM_ERROR;
-
- ctrlsW = controlarrayAtoW( ctrls );
- if (!ctrlsW) return WLDAP32_LDAP_NO_MEMORY;
+ if (!ld || !ctrls || !count || !cookie) return WLDAP32_LDAP_PARAM_ERROR;
+ if (!(ctrlsW = controlarrayAtoW( ctrls ))) return WLDAP32_LDAP_NO_MEMORY;
ret = ldap_parse_page_controlW( ld, ctrlsW, count, cookie );
controlarrayfreeW( ctrlsW );
-
-#endif
return ret;
}
/***********************************************************************
* ldap_parse_page_controlW (WLDAP32.@)
*/
-ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, PLDAPControlW *ctrls,
- ULONG *count, struct WLDAP32_berval **cookie )
+ULONG CDECL ldap_parse_page_controlW( WLDAP32_LDAP *ld, LDAPControlW **ctrls, ULONG *count,
+ struct WLDAP32_berval **cookie )
{
- ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+ ULONG ret;
LDAPControlW *control = NULL;
- struct berval *cookieU = NULL, *valueU;
- BerElement *ber;
- ber_tag_t tag;
+ WLDAP32_BerElement *ber;
+ struct WLDAP32_berval *vec[2];
+ int tag;
ULONG i;
TRACE( "(%p, %p, %p, %p)\n", ld, ctrls, count, cookie );
- if (!ld || !ctrls || !count || !cookie)
- return WLDAP32_LDAP_PARAM_ERROR;
+ if (!ld || !ctrls || !count || !cookie) return WLDAP32_LDAP_PARAM_ERROR;
for (i = 0; ctrls[i]; i++)
{
if (!lstrcmpW( LDAP_PAGED_RESULT_OID_STRING_W, ctrls[i]->ldctl_oid ))
control = ctrls[i];
}
+ if (!control) return WLDAP32_LDAP_CONTROL_NOT_FOUND;
- if (!control)
- return WLDAP32_LDAP_CONTROL_NOT_FOUND;
-
- if (cookie && !(cookieU = bervalWtoU( *cookie )))
- return WLDAP32_LDAP_NO_MEMORY;
-
- if (!(valueU = bervalWtoU( &control->ldctl_value )))
- {
- heap_free( cookieU );
- return WLDAP32_LDAP_NO_MEMORY;
- }
+ if (!(ber = WLDAP32_ber_init( &control->ldctl_value ))) return WLDAP32_LDAP_NO_MEMORY;
- ber = ber_init( valueU );
- heap_free( valueU );
- if (!ber)
- {
- heap_free( cookieU );
- return WLDAP32_LDAP_NO_MEMORY;
- }
-
- tag = ber_scanf( ber, "{iO}", count, &cookieU );
- if (tag == LBER_ERROR)
+ vec[0] = *cookie;
+ vec[1] = 0;
+ tag = WLDAP32_ber_scanf( ber, (char *)"{iV}", count, vec );
+ if (tag == WLDAP32_LBER_ERROR)
ret = WLDAP32_LDAP_DECODING_ERROR;
else
ret = WLDAP32_LDAP_SUCCESS;
- heap_free( cookieU );
- ber_free( ber, 1 );
-
-#endif
+ WLDAP32_ber_free( ber, 1 );
return ret;
}
-ULONG CDECL ldap_search_abandon_page( WLDAP32_LDAP *ld, PLDAPSearch search )
+ULONG CDECL ldap_search_abandon_page( WLDAP32_LDAP *ld, LDAPSearch *search )
{
-#ifdef HAVE_LDAP
LDAPControlW **ctrls;
TRACE( "(%p, %p)\n", ld, search );
@@ -357,91 +281,70 @@ ULONG CDECL ldap_search_abandon_page( WLDAP32_LDAP *ld, PLDAPSearch search )
while (*ctrls) controlfreeW( *ctrls++ );
heap_free( search->serverctrls );
controlarrayfreeW( search->clientctrls );
- if (search->cookie && search->cookie != &null_cookieW)
- heap_free( search->cookie );
+ if (search->cookie && search->cookie != &null_cookieW) heap_free( search->cookie );
heap_free( search );
return WLDAP32_LDAP_SUCCESS;
-
-#else
- return WLDAP32_LDAP_NOT_SUPPORTED;
-#endif
}
-PLDAPSearch CDECL ldap_search_init_pageA( WLDAP32_LDAP *ld, PCHAR dn, ULONG scope,
- PCHAR filter, PCHAR attrs[], ULONG attrsonly, PLDAPControlA *serverctrls,
- PLDAPControlA *clientctrls, ULONG timelimit, ULONG sizelimit, PLDAPSortKeyA *sortkeys )
+LDAPSearch * CDECL ldap_search_init_pageA( WLDAP32_LDAP *ld, char *dn, ULONG scope, char *filter, char **attrs,
+ ULONG attrsonly, LDAPControlA **serverctrls, LDAPControlA **clientctrls, ULONG timelimit, ULONG sizelimit,
+ LDAPSortKeyA **sortkeys )
{
- FIXME( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_a(dn),
- scope, debugstr_a(filter), attrs, attrsonly );
+ FIXME( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n", ld, debugstr_a(dn), scope,
+ debugstr_a(filter), attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, sortkeys );
return NULL;
}
-PLDAPSearch CDECL ldap_search_init_pageW( WLDAP32_LDAP *ld, PWCHAR dn, ULONG scope,
- PWCHAR filter, PWCHAR attrs[], ULONG attrsonly, PLDAPControlW *serverctrls,
- PLDAPControlW *clientctrls, ULONG timelimit, ULONG sizelimit, PLDAPSortKeyW *sortkeys )
+LDAPSearch * CDECL ldap_search_init_pageW( WLDAP32_LDAP *ld, WCHAR *dn, ULONG scope, WCHAR *filter, WCHAR **attrs,
+ ULONG attrsonly, LDAPControlW **serverctrls, LDAPControlW **clientctrls, ULONG timelimit, ULONG sizelimit,
+ LDAPSortKeyW **sortkeys )
{
-#ifdef HAVE_LDAP
LDAPSearch *search;
DWORD i, len;
- TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n",
- ld, debugstr_w(dn), scope, debugstr_w(filter), attrs, attrsonly,
- serverctrls, clientctrls, timelimit, sizelimit, sortkeys );
+ TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n", ld, debugstr_w(dn), scope,
+ debugstr_w(filter), attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, sortkeys );
- search = heap_alloc_zero( sizeof(*search) );
- if (!search)
+ if (!(search = heap_alloc_zero( sizeof(*search) )))
{
ld->ld_errno = WLDAP32_LDAP_NO_MEMORY;
return NULL;
}
- if (dn)
- {
- search->dn = strdupW( dn );
- if (!search->dn) goto fail;
- }
- if (filter)
- {
- search->filter = strdupW( filter );
- if (!search->filter) goto fail;
- }
- if (attrs)
- {
- search->attrs = strarraydupW( attrs );
- if (!search->attrs) goto fail;
- }
+ if (dn && !(search->dn = strdupW( dn ))) goto fail;
+ if (filter && !(search->filter = strdupW( filter ))) goto fail;
+ if (attrs && !(search->attrs = strarraydupW( attrs ))) goto fail;
len = serverctrls ? controlarraylenW( serverctrls ) : 0;
- search->serverctrls = heap_alloc( sizeof(LDAPControl *) * (len + 2) );
- if (!search->serverctrls) goto fail;
+ if (!(search->serverctrls = heap_alloc( sizeof(LDAPControlW *) * (len + 2) ))) goto fail;
search->serverctrls[0] = NULL; /* reserve 0 for page control */
for (i = 0; i < len; i++)
{
- search->serverctrls[i + 1] = controldupW( serverctrls[i] );
- if (!search->serverctrls[i + 1]) goto fail;
+ if (!(search->serverctrls[i + 1] = controldupW( serverctrls[i] )))
+ {
+ for (; i > 0; i--) controlfreeW( search->serverctrls[i] );
+ goto fail;
+ }
}
search->serverctrls[len + 1] = NULL;
- if (clientctrls)
+ if (clientctrls && !(search->clientctrls = controlarraydupW( clientctrls )))
{
- search->clientctrls = controlarraydupW( clientctrls );
- if (!search->clientctrls) goto fail;
+ for (i = 0; i < len; i++) controlfreeW( search->serverctrls[i] );
+ goto fail;
}
- search->scope = scope;
- search->attrsonly = attrsonly;
- search->timeout.tv_sec = timelimit;
+ search->scope = scope;
+ search->attrsonly = attrsonly;
+ search->timeout.tv_sec = timelimit;
search->timeout.tv_usec = 0;
- search->sizelimit = sizelimit;
- search->cookie = NULL;
-
+ search->sizelimit = sizelimit;
+ search->cookie = NULL;
return search;
fail:
ldap_search_abandon_page( ld, search );
ld->ld_errno = WLDAP32_LDAP_NO_MEMORY;
-
-#endif
return NULL;
}
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 32ed3f5a266..e488db954c8 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -40,6 +40,8 @@
#define WLDAP32_LDAP_SCOPE_ONELEVEL 0x01
#define WLDAP32_LDAP_SCOPE_SUBTREE 0x02
+#define WLDAP32_LBER_USE_DER 0x01
+
typedef enum {
WLDAP32_LDAP_SUCCESS = 0x00,
WLDAP32_LDAP_UNWILLING_TO_PERFORM = 0x35,
@@ -312,6 +314,14 @@ typedef struct ldap_apifeature_infoW
int ldapaif_version;
} LDAPAPIFeatureInfoW;
+WLDAP32_BerElement * CDECL WLDAP32_ber_alloc_t(int);
+void CDECL WLDAP32_ber_bvfree(BERVAL *);
+int CDECL WLDAP32_ber_flatten(WLDAP32_BerElement *, BERVAL **);
+void CDECL WLDAP32_ber_free(WLDAP32_BerElement *, int);
+WLDAP32_BerElement * CDECL WLDAP32_ber_init(BERVAL *);
+int WINAPIV WLDAP32_ber_printf(WLDAP32_BerElement *, char *, ...);
+ULONG WINAPIV WLDAP32_ber_scanf(WLDAP32_BerElement *, char *, ...);
+
WLDAP32_LDAP * CDECL cldap_openA(PCHAR,ULONG);
WLDAP32_LDAP * CDECL cldap_openW(PWCHAR,ULONG);
ULONG CDECL WLDAP32_ldap_abandon(WLDAP32_LDAP*,ULONG);
@@ -614,6 +624,26 @@ static inline char **strarrayWtoU( WCHAR **strarray )
return strarrayU;
}
+static inline WCHAR **strarraydupW( WCHAR **strarray )
+{
+ WCHAR **strarrayW = NULL;
+ DWORD size;
+
+ if (strarray)
+ {
+ size = sizeof(WCHAR *) * (strarraylenW( strarray ) + 1);
+ if ((strarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ WCHAR **p = strarray;
+ WCHAR **q = strarrayW;
+
+ while (*p) *q++ = strdupW( *p++ );
+ *q = NULL;
+ }
+ }
+ return strarrayW;
+}
+
static inline char *strWtoA( const WCHAR *str )
{
char *ret = NULL;
@@ -1161,6 +1191,52 @@ static inline DWORD controlarraylenU( LDAPControlU **controlarray )
return p - controlarray;
}
+static inline LDAPControlW *controldupW( LDAPControlW *control )
+{
+ LDAPControlW *controlW;
+ DWORD len = control->ldctl_value.bv_len;
+ char *val = NULL;
+
+ if (control->ldctl_value.bv_val)
+ {
+ if (!(val = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return NULL;
+ memcpy( val, control->ldctl_value.bv_val, len );
+ }
+
+ if (!(controlW = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(LDAPControlW) )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, val );
+ return NULL;
+ }
+
+ controlW->ldctl_oid = strdupW( control->ldctl_oid );
+ controlW->ldctl_value.bv_len = len;
+ controlW->ldctl_value.bv_val = val;
+ controlW->ldctl_iscritical = control->ldctl_iscritical;
+
+ return controlW;
+}
+
+static inline LDAPControlW **controlarraydupW( LDAPControlW **controlarray )
+{
+ LDAPControlW **controlarrayW = NULL;
+ DWORD size;
+
+ if (controlarray)
+ {
+ size = sizeof(LDAPControlW *) * (controlarraylenW( controlarray ) + 1);
+ if ((controlarrayW = RtlAllocateHeap( GetProcessHeap(), 0, size )))
+ {
+ LDAPControlW **p = controlarray;
+ LDAPControlW **q = controlarrayW;
+
+ while (*p) *q++ = controldupW( *p++ );
+ *q = NULL;
+ }
+ }
+ return controlarrayW;
+}
+
static inline WCHAR *strUtoW( const char *str )
{
WCHAR *ret = NULL;
--
2.30.2
1
0