Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 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
December 2020
- 68 participants
- 931 messages
[PATCH 1/5] wined3d: Reference the source/destination bo in wined3d_context_gl_copy_bo_address().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/context_gl.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index ee1adfcf559..4aaf50434a6 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2728,6 +2728,9 @@ void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl,
GL_EXTCALL(glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER,
(GLintptr)src->addr, (GLintptr)dst->addr, size));
checkGLcall("direct buffer copy");
+
+ wined3d_context_gl_reference_bo(context_gl, src_bo);
+ wined3d_context_gl_reference_bo(context_gl, dst_bo);
}
else
{
@@ -2747,12 +2750,16 @@ void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl,
wined3d_context_gl_bind_bo(context_gl, src_bo->binding, src_bo->id);
GL_EXTCALL(glGetBufferSubData(src_bo->binding, (GLintptr)src->addr, size, dst->addr));
checkGLcall("buffer download");
+
+ wined3d_context_gl_reference_bo(context_gl, src_bo);
}
else if (dst_bo && !src_bo)
{
wined3d_context_gl_bind_bo(context_gl, dst_bo->binding, dst_bo->id);
GL_EXTCALL(glBufferSubData(dst_bo->binding, (GLintptr)dst->addr, size, src->addr));
checkGLcall("buffer upload");
+
+ wined3d_context_gl_reference_bo(context_gl, dst_bo);
}
else
{
--
2.20.1
Dec. 1, 2020
[PATCH 4/4] kernelbase: Simplify CreateFileW.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/kernelbase/file.c | 24 ++++++------------------
1 file changed, 6 insertions(+), 18 deletions(-)
Dec. 1, 2020
[PATCH 3/4] kernel32: Remove no longer needed CONSOLE_Init.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/kernel32/console.c | 25 -------------------------
dlls/kernel32/kernel_main.c | 4 ----
dlls/kernel32/kernel_private.h | 12 ------------
3 files changed, 41 deletions(-)
Dec. 1, 2020
[PATCH 2/4] kernelbase: Remove no longer needed console handle mapping.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/kernelbase/console.c | 6 +++---
dlls/kernelbase/file.c | 6 ------
dlls/kernelbase/kernelbase.h | 11 -----------
dlls/kernelbase/process.c | 10 ----------
4 files changed, 3 insertions(+), 30 deletions(-)
Dec. 1, 2020
[PATCH 1/4] cmd: Don't use WCMD_is_console_handle.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
programs/cmd/batch.c | 5 ++---
programs/cmd/wcmd.h | 4 ----
programs/cmd/wcmdmain.c | 5 ++---
3 files changed, 4 insertions(+), 10 deletions(-)
Dec. 1, 2020
Re: [PATCH vkd3d v2 3/3] vkd3d-compiler: Default to HLSL as a source format when preprocessing.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 1, 2020
Re: [PATCH vkd3d v2 2/3] vkd3d-compiler: Check whether the source format is binary when checking if the output is a tty, when preprocessing.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 1, 2020
Re: [PATCH vkd3d v2 1/3] vkd3d-compiler: Do not validate the target type when preprocessing.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 1, 2020
Re: [PATCH] windowscodecs: Don't make variables const just to cast the const away.
by Esme Povirk (they/them)
I would rather have these inlined.
Dec. 1, 2020
[PATCH 6/6] gdi32: Use FreeType as a fallback when loading font faces.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
We keep FreeType code path as it's still used for some corner cases like
WinFNT fonts, although we could also implement the parsing of such fonts
ourselves in a similar way.
dlls/gdi32/freetype.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index f9d82644176..0ffd2f8f34a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1218,15 +1218,10 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
if (!(This = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This) ))) goto done;
- if (!(This->ft_face = new_ft_face( unix_name, data_ptr, data_size, face_index, flags & ADDFONT_ALLOW_BITMAP )))
- {
- RtlFreeHeap( GetProcessHeap(), 0, This );
- This = NULL;
- }
- else if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ) &&
- opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ) &&
- opentype_get_properties( data_ptr, data_size, ttc_sfnt_v1, &This->font_version,
- &This->fs, &This->ntm_flags ))
+ if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ) &&
+ opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ) &&
+ opentype_get_properties( data_ptr, data_size, ttc_sfnt_v1, &This->font_version,
+ &This->fs, &This->ntm_flags ))
{
struct family_names_data family_names;
struct face_name_data style_name;
@@ -1268,7 +1263,7 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
WARN( "full name not found, using %s instead\n", debugstr_w(This->full_name) );
}
}
- else
+ else if ((This->ft_face = new_ft_face( unix_name, data_ptr, data_size, face_index, flags & ADDFONT_ALLOW_BITMAP )))
{
WARN( "unable to parse font, falling back to FreeType\n" );
This->scalable = FT_IS_SCALABLE( This->ft_face );
@@ -1299,6 +1294,11 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
if (!This->scalable) get_bitmap_size( This->ft_face, &This->size );
get_fontsig( This->ft_face, &This->fs );
}
+ else
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, This );
+ This = NULL;
+ }
done:
if (unix_name) munmap( data_ptr, data_size );
@@ -1307,7 +1307,7 @@ done:
static void unix_face_destroy( struct unix_face *This )
{
- pFT_Done_Face( This->ft_face );
+ if (This->ft_face) pFT_Done_Face( This->ft_face );
RtlFreeHeap( GetProcessHeap(), 0, This->full_name );
RtlFreeHeap( GetProcessHeap(), 0, This->style_name );
RtlFreeHeap( GetProcessHeap(), 0, This->second_name );
--
2.29.2
Dec. 1, 2020
[PATCH 5/6] gdi32: Try to parse font props without FreeType.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
This makes a tiny difference to the dump_gdi_font_list report, for some
fonts that do not have any bit set in fs->fsCsb[0]. This is the case for
instance for Noto Arabic font family. We were previously filling it with
FS_LATIN1 as fallback because FreeType reported some charmap encoded with
FT_ENCODING_APPLE_ROMAN, but I don't think it was correct.
dlls/gdi32/freetype.c | 7 ++--
dlls/gdi32/gdi_private.h | 3 ++
dlls/gdi32/opentype.c | 91 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 06bc29ff86a..f9d82644176 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1224,7 +1224,9 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
This = NULL;
}
else if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ) &&
- opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ))
+ opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ) &&
+ opentype_get_properties( data_ptr, data_size, ttc_sfnt_v1, &This->font_version,
+ &This->fs, &This->ntm_flags ))
{
struct family_names_data family_names;
struct face_name_data style_name;
@@ -1291,10 +1293,7 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
This->style_name = ft_face_get_style_name( This->ft_face, system_lcid );
This->full_name = ft_face_get_full_name( This->ft_face, system_lcid );
- }
- if (This)
- {
This->ntm_flags = get_ntm_flags( This->ft_face );
This->font_version = get_font_version( This->ft_face );
if (!This->scalable) get_bitmap_size( This->ft_face, &This->size );
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 9a988d08d7e..8d917a795c0 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -439,6 +439,9 @@ extern BOOL opentype_enum_style_names( const struct tt_name_v0 *tt_name_v0,
extern BOOL opentype_enum_full_names( const struct tt_name_v0 *tt_name_v0,
opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN;
+extern BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
+ DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags ) DECLSPEC_HIDDEN;
+
/* gdiobj.c */
extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/opentype.c b/dlls/gdi32/opentype.c
index 4200b08d318..67af44dfe91 100644
--- a/dlls/gdi32/opentype.c
+++ b/dlls/gdi32/opentype.c
@@ -42,6 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(font);
#define MS_EBDT_TAG MS_MAKE_TAG('E','B','D','T')
#define MS_CBDT_TAG MS_MAKE_TAG('C','B','D','T')
#define MS_NAME_TAG MS_MAKE_TAG('n','a','m','e')
+#define MS_CFF__TAG MS_MAKE_TAG('C','F','F',' ')
#ifdef WORDS_BIGENDIAN
#define GET_BE_WORD(x) (x)
@@ -135,6 +136,28 @@ struct tt_name_v0
WORD stringOffset;
struct tt_namerecord nameRecord[1];
};
+
+struct tt_head
+{
+ USHORT majorVersion;
+ USHORT minorVersion;
+ ULONG revision;
+ ULONG checksumadj;
+ ULONG magic;
+ USHORT flags;
+ USHORT unitsPerEm;
+ ULONGLONG created;
+ ULONGLONG modified;
+ SHORT xMin;
+ SHORT yMin;
+ SHORT xMax;
+ SHORT yMax;
+ USHORT macStyle;
+ USHORT lowestRecPPEM;
+ SHORT direction_hint;
+ SHORT index_format;
+ SHORT glyphdata_format;
+};
#include "poppack.h"
enum OPENTYPE_PLATFORM_ID
@@ -236,6 +259,20 @@ enum OPENTYPE_NAME_ID
OPENTYPE_NAME_WWS_SUBFAMILY
};
+enum OS2_FSSELECTION
+{
+ OS2_FSSELECTION_ITALIC = 1 << 0,
+ OS2_FSSELECTION_UNDERSCORE = 1 << 1,
+ OS2_FSSELECTION_NEGATIVE = 1 << 2,
+ OS2_FSSELECTION_OUTLINED = 1 << 3,
+ OS2_FSSELECTION_STRIKEOUT = 1 << 4,
+ OS2_FSSELECTION_BOLD = 1 << 5,
+ OS2_FSSELECTION_REGULAR = 1 << 6,
+ OS2_FSSELECTION_USE_TYPO_METRICS = 1 << 7,
+ OS2_FSSELECTION_WWS = 1 << 8,
+ OS2_FSSELECTION_OBLIQUE = 1 << 9
+};
+
static BOOL opentype_get_table_ptr( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
UINT32 table_tag, const void **table_ptr, UINT32 *table_size )
{
@@ -270,6 +307,13 @@ static BOOL opentype_get_tt_os2_v1( const void *data, size_t size, const struct
return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_OS_2_TAG, (const void **)tt_os2_v1, &table_size );
}
+static BOOL opentype_get_tt_head( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
+ const struct tt_head **tt_head )
+{
+ UINT32 table_size = sizeof(**tt_head);
+ return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_HEAD_TAG, (const void **)tt_head, &table_size );
+}
+
static UINT get_name_record_codepage( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding )
{
switch (platform)
@@ -677,3 +721,50 @@ BOOL opentype_enum_full_names( const struct tt_name_v0 *header, opentype_enum_na
return TRUE;
return FALSE;
}
+
+BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
+ DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags )
+{
+ const struct tt_os2_v1 *tt_os2_v1;
+ const struct tt_head *tt_head;
+ const void *cff_header;
+ UINT32 table_size = 0;
+ USHORT idx, selection;
+ DWORD flags = 0;
+
+ if (!opentype_get_tt_head( data, size, ttc_sfnt_v1, &tt_head )) return FALSE;
+ if (!opentype_get_tt_os2_v1( data, size, ttc_sfnt_v1, &tt_os2_v1 )) return FALSE;
+
+ *version = GET_BE_DWORD( tt_head->revision );
+
+ fs->fsUsb[0] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange1 );
+ fs->fsUsb[1] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange2 );
+ fs->fsUsb[2] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange3 );
+ fs->fsUsb[3] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange4 );
+
+ if (tt_os2_v1->version == 0)
+ {
+ idx = GET_BE_WORD( tt_os2_v1->usFirstCharIndex );
+ if (idx >= 0xf000 && idx < 0xf100) fs->fsCsb[0] = FS_SYMBOL;
+ else fs->fsCsb[0] = FS_LATIN1;
+ fs->fsCsb[1] = 0;
+ }
+ else
+ {
+ fs->fsCsb[0] = GET_BE_DWORD( tt_os2_v1->ulCodePageRange1 );
+ fs->fsCsb[1] = GET_BE_DWORD( tt_os2_v1->ulCodePageRange2 );
+ }
+
+ selection = GET_BE_WORD( tt_os2_v1->fsSelection );
+
+ if (selection & OS2_FSSELECTION_ITALIC) flags |= NTM_ITALIC;
+ if (selection & OS2_FSSELECTION_BOLD) flags |= NTM_BOLD;
+ if (selection & OS2_FSSELECTION_REGULAR) flags |= NTM_REGULAR;
+ if (flags == 0) flags = NTM_REGULAR;
+
+ if (opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_CFF__TAG, &cff_header, &table_size ))
+ flags |= NTM_PS_OPENTYPE;
+
+ *ntm_flags = flags;
+ return TRUE;
+}
--
2.29.2
Dec. 1, 2020
[PATCH 4/6] gdi32: Try to parse font names without FreeType.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/gdi32/freetype.c | 131 ++++++++++-
dlls/gdi32/gdi_private.h | 18 ++
dlls/gdi32/opentype.c | 459 +++++++++++++++++++++++++++++++++++++++
3 files changed, 603 insertions(+), 5 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 686f2b54682..06bc29ff86a 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1092,6 +1092,86 @@ fail:
return NULL;
}
+struct family_names_data
+{
+ LANGID primary_langid;
+ struct opentype_name family_name;
+ struct opentype_name second_name;
+ BOOL primary_seen;
+ BOOL english_seen;
+};
+
+static BOOL search_family_names_callback( LANGID langid, struct opentype_name *name, void *user )
+{
+ struct family_names_data *data = user;
+
+ if (langid == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT))
+ {
+ data->english_seen = TRUE;
+ if (data->primary_langid == langid) data->primary_seen = TRUE;
+
+ if (!data->family_name.bytes) data->family_name = *name;
+ else if (data->primary_langid != langid) data->second_name = *name;
+ }
+ else if (data->primary_langid == langid)
+ {
+ data->primary_seen = TRUE;
+ if (!data->second_name.bytes) data->second_name = data->family_name;
+ data->family_name = *name;
+ }
+ else if (!data->second_name.bytes) data->second_name = *name;
+
+ if (data->family_name.bytes && data->second_name.bytes && data->primary_seen && data->english_seen)
+ return TRUE;
+ return FALSE;
+}
+
+struct face_name_data
+{
+ LANGID primary_langid;
+ struct opentype_name face_name;;
+};
+
+static BOOL search_face_name_callback( LANGID langid, struct opentype_name *name, void *user )
+{
+ struct face_name_data *data = user;
+
+ if (langid == data->primary_langid || (langid == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) && !data->face_name.bytes))
+ data->face_name = *name;
+
+ return langid == data->primary_langid;
+}
+
+static WCHAR *decode_opentype_name( struct opentype_name *name )
+{
+ CPTABLEINFO codepage_info;
+ USHORT *codepage_ptr;
+ SIZE_T codepage_size;
+ WCHAR buffer[512];
+ DWORD len;
+
+ if (!name->codepage)
+ {
+ len = min( ARRAY_SIZE(buffer), name->length / sizeof(WCHAR) );
+ while (len--) buffer[len] = GET_BE_WORD( ((WORD *)name->bytes)[len] );
+ len = min( ARRAY_SIZE(buffer), name->length / sizeof(WCHAR) );
+ }
+ else
+ {
+ NtGetNlsSectionPtr( 11, name->codepage, NULL, (void **)&codepage_ptr, &codepage_size );
+ RtlInitCodePageTable( codepage_ptr, &codepage_info );
+ RtlCustomCPToUnicodeN( &codepage_info, buffer, sizeof(buffer), &len, name->bytes, name->length );
+ len /= sizeof(WCHAR);
+ NtUnmapViewOfSection( GetCurrentProcess(), codepage_ptr );
+ }
+
+ buffer[ARRAY_SIZE(buffer) - 1] = 0;
+ if (len == ARRAY_SIZE(buffer)) WARN("Truncated font name %s -> %s\n", debugstr_an(name->bytes, name->length), debugstr_w(buffer));
+ else buffer[len] = 0;
+
+ return strdupW( buffer );
+}
+
struct unix_face
{
FT_Face ft_face;
@@ -1110,11 +1190,14 @@ struct unix_face
static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr, DWORD data_size,
UINT face_index, DWORD flags )
{
+ static const WCHAR space_w[] = {' ',0};
+
const struct ttc_sfnt_v1 *ttc_sfnt_v1;
+ const struct tt_name_v0 *tt_name_v0;
struct unix_face *This;
struct stat st;
DWORD face_count;
- int fd;
+ int fd, length;
TRACE( "unix_name %s, face_index %u, data_ptr %p, data_size %u, flags %#x\n",
unix_name, face_index, data_ptr, data_size, flags );
@@ -1140,20 +1223,55 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
RtlFreeHeap( GetProcessHeap(), 0, This );
This = NULL;
}
- else if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ))
+ else if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ) &&
+ opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ))
{
+ struct family_names_data family_names;
+ struct face_name_data style_name;
+ struct face_name_data full_name;
+ LANGID primary_langid = system_lcid;
+
This->scalable = TRUE;
This->num_faces = face_count;
+
+ memset( &family_names, 0, sizeof(family_names) );
+ family_names.primary_langid = primary_langid;
+ opentype_enum_family_names( tt_name_v0, search_family_names_callback, &family_names );
+ This->family_name = decode_opentype_name( &family_names.family_name );
+ This->second_name = decode_opentype_name( &family_names.second_name );
+
+ memset( &style_name, 0, sizeof(style_name) );
+ style_name.primary_langid = primary_langid;
+ opentype_enum_style_names( tt_name_v0, search_face_name_callback, &style_name );
+ This->style_name = decode_opentype_name( &style_name.face_name );
+
+ memset( &full_name, 0, sizeof(full_name) );
+ style_name.primary_langid = primary_langid;
+ opentype_enum_full_names( tt_name_v0, search_face_name_callback, &full_name );
+ This->full_name = decode_opentype_name( &full_name.face_name );
+
+ TRACE( "parsed font names family_name %s, second_name %s, primary_seen %d, english_seen %d, "
+ "full_name %s, style_name %s\n",
+ debugstr_w(This->family_name), debugstr_w(This->second_name),
+ family_names.primary_seen, family_names.english_seen,
+ debugstr_w(This->full_name), debugstr_w(This->style_name) );
+
+ if (!This->full_name && This->family_name && This->style_name)
+ {
+ length = lstrlenW( This->family_name ) + lstrlenW( space_w ) + lstrlenW( This->style_name ) + 1;
+ This->full_name = RtlAllocateHeap( GetProcessHeap(), 0, length * sizeof(WCHAR) );
+ lstrcpyW( This->full_name, This->family_name );
+ lstrcatW( This->full_name, space_w );
+ lstrcatW( This->full_name, This->style_name );
+ WARN( "full name not found, using %s instead\n", debugstr_w(This->full_name) );
+ }
}
else
{
WARN( "unable to parse font, falling back to FreeType\n" );
This->scalable = FT_IS_SCALABLE( This->ft_face );
This->num_faces = This->ft_face->num_faces;
- }
- if (This)
- {
This->family_name = ft_face_get_family_name( This->ft_face, system_lcid );
This->second_name = ft_face_get_family_name( This->ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) );
@@ -1173,7 +1291,10 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
This->style_name = ft_face_get_style_name( This->ft_face, system_lcid );
This->full_name = ft_face_get_full_name( This->ft_face, system_lcid );
+ }
+ if (This)
+ {
This->ntm_flags = get_ntm_flags( This->ft_face );
This->font_version = get_font_version( This->ft_face );
if (!This->scalable) get_bitmap_size( This->ft_face, &This->size );
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index a529cb0890c..9a988d08d7e 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -417,9 +417,27 @@ extern void font_init(void) DECLSPEC_HIDDEN;
/* opentype.c */
struct ttc_sfnt_v1;
+struct tt_name_v0;
+
+struct opentype_name
+{
+ DWORD codepage;
+ DWORD length;
+ const void *bytes;
+};
extern BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD *count,
const struct ttc_sfnt_v1 **ttc_sfnt_v1 ) DECLSPEC_HIDDEN;
+extern BOOL opentype_get_tt_name_v0( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
+ const struct tt_name_v0 **tt_name_v0 ) DECLSPEC_HIDDEN;
+
+typedef BOOL ( *opentype_enum_names_cb )( LANGID langid, struct opentype_name *name, void *user );
+extern BOOL opentype_enum_family_names( const struct tt_name_v0 *tt_name_v0,
+ opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN;
+extern BOOL opentype_enum_style_names( const struct tt_name_v0 *tt_name_v0,
+ opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN;
+extern BOOL opentype_enum_full_names( const struct tt_name_v0 *tt_name_v0,
+ opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN;
/* gdiobj.c */
extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/opentype.c b/dlls/gdi32/opentype.c
index 2363439cdc5..4200b08d318 100644
--- a/dlls/gdi32/opentype.c
+++ b/dlls/gdi32/opentype.c
@@ -26,6 +26,7 @@
#include "windef.h"
#include "winbase.h"
+#include "winnls.h"
#include "wine/debug.h"
@@ -40,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(font);
#define MS_EBSC_TAG MS_MAKE_TAG('E','B','S','C')
#define MS_EBDT_TAG MS_MAKE_TAG('E','B','D','T')
#define MS_CBDT_TAG MS_MAKE_TAG('C','B','D','T')
+#define MS_NAME_TAG MS_MAKE_TAG('n','a','m','e')
#ifdef WORDS_BIGENDIAN
#define GET_BE_WORD(x) (x)
@@ -115,8 +117,125 @@ struct tt_os2_v1
ULONG ulCodePageRange1;
ULONG ulCodePageRange2;
};
+
+struct tt_namerecord
+{
+ WORD platformID;
+ WORD encodingID;
+ WORD languageID;
+ WORD nameID;
+ WORD length;
+ WORD offset;
+};
+
+struct tt_name_v0
+{
+ WORD format;
+ WORD count;
+ WORD stringOffset;
+ struct tt_namerecord nameRecord[1];
+};
#include "poppack.h"
+enum OPENTYPE_PLATFORM_ID
+{
+ OPENTYPE_PLATFORM_UNICODE = 0,
+ OPENTYPE_PLATFORM_MAC,
+ OPENTYPE_PLATFORM_ISO,
+ OPENTYPE_PLATFORM_WIN,
+ OPENTYPE_PLATFORM_CUSTOM
+};
+
+enum TT_NAME_WIN_ENCODING_ID
+{
+ TT_NAME_WIN_ENCODING_SYMBOL = 0,
+ TT_NAME_WIN_ENCODING_UNICODE_BMP,
+ TT_NAME_WIN_ENCODING_SJIS,
+ TT_NAME_WIN_ENCODING_PRC,
+ TT_NAME_WIN_ENCODING_BIG5,
+ TT_NAME_WIN_ENCODING_WANSUNG,
+ TT_NAME_WIN_ENCODING_JOHAB,
+ TT_NAME_WIN_ENCODING_RESERVED1,
+ TT_NAME_WIN_ENCODING_RESERVED2,
+ TT_NAME_WIN_ENCODING_RESERVED3,
+ TT_NAME_WIN_ENCODING_UNICODE_FULL
+};
+
+enum TT_NAME_UNICODE_ENCODING_ID
+{
+ TT_NAME_UNICODE_ENCODING_1_0 = 0,
+ TT_NAME_UNICODE_ENCODING_1_1,
+ TT_NAME_UNICODE_ENCODING_ISO_10646,
+ TT_NAME_UNICODE_ENCODING_2_0_BMP,
+ TT_NAME_UNICODE_ENCODING_2_0_FULL,
+ TT_NAME_UNICODE_ENCODING_VAR,
+ TT_NAME_UNICODE_ENCODING_FULL,
+};
+
+enum TT_NAME_MAC_ENCODING_ID
+{
+ TT_NAME_MAC_ENCODING_ROMAN = 0,
+ TT_NAME_MAC_ENCODING_JAPANESE,
+ TT_NAME_MAC_ENCODING_TRAD_CHINESE,
+ TT_NAME_MAC_ENCODING_KOREAN,
+ TT_NAME_MAC_ENCODING_ARABIC,
+ TT_NAME_MAC_ENCODING_HEBREW,
+ TT_NAME_MAC_ENCODING_GREEK,
+ TT_NAME_MAC_ENCODING_RUSSIAN,
+ TT_NAME_MAC_ENCODING_RSYMBOL,
+ TT_NAME_MAC_ENCODING_DEVANAGARI,
+ TT_NAME_MAC_ENCODING_GURMUKHI,
+ TT_NAME_MAC_ENCODING_GUJARATI,
+ TT_NAME_MAC_ENCODING_ORIYA,
+ TT_NAME_MAC_ENCODING_BENGALI,
+ TT_NAME_MAC_ENCODING_TAMIL,
+ TT_NAME_MAC_ENCODING_TELUGU,
+ TT_NAME_MAC_ENCODING_KANNADA,
+ TT_NAME_MAC_ENCODING_MALAYALAM,
+ TT_NAME_MAC_ENCODING_SINHALESE,
+ TT_NAME_MAC_ENCODING_BURMESE,
+ TT_NAME_MAC_ENCODING_KHMER,
+ TT_NAME_MAC_ENCODING_THAI,
+ TT_NAME_MAC_ENCODING_LAOTIAN,
+ TT_NAME_MAC_ENCODING_GEORGIAN,
+ TT_NAME_MAC_ENCODING_ARMENIAN,
+ TT_NAME_MAC_ENCODING_SIMPL_CHINESE,
+ TT_NAME_MAC_ENCODING_TIBETAN,
+ TT_NAME_MAC_ENCODING_MONGOLIAN,
+ TT_NAME_MAC_ENCODING_GEEZ,
+ TT_NAME_MAC_ENCODING_SLAVIC,
+ TT_NAME_MAC_ENCODING_VIETNAMESE,
+ TT_NAME_MAC_ENCODING_SINDHI,
+ TT_NAME_MAC_ENCODING_UNINTERPRETED
+};
+
+enum OPENTYPE_NAME_ID
+{
+ OPENTYPE_NAME_COPYRIGHT_NOTICE = 0,
+ OPENTYPE_NAME_FAMILY,
+ OPENTYPE_NAME_SUBFAMILY,
+ OPENTYPE_NAME_UNIQUE_IDENTIFIER,
+ OPENTYPE_NAME_FULLNAME,
+ OPENTYPE_NAME_VERSION_STRING,
+ OPENTYPE_NAME_POSTSCRIPT,
+ OPENTYPE_NAME_TRADEMARK,
+ OPENTYPE_NAME_MANUFACTURER,
+ OPENTYPE_NAME_DESIGNER,
+ OPENTYPE_NAME_DESCRIPTION,
+ OPENTYPE_NAME_VENDOR_URL,
+ OPENTYPE_NAME_DESIGNER_URL,
+ OPENTYPE_NAME_LICENSE_DESCRIPTION,
+ OPENTYPE_NAME_LICENSE_INFO_URL,
+ OPENTYPE_NAME_RESERVED_ID15,
+ OPENTYPE_NAME_TYPOGRAPHIC_FAMILY,
+ OPENTYPE_NAME_TYPOGRAPHIC_SUBFAMILY,
+ OPENTYPE_NAME_COMPATIBLE_FULLNAME,
+ OPENTYPE_NAME_SAMPLE_TEXT,
+ OPENTYPE_NAME_POSTSCRIPT_CID,
+ OPENTYPE_NAME_WWS_FAMILY,
+ OPENTYPE_NAME_WWS_SUBFAMILY
+};
+
static BOOL opentype_get_table_ptr( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
UINT32 table_tag, const void **table_ptr, UINT32 *table_size )
{
@@ -151,6 +270,306 @@ static BOOL opentype_get_tt_os2_v1( const void *data, size_t size, const struct
return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_OS_2_TAG, (const void **)tt_os2_v1, &table_size );
}
+static UINT get_name_record_codepage( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding )
+{
+ switch (platform)
+ {
+ case OPENTYPE_PLATFORM_UNICODE:
+ return 0;
+ case OPENTYPE_PLATFORM_MAC:
+ switch (encoding)
+ {
+ case TT_NAME_MAC_ENCODING_ROMAN:
+ return 10000;
+ case TT_NAME_MAC_ENCODING_JAPANESE:
+ return 10001;
+ case TT_NAME_MAC_ENCODING_TRAD_CHINESE:
+ return 10002;
+ case TT_NAME_MAC_ENCODING_KOREAN:
+ return 10003;
+ case TT_NAME_MAC_ENCODING_ARABIC:
+ return 10004;
+ case TT_NAME_MAC_ENCODING_HEBREW:
+ return 10005;
+ case TT_NAME_MAC_ENCODING_GREEK:
+ return 10006;
+ case TT_NAME_MAC_ENCODING_RUSSIAN:
+ return 10007;
+ case TT_NAME_MAC_ENCODING_SIMPL_CHINESE:
+ return 10008;
+ case TT_NAME_MAC_ENCODING_THAI:
+ return 10021;
+ default:
+ FIXME( "encoding %u not handled, platform %d.\n", encoding, platform );
+ break;
+ }
+ break;
+ case OPENTYPE_PLATFORM_WIN:
+ switch (encoding)
+ {
+ case TT_NAME_WIN_ENCODING_SYMBOL:
+ case TT_NAME_WIN_ENCODING_UNICODE_BMP:
+ case TT_NAME_WIN_ENCODING_UNICODE_FULL:
+ return 0;
+ case TT_NAME_WIN_ENCODING_SJIS:
+ return 932;
+ case TT_NAME_WIN_ENCODING_PRC:
+ return 936;
+ case TT_NAME_WIN_ENCODING_BIG5:
+ return 950;
+ case TT_NAME_WIN_ENCODING_WANSUNG:
+ return 20949;
+ case TT_NAME_WIN_ENCODING_JOHAB:
+ return 1361;
+ default:
+ FIXME( "encoding %u not handled, platform %d.\n", encoding, platform );
+ break;
+ }
+ break;
+ default:
+ FIXME( "unknown platform %d\n", platform );
+ break;
+ }
+
+ return 0;
+}
+
+static const LANGID mac_langid_table[] =
+{
+ MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_GERMAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ITALIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_DUTCH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SWEDISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_PORTUGUESE, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_NORWEGIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_FINNISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_GREEK, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ICELANDIC, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_MALTESE, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_CROATIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_URDU, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_HINDI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_THAI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_LITHUANIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_HUNGARIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ESTONIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_LATVIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SAMI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_FAEROESE, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH_BELGIAN),
+ MAKELANGID(LANG_IRISH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ALBANIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ROMANIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_CZECH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SLOVAK, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SLOVENIAN, SUBLANG_DEFAULT),
+ 0,
+ MAKELANGID(LANG_SERBIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_MACEDONIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_BULGARIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_UKRAINIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_BELARUSIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_UZBEK, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_KAZAK, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_AZERI, SUBLANG_AZERI_CYRILLIC),
+ 0,
+ MAKELANGID(LANG_ARMENIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_GEORGIAN, SUBLANG_DEFAULT),
+ 0,
+ MAKELANGID(LANG_KYRGYZ, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_TAJIK, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_TURKMEN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_MONGOLIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_MONGOLIAN, SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA),
+ MAKELANGID(LANG_PASHTO, SUBLANG_DEFAULT),
+ 0,
+ MAKELANGID(LANG_KASHMIRI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SINDHI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_TIBETAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_NEPALI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SANSKRIT, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_MARATHI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_BENGALI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ASSAMESE, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_GUJARATI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_PUNJABI, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ORIYA, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_MALAYALAM, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_KANNADA, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_TAMIL, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_TELUGU, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SINHALESE, SUBLANG_DEFAULT),
+ 0,
+ MAKELANGID(LANG_KHMER, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_LAO, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_VIETNAMESE, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_INDONESIAN, SUBLANG_DEFAULT),
+ 0,
+ MAKELANGID(LANG_MALAY, SUBLANG_DEFAULT),
+ 0,
+ MAKELANGID(LANG_AMHARIC, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_TIGRIGNA, SUBLANG_DEFAULT),
+ 0,
+ 0,
+ MAKELANGID(LANG_SWAHILI, SUBLANG_DEFAULT),
+ 0,
+ 0,
+ 0,
+ MAKELANGID(LANG_MALAGASY, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_ESPERANTO, SUBLANG_DEFAULT),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ MAKELANGID(LANG_WELSH, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_BASQUE, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_CATALAN, SUBLANG_DEFAULT),
+ 0,
+ MAKELANGID(LANG_QUECHUA, SUBLANG_DEFAULT),
+ 0,
+ 0,
+ MAKELANGID(LANG_TATAR, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_UIGHUR, SUBLANG_DEFAULT),
+ 0,
+ 0,
+ 0,
+ MAKELANGID(LANG_GALICIAN, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_AFRIKAANS, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_BRETON, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_INUKTITUT, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_SCOTTISH_GAELIC, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_MANX_GAELIC, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_IRISH, SUBLANG_IRISH_IRELAND),
+ 0,
+ 0,
+ MAKELANGID(LANG_GREENLANDIC, SUBLANG_DEFAULT),
+ MAKELANGID(LANG_AZERI, SUBLANG_AZERI_LATIN),
+};
+
+static LANGID get_name_record_langid( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding, USHORT language )
+{
+ switch (platform)
+ {
+ case OPENTYPE_PLATFORM_WIN:
+ return language;
+ case OPENTYPE_PLATFORM_MAC:
+ if (language < ARRAY_SIZE(mac_langid_table)) return mac_langid_table[language];
+ WARN( "invalid mac lang id %d\n", language );
+ break;
+ case OPENTYPE_PLATFORM_UNICODE:
+ switch (encoding)
+ {
+ case TT_NAME_UNICODE_ENCODING_1_0:
+ case TT_NAME_UNICODE_ENCODING_ISO_10646:
+ case TT_NAME_UNICODE_ENCODING_2_0_BMP:
+ if (language < ARRAY_SIZE(mac_langid_table)) return mac_langid_table[language];
+ WARN( "invalid unicode lang id %d\n", language );
+ break;
+ default:
+ break;
+ }
+ default:
+ FIXME( "unknown platform %d\n", platform );
+ break;
+ }
+
+ return MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
+}
+
+static BOOL opentype_enum_font_names( const struct tt_name_v0 *header, enum OPENTYPE_PLATFORM_ID platform,
+ enum OPENTYPE_NAME_ID name, opentype_enum_names_cb callback, void *user )
+{
+ const char *name_data;
+ USHORT i, name_count, encoding, language, length, offset;
+ USHORT platform_id = GET_BE_WORD( platform ), name_id = GET_BE_WORD( name );
+ LANGID langid;
+ BOOL ret = FALSE;
+
+ switch (GET_BE_WORD( header->format ))
+ {
+ case 0:
+ case 1:
+ break;
+ default:
+ FIXME( "unsupported name format %d\n", GET_BE_WORD( header->format ) );
+ return FALSE;
+ }
+
+ name_data = (const char *)header + GET_BE_WORD( header->stringOffset );
+ name_count = GET_BE_WORD( header->count );
+ for (i = 0; i < name_count; i++)
+ {
+ const struct tt_namerecord *record = &header->nameRecord[i];
+ struct opentype_name opentype_name;
+
+ if (record->nameID != name_id) continue;
+ if (record->platformID != platform_id) continue;
+
+ language = GET_BE_WORD( record->languageID );
+ if (language >= 0x8000)
+ {
+ FIXME( "handle name format 1\n" );
+ continue;
+ }
+
+ encoding = GET_BE_WORD( record->encodingID );
+ offset = GET_BE_WORD( record->offset );
+ length = GET_BE_WORD( record->length );
+ langid = get_name_record_langid( platform, encoding, language );
+
+ opentype_name.codepage = get_name_record_codepage( platform, encoding );
+ opentype_name.length = length;
+ opentype_name.bytes = name_data + offset;
+
+ if ((ret = callback( langid, &opentype_name, user ))) break;
+ }
+
+ return ret;
+}
+
BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD *count, const struct ttc_sfnt_v1 **ttc_sfnt_v1 )
{
const struct ttc_header_v1 *ttc_header_v1 = data;
@@ -218,3 +637,43 @@ BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD
return TRUE;
}
+
+BOOL opentype_get_tt_name_v0( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
+ const struct tt_name_v0 **tt_name_v0 )
+{
+ UINT32 table_size = sizeof(**tt_name_v0);
+ return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_NAME_TAG, (const void **)tt_name_v0, &table_size );
+}
+
+BOOL opentype_enum_family_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
+{
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_FAMILY, callback, user ))
+ return TRUE;
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_FAMILY, callback, user ))
+ return TRUE;
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_FAMILY, callback, user ))
+ return TRUE;
+ return FALSE;
+}
+
+BOOL opentype_enum_style_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
+{
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_SUBFAMILY, callback, user ))
+ return TRUE;
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_SUBFAMILY, callback, user ))
+ return TRUE;
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_SUBFAMILY, callback, user ))
+ return TRUE;
+ return FALSE;
+}
+
+BOOL opentype_enum_full_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
+{
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_FULLNAME, callback, user ))
+ return TRUE;
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_FULLNAME, callback, user ))
+ return TRUE;
+ if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_FULLNAME, callback, user ))
+ return TRUE;
+ return FALSE;
+}
--
2.29.2
Dec. 1, 2020
[PATCH 3/6] gdi32: Introduce new opentype font parsing helpers.
by Rémi Bernon
Mostly taken from dwrite source, adapted to make it more flexible.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/gdi32/Makefile.in | 1 +
dlls/gdi32/freetype.c | 11 ++
dlls/gdi32/gdi_private.h | 7 ++
dlls/gdi32/opentype.c | 220 +++++++++++++++++++++++++++++++++++++++
4 files changed, 239 insertions(+)
create mode 100644 dlls/gdi32/opentype.c
diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in
index a965e80001c..910450b9f64 100644
--- a/dlls/gdi32/Makefile.in
+++ b/dlls/gdi32/Makefile.in
@@ -42,6 +42,7 @@ C_SRCS = \
mfdrv/objects.c \
mfdrv/text.c \
opengl.c \
+ opentype.c \
painting.c \
palette.c \
path.c \
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index cb993034d09..686f2b54682 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1110,8 +1110,10 @@ struct unix_face
static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr, DWORD data_size,
UINT face_index, DWORD flags )
{
+ const struct ttc_sfnt_v1 *ttc_sfnt_v1;
struct unix_face *This;
struct stat st;
+ DWORD face_count;
int fd;
TRACE( "unix_name %s, face_index %u, data_ptr %p, data_size %u, flags %#x\n",
@@ -1138,11 +1140,20 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
RtlFreeHeap( GetProcessHeap(), 0, This );
This = NULL;
}
+ else if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ))
+ {
+ This->scalable = TRUE;
+ This->num_faces = face_count;
+ }
else
{
+ WARN( "unable to parse font, falling back to FreeType\n" );
This->scalable = FT_IS_SCALABLE( This->ft_face );
This->num_faces = This->ft_face->num_faces;
+ }
+ if (This)
+ {
This->family_name = ft_face_get_family_name( This->ft_face, system_lcid );
This->second_name = ft_face_get_family_name( This->ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) );
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index b9a06415538..a529cb0890c 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -414,6 +414,13 @@ struct font_callback_funcs
extern void font_init(void) DECLSPEC_HIDDEN;
+/* opentype.c */
+
+struct ttc_sfnt_v1;
+
+extern BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD *count,
+ const struct ttc_sfnt_v1 **ttc_sfnt_v1 ) DECLSPEC_HIDDEN;
+
/* gdiobj.c */
extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/opentype.c b/dlls/gdi32/opentype.c
new file mode 100644
index 00000000000..2363439cdc5
--- /dev/null
+++ b/dlls/gdi32/opentype.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2020 Rémi Bernon for CodeWeavers
+ * Copyright 2014 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+
+#include "wine/debug.h"
+
+#include "gdi_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(font);
+
+#define MS_OTTO_TAG MS_MAKE_TAG('O','T','T','O')
+#define MS_HEAD_TAG MS_MAKE_TAG('h','e','a','d')
+#define MS_HHEA_TAG MS_MAKE_TAG('h','h','e','a')
+#define MS_OS_2_TAG MS_MAKE_TAG('O','S','/','2')
+#define MS_EBSC_TAG MS_MAKE_TAG('E','B','S','C')
+#define MS_EBDT_TAG MS_MAKE_TAG('E','B','D','T')
+#define MS_CBDT_TAG MS_MAKE_TAG('C','B','D','T')
+
+#ifdef WORDS_BIGENDIAN
+#define GET_BE_WORD(x) (x)
+#define GET_BE_DWORD(x) (x)
+#else
+#define GET_BE_WORD(x) RtlUshortByteSwap(x)
+#define GET_BE_DWORD(x) RtlUlongByteSwap(x)
+#endif
+
+#include "pshpack2.h"
+struct ttc_header_v1
+{
+ CHAR TTCTag[4];
+ DWORD Version;
+ DWORD numFonts;
+ DWORD OffsetTable[1];
+};
+
+struct ttc_sfnt_v1
+{
+ DWORD version;
+ WORD numTables;
+ WORD searchRange;
+ WORD entrySelector;
+ WORD rangeShift;
+};
+
+struct tt_tablerecord
+{
+ DWORD tag;
+ DWORD checkSum;
+ DWORD offset;
+ DWORD length;
+};
+
+struct tt_os2_v1
+{
+ USHORT version;
+ SHORT xAvgCharWidth;
+ USHORT usWeightClass;
+ USHORT usWidthClass;
+ SHORT fsType;
+ SHORT ySubscriptXSize;
+ SHORT ySubscriptYSize;
+ SHORT ySubscriptXOffset;
+ SHORT ySubscriptYOffset;
+ SHORT ySuperscriptXSize;
+ SHORT ySuperscriptYSize;
+ SHORT ySuperscriptXOffset;
+ SHORT ySuperscriptYOffset;
+ SHORT yStrikeoutSize;
+ SHORT yStrikeoutPosition;
+ SHORT sFamilyClass;
+ PANOSE panose;
+ ULONG ulUnicodeRange1;
+ ULONG ulUnicodeRange2;
+ ULONG ulUnicodeRange3;
+ ULONG ulUnicodeRange4;
+ CHAR achVendID[4];
+ USHORT fsSelection;
+ USHORT usFirstCharIndex;
+ USHORT usLastCharIndex;
+ /* According to the Apple spec, original version didn't have the below fields,
+ * version numbers were taken from the OpenType spec.
+ */
+ /* version 0 (TrueType 1.5) */
+ USHORT sTypoAscender;
+ USHORT sTypoDescender;
+ USHORT sTypoLineGap;
+ USHORT usWinAscent;
+ USHORT usWinDescent;
+ /* version 1 (TrueType 1.66) */
+ ULONG ulCodePageRange1;
+ ULONG ulCodePageRange2;
+};
+#include "poppack.h"
+
+static BOOL opentype_get_table_ptr( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
+ UINT32 table_tag, const void **table_ptr, UINT32 *table_size )
+{
+ const struct tt_tablerecord *table_record;
+ UINT16 i, table_count;
+ UINT32 offset, length;
+
+ if (!ttc_sfnt_v1) return FALSE;
+
+ table_record = (const struct tt_tablerecord *)(ttc_sfnt_v1 + 1);
+ table_count = GET_BE_WORD( ttc_sfnt_v1->numTables );
+ for (i = 0; i < table_count; i++, table_record++)
+ {
+ if (table_record->tag != table_tag) continue;
+ offset = GET_BE_DWORD( table_record->offset );
+ length = GET_BE_DWORD( table_record->length );
+ if (size < offset + length) return FALSE;
+ if (table_size && length < *table_size) return FALSE;
+
+ if (table_ptr) *table_ptr = (const char *)data + offset;
+ if (table_size) *table_size = length;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL opentype_get_tt_os2_v1( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
+ const struct tt_os2_v1 **tt_os2_v1 )
+{
+ UINT32 table_size = sizeof(**tt_os2_v1);
+ return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_OS_2_TAG, (const void **)tt_os2_v1, &table_size );
+}
+
+BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD *count, const struct ttc_sfnt_v1 **ttc_sfnt_v1 )
+{
+ const struct ttc_header_v1 *ttc_header_v1 = data;
+ const struct tt_os2_v1 *tt_os2_v1;
+ UINT32 offset, fourcc;
+
+ *ttc_sfnt_v1 = NULL;
+ *count = 1;
+
+ if (size < sizeof(fourcc)) return FALSE;
+ memcpy( &fourcc, data, sizeof(fourcc) );
+
+ switch (fourcc)
+ {
+ default:
+ WARN( "unsupported font format %x\n", fourcc );
+ return FALSE;
+ case MS_TTCF_TAG:
+ if (size < sizeof(ttc_header_v1)) return FALSE;
+ if (index >= (*count = GET_BE_DWORD( ttc_header_v1->numFonts ))) return FALSE;
+ offset = GET_BE_DWORD( ttc_header_v1->OffsetTable[index] );
+ break;
+ case 0x00000100:
+ case MS_OTTO_TAG:
+ offset = 0;
+ break;
+ }
+
+ if (size < offset + sizeof(**ttc_sfnt_v1)) return FALSE;
+ *ttc_sfnt_v1 = (const struct ttc_sfnt_v1 *)((const char *)data + offset);
+
+ if (!opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_HEAD_TAG, NULL, NULL ))
+ {
+ WARN( "unsupported sfnt font: missing head table.\n" );
+ return FALSE;
+ }
+
+ if (!opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_HHEA_TAG, NULL, NULL ))
+ {
+ WARN( "unsupported sfnt font: missing hhea table.\n" );
+ return FALSE;
+ }
+
+ if (!opentype_get_tt_os2_v1( data, size, *ttc_sfnt_v1, &tt_os2_v1 ))
+ {
+ WARN( "unsupported sfnt font: missing OS/2 table.\n" );
+ return FALSE;
+ }
+
+ /* Wine uses ttfs as an intermediate step in building its bitmap fonts;
+ we don't want to load these. */
+ if (!memcmp( tt_os2_v1->achVendID, "Wine", sizeof(tt_os2_v1->achVendID) ) &&
+ opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_EBSC_TAG, NULL, NULL ))
+ {
+ TRACE( "ignoring wine bitmap-only sfnt font.\n" );
+ return FALSE;
+ }
+
+ if (opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_EBDT_TAG, NULL, NULL ) ||
+ opentype_get_table_ptr( data, size, *ttc_sfnt_v1, MS_CBDT_TAG, NULL, NULL ))
+ {
+ WARN( "unsupported sfnt font: embedded bitmap data.\n" );
+ return FALSE;
+ }
+
+ return TRUE;
+}
--
2.29.2
Dec. 1, 2020
[PATCH 2/6] gdi32: Store ft_face font props on unix_face.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/gdi32/freetype.c | 38 +++++++++++++++++++++-----------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 00334b470c8..cb993034d09 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1099,6 +1099,12 @@ struct unix_face
UINT num_faces;
WCHAR *family_name;
WCHAR *second_name;
+ WCHAR *style_name;
+ WCHAR *full_name;
+ DWORD ntm_flags;
+ DWORD font_version;
+ FONTSIGNATURE fs;
+ struct bitmap_font_size size;
};
static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr, DWORD data_size,
@@ -1153,6 +1159,14 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
This->second_name = NULL;
}
}
+
+ This->style_name = ft_face_get_style_name( This->ft_face, system_lcid );
+ This->full_name = ft_face_get_full_name( This->ft_face, system_lcid );
+
+ This->ntm_flags = get_ntm_flags( This->ft_face );
+ This->font_version = get_font_version( This->ft_face );
+ if (!This->scalable) get_bitmap_size( This->ft_face, &This->size );
+ get_fontsig( This->ft_face, &This->fs );
}
done:
@@ -1163,6 +1177,8 @@ done:
static void unix_face_destroy( struct unix_face *This )
{
pFT_Done_Face( This->ft_face );
+ RtlFreeHeap( GetProcessHeap(), 0, This->full_name );
+ RtlFreeHeap( GetProcessHeap(), 0, This->style_name );
RtlFreeHeap( GetProcessHeap(), 0, This->second_name );
RtlFreeHeap( GetProcessHeap(), 0, This->family_name );
RtlFreeHeap( GetProcessHeap(), 0, This );
@@ -1172,9 +1188,6 @@ static int add_unix_face( const char *unix_name, const WCHAR *file, void *data_p
DWORD face_index, DWORD flags, DWORD *num_faces )
{
struct unix_face *unix_face;
- struct bitmap_font_size size;
- FONTSIGNATURE fs;
- WCHAR *style_name, *full_name;
int ret;
if (num_faces) *num_faces = 0;
@@ -1189,23 +1202,14 @@ static int add_unix_face( const char *unix_name, const WCHAR *file, void *data_p
return 0;
}
- style_name = ft_face_get_style_name( unix_face->ft_face, system_lcid );
- full_name = ft_face_get_full_name( unix_face->ft_face, system_lcid );
-
- get_fontsig( unix_face->ft_face, &fs );
- if (!unix_face->scalable) get_bitmap_size( unix_face->ft_face, &size );
if (!HIWORD( flags )) flags |= ADDFONT_AA_FLAGS( default_aa_flags );
- ret = callback_funcs->add_gdi_face( unix_face->family_name, unix_face->second_name, style_name, full_name,
- file, data_ptr, data_size, face_index, fs, get_ntm_flags( unix_face->ft_face ),
- get_font_version( unix_face->ft_face ), flags,
- unix_face->scalable ? NULL : &size );
+ ret = callback_funcs->add_gdi_face( unix_face->family_name, unix_face->second_name, unix_face->style_name, unix_face->full_name,
+ file, data_ptr, data_size, face_index, unix_face->fs, unix_face->ntm_flags,
+ unix_face->font_version, flags, unix_face->scalable ? NULL : &unix_face->size );
- TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
- fs.fsCsb[0], fs.fsCsb[1], fs.fsUsb[0], fs.fsUsb[1], fs.fsUsb[2], fs.fsUsb[3]);
-
- RtlFreeHeap( GetProcessHeap(), 0, style_name );
- RtlFreeHeap( GetProcessHeap(), 0, full_name );
+ TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n", unix_face->fs.fsCsb[0], unix_face->fs.fsCsb[1],
+ unix_face->fs.fsUsb[0], unix_face->fs.fsUsb[1], unix_face->fs.fsUsb[2], unix_face->fs.fsUsb[3]);
if (num_faces) *num_faces = unix_face->num_faces;
unix_face_destroy( unix_face );
--
2.29.2
Dec. 1, 2020
[PATCH 1/6] gdi32: Introduce struct unix_face as a ft_face wrapper.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
So I'm sending this last series now as it seems everybody rushes for
their patches to go in before the freeze, and as it should not have any
conflict with 196676-196680, or with the other series on the ML as it's
mostly only touching freetype.c, it'll leave more time for review.
With 196676-196680 applied, this brings some ~250ms improvement to
prefix startup (from 1.25s to 1s runtime on average for "cmd /c exit"),
and 50ms improvement to process startup (from 0.15s to 0.1s on average).
(I probably changed my test setup a bit and upgraded some font packages
since the other series so it's not exactly comparable with the previous
numbers, but the improvement indicated was measured in a consistent way
with / without this series applied)
dlls/gdi32/freetype.c | 124 +++++++++++++++++++++++++++++++-----------
1 file changed, 91 insertions(+), 33 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 1ee02795bed..00334b470c8 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -1092,65 +1092,123 @@ fail:
return NULL;
}
+struct unix_face
+{
+ FT_Face ft_face;
+ BOOL scalable;
+ UINT num_faces;
+ WCHAR *family_name;
+ WCHAR *second_name;
+};
+
+static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr, DWORD data_size,
+ UINT face_index, DWORD flags )
+{
+ struct unix_face *This;
+ struct stat st;
+ int fd;
+
+ TRACE( "unix_name %s, face_index %u, data_ptr %p, data_size %u, flags %#x\n",
+ unix_name, face_index, data_ptr, data_size, flags );
+
+ if (unix_name)
+ {
+ if ((fd = open( unix_name, O_RDONLY )) == -1) return NULL;
+ if (fstat( fd, &st ) == -1)
+ {
+ close( fd );
+ return NULL;
+ }
+ data_size = st.st_size;
+ data_ptr = mmap( NULL, data_size, PROT_READ, MAP_PRIVATE, fd, 0 );
+ close( fd );
+ if (data_ptr == MAP_FAILED) return NULL;
+ }
+
+ if (!(This = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This) ))) goto done;
+
+ if (!(This->ft_face = new_ft_face( unix_name, data_ptr, data_size, face_index, flags & ADDFONT_ALLOW_BITMAP )))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, This );
+ This = NULL;
+ }
+ else
+ {
+ This->scalable = FT_IS_SCALABLE( This->ft_face );
+ This->num_faces = This->ft_face->num_faces;
+
+ This->family_name = ft_face_get_family_name( This->ft_face, system_lcid );
+ This->second_name = ft_face_get_family_name( This->ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) );
+
+ /* try to find another secondary name, preferring the lowest langids */
+ if (!RtlCompareUnicodeStrings( This->family_name, lstrlenW( This->family_name ),
+ This->second_name, lstrlenW( This->second_name ), TRUE ))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, This->second_name );
+ This->second_name = ft_face_get_family_name( This->ft_face, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) );
+ if (!RtlCompareUnicodeStrings( This->family_name, lstrlenW( This->family_name ),
+ This->second_name, lstrlenW( This->second_name ), TRUE ))
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, This->second_name );
+ This->second_name = NULL;
+ }
+ }
+ }
+
+done:
+ if (unix_name) munmap( data_ptr, data_size );
+ return This;
+}
+
+static void unix_face_destroy( struct unix_face *This )
+{
+ pFT_Done_Face( This->ft_face );
+ RtlFreeHeap( GetProcessHeap(), 0, This->second_name );
+ RtlFreeHeap( GetProcessHeap(), 0, This->family_name );
+ RtlFreeHeap( GetProcessHeap(), 0, This );
+}
+
static int add_unix_face( const char *unix_name, const WCHAR *file, void *data_ptr, SIZE_T data_size,
DWORD face_index, DWORD flags, DWORD *num_faces )
{
+ struct unix_face *unix_face;
struct bitmap_font_size size;
FONTSIGNATURE fs;
- FT_Face ft_face;
- WCHAR *family_name, *second_name, *style_name, *full_name;
+ WCHAR *style_name, *full_name;
int ret;
if (num_faces) *num_faces = 0;
- if (!(ft_face = new_ft_face( unix_name, data_ptr, data_size, face_index, flags & ADDFONT_ALLOW_BITMAP )))
+ if (!(unix_face = unix_face_create( unix_name, data_ptr, data_size, face_index, flags )))
return 0;
- if (ft_face->family_name[0] == '.') /* Ignore fonts with names beginning with a dot */
+ if (unix_face->family_name[0] == '.') /* Ignore fonts with names beginning with a dot */
{
TRACE("Ignoring %s since its family name begins with a dot\n", debugstr_a(unix_name));
- pFT_Done_Face( ft_face );
+ unix_face_destroy( unix_face );
return 0;
}
- family_name = ft_face_get_family_name( ft_face, system_lcid );
- second_name = ft_face_get_family_name( ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) );
- style_name = ft_face_get_style_name( ft_face, system_lcid );
- full_name = ft_face_get_full_name( ft_face, system_lcid );
-
- /* try to find another secondary name, preferring the lowest langids */
- if (!RtlCompareUnicodeStrings( family_name, lstrlenW(family_name),
- second_name, lstrlenW(second_name), TRUE ))
- {
- RtlFreeHeap( GetProcessHeap(), 0, second_name );
- second_name = ft_face_get_family_name( ft_face, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) );
- if (!RtlCompareUnicodeStrings( family_name, lstrlenW(family_name),
- second_name, lstrlenW(second_name), TRUE ))
- {
- RtlFreeHeap( GetProcessHeap(), 0, second_name );
- second_name = NULL;
- }
- }
+ style_name = ft_face_get_style_name( unix_face->ft_face, system_lcid );
+ full_name = ft_face_get_full_name( unix_face->ft_face, system_lcid );
- get_fontsig( ft_face, &fs );
- if (!FT_IS_SCALABLE( ft_face )) get_bitmap_size( ft_face, &size );
+ get_fontsig( unix_face->ft_face, &fs );
+ if (!unix_face->scalable) get_bitmap_size( unix_face->ft_face, &size );
if (!HIWORD( flags )) flags |= ADDFONT_AA_FLAGS( default_aa_flags );
- ret = callback_funcs->add_gdi_face( family_name, second_name, style_name, full_name, file,
- data_ptr, data_size, face_index, fs, get_ntm_flags( ft_face ),
- get_font_version( ft_face ), flags,
- FT_IS_SCALABLE(ft_face) ? NULL : &size );
+ ret = callback_funcs->add_gdi_face( unix_face->family_name, unix_face->second_name, style_name, full_name,
+ file, data_ptr, data_size, face_index, fs, get_ntm_flags( unix_face->ft_face ),
+ get_font_version( unix_face->ft_face ), flags,
+ unix_face->scalable ? NULL : &size );
TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
fs.fsCsb[0], fs.fsCsb[1], fs.fsUsb[0], fs.fsUsb[1], fs.fsUsb[2], fs.fsUsb[3]);
- RtlFreeHeap( GetProcessHeap(), 0, family_name );
- RtlFreeHeap( GetProcessHeap(), 0, second_name );
RtlFreeHeap( GetProcessHeap(), 0, style_name );
RtlFreeHeap( GetProcessHeap(), 0, full_name );
- if (num_faces) *num_faces = ft_face->num_faces;
- pFT_Done_Face( ft_face );
+ if (num_faces) *num_faces = unix_face->num_faces;
+ unix_face_destroy( unix_face );
return ret;
}
--
2.29.2
Dec. 1, 2020
[PATCH v2 4/4] widl: Support WinRT contract attribute.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
This makes the following kind of changes to the generated header files,
according to the contract and version specified on each type:
--- a/windows.foundation.h
+++ b/windows.foundation.h
@@ -35,11 +35,13 @@ namespace ABI {
/* Headers for imported files */
#include <inspectable.h>
+#include <windowscontracts.h>
#ifdef __cplusplus
extern "C" {
#endif
+#if WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION >= 0x10000
#ifdef __cplusplus
} /* extern "C" */
namespace ABI {
@@ -138,6 +140,8 @@ enum __x_ABI_CWindows_CFoundation_CPropertyType {
};
#endif
+#endif /* WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION >= 0x10000 */
+#if WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION >= 0x10000
#ifdef __cplusplus
} /* extern "C" */
namespace ABI {
include/windows.foundation.idl | 14 +++----
tools/widl/header.c | 72 ++++++++++++++++++++++++++++++++--
tools/widl/parser.l | 1 +
tools/widl/parser.y | 10 +++++
tools/widl/widltypes.h | 1 +
5 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
index 2a38e9f671b..5e17062f399 100644
--- a/include/windows.foundation.idl
+++ b/include/windows.foundation.idl
@@ -28,7 +28,7 @@ import "windowscontracts.idl";
namespace Windows {
namespace Foundation {
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
enum PropertyType {
Empty = 0,
UInt8 = 1,
@@ -73,19 +73,19 @@ namespace Windows {
OtherTypeArray = 1044
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct Point {
FLOAT X;
FLOAT Y;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct Size {
FLOAT Width;
FLOAT Height;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct Rect {
FLOAT X;
FLOAT Y;
@@ -93,18 +93,18 @@ namespace Windows {
FLOAT Height;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct DateTime {
INT64 UniversalTime;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct TimeSpan {
INT64 Duration;
};
[
- version(0x06030000),
+ contract(Windows.Foundation.FoundationContract, 1.0),
uuid(96369f54-8eb6-48f0-abce-c1b211e627c3)
]
interface IStringable : IInspectable
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 657ce50c679..223ab5c5ca9 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -45,6 +45,11 @@ generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name, enum name_type name_type);
+static void write_winrt_type_comments(FILE *header, const type_t *type);
+
+static void write_apicontract_guard_start(FILE *header, const expr_t *expr);
+static void write_apicontract_guard_end(FILE *header, const expr_t *expr);
+
static void indent(FILE *h, int delta)
{
int c;
@@ -218,7 +223,9 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type)
}
LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
+ expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT);
if (!v || !v->declspec.type) continue;
+ if (contract) write_apicontract_guard_start(h, contract);
indent(h, 0);
name = v->name;
@@ -252,6 +259,7 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type)
}
write_type_v(h, &v->declspec, TRUE, v->declonly, name, name_type);
fprintf(h, ";\n");
+ if (contract) write_apicontract_guard_end(h, contract);
}
}
@@ -261,6 +269,8 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name)
if (!enums) return;
LIST_FOR_EACH_ENTRY( v, enums, var_t, entry )
{
+ expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT);
+ if (contract) write_apicontract_guard_start(h, contract);
if (v->name) {
indent(h, 0);
if(!enum_name)
@@ -273,8 +283,9 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name)
}
}
if (list_next( enums, &v->entry )) fprintf(h, ",\n");
+ else fprintf(h, "\n");
+ if (contract) write_apicontract_guard_end(h, contract);
}
- fprintf(h, "\n");
}
int needs_space_after(type_t *t)
@@ -563,7 +574,9 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
int in_namespace = t->namespace && !is_global_namespace(t->namespace);
int save_written = t->written;
decl_spec_t ds = {.type = t};
+ expr_t *contract = get_attrp(t->attrs, ATTR_CONTRACT);
+ if (contract) write_apicontract_guard_start(f, contract);
if(in_namespace) {
fprintf(f, "#ifdef __cplusplus\n");
fprintf(f, "} /* extern \"C\" */\n");
@@ -581,6 +594,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
fprintf(f, ";\n");
fprintf(f, "#endif\n\n");
}
+ if (contract) write_apicontract_guard_end(f, contract);
}
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name)
@@ -1468,12 +1482,55 @@ static char *format_apicontract_macro(const type_t *type)
return name;
}
+static void write_winrt_type_comments(FILE *header, const type_t *type)
+{
+ expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT);
+ fprintf(header, " *\n");
+ if (contract)
+ {
+ const type_t *type = contract->u.tref.type;
+ char *name = format_namespace(type->namespace, "", ".", type->name, NULL);
+ int ver = contract->ref->u.lval;
+ fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff);
+ free(name);
+ }
+}
+
+static void write_apicontract_guard_start(FILE *header, const expr_t *expr)
+{
+ const type_t *type;
+ char *name;
+ int ver;
+ if (!winrt_mode) return;
+ type = expr->u.tref.type;
+ ver = expr->ref->u.lval;
+ name = format_apicontract_macro(type);
+ fprintf(header, "#if %s_VERSION >= %#x\n", name, ver);
+ free(name);
+}
+
+static void write_apicontract_guard_end(FILE *header, const expr_t *expr)
+{
+ const type_t *type;
+ char *name;
+ int ver;
+ if (!winrt_mode) return;
+ type = expr->u.tref.type;
+ ver = expr->ref->u.lval;
+ name = format_apicontract_macro(type);
+ fprintf(header, "#endif /* %s_VERSION >= %#x */\n", name, ver);
+ free(name);
+}
+
static void write_com_interface_start(FILE *header, const type_t *iface)
{
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
fprintf(header, "/*****************************************************************************\n");
fprintf(header, " * %s %sinterface\n", iface->name, dispinterface ? "disp" : "");
+ if (winrt_mode) write_winrt_type_comments(header, iface);
fprintf(header, " */\n");
+ if (contract) write_apicontract_guard_start(header, contract);
fprintf(header,"#ifndef __%s_%sINTERFACE_DEFINED__\n", iface->c_name, dispinterface ? "DISP" : "");
fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : "");
}
@@ -1482,6 +1539,7 @@ static void write_com_interface_end(FILE *header, type_t *iface)
{
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
type_t *type;
if (uuid)
@@ -1559,17 +1617,22 @@ static void write_com_interface_end(FILE *header, type_t *iface)
write_locals(header, iface, FALSE);
fprintf(header, "\n");
}
- fprintf(header,"#endif /* __%s_%sINTERFACE_DEFINED__ */\n\n", iface->c_name, dispinterface ? "DISP" : "");
+ fprintf(header, "#endif /* __%s_%sINTERFACE_DEFINED__ */\n", iface->c_name, dispinterface ? "DISP" : "");
+ if (contract) write_apicontract_guard_end(header, contract);
+ fprintf(header, "\n");
}
static void write_rpc_interface_start(FILE *header, const type_t *iface)
{
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
const var_t *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
fprintf(header, "/*****************************************************************************\n");
fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver));
+ if (winrt_mode) write_winrt_type_comments(header, iface);
fprintf(header, " */\n");
+ if (contract) write_apicontract_guard_start(header, contract);
fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
if (var)
@@ -1594,7 +1657,10 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
static void write_rpc_interface_end(FILE *header, const type_t *iface)
{
- fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
+ fprintf(header, "\n#endif /* __%s_INTERFACE_DEFINED__ */\n", iface->name);
+ if (contract) write_apicontract_guard_end(header, contract);
+ fprintf(header, "\n");
}
static void write_coclass(FILE *header, type_t *cocl)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 6a9bb65a483..9dce03577c6 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -339,6 +339,7 @@ static const struct keyword attr_keywords[] =
{"context_handle", tCONTEXTHANDLE, 0},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0},
+ {"contract", tCONTRACT, 1},
{"contractversion", tCONTRACTVERSION, 1},
{"control", tCONTROL, 0},
{"custom", tCUSTOM, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 5b4bd518a0b..1d413ca74f4 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -181,6 +181,7 @@ static typelib_t *current_typelib;
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
%token tCONTEXTHANDLESERIALIZE
+%token tCONTRACT
%token tCONTRACTVERSION
%token tCONTROL tCPPQUOTE
%token tCUSTOM
@@ -271,6 +272,7 @@ static typelib_t *current_typelib;
%type <str_list> str_list
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
+%type <expr> contract_req
%type <type> interfacehdr
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
@@ -508,6 +510,12 @@ contract_ver:
| aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); }
;
+contract_req: decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICONTRACT)
+ error_loc("type %s is not an apicontract\n", $1->type->name);
+ $$ = make_exprl(EXPR_NUM, $3);
+ $$ = make_exprt(EXPR_GTREQL, declare_var(NULL, $1, make_declarator(NULL), 0), $$);
+ }
+
attribute: { $$ = NULL; }
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
@@ -523,6 +531,7 @@ attribute: { $$ = NULL; }
| tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
| tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
| tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
+ | tCONTRACT '(' contract_req ')' { $$ = make_attrp(ATTR_CONTRACT, $3); }
| tCONTRACTVERSION '(' contract_ver ')' { $$ = make_attrv(ATTR_CONTRACTVERSION, $3); }
| tCONTROL { $$ = make_attr(ATTR_CONTROL); }
| tCUSTOM '(' uuid_string ',' expr_const ')' { $$ = make_custom_attr($3, $5); }
@@ -2180,6 +2189,7 @@ struct allowed_attr allowed_attr[] =
/* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
/* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, "contract" },
/* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "contractversion" },
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, "control" },
/* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, "custom" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 878650d9c27..d5862426ad4 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -84,6 +84,7 @@ enum attr_type
ATTR_CODE,
ATTR_COMMSTATUS,
ATTR_CONTEXTHANDLE,
+ ATTR_CONTRACT,
ATTR_CONTRACTVERSION,
ATTR_CONTROL,
ATTR_CUSTOM,
--
2.29.2
Dec. 1, 2020
[PATCH v2 3/4] widl: Support WinRT apicontract type.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
These types generate this kind of preprocessor macros in
windowscontracts.h:
#if !defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION)
#define WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION 0x40000
#endif // defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION)
#if !defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION)
#define WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION 0xa0000
#endif // defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION)
include/Makefile.in | 1 +
include/windows.foundation.idl | 1 +
include/windowscontracts.idl | 33 +++++
tools/widl/expr.c | 1 +
tools/widl/header.c | 27 ++++
tools/widl/parser.l | 1 +
tools/widl/parser.y | 239 +++++++++++++++++++--------------
tools/widl/typegen.c | 6 +
tools/widl/typelib.c | 3 +-
tools/widl/typetree.h | 3 +
tools/widl/widltypes.h | 1 +
11 files changed, 211 insertions(+), 105 deletions(-)
create mode 100644 include/windowscontracts.idl
diff --git a/include/Makefile.in b/include/Makefile.in
index 3df4da64233..a84e44998cc 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -744,6 +744,7 @@ SOURCES = \
windns.h \
windows.foundation.idl \
windows.h \
+ windowscontracts.idl \
windowsx.h \
wine/debug.h \
wine/exception.h \
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
index 2c16fa2da22..2a38e9f671b 100644
--- a/include/windows.foundation.idl
+++ b/include/windows.foundation.idl
@@ -22,6 +22,7 @@
import "inspectable.idl";
/* import "asyncinfo.idl"; */
+import "windowscontracts.idl";
/* import "eventtoken.idl"; */
/* import "ivectorchangedeventargs.idl"; */
diff --git a/include/windowscontracts.idl b/include/windowscontracts.idl
new file mode 100644
index 00000000000..6bcf80ac954
--- /dev/null
+++ b/include/windowscontracts.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 Rémi Bernon for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef __WIDL__
+#pragma winrt ns_prefix
+#endif
+
+namespace Windows {
+ namespace Foundation {
+ [contractversion(4)]
+ apicontract FoundationContract
+ {};
+
+ [contractversion(10)]
+ apicontract UniversalApiContract
+ {};
+ }
+}
diff --git a/tools/widl/expr.c b/tools/widl/expr.c
index d1ee599a39e..be8311cfb7f 100644
--- a/tools/widl/expr.c
+++ b/tools/widl/expr.c
@@ -462,6 +462,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
case TYPE_POINTER:
case TYPE_ARRAY:
case TYPE_BITFIELD:
+ case TYPE_APICONTRACT:
/* nothing to do */
break;
case TYPE_ALIAS:
diff --git a/tools/widl/header.c b/tools/widl/header.c
index a892243fb54..657ce50c679 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -471,6 +471,10 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
else write_type_left(h, ds, name_type, declonly, write_callconv);
break;
}
+ case TYPE_APICONTRACT:
+ /* shouldn't be here */
+ assert(0);
+ break;
}
}
}
@@ -533,6 +537,10 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_COCLASS:
case TYPE_INTERFACE:
break;
+ case TYPE_APICONTRACT:
+ /* not supposed to be here */
+ assert(0);
+ break;
}
}
@@ -1452,6 +1460,14 @@ static void write_forward(FILE *header, type_t *iface)
fprintf(header, "#endif\n\n" );
}
+static char *format_apicontract_macro(const type_t *type)
+{
+ char *name = format_namespace(type->namespace, "", "_", type->name, NULL);
+ int i;
+ for (i = strlen(name); i > 0; --i) name[i - 1] = toupper(name[i - 1]);
+ return name;
+}
+
static void write_com_interface_start(FILE *header, const type_t *iface)
{
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
@@ -1616,6 +1632,15 @@ static void write_coclass_forward(FILE *header, type_t *cocl)
fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name );
}
+static void write_apicontract(FILE *header, type_t *apicontract)
+{
+ char *name = format_apicontract_macro(apicontract);
+ fprintf(header, "#if !defined(%s_VERSION)\n", name);
+ fprintf(header, "#define %s_VERSION %#x\n", name, get_attrv(apicontract->attrs, ATTR_CONTRACTVERSION));
+ fprintf(header, "#endif // defined(%s_VERSION)\n\n", name);
+ free(name);
+}
+
static void write_import(FILE *header, const char *fname)
{
char *hname, *p;
@@ -1734,6 +1759,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
}
else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
write_coclass(header, stmt->u.type);
+ else if (type_get_type(stmt->u.type) == TYPE_APICONTRACT)
+ write_apicontract(header, stmt->u.type);
else
{
write_type_definition(header, stmt->u.type, stmt->declonly);
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index a4e1d0d2c47..6a9bb65a483 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -267,6 +267,7 @@ static const struct keyword keywords[] = {
{"_fastcall", tFASTCALL, 0},
{"_pascal", tPASCAL, 0},
{"_stdcall", tSTDCALL, 0},
+ {"apicontract", tAPICONTRACT, 1},
{"boolean", tBOOLEAN, 0},
{"byte", tBYTE, 0},
{"case", tCASE, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 3c4c8041a1c..5b4bd518a0b 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -100,6 +100,7 @@ static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
+static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
const char *get_attr_display_name(enum attr_type type);
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
static void check_def(const type_t *t);
@@ -173,7 +174,9 @@ static typelib_t *current_typelib;
%token GREATEREQUAL LESSEQUAL
%token LOGICALOR LOGICALAND
%token ELLIPSIS
-%token tAGGREGATABLE tALLNODES tALLOCATE tANNOTATION tAPPOBJECT tASYNC tASYNCUUID
+%token tAGGREGATABLE tALLNODES tALLOCATE tANNOTATION
+%token tAPICONTRACT
+%token tAPPOBJECT tASYNC tASYNCUUID
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
@@ -292,6 +295,7 @@ static typelib_t *current_typelib;
%type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator
%type <declarator_list> declarator_list struct_declarator_list
%type <type> coclass coclasshdr coclassdef
+%type <type> apicontract
%type <num> contract_ver
%type <num> pointer_type threading_type version
%type <str> libraryhdr callconv cppquote importlib import t_ident
@@ -349,6 +353,8 @@ gbl_statements: { $$ = NULL; }
| gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, current_namespace, 0);
}
+ | gbl_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
+ reg_type($2, $2->name, current_namespace, 0); }
| gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
| gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
| gbl_statements statement { $$ = append_statement($1, $2); }
@@ -363,6 +369,8 @@ imp_statements: { $$ = NULL; }
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, current_namespace, 0);
}
+ | imp_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
+ reg_type($2, $2->name, current_namespace, 0); }
| imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
| imp_statements statement { $$ = append_statement($1, $2); }
| imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); }
@@ -868,6 +876,13 @@ coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
{ $$ = type_coclass_define($1, $3); }
;
+apicontract: attributes tAPICONTRACT aIDENTIFIER '{' '}'
+ { $$ = get_type(TYPE_APICONTRACT, $3, current_namespace, 0);
+ check_def($$);
+ $$->attrs = check_apicontract_attrs($$->name, $1);
+ }
+ ;
+
namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; }
| tNAMESPACE aNAMESPACE { $$ = $2; }
;
@@ -2143,114 +2158,115 @@ struct allowed_attr
unsigned int on_dispinterface : 1;
unsigned int on_module : 1;
unsigned int on_coclass : 1;
+ unsigned int on_apicontract : 1;
const char *display_name;
};
struct allowed_attr allowed_attr[] =
{
- /* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C <display name> } */
- /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "aggregatable" },
- /* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
- /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
- /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "appobject" },
- /* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
- /* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "async_uuid" },
- /* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
- /* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
- /* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
- /* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
- /* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
- /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
- /* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
- /* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
- /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
- /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "contractversion" },
- /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
- /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, "custom" },
- /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
- /* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, "default" },
- /* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
- /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
- /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
- /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" },
- /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
- /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
- /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
- /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" },
- /* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
- /* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
- /* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
- /* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
- /* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
- /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
- /* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
- /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
- /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
- /* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpcontext" },
- /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpfile" },
- /* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstring" },
- /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstringcontext" },
- /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpstringdll" },
- /* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, "hidden" },
- /* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, "id" },
- /* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
- /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "ignore" },
- /* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "iid_is" },
- /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
- /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
- /* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
- /* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
- /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
- /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
- /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "licensed" },
- /* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
- /* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
- /* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
- /* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
- /* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
- /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" },
- /* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
- /* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
- /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
- /* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
- /* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "odl" },
- /* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
- /* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
- /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
- /* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
- /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
- /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
- /* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
- /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "ref, unique or ptr" },
- /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "progid" },
- /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
- /* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
- /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
- /* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
- /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
- /* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, "range" },
- /* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "readonly" },
- /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
- /* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
- /* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "restricted" },
- /* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
- /* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "size_is" },
- /* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "source" },
- /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
- /* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "string" },
- /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_is" },
- /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_type" },
- /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "threading" },
- /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
- /* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
- /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
- /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
- /* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "uuid" },
- /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
- /* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
- /* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, "version" },
- /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "vi_progid" },
- /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
+ /* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC <display name> } */
+ /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "aggregatable" },
+ /* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
+ /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
+ /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "appobject" },
+ /* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
+ /* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "async_uuid" },
+ /* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
+ /* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
+ /* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
+ /* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
+ /* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "contractversion" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, "control" },
+ /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, "custom" },
+ /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+ /* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, "default" },
+ /* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
+ /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
+ /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
+ /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "defaultvtable" },
+ /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
+ /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
+ /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
+ /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "dllname" },
+ /* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
+ /* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
+ /* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
+ /* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
+ /* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
+ /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
+ /* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
+ /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
+ /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
+ /* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpcontext" },
+ /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpfile" },
+ /* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstring" },
+ /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstringcontext" },
+ /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpstringdll" },
+ /* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, "hidden" },
+ /* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, "id" },
+ /* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
+ /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ignore" },
+ /* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "iid_is" },
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "lcid" },
+ /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "licensed" },
+ /* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
+ /* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
+ /* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
+ /* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
+ /* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
+ /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "noncreatable" },
+ /* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
+ /* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
+ /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
+ /* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
+ /* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "odl" },
+ /* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
+ /* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
+ /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
+ /* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
+ /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
+ /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
+ /* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
+ /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ref, unique or ptr" },
+ /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "progid" },
+ /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
+ /* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
+ /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
+ /* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
+ /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
+ /* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, "range" },
+ /* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "readonly" },
+ /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
+ /* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
+ /* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "restricted" },
+ /* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
+ /* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "size_is" },
+ /* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "source" },
+ /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
+ /* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "string" },
+ /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_is" },
+ /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_type" },
+ /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "threading" },
+ /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
+ /* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
+ /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
+ /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
+ /* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "uuid" },
+ /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
+ /* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
+ /* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 0, "version" },
+ /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "vi_progid" },
+ /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
};
static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
@@ -2465,6 +2481,17 @@ static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
return attrs;
}
+static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
+{
+ const attr_t *attr;
+ if (!attrs) return attrs;
+ LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
+ if (!allowed_attr[attr->type].on_apicontract)
+ error_loc("inapplicable attribute %s for apicontract %s\n",
+ allowed_attr[attr->type].display_name, name);
+ return attrs;
+}
+
static int is_allowed_conf_type(const type_t *type)
{
switch (type_get_type(type))
@@ -2504,6 +2531,10 @@ static int is_allowed_conf_type(const type_t *type)
case TYPE_INTERFACE:
case TYPE_BITFIELD:
return FALSE;
+ case TYPE_APICONTRACT:
+ /* not supposed to be here */
+ assert(0);
+ break;
}
return FALSE;
}
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 4874dfd6c24..5d0f24be06f 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -374,6 +374,10 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
case TYPE_ALIAS:
case TYPE_BITFIELD:
break;
+ case TYPE_APICONTRACT:
+ /* not supposed to be here */
+ assert(0);
+ break;
}
return TGT_INVALID;
}
@@ -1966,6 +1970,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
case TYPE_MODULE:
case TYPE_FUNCTION:
case TYPE_BITFIELD:
+ case TYPE_APICONTRACT:
/* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or
@@ -2067,6 +2072,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
case TYPE_MODULE:
case TYPE_FUNCTION:
case TYPE_BITFIELD:
+ case TYPE_APICONTRACT:
/* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index cf027558d0a..faf76440f93 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -224,7 +224,8 @@ unsigned short get_type_vt(type_t *t)
return VT_VOID;
case TYPE_ALIAS:
- /* aliases should be filtered out by the type_get_type call above */
+ case TYPE_APICONTRACT:
+ /* not supposed to be here */
assert(0);
break;
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index e288c574002..7abec41a8fd 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -223,6 +223,9 @@ static inline int type_is_complete(const type_t *type)
case TYPE_ARRAY:
case TYPE_BITFIELD:
return TRUE;
+ case TYPE_APICONTRACT:
+ assert(0);
+ break;
}
return FALSE;
}
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 78401cf8278..878650d9c27 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -440,6 +440,7 @@ enum type_type
TYPE_POINTER,
TYPE_ARRAY,
TYPE_BITFIELD,
+ TYPE_APICONTRACT,
};
struct _type_t {
--
2.29.2
Dec. 1, 2020
[PATCH v2 2/4] widl: Support WinRT contractversion attribute parsing.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
tools/widl/parser.l | 1 +
tools/widl/parser.y | 12 +++++++++++-
tools/widl/widltypes.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index d7d96702322..a4e1d0d2c47 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -338,6 +338,7 @@ static const struct keyword attr_keywords[] =
{"context_handle", tCONTEXTHANDLE, 0},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0},
+ {"contractversion", tCONTRACTVERSION, 1},
{"control", tCONTROL, 0},
{"custom", tCUSTOM, 0},
{"decode", tDECODE, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 1bbb2e78f7e..3c4c8041a1c 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -177,7 +177,9 @@ static typelib_t *current_typelib;
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
-%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE
+%token tCONTEXTHANDLESERIALIZE
+%token tCONTRACTVERSION
+%token tCONTROL tCPPQUOTE
%token tCUSTOM
%token tDECODE tDEFAULT tDEFAULTBIND
%token tDEFAULTCOLLELEM
@@ -290,6 +292,7 @@ static typelib_t *current_typelib;
%type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator
%type <declarator_list> declarator_list struct_declarator_list
%type <type> coclass coclasshdr coclassdef
+%type <num> contract_ver
%type <num> pointer_type threading_type version
%type <str> libraryhdr callconv cppquote importlib import t_ident
%type <uuid> uuid_string
@@ -492,6 +495,11 @@ str_list: aSTRING { $$ = append_str( NULL, $1 ); }
| str_list ',' aSTRING { $$ = append_str( $1, $3 ); }
;
+contract_ver:
+ aNUM { $$ = MAKEVERSION(0, $1); }
+ | aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); }
+ ;
+
attribute: { $$ = NULL; }
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
@@ -507,6 +515,7 @@ attribute: { $$ = NULL; }
| tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
| tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
| tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
+ | tCONTRACTVERSION '(' contract_ver ')' { $$ = make_attrv(ATTR_CONTRACTVERSION, $3); }
| tCONTROL { $$ = make_attr(ATTR_CONTROL); }
| tCUSTOM '(' uuid_string ',' expr_const ')' { $$ = make_custom_attr($3, $5); }
| tDECODE { $$ = make_attr(ATTR_DECODE); }
@@ -2155,6 +2164,7 @@ struct allowed_attr allowed_attr[] =
/* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
/* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "contractversion" },
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
/* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, "custom" },
/* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 7a43e517698..78401cf8278 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -84,6 +84,7 @@ enum attr_type
ATTR_CODE,
ATTR_COMMSTATUS,
ATTR_CONTEXTHANDLE,
+ ATTR_CONTRACTVERSION,
ATTR_CONTROL,
ATTR_CUSTOM,
ATTR_DECODE,
--
2.29.2
Dec. 1, 2020
[PATCH v2 1/4] widl: Add abi_prefix parameter to format_namespace.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
v2: Just add the explicit abi_prefix parameter, we don't really need
the buffer management for now. I'll add a strappend helper in some
future series.
Supersedes: 196372-196375
tools/widl/header.c | 2 +-
tools/widl/parser.y | 2 +-
tools/widl/typetree.c | 18 +++++++++---------
tools/widl/widltypes.h | 3 ++-
4 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 015bbe2ece7..a892243fb54 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -132,7 +132,7 @@ static void write_guid(FILE *f, const char *guid_prefix, const char *name, const
static void write_uuid_decl(FILE *f, type_t *type, const UUID *uuid)
{
- char *name = format_namespace(type->namespace, "", "::", type->name);
+ char *name = format_namespace(type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL);
fprintf(f, "#ifdef __CRT_UUID_DECL\n");
fprintf(f, "__CRT_UUID_DECL(%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,"
"0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 160e4029a6e..1bbb2e78f7e 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1922,7 +1922,7 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
if (is_global_namespace(namespace))
type->c_name = name;
else
- type->c_name = format_namespace(namespace, "__x_", "_C", name);
+ type->c_name = format_namespace(namespace, "__x_", "_C", name, use_abi_namespace ? "ABI" : NULL);
nt->type = type;
nt->t = t;
nt->next = namespace->type_hash[hash];
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index c0547b36a96..df883576915 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -89,38 +89,38 @@ const char *type_get_name(const type_t *type, enum name_type name_type)
return NULL;
}
-static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator)
+static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator, const char *abi_prefix)
{
if(is_global_namespace(namespace)) {
- if(!use_abi_namespace)
- return ptr;
- strcpy(ptr, "ABI");
+ if(!abi_prefix) return ptr;
+ strcpy(ptr, abi_prefix);
strcat(ptr, separator);
return ptr + strlen(ptr);
}
- ptr = append_namespace(ptr, namespace->parent, separator);
+ ptr = append_namespace(ptr, namespace->parent, separator, abi_prefix);
strcpy(ptr, namespace->name);
strcat(ptr, separator);
return ptr + strlen(ptr);
}
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix)
+char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
+ const char *abi_prefix)
{
unsigned len = strlen(prefix) + strlen(suffix);
unsigned sep_len = strlen(separator);
struct namespace *iter;
char *ret, *ptr;
- if(use_abi_namespace && !is_global_namespace(namespace))
- len += 3 /* strlen("ABI") */ + sep_len;
+ if(abi_prefix)
+ len += strlen(abi_prefix) + sep_len;
for(iter = namespace; !is_global_namespace(iter); iter = iter->parent)
len += strlen(iter->name) + sep_len;
ret = xmalloc(len+1);
strcpy(ret, prefix);
- ptr = append_namespace(ret + strlen(ret), namespace, separator);
+ ptr = append_namespace(ret + strlen(ret), namespace, separator, abi_prefix);
strcpy(ptr, suffix);
return ret;
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index b02b80e122c..7a43e517698 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -613,7 +613,8 @@ var_list_t *append_var(var_list_t *list, var_t *var);
void init_loc_info(loc_info_t *);
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
+char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
+ const char *abi_prefix);
static inline enum type_type type_get_type_detect_alias(const type_t *type)
{
--
2.29.2
Dec. 1, 2020
[PATCH v2] conhost: Respect the StartupInfo's wShowWindow.
by Gabriel Ivăncescu
Since 859b526c81a2af841b5b7b28d06f3d782bccdab5, console windows are always
shown even if they're supposed to start in some other state, e.g. minimized.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
This fixes the regression.
programs/conhost/conhost.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c
index e3a9a25..f864bbb 100644
--- a/programs/conhost/conhost.c
+++ b/programs/conhost/conhost.c
@@ -2756,7 +2756,7 @@ int __cdecl wmain(int argc, WCHAR *argv[])
if (!init_window( &console )) return 1;
GetStartupInfoW( &si );
set_console_title( &console, si.lpTitle, wcslen( si.lpTitle ) * sizeof(WCHAR) );
- ShowWindow( console.win, SW_SHOW );
+ ShowWindow( console.win, (si.dwFlags & STARTF_USESHOWWINDOW) ? si.wShowWindow : SW_SHOW );
}
return main_loop( &console, signal );
--
2.21.0
Dec. 1, 2020
Re: [PATCH 7/7] mf/topoloader: Add copier transform automatically for D3D-aware outputs.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=82861
Your paranoid android.
=== wvistau64 (64 bit report) ===
mf:
mf: Timeout
Dec. 1, 2020
Re: [PATCH 6/7] mf/topoloader: Set MF_TOPONODE_MEDIASTART for all source nodes.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=82860
Your paranoid android.
=== wvistau64 (64 bit report) ===
mf:
mf: Timeout
Dec. 1, 2020
Re: [PATCH 5/7] mf/topoloader: Make sure MF_TOPONODE_STREAMID is set for all outputs.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=82859
Your paranoid android.
=== wvistau64 (64 bit report) ===
mf:
mf: Timeout
Dec. 1, 2020
Re: [PATCH 4/7] mf/topoloader: Set MF_TOPONODE_TRANSFORM_OBJECTID for created transforms when CLSID is available.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=82858
Your paranoid android.
=== wvistau64 (64 bit report) ===
mf:
mf: Timeout
Dec. 1, 2020
Re: [PATCH 3/7] mf/topoloader: Set MF_TOPONODE_DECODER for the decoders.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=82857
Your paranoid android.
=== wvistau64 (64 bit report) ===
mf:
mf: Timeout
Dec. 1, 2020