120
patches/app-emulation/wine-staging-5.1/patch.patch
Normal file
120
patches/app-emulation/wine-staging-5.1/patch.patch
Normal file
@ -0,0 +1,120 @@
|
||||
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
||||
index fd761246c5..29a5ad7db8 100644
|
||||
--- a/dlls/ntdll/signal_i386.c
|
||||
+++ b/dlls/ntdll/signal_i386.c
|
||||
@@ -442,6 +442,8 @@ static size_t signal_stack_size;
|
||||
|
||||
static wine_signal_handler handlers[256];
|
||||
|
||||
+static int wine_cs;
|
||||
+
|
||||
enum i386_trap_code
|
||||
{
|
||||
TRAP_x86_UNKNOWN = -1, /* Unknown fault (TRAP_sig not defined) */
|
||||
@@ -846,7 +848,7 @@ static inline void *init_handler( const ucontext_t *sigcontext, WORD *fs, WORD *
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
|
||||
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) ||
|
||||
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
|
||||
{
|
||||
/*
|
||||
@@ -1533,7 +1535,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
|
||||
BYTE instr[16];
|
||||
unsigned int i, len, prefix_count = 0;
|
||||
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return 0;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
|
||||
|
||||
for (i = 0; i < len; i++) switch (instr[i])
|
||||
@@ -1600,7 +1602,7 @@ static inline BOOL check_invalid_gs( ucontext_t *sigcontext, CONTEXT *context )
|
||||
WORD system_gs = x86_thread_data()->gs;
|
||||
|
||||
if (context->SegGs == system_gs) return FALSE;
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return FALSE;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
/* only handle faults in system libraries */
|
||||
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
|
||||
|
||||
@@ -1883,7 +1885,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
|
||||
EIP_sig(sigcontext) = (DWORD)raise_generic_exception;
|
||||
/* clear single-step, direction, and align check flag */
|
||||
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
|
||||
- CS_sig(sigcontext) = wine_get_cs();
|
||||
+ CS_sig(sigcontext) = wine_cs;
|
||||
DS_sig(sigcontext) = wine_get_ds();
|
||||
ES_sig(sigcontext) = wine_get_es();
|
||||
FS_sig(sigcontext) = wine_get_fs();
|
||||
@@ -2275,6 +2277,21 @@ static void ldt_unlock(void)
|
||||
}
|
||||
|
||||
|
||||
+void signal_init_cs(void)
|
||||
+{
|
||||
+ LDT_ENTRY entry;
|
||||
+
|
||||
+ if (!wine_cs)
|
||||
+ wine_cs = wine_ldt_alloc_entries( 1 );
|
||||
+
|
||||
+ wine_ldt_set_base( &entry, 0 );
|
||||
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
|
||||
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
|
||||
+ wine_ldt_set_entry( wine_cs, &entry );
|
||||
+
|
||||
+ wine_set_cs( wine_cs );
|
||||
+}
|
||||
+
|
||||
/**********************************************************************
|
||||
* signal_alloc_thread
|
||||
*/
|
||||
@@ -2311,6 +2328,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
status = STATUS_TOO_MANY_THREADS;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ signal_init_cs();
|
||||
+
|
||||
return status;
|
||||
}
|
||||
|
||||
diff --git a/include/wine/library.h b/include/wine/library.h
|
||||
index af9deaf93f..cac3e3bc64 100644
|
||||
--- a/include/wine/library.h
|
||||
+++ b/include/wine/library.h
|
||||
@@ -193,6 +193,7 @@ __DEFINE_SET_SEG(fs)
|
||||
__DEFINE_SET_SEG(gs)
|
||||
#undef __DEFINE_GET_SEG
|
||||
#undef __DEFINE_SET_SEG
|
||||
+extern void wine_set_cs(unsigned int);
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
|
||||
index baf12a2e3a..edf7247dc0 100644
|
||||
--- a/libs/wine/ldt.c
|
||||
+++ b/libs/wine/ldt.c
|
||||
@@ -463,6 +463,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
|
||||
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
|
||||
+ "xchg 0(%esp),%eax\n\t"
|
||||
+ "push %eax\n\t"
|
||||
+ "retf" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
|
||||
|
||||
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
|
||||
index 2159fac852..43c735cc59 100644
|
||||
--- a/libs/wine/wine.map
|
||||
+++ b/libs/wine/wine.map
|
||||
@@ -63,6 +63,7 @@ WINE_1.0
|
||||
wine_mmap_enum_free_areas;
|
||||
wine_mmap_is_in_free_area;
|
||||
wine_mmap_remove_free_area;
|
||||
+ wine_set_cs;
|
||||
wine_set_fs;
|
||||
wine_set_gs;
|
||||
wine_utf8_mbstowcs;
|
10
patches/app-emulation/wine-staging-5.1/winenew
Normal file
10
patches/app-emulation/wine-staging-5.1/winenew
Normal file
@ -0,0 +1,10 @@
|
||||
--- wine.map 2020-02-09 00:13:26.145060709 +0100
|
||||
+++ wine.mapNEW 2020-02-09 00:17:59.837068528 +0100
|
||||
@@ -63,6 +63,7 @@
|
||||
wine_mmap_enum_free_areas;
|
||||
wine_mmap_is_in_free_area;
|
||||
wine_mmap_remove_free_area;
|
||||
+ wine_set_cs;
|
||||
wine_set_fs;
|
||||
wine_set_gs;
|
||||
wine_utf8_mbstowcs;
|
120
patches/app-emulation/wine-staging-5.2/patch.patch
Normal file
120
patches/app-emulation/wine-staging-5.2/patch.patch
Normal file
@ -0,0 +1,120 @@
|
||||
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
||||
index fd761246c5..29a5ad7db8 100644
|
||||
--- a/dlls/ntdll/signal_i386.c
|
||||
+++ b/dlls/ntdll/signal_i386.c
|
||||
@@ -442,6 +442,8 @@ static size_t signal_stack_size;
|
||||
|
||||
static wine_signal_handler handlers[256];
|
||||
|
||||
+static int wine_cs;
|
||||
+
|
||||
enum i386_trap_code
|
||||
{
|
||||
TRAP_x86_UNKNOWN = -1, /* Unknown fault (TRAP_sig not defined) */
|
||||
@@ -846,7 +848,7 @@ static inline void *init_handler( const ucontext_t *sigcontext, WORD *fs, WORD *
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
|
||||
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) ||
|
||||
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
|
||||
{
|
||||
/*
|
||||
@@ -1533,7 +1535,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
|
||||
BYTE instr[16];
|
||||
unsigned int i, len, prefix_count = 0;
|
||||
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return 0;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
|
||||
|
||||
for (i = 0; i < len; i++) switch (instr[i])
|
||||
@@ -1600,7 +1602,7 @@ static inline BOOL check_invalid_gs( ucontext_t *sigcontext, CONTEXT *context )
|
||||
WORD system_gs = x86_thread_data()->gs;
|
||||
|
||||
if (context->SegGs == system_gs) return FALSE;
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return FALSE;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
/* only handle faults in system libraries */
|
||||
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
|
||||
|
||||
@@ -1883,7 +1885,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
|
||||
EIP_sig(sigcontext) = (DWORD)raise_generic_exception;
|
||||
/* clear single-step, direction, and align check flag */
|
||||
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
|
||||
- CS_sig(sigcontext) = wine_get_cs();
|
||||
+ CS_sig(sigcontext) = wine_cs;
|
||||
DS_sig(sigcontext) = wine_get_ds();
|
||||
ES_sig(sigcontext) = wine_get_es();
|
||||
FS_sig(sigcontext) = wine_get_fs();
|
||||
@@ -2275,6 +2277,21 @@ static void ldt_unlock(void)
|
||||
}
|
||||
|
||||
|
||||
+void signal_init_cs(void)
|
||||
+{
|
||||
+ LDT_ENTRY entry;
|
||||
+
|
||||
+ if (!wine_cs)
|
||||
+ wine_cs = wine_ldt_alloc_entries( 1 );
|
||||
+
|
||||
+ wine_ldt_set_base( &entry, 0 );
|
||||
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
|
||||
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
|
||||
+ wine_ldt_set_entry( wine_cs, &entry );
|
||||
+
|
||||
+ wine_set_cs( wine_cs );
|
||||
+}
|
||||
+
|
||||
/**********************************************************************
|
||||
* signal_alloc_thread
|
||||
*/
|
||||
@@ -2311,6 +2328,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
status = STATUS_TOO_MANY_THREADS;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ signal_init_cs();
|
||||
+
|
||||
return status;
|
||||
}
|
||||
|
||||
diff --git a/include/wine/library.h b/include/wine/library.h
|
||||
index af9deaf93f..cac3e3bc64 100644
|
||||
--- a/include/wine/library.h
|
||||
+++ b/include/wine/library.h
|
||||
@@ -193,6 +193,7 @@ __DEFINE_SET_SEG(fs)
|
||||
__DEFINE_SET_SEG(gs)
|
||||
#undef __DEFINE_GET_SEG
|
||||
#undef __DEFINE_SET_SEG
|
||||
+extern void wine_set_cs(unsigned int);
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
|
||||
index baf12a2e3a..edf7247dc0 100644
|
||||
--- a/libs/wine/ldt.c
|
||||
+++ b/libs/wine/ldt.c
|
||||
@@ -463,6 +463,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
|
||||
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
|
||||
+ "xchg 0(%esp),%eax\n\t"
|
||||
+ "push %eax\n\t"
|
||||
+ "retf" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
|
||||
|
||||
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
|
||||
index 2159fac852..43c735cc59 100644
|
||||
--- a/libs/wine/wine.map
|
||||
+++ b/libs/wine/wine.map
|
||||
@@ -63,6 +63,7 @@ WINE_1.0
|
||||
wine_mmap_enum_free_areas;
|
||||
wine_mmap_is_in_free_area;
|
||||
wine_mmap_remove_free_area;
|
||||
+ wine_set_cs;
|
||||
wine_set_fs;
|
||||
wine_set_gs;
|
||||
wine_utf8_mbstowcs;
|
10
patches/app-emulation/wine-staging-5.2/winenew
Normal file
10
patches/app-emulation/wine-staging-5.2/winenew
Normal file
@ -0,0 +1,10 @@
|
||||
--- wine.map 2020-02-09 00:13:26.145060709 +0100
|
||||
+++ wine.mapNEW 2020-02-09 00:17:59.837068528 +0100
|
||||
@@ -63,6 +63,7 @@
|
||||
wine_mmap_enum_free_areas;
|
||||
wine_mmap_is_in_free_area;
|
||||
wine_mmap_remove_free_area;
|
||||
+ wine_set_cs;
|
||||
wine_set_fs;
|
||||
wine_set_gs;
|
||||
wine_utf8_mbstowcs;
|
120
patches/app-emulation/wine-staging.5.0/patch.patch
Normal file
120
patches/app-emulation/wine-staging.5.0/patch.patch
Normal file
@ -0,0 +1,120 @@
|
||||
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
||||
index fd761246c5..29a5ad7db8 100644
|
||||
--- a/dlls/ntdll/signal_i386.c
|
||||
+++ b/dlls/ntdll/signal_i386.c
|
||||
@@ -442,6 +442,8 @@ static size_t signal_stack_size;
|
||||
|
||||
static wine_signal_handler handlers[256];
|
||||
|
||||
+static int wine_cs;
|
||||
+
|
||||
enum i386_trap_code
|
||||
{
|
||||
TRAP_x86_UNKNOWN = -1, /* Unknown fault (TRAP_sig not defined) */
|
||||
@@ -846,7 +848,7 @@ static inline void *init_handler( const ucontext_t *sigcontext, WORD *fs, WORD *
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
|
||||
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) ||
|
||||
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
|
||||
{
|
||||
/*
|
||||
@@ -1533,7 +1535,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
|
||||
BYTE instr[16];
|
||||
unsigned int i, len, prefix_count = 0;
|
||||
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return 0;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
|
||||
|
||||
for (i = 0; i < len; i++) switch (instr[i])
|
||||
@@ -1600,7 +1602,7 @@ static inline BOOL check_invalid_gs( ucontext_t *sigcontext, CONTEXT *context )
|
||||
WORD system_gs = x86_thread_data()->gs;
|
||||
|
||||
if (context->SegGs == system_gs) return FALSE;
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return FALSE;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
/* only handle faults in system libraries */
|
||||
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
|
||||
|
||||
@@ -1883,7 +1885,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
|
||||
EIP_sig(sigcontext) = (DWORD)raise_generic_exception;
|
||||
/* clear single-step, direction, and align check flag */
|
||||
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
|
||||
- CS_sig(sigcontext) = wine_get_cs();
|
||||
+ CS_sig(sigcontext) = wine_cs;
|
||||
DS_sig(sigcontext) = wine_get_ds();
|
||||
ES_sig(sigcontext) = wine_get_es();
|
||||
FS_sig(sigcontext) = wine_get_fs();
|
||||
@@ -2275,6 +2277,21 @@ static void ldt_unlock(void)
|
||||
}
|
||||
|
||||
|
||||
+void signal_init_cs(void)
|
||||
+{
|
||||
+ LDT_ENTRY entry;
|
||||
+
|
||||
+ if (!wine_cs)
|
||||
+ wine_cs = wine_ldt_alloc_entries( 1 );
|
||||
+
|
||||
+ wine_ldt_set_base( &entry, 0 );
|
||||
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
|
||||
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
|
||||
+ wine_ldt_set_entry( wine_cs, &entry );
|
||||
+
|
||||
+ wine_set_cs( wine_cs );
|
||||
+}
|
||||
+
|
||||
/**********************************************************************
|
||||
* signal_alloc_thread
|
||||
*/
|
||||
@@ -2311,6 +2328,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
status = STATUS_TOO_MANY_THREADS;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ signal_init_cs();
|
||||
+
|
||||
return status;
|
||||
}
|
||||
|
||||
diff --git a/include/wine/library.h b/include/wine/library.h
|
||||
index af9deaf93f..cac3e3bc64 100644
|
||||
--- a/include/wine/library.h
|
||||
+++ b/include/wine/library.h
|
||||
@@ -193,6 +193,7 @@ __DEFINE_SET_SEG(fs)
|
||||
__DEFINE_SET_SEG(gs)
|
||||
#undef __DEFINE_GET_SEG
|
||||
#undef __DEFINE_SET_SEG
|
||||
+extern void wine_set_cs(unsigned int);
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
|
||||
index baf12a2e3a..edf7247dc0 100644
|
||||
--- a/libs/wine/ldt.c
|
||||
+++ b/libs/wine/ldt.c
|
||||
@@ -463,6 +463,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
|
||||
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
|
||||
+ "xchg 0(%esp),%eax\n\t"
|
||||
+ "push %eax\n\t"
|
||||
+ "retf" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
|
||||
|
||||
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
|
||||
index 2159fac852..43c735cc59 100644
|
||||
--- a/libs/wine/wine.map
|
||||
+++ b/libs/wine/wine.map
|
||||
@@ -111,6 +111,7 @@ WINE_1.0
|
||||
wine_mmap_remove_reserved_area;
|
||||
wine_pthread_get_functions;
|
||||
wine_pthread_set_functions;
|
||||
+ wine_set_cs;
|
||||
wine_set_fs;
|
||||
wine_set_gs;
|
||||
wine_switch_to_stack;
|
120
patches/app-emulation/wine-staging/patch.patch
Normal file
120
patches/app-emulation/wine-staging/patch.patch
Normal file
@ -0,0 +1,120 @@
|
||||
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
|
||||
index fd761246c5..29a5ad7db8 100644
|
||||
--- a/dlls/ntdll/signal_i386.c
|
||||
+++ b/dlls/ntdll/signal_i386.c
|
||||
@@ -442,6 +442,8 @@ static size_t signal_stack_size;
|
||||
|
||||
static wine_signal_handler handlers[256];
|
||||
|
||||
+static int wine_cs;
|
||||
+
|
||||
enum i386_trap_code
|
||||
{
|
||||
TRAP_x86_UNKNOWN = -1, /* Unknown fault (TRAP_sig not defined) */
|
||||
@@ -846,7 +848,7 @@ static inline void *init_handler( const ucontext_t *sigcontext, WORD *fs, WORD *
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (!wine_ldt_is_system(CS_sig(sigcontext)) ||
|
||||
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) ||
|
||||
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */
|
||||
{
|
||||
/*
|
||||
@@ -1533,7 +1535,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context )
|
||||
BYTE instr[16];
|
||||
unsigned int i, len, prefix_count = 0;
|
||||
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return 0;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) );
|
||||
|
||||
for (i = 0; i < len; i++) switch (instr[i])
|
||||
@@ -1600,7 +1602,7 @@ static inline BOOL check_invalid_gs( ucontext_t *sigcontext, CONTEXT *context )
|
||||
WORD system_gs = x86_thread_data()->gs;
|
||||
|
||||
if (context->SegGs == system_gs) return FALSE;
|
||||
- if (!wine_ldt_is_system( context->SegCs )) return FALSE;
|
||||
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0;
|
||||
/* only handle faults in system libraries */
|
||||
if (virtual_is_valid_code_address( instr, 1 )) return FALSE;
|
||||
|
||||
@@ -1883,7 +1885,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
|
||||
EIP_sig(sigcontext) = (DWORD)raise_generic_exception;
|
||||
/* clear single-step, direction, and align check flag */
|
||||
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000);
|
||||
- CS_sig(sigcontext) = wine_get_cs();
|
||||
+ CS_sig(sigcontext) = wine_cs;
|
||||
DS_sig(sigcontext) = wine_get_ds();
|
||||
ES_sig(sigcontext) = wine_get_es();
|
||||
FS_sig(sigcontext) = wine_get_fs();
|
||||
@@ -2275,6 +2277,21 @@ static void ldt_unlock(void)
|
||||
}
|
||||
|
||||
|
||||
+void signal_init_cs(void)
|
||||
+{
|
||||
+ LDT_ENTRY entry;
|
||||
+
|
||||
+ if (!wine_cs)
|
||||
+ wine_cs = wine_ldt_alloc_entries( 1 );
|
||||
+
|
||||
+ wine_ldt_set_base( &entry, 0 );
|
||||
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 );
|
||||
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT );
|
||||
+ wine_ldt_set_entry( wine_cs, &entry );
|
||||
+
|
||||
+ wine_set_cs( wine_cs );
|
||||
+}
|
||||
+
|
||||
/**********************************************************************
|
||||
* signal_alloc_thread
|
||||
*/
|
||||
@@ -2311,6 +2328,9 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||
status = STATUS_TOO_MANY_THREADS;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ signal_init_cs();
|
||||
+
|
||||
return status;
|
||||
}
|
||||
|
||||
diff --git a/include/wine/library.h b/include/wine/library.h
|
||||
index af9deaf93f..cac3e3bc64 100644
|
||||
--- a/include/wine/library.h
|
||||
+++ b/include/wine/library.h
|
||||
@@ -193,6 +193,7 @@ __DEFINE_SET_SEG(fs)
|
||||
__DEFINE_SET_SEG(gs)
|
||||
#undef __DEFINE_GET_SEG
|
||||
#undef __DEFINE_SET_SEG
|
||||
+extern void wine_set_cs(unsigned int);
|
||||
|
||||
#endif /* __i386__ */
|
||||
|
||||
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c
|
||||
index baf12a2e3a..edf7247dc0 100644
|
||||
--- a/libs/wine/ldt.c
|
||||
+++ b/libs/wine/ldt.c
|
||||
@@ -463,6 +463,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" )
|
||||
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t"
|
||||
+ "xchg 0(%esp),%eax\n\t"
|
||||
+ "push %eax\n\t"
|
||||
+ "retf" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" )
|
||||
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" )
|
||||
|
||||
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
|
||||
index 2159fac852..43c735cc59 100644
|
||||
--- a/libs/wine/wine.map
|
||||
+++ b/libs/wine/wine.map
|
||||
@@ -111,6 +111,7 @@ WINE_1.0
|
||||
wine_mmap_remove_reserved_area;
|
||||
wine_pthread_get_functions;
|
||||
wine_pthread_set_functions;
|
||||
+ wine_set_cs;
|
||||
wine_set_fs;
|
||||
wine_set_gs;
|
||||
wine_switch_to_stack;
|
@ -0,0 +1,26 @@
|
||||
diff --git a/common/glib-gen.mak b/common/glib-gen.mak
|
||||
index ef93a5f..e43e126 100644
|
||||
--- a/common/glib-gen.mak
|
||||
+++ b/common/glib-gen.mak
|
||||
@@ -5,7 +5,7 @@
|
||||
#glib_enum_define=GST_COLOR_BALANCE
|
||||
#glib_enum_prefix=gst_color_balance
|
||||
|
||||
-enum_headers=$(foreach h,$(glib_enum_headers),\n\#include \"$(h)\")
|
||||
+enum_headers=$(foreach h,$(glib_enum_headers),\n#include \"$(h)\")
|
||||
|
||||
# these are all the rules generating the relevant files
|
||||
%-marshal.h: %-marshal.list
|
||||
diff --git a/sys/v4l2/Makefile.in b/sys/v4l2/Makefile.in
|
||||
index 048ee8e..eb62bbc 100644
|
||||
--- a/sys/v4l2/Makefile.in
|
||||
+++ b/sys/v4l2/Makefile.in
|
||||
@@ -669,7 +669,7 @@ top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
plugin_LTLIBRARIES = libgstvideo4linux2.la
|
||||
-enum_headers = $(foreach h,$(glib_enum_headers),\n\#include \"$(h)\")
|
||||
+enum_headers = $(foreach h,$(glib_enum_headers),\n#include \"$(h)\")
|
||||
libgstvideo4linux2_la_SOURCES = gstv4l2.c \
|
||||
gstv4l2allocator.c \
|
||||
gstv4l2colorbalance.c \
|
@ -0,0 +1,13 @@
|
||||
diff --git a/sys/v4l2/Makefile.in b/sys/v4l2/Makefile.in
|
||||
index 048ee8e..eb62bbc 100644
|
||||
--- a/sys/v4l2/Makefile.in
|
||||
+++ b/sys/v4l2/Makefile.in
|
||||
@@ -669,7 +669,7 @@ top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
plugin_LTLIBRARIES = libgstvideo4linux2.la
|
||||
-enum_headers = $(foreach h,$(glib_enum_headers),\n\#include \"$(h)\")
|
||||
+enum_headers = $(foreach h,$(glib_enum_headers),\n#include \"$(h)\")
|
||||
libgstvideo4linux2_la_SOURCES = gstv4l2.c \
|
||||
gstv4l2allocator.c \
|
||||
gstv4l2colorbalance.c \
|
2268
patches/sys-kernel/gentoo-sources-5.7.6/0001-fsgsbase-patches.patch
Normal file
2268
patches/sys-kernel/gentoo-sources-5.7.6/0001-fsgsbase-patches.patch
Normal file
File diff suppressed because it is too large
Load Diff
2268
patches/sys-kernel/gentoo-sources-5.7/0001-fsgsbase-patches.patch
Normal file
2268
patches/sys-kernel/gentoo-sources-5.7/0001-fsgsbase-patches.patch
Normal file
File diff suppressed because it is too large
Load Diff
395
patches/x11-drivers/nvidia-drivers-440.44-r1/kernel-5.5.patch
Normal file
395
patches/x11-drivers/nvidia-drivers-440.44-r1/kernel-5.5.patch
Normal file
@ -0,0 +1,395 @@
|
||||
diff --git a/.manifest b/.manifest
|
||||
index a53265d..bc46234 100644
|
||||
--- a/.manifest
|
||||
+++ b/.manifest
|
||||
@@ -36,6 +36,7 @@ kernel/nvidia/nv-rsync.c 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resm
|
||||
kernel/nvidia/nv-msi.c 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman
|
||||
kernel/conftest.sh 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman
|
||||
kernel/common/inc/nv.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman
|
||||
+kernel/common/inc/nv-drm.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman
|
||||
kernel/common/inc/nv-pci.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman
|
||||
kernel/common/inc/nv-pgprot.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman
|
||||
kernel/common/inc/nv-mm.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:resman
|
||||
diff --git a/kernel/common/inc/nv-drm.h b/kernel/common/inc/nv-drm.h
|
||||
new file mode 100644
|
||||
index 0000000..07e9f3c
|
||||
--- /dev/null
|
||||
+++ b/kernel/common/inc/nv-drm.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+#ifndef _NV_DRM_H_
|
||||
+#define _NV_DRM_H_
|
||||
+
|
||||
+#include "conftest.h"
|
||||
+
|
||||
+#if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
+#include <drm/drmP.h>
|
||||
+#else
|
||||
+#include <linux/agp_backend.h>
|
||||
+#include <linux/file.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <asm/pgalloc.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+
|
||||
+#include <uapi/drm/drm.h>
|
||||
+#include <uapi/drm/drm_mode.h>
|
||||
+
|
||||
+#include <drm/drm_agpsupport.h>
|
||||
+#include <drm/drm_crtc.h>
|
||||
+#include <drm/drm_drv.h>
|
||||
+#include <drm/drm_prime.h>
|
||||
+#include <drm/drm_pci.h>
|
||||
+#include <drm/drm_ioctl.h>
|
||||
+#include <drm/drm_sysfs.h>
|
||||
+#include <drm/drm_vblank.h>
|
||||
+#include <drm/drm_device.h>
|
||||
+
|
||||
+#include <drm/drm_gem.h>
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/kernel/conftest.sh b/kernel/conftest.sh
|
||||
index c9c2db3..dd22bb0 100755
|
||||
--- a/kernel/conftest.sh
|
||||
+++ b/kernel/conftest.sh
|
||||
@@ -1150,6 +1150,9 @@ compile_test() {
|
||||
CODE="
|
||||
#if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #else
|
||||
+ #include <drm/drm_drv.h>
|
||||
+ #include <drm/drm_prime.h>
|
||||
#endif
|
||||
#if !defined(CONFIG_DRM) && !defined(CONFIG_DRM_MODULE)
|
||||
#error DRM not enabled
|
||||
@@ -1781,6 +1784,8 @@ compile_test() {
|
||||
echo "$CONFTEST_PREAMBLE
|
||||
#if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #else
|
||||
+ #include <drm/drm_drv.h>
|
||||
#endif
|
||||
#include <drm/drm_atomic.h>
|
||||
#if !defined(CONFIG_DRM) && !defined(CONFIG_DRM_MODULE)
|
||||
@@ -1909,7 +1914,11 @@ compile_test() {
|
||||
# attached drivers") in v3.14 (2013-12-11)
|
||||
#
|
||||
CODE="
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #else
|
||||
+ #include <drm/drm_drv.h>
|
||||
+ #endif
|
||||
int conftest_drm_driver_has_legacy_dev_list(void) {
|
||||
return offsetof(struct drm_driver, legacy_dev_list);
|
||||
}"
|
||||
@@ -1933,7 +1942,11 @@ compile_test() {
|
||||
# 2017-07-23 e6fc3b68558e4c6d8d160b5daf2511b99afa8814
|
||||
#
|
||||
CODE="
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #else
|
||||
+ #include <drm/drm_crtc.h>
|
||||
+ #endif
|
||||
|
||||
int conftest_drm_crtc_init_with_planes_has_name_arg(void) {
|
||||
return
|
||||
@@ -1949,7 +1962,11 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_DRM_CRTC_INIT_WITH_PLANES_HAS_NAME_ARG" "" "types"
|
||||
|
||||
CODE="
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #else
|
||||
+ #include <drm/drm_encoder.h>
|
||||
+ #endif
|
||||
|
||||
int conftest_drm_encoder_init_has_name_arg(void) {
|
||||
return
|
||||
@@ -1964,7 +1981,11 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_DRM_ENCODER_INIT_HAS_NAME_ARG" "" "types"
|
||||
|
||||
echo "$CONFTEST_PREAMBLE
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #else
|
||||
+ #include <drm/drm_plane.h>
|
||||
+ #endif
|
||||
|
||||
int conftest_drm_universal_plane_init_has_format_modifiers_arg(void) {
|
||||
return
|
||||
@@ -1991,7 +2012,11 @@ compile_test() {
|
||||
echo "#undef NV_DRM_UNIVERSAL_PLANE_INIT_HAS_FORMAT_MODIFIERS_ARG" | append_conftest "types"
|
||||
|
||||
echo "$CONFTEST_PREAMBLE
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #else
|
||||
+ #include <drm/drm_plane.h>
|
||||
+ #endif
|
||||
|
||||
int conftest_drm_universal_plane_init_has_name_arg(void) {
|
||||
return
|
||||
@@ -3084,7 +3109,9 @@ compile_test() {
|
||||
# drm_framebuffer_{get,put}()") in v4.12 (2017-02-28).
|
||||
#
|
||||
CODE="
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #endif
|
||||
#if defined(NV_DRM_DRM_FRAMEBUFFER_H_PRESENT)
|
||||
#include <drm/drm_framebuffer.h>
|
||||
#endif
|
||||
@@ -3103,7 +3130,9 @@ compile_test() {
|
||||
# drm_gem_object_{get,put}()") in v4.12 (2017-02-28).
|
||||
#
|
||||
CODE="
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #endif
|
||||
#if defined(NV_DRM_DRM_GEM_H_PRESENT)
|
||||
#include <drm/drm_gem.h>
|
||||
#endif
|
||||
@@ -3122,7 +3151,9 @@ compile_test() {
|
||||
# functions") in v4.15 (2017-09-26).
|
||||
#
|
||||
CODE="
|
||||
+ #if defined(NV_DRM_DRMP_H_PRESENT)
|
||||
#include <drm/drmP.h>
|
||||
+ #endif
|
||||
#if defined(NV_DRM_DRM_DRV_H_PRESENT)
|
||||
#include <drm/drm_drv.h>
|
||||
#endif
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-connector.c b/kernel/nvidia-drm/nvidia-drm-connector.c
|
||||
index 1553ebc..f851561 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-connector.c
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-connector.c
|
||||
@@ -20,6 +20,8 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
+#include <linux/version.h>
|
||||
+
|
||||
#include "nvidia-drm-conftest.h" /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
@@ -71,7 +73,11 @@ static enum drm_connector_status __nv_drm_connector_detect_internal(
|
||||
struct nv_drm_encoder *nv_detected_encoder = NULL;
|
||||
|
||||
struct NvKmsKapiDynamicDisplayParams *pDetectParams = NULL;
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)
|
||||
unsigned int i;
|
||||
+#else
|
||||
+ struct drm_encoder *encoder = NULL;
|
||||
+#endif
|
||||
|
||||
BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
|
||||
|
||||
@@ -87,11 +93,16 @@ static enum drm_connector_status __nv_drm_connector_detect_internal(
|
||||
goto done;
|
||||
}
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)
|
||||
for (i = 0;
|
||||
i < DRM_CONNECTOR_MAX_ENCODER && detected_encoder == NULL; i++) {
|
||||
struct drm_encoder *encoder;
|
||||
+#else
|
||||
+ drm_connector_for_each_possible_encoder(connector, encoder) {
|
||||
+#endif
|
||||
struct nv_drm_encoder *nv_encoder;
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)
|
||||
if (connector->encoder_ids[i] == 0) {
|
||||
break;
|
||||
}
|
||||
@@ -102,6 +113,7 @@ static enum drm_connector_status __nv_drm_connector_detect_internal(
|
||||
BUG_ON(encoder != NULL);
|
||||
continue;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* DVI-I connectors can drive both digital and analog
|
||||
@@ -169,6 +181,8 @@ static enum drm_connector_status __nv_drm_connector_detect_internal(
|
||||
}
|
||||
|
||||
detected_encoder = encoder;
|
||||
+
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-connector.h b/kernel/nvidia-drm/nvidia-drm-connector.h
|
||||
index f74e22c..099390d 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-connector.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-connector.h
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
|
||||
#include "nvtypes.h"
|
||||
#include "nvkms-api-types.h"
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-crtc.h b/kernel/nvidia-drm/nvidia-drm-crtc.h
|
||||
index 31ef3b5..5de3a51 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-crtc.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-crtc.h
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "nvidia-drm-helper.h"
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
#include "nvtypes.h"
|
||||
#include "nvkms-kapi.h"
|
||||
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-drv.c b/kernel/nvidia-drm/nvidia-drm-drv.c
|
||||
index a66d3cc..06bf859 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-drv.c
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-drv.c
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#include "nvidia-drm-ioctl.h"
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
|
||||
/*
|
||||
* Commit fcd70cd36b9b ("drm: Split out drm_probe_helper.h")
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-encoder.h b/kernel/nvidia-drm/nvidia-drm-encoder.h
|
||||
index bbaf986..af341a8 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-encoder.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-encoder.h
|
||||
@@ -32,7 +32,7 @@
|
||||
#if defined(NV_DRM_DRM_ENCODER_H_PRESENT)
|
||||
#include <drm/drm_encoder.h>
|
||||
#else
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
#endif
|
||||
|
||||
#include "nvkms-kapi.h"
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-fb.h b/kernel/nvidia-drm/nvidia-drm-fb.h
|
||||
index 7f292ce..d13bc4c 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-fb.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-fb.h
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
#include "nvidia-drm-gem-nvkms-memory.h"
|
||||
#include "nvkms-kapi.h"
|
||||
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-gem.h b/kernel/nvidia-drm/nvidia-drm-gem.h
|
||||
index b621969..326f810 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-gem.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-gem.h
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "nvidia-drm-priv.h"
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
#include "nvkms-kapi.h"
|
||||
|
||||
#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-helper.c b/kernel/nvidia-drm/nvidia-drm-helper.c
|
||||
index da602ac..e5d6daa 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-helper.c
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-helper.c
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
#if defined(NV_DRM_DRM_ATOMIC_UAPI_H_PRESENT)
|
||||
#include <drm/drm_atomic_uapi.h>
|
||||
#endif
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-helper.h b/kernel/nvidia-drm/nvidia-drm-helper.h
|
||||
index 8f050d8..71c4b90 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-helper.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-helper.h
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NV_DRM_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
|
||||
/*
|
||||
* drm_dev_put() is added by commit 9a96f55034e41b4e002b767e9218d55f03bdff7d
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-modeset.h b/kernel/nvidia-drm/nvidia-drm-modeset.h
|
||||
index 06659c5..e9d7b70 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-modeset.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-modeset.h
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
|
||||
struct drm_atomic_state *nv_drm_atomic_state_alloc(struct drm_device *dev);
|
||||
void nv_drm_atomic_state_clear(struct drm_atomic_state *state);
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-os-interface.h b/kernel/nvidia-drm/nvidia-drm-os-interface.h
|
||||
index f43f851..7f4ff8b 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-os-interface.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-os-interface.h
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#if defined(NV_DRM_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
|
||||
/* Set to true when the atomic modeset feature is enabled. */
|
||||
extern bool nv_drm_modeset_module_param;
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-prime-fence.h b/kernel/nvidia-drm/nvidia-drm-prime-fence.h
|
||||
index 20da923..f3cc2b4 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-prime-fence.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-prime-fence.h
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NV_DRM_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
|
||||
#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
|
||||
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-priv.h b/kernel/nvidia-drm/nvidia-drm-priv.h
|
||||
index 9076835..77a95f3 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-priv.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-priv.h
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NV_DRM_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
|
||||
#if defined(NV_DRM_DRM_GEM_H_PRESENT)
|
||||
#include <drm/drm_gem.h>
|
||||
diff --git a/kernel/nvidia-drm/nvidia-drm-utils.h b/kernel/nvidia-drm/nvidia-drm-utils.h
|
||||
index 6d24120..95190c4 100644
|
||||
--- a/kernel/nvidia-drm/nvidia-drm-utils.h
|
||||
+++ b/kernel/nvidia-drm/nvidia-drm-utils.h
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
|
||||
|
||||
-#include <drm/drmP.h>
|
||||
+#include "nv-drm.h"
|
||||
#include "nvkms-kapi.h"
|
||||
|
||||
struct NvKmsKapiConnectorInfo*
|
503
patches/x11-drivers/nvidia-drivers-440.64/kernel-5.6.patch
Normal file
503
patches/x11-drivers/nvidia-drivers-440.64/kernel-5.6.patch
Normal file
@ -0,0 +1,503 @@
|
||||
diff --git a/kernel/common/inc/nv-procfs.h b/kernel/common/inc/nv-procfs.h
|
||||
index 8b53f86..4c5aceb 100644
|
||||
--- a/kernel/common/inc/nv-procfs.h
|
||||
+++ b/kernel/common/inc/nv-procfs.h
|
||||
@@ -28,6 +28,18 @@
|
||||
|
||||
#define IS_EXERCISE_ERROR_FORWARDING_ENABLED() (EXERCISE_ERROR_FORWARDING)
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
|
||||
+ ({ \
|
||||
+ struct proc_dir_entry *__entry; \
|
||||
+ int mode = (S_IFREG | S_IRUGO); \
|
||||
+ const struct proc_ops *fops = &nv_procfs_##__name##_fops; \
|
||||
+ if (fops->proc_write != 0) \
|
||||
+ mode |= S_IWUSR; \
|
||||
+ __entry = proc_create_data(filename, mode, parent, fops, __data);\
|
||||
+ __entry; \
|
||||
+ })
|
||||
+#else
|
||||
#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
|
||||
({ \
|
||||
struct proc_dir_entry *__entry; \
|
||||
@@ -38,6 +50,7 @@
|
||||
__entry = proc_create_data(filename, mode, parent, fops, __data);\
|
||||
__entry; \
|
||||
})
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0.
|
||||
@@ -77,6 +90,44 @@
|
||||
remove_proc_entry(entry->name, entry->parent);
|
||||
#endif
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+#define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
|
||||
+ static int nv_procfs_open_##name( \
|
||||
+ struct inode *inode, \
|
||||
+ struct file *filep \
|
||||
+ ) \
|
||||
+ { \
|
||||
+ int ret; \
|
||||
+ ret = single_open(filep, nv_procfs_read_##name, \
|
||||
+ NV_PDE_DATA(inode)); \
|
||||
+ if (ret < 0) \
|
||||
+ { \
|
||||
+ return ret; \
|
||||
+ } \
|
||||
+ ret = open_callback(); \
|
||||
+ if (ret < 0) \
|
||||
+ { \
|
||||
+ single_release(inode, filep); \
|
||||
+ } \
|
||||
+ return ret; \
|
||||
+ } \
|
||||
+ \
|
||||
+ static int nv_procfs_release_##name( \
|
||||
+ struct inode *inode, \
|
||||
+ struct file *filep \
|
||||
+ ) \
|
||||
+ { \
|
||||
+ close_callback(); \
|
||||
+ return single_release(inode, filep); \
|
||||
+ } \
|
||||
+ \
|
||||
+ static const struct proc_ops nv_procfs_##name##_fops = { \
|
||||
+ .proc_open = nv_procfs_open_##name, \
|
||||
+ .proc_read = seq_read, \
|
||||
+ .proc_lseek = seq_lseek, \
|
||||
+ .proc_release = nv_procfs_release_##name, \
|
||||
+ };
|
||||
+#else
|
||||
#define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
|
||||
static int nv_procfs_open_##name( \
|
||||
struct inode *inode, \
|
||||
@@ -114,6 +165,7 @@
|
||||
.llseek = seq_lseek, \
|
||||
.release = nv_procfs_release_##name, \
|
||||
};
|
||||
+#endif
|
||||
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
diff --git a/kernel/common/inc/nv-time.h b/kernel/common/inc/nv-time.h
|
||||
index 968b873..f03c7b0 100644
|
||||
--- a/kernel/common/inc/nv-time.h
|
||||
+++ b/kernel/common/inc/nv-time.h
|
||||
@@ -27,7 +27,12 @@
|
||||
|
||||
#include <linux/ktime.h>
|
||||
|
||||
-static inline void nv_gettimeofday(struct timeval *tv)
|
||||
+struct nv_timeval {
|
||||
+ __kernel_long_t tv_sec;
|
||||
+ __kernel_suseconds_t tv_usec;
|
||||
+};
|
||||
+
|
||||
+static inline void nv_gettimeofday(struct nv_timeval *tv)
|
||||
{
|
||||
#ifdef NV_DO_GETTIMEOFDAY_PRESENT
|
||||
do_gettimeofday(tv);
|
||||
@@ -36,7 +41,7 @@ static inline void nv_gettimeofday(struct timeval *tv)
|
||||
|
||||
ktime_get_real_ts64(&now);
|
||||
|
||||
- *tv = (struct timeval) {
|
||||
+ *tv = (struct nv_timeval) {
|
||||
.tv_sec = now.tv_sec,
|
||||
.tv_usec = now.tv_nsec/1000,
|
||||
};
|
||||
diff --git a/kernel/conftest.sh b/kernel/conftest.sh
|
||||
index 57d85a4..4eb703f 100755
|
||||
--- a/kernel/conftest.sh
|
||||
+++ b/kernel/conftest.sh
|
||||
@@ -806,6 +806,46 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_FILE_OPERATIONS_HAS_IOCTL" "" "types"
|
||||
;;
|
||||
|
||||
+ proc_ops)
|
||||
+ CODE="
|
||||
+ #include <linux/proc_fs.h>
|
||||
+ int conftest_proc_ops(void) {
|
||||
+ return offsetof(struct proc_ops, proc_open);
|
||||
+ }"
|
||||
+
|
||||
+ compile_check_conftest "$CODE" "NV_HAVE_PROC_OPS" "" "types"
|
||||
+ ;;
|
||||
+
|
||||
+ ktime_get_raw_ts64)
|
||||
+ #
|
||||
+ # Determine if the ktime_get_raw_ts64() function is present.
|
||||
+ #
|
||||
+ CODE="
|
||||
+ #include <linux/ktime.h>
|
||||
+ int conftest_ktime_get_raw_ts64(void) {
|
||||
+ struct timespec64 ts = {0};
|
||||
+
|
||||
+ ktime_get_raw_ts64(&ts64);
|
||||
+ }"
|
||||
+
|
||||
+ compile_check_conftest "$CODE" "NV_KTIME_GET_RAW_TS64_PRESENT" "" "functions"
|
||||
+ ;;
|
||||
+
|
||||
+ ktime_get_real_ts64)
|
||||
+ #
|
||||
+ # Determine if the ktime_get_real_ts64() function is present.
|
||||
+ #
|
||||
+ CODE="
|
||||
+ #include <linux/ktime.h>
|
||||
+ int conftest_ktime_get_raw_ts64(void) {
|
||||
+ struct timespec64 ts = {0};
|
||||
+
|
||||
+ ktime_get_real_ts64(&ts64);
|
||||
+ }"
|
||||
+
|
||||
+ compile_check_conftest "$CODE" "NV_KTIME_GET_REAL_TS64_PRESENT" "" "functions"
|
||||
+ ;;
|
||||
+
|
||||
sg_alloc_table)
|
||||
#
|
||||
# sg_alloc_table_from_pages added by commit efc42bc98058
|
||||
diff --git a/kernel/nvidia-modeset/nvidia-modeset-linux.c b/kernel/nvidia-modeset/nvidia-modeset-linux.c
|
||||
index 0ca2c7d..8902143 100644
|
||||
--- a/kernel/nvidia-modeset/nvidia-modeset-linux.c
|
||||
+++ b/kernel/nvidia-modeset/nvidia-modeset-linux.c
|
||||
@@ -266,7 +266,7 @@ void NVKMS_API_CALL nvkms_usleep(NvU64 usec)
|
||||
|
||||
NvU64 NVKMS_API_CALL nvkms_get_usec(void)
|
||||
{
|
||||
- struct timeval tv;
|
||||
+ struct nv_timeval tv;
|
||||
|
||||
nv_gettimeofday(&tv);
|
||||
|
||||
diff --git a/kernel/nvidia-uvm/uvm_linux.h b/kernel/nvidia-uvm/uvm_linux.h
|
||||
index 30a9dea..1a20eff 100644
|
||||
--- a/kernel/nvidia-uvm/uvm_linux.h
|
||||
+++ b/kernel/nvidia-uvm/uvm_linux.h
|
||||
@@ -301,7 +301,16 @@ static inline uint64_t NV_DIV64(uint64_t dividend, uint64_t divisor, uint64_t *r
|
||||
}
|
||||
#endif
|
||||
|
||||
-#if defined(CLOCK_MONOTONIC_RAW)
|
||||
+#if defined(NV_KTIME_GET_RAW_TS64_PRESENT)
|
||||
+static inline NvU64 NV_GETTIME(void)
|
||||
+{
|
||||
+ struct timespec64 ts;
|
||||
+
|
||||
+ ktime_get_raw_ts64(&ts);
|
||||
+
|
||||
+ return (ts.tv_sec * 1000000000ULL + ts.tv_nsec);
|
||||
+}
|
||||
+#elif defined(CLOCK_MONOTONIC_RAW)
|
||||
/* Return a nanosecond-precise value */
|
||||
static inline NvU64 NV_GETTIME(void)
|
||||
{
|
||||
@@ -317,7 +326,7 @@ static inline NvU64 NV_GETTIME(void)
|
||||
* available non-GPL symbols. */
|
||||
static inline NvU64 NV_GETTIME(void)
|
||||
{
|
||||
- struct timeval tv = {0};
|
||||
+ struct nv_timeval tv = {0};
|
||||
|
||||
nv_gettimeofday(&tv);
|
||||
|
||||
diff --git a/kernel/nvidia/linux_nvswitch.c b/kernel/nvidia/linux_nvswitch.c
|
||||
index 1d2c1bc..0a0b4e8 100644
|
||||
--- a/kernel/nvidia/linux_nvswitch.c
|
||||
+++ b/kernel/nvidia/linux_nvswitch.c
|
||||
@@ -1578,10 +1578,17 @@ nvswitch_os_get_platform_time
|
||||
void
|
||||
)
|
||||
{
|
||||
+#if defined(NV_KTIME_GET_REAL_TS64_PRESENT)
|
||||
+ struct timespec64 ts64;
|
||||
+
|
||||
+ ktime_get_real_ts64(&ts64);
|
||||
+ return ((NvU64)(ts64.tv_sec * NSEC_PER_SEC) + ts64.tv_nsec);
|
||||
+#else
|
||||
struct timespec ts;
|
||||
|
||||
getnstimeofday(&ts);
|
||||
return ((NvU64) timespec_to_ns(&ts));
|
||||
+#endif
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/kernel/nvidia/nv-procfs.c b/kernel/nvidia/nv-procfs.c
|
||||
index 064d727..a7308d3 100644
|
||||
--- a/kernel/nvidia/nv-procfs.c
|
||||
+++ b/kernel/nvidia/nv-procfs.c
|
||||
@@ -452,6 +452,15 @@ done:
|
||||
return ((status < 0) ? status : (int)count);
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_registry_fops = {
|
||||
+ .proc_open = nv_procfs_open_registry,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_registry,
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_registry_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_registry,
|
||||
@@ -460,6 +469,7 @@ static struct file_operations nv_procfs_registry_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = nv_procfs_close_registry,
|
||||
};
|
||||
+#endif
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
static int
|
||||
@@ -531,6 +541,15 @@ nv_procfs_open_suspend_depth(
|
||||
return single_open(file, nv_procfs_show_suspend_depth, NULL);
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_suspend_depth_fops = {
|
||||
+ .proc_open = nv_procfs_open_suspend_depth,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_suspend_depth,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_suspend_depth_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_suspend_depth,
|
||||
@@ -539,6 +558,7 @@ static struct file_operations nv_procfs_suspend_depth_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release
|
||||
};
|
||||
+#endif
|
||||
|
||||
static int
|
||||
nv_procfs_show_suspend(
|
||||
@@ -613,6 +633,15 @@ nv_procfs_open_suspend(
|
||||
return single_open(file, nv_procfs_show_suspend, NULL);
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_suspend_fops = {
|
||||
+ .proc_open = nv_procfs_open_suspend,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_suspend,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_suspend_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_suspend,
|
||||
@@ -622,6 +651,7 @@ static struct file_operations nv_procfs_suspend_fops = {
|
||||
.release = single_release
|
||||
};
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Forwards error to nv_log_error which exposes data to vendor callback
|
||||
@@ -724,12 +754,20 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_exercise_error_forwarding_fops = {
|
||||
+ .proc_open = nv_procfs_open_exercise_error_forwarding,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_release = nv_procfs_close_exercise_error_forwarding,
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_exercise_error_forwarding_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_exercise_error_forwarding,
|
||||
.write = nv_procfs_write_file,
|
||||
.release = nv_procfs_close_exercise_error_forwarding,
|
||||
};
|
||||
+#endif
|
||||
|
||||
static int
|
||||
nv_procfs_read_unbind_lock(
|
||||
@@ -851,6 +889,15 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_unbind_lock_fops = {
|
||||
+ .proc_open = nv_procfs_open_unbind_lock,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_unbind_lock,
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_unbind_lock_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_unbind_lock,
|
||||
@@ -859,6 +906,7 @@ static struct file_operations nv_procfs_unbind_lock_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = nv_procfs_close_unbind_lock,
|
||||
};
|
||||
+#endif
|
||||
|
||||
static const char*
|
||||
numa_status_describe(nv_numa_status_t state)
|
||||
@@ -1187,6 +1235,22 @@ done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static const struct proc_ops nv_procfs_numa_status_fops = {
|
||||
+ .proc_open = nv_procfs_open_numa_status,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_numa_status,
|
||||
+};
|
||||
+
|
||||
+static const struct proc_ops nv_procfs_offline_pages_fops = {
|
||||
+ .proc_open = nv_procfs_open_offline_pages,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_offline_pages,
|
||||
+};
|
||||
+#else
|
||||
static const struct file_operations nv_procfs_numa_status_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_numa_status,
|
||||
@@ -1203,6 +1267,7 @@ static const struct file_operations nv_procfs_offline_pages_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = nv_procfs_close_offline_pages,
|
||||
};
|
||||
+#endif
|
||||
|
||||
static int
|
||||
nv_procfs_read_text_file(
|
||||
diff --git a/kernel/nvidia/nvidia.Kbuild b/kernel/nvidia/nvidia.Kbuild
|
||||
index 5ec3e65..339a757 100644
|
||||
--- a/kernel/nvidia/nvidia.Kbuild
|
||||
+++ b/kernel/nvidia/nvidia.Kbuild
|
||||
@@ -150,6 +150,9 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_swiotlb_dma_ops
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += acpi_op_remove
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += outer_flush_all
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += file_operations
|
||||
+NV_CONFTEST_TYPE_COMPILE_TESTS += proc_ops
|
||||
+NV_CONFTEST_TYPE_COMPILE_TESTS += ktime_get_raw_ts64
|
||||
+NV_CONFTEST_TYPE_COMPILE_TESTS += ktime_get_real_ts64
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += file_inode
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += kuid_t
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops
|
||||
diff --git a/kernel/nvidia/nvlink_linux.c b/kernel/nvidia/nvlink_linux.c
|
||||
index c84b36a..54fe244 100644
|
||||
--- a/kernel/nvidia/nvlink_linux.c
|
||||
+++ b/kernel/nvidia/nvlink_linux.c
|
||||
@@ -513,8 +513,8 @@ int NVLINK_API_CALL nvlink_memcmp(const void *s1, const void *s2, NvLength size)
|
||||
|
||||
static NvBool nv_timer_less_than
|
||||
(
|
||||
- const struct timeval *a,
|
||||
- const struct timeval *b
|
||||
+ const struct nv_timeval *a,
|
||||
+ const struct nv_timeval *b
|
||||
)
|
||||
{
|
||||
return (a->tv_sec == b->tv_sec) ? (a->tv_usec < b->tv_usec)
|
||||
@@ -523,9 +523,9 @@ static NvBool nv_timer_less_than
|
||||
|
||||
static void nv_timeradd
|
||||
(
|
||||
- const struct timeval *a,
|
||||
- const struct timeval *b,
|
||||
- struct timeval *result
|
||||
+ const struct nv_timeval *a,
|
||||
+ const struct nv_timeval *b,
|
||||
+ struct nv_timeval *result
|
||||
)
|
||||
{
|
||||
result->tv_sec = a->tv_sec + b->tv_sec;
|
||||
@@ -539,9 +539,9 @@ static void nv_timeradd
|
||||
|
||||
static void nv_timersub
|
||||
(
|
||||
- const struct timeval *a,
|
||||
- const struct timeval *b,
|
||||
- struct timeval *result
|
||||
+ const struct nv_timeval *a,
|
||||
+ const struct nv_timeval *b,
|
||||
+ struct nv_timeval *result
|
||||
)
|
||||
{
|
||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||
@@ -561,7 +561,7 @@ void NVLINK_API_CALL nvlink_sleep(unsigned int ms)
|
||||
unsigned long us;
|
||||
unsigned long jiffies;
|
||||
unsigned long mdelay_safe_msec;
|
||||
- struct timeval tm_end, tm_aux;
|
||||
+ struct nv_timeval tm_end, tm_aux;
|
||||
|
||||
nv_gettimeofday(&tm_aux);
|
||||
|
||||
diff --git a/kernel/nvidia/os-interface.c b/kernel/nvidia/os-interface.c
|
||||
index 07f1b77..239be58 100644
|
||||
--- a/kernel/nvidia/os-interface.c
|
||||
+++ b/kernel/nvidia/os-interface.c
|
||||
@@ -463,7 +463,7 @@ NV_STATUS NV_API_CALL os_get_current_time(
|
||||
NvU32 *useconds
|
||||
)
|
||||
{
|
||||
- struct timeval tm;
|
||||
+ struct nv_timeval tm;
|
||||
|
||||
nv_gettimeofday(&tm);
|
||||
|
||||
@@ -477,9 +477,15 @@ NV_STATUS NV_API_CALL os_get_current_time(
|
||||
|
||||
void NV_API_CALL os_get_current_tick(NvU64 *nseconds)
|
||||
{
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
|
||||
+ struct timespec64 ts;
|
||||
+
|
||||
+ jiffies_to_timespec64(jiffies, &ts);
|
||||
+#else
|
||||
struct timespec ts;
|
||||
|
||||
jiffies_to_timespec(jiffies, &ts);
|
||||
+#endif
|
||||
|
||||
*nseconds = ((NvU64)ts.tv_sec * NSEC_PER_SEC + (NvU64)ts.tv_nsec);
|
||||
}
|
||||
@@ -549,7 +555,7 @@ NV_STATUS NV_API_CALL os_delay_us(NvU32 MicroSeconds)
|
||||
unsigned long usec;
|
||||
|
||||
#ifdef NV_CHECK_DELAY_ACCURACY
|
||||
- struct timeval tm1, tm2;
|
||||
+ struct nv_timeval tm1, tm2;
|
||||
|
||||
nv_gettimeofday(&tm1);
|
||||
#endif
|
||||
@@ -589,9 +595,9 @@ NV_STATUS NV_API_CALL os_delay(NvU32 MilliSeconds)
|
||||
unsigned long MicroSeconds;
|
||||
unsigned long jiffies;
|
||||
unsigned long mdelay_safe_msec;
|
||||
- struct timeval tm_end, tm_aux;
|
||||
+ struct nv_timeval tm_end, tm_aux;
|
||||
#ifdef NV_CHECK_DELAY_ACCURACY
|
||||
- struct timeval tm_start;
|
||||
+ struct nv_timeval tm_start;
|
||||
#endif
|
||||
|
||||
nv_gettimeofday(&tm_aux);
|
||||
@@ -1954,7 +1960,7 @@ static NV_STATUS NV_API_CALL _os_ipmi_receive_resp
|
||||
{
|
||||
struct ipmi_recv_msg *rx_msg;
|
||||
int err_no;
|
||||
- struct timeval tv;
|
||||
+ struct nv_timeval tv;
|
||||
NvU64 start_time;
|
||||
|
||||
nv_gettimeofday(&tv);
|
503
patches/x11-drivers/nvidia-drivers-440.66.04/kernel-5.6.patch
Normal file
503
patches/x11-drivers/nvidia-drivers-440.66.04/kernel-5.6.patch
Normal file
@ -0,0 +1,503 @@
|
||||
diff --git a/kernel/common/inc/nv-procfs.h b/kernel/common/inc/nv-procfs.h
|
||||
index 8b53f86..4c5aceb 100644
|
||||
--- a/kernel/common/inc/nv-procfs.h
|
||||
+++ b/kernel/common/inc/nv-procfs.h
|
||||
@@ -28,6 +28,18 @@
|
||||
|
||||
#define IS_EXERCISE_ERROR_FORWARDING_ENABLED() (EXERCISE_ERROR_FORWARDING)
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
|
||||
+ ({ \
|
||||
+ struct proc_dir_entry *__entry; \
|
||||
+ int mode = (S_IFREG | S_IRUGO); \
|
||||
+ const struct proc_ops *fops = &nv_procfs_##__name##_fops; \
|
||||
+ if (fops->proc_write != 0) \
|
||||
+ mode |= S_IWUSR; \
|
||||
+ __entry = proc_create_data(filename, mode, parent, fops, __data);\
|
||||
+ __entry; \
|
||||
+ })
|
||||
+#else
|
||||
#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
|
||||
({ \
|
||||
struct proc_dir_entry *__entry; \
|
||||
@@ -38,6 +50,7 @@
|
||||
__entry = proc_create_data(filename, mode, parent, fops, __data);\
|
||||
__entry; \
|
||||
})
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0.
|
||||
@@ -77,6 +90,44 @@
|
||||
remove_proc_entry(entry->name, entry->parent);
|
||||
#endif
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+#define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
|
||||
+ static int nv_procfs_open_##name( \
|
||||
+ struct inode *inode, \
|
||||
+ struct file *filep \
|
||||
+ ) \
|
||||
+ { \
|
||||
+ int ret; \
|
||||
+ ret = single_open(filep, nv_procfs_read_##name, \
|
||||
+ NV_PDE_DATA(inode)); \
|
||||
+ if (ret < 0) \
|
||||
+ { \
|
||||
+ return ret; \
|
||||
+ } \
|
||||
+ ret = open_callback(); \
|
||||
+ if (ret < 0) \
|
||||
+ { \
|
||||
+ single_release(inode, filep); \
|
||||
+ } \
|
||||
+ return ret; \
|
||||
+ } \
|
||||
+ \
|
||||
+ static int nv_procfs_release_##name( \
|
||||
+ struct inode *inode, \
|
||||
+ struct file *filep \
|
||||
+ ) \
|
||||
+ { \
|
||||
+ close_callback(); \
|
||||
+ return single_release(inode, filep); \
|
||||
+ } \
|
||||
+ \
|
||||
+ static const struct proc_ops nv_procfs_##name##_fops = { \
|
||||
+ .proc_open = nv_procfs_open_##name, \
|
||||
+ .proc_read = seq_read, \
|
||||
+ .proc_lseek = seq_lseek, \
|
||||
+ .proc_release = nv_procfs_release_##name, \
|
||||
+ };
|
||||
+#else
|
||||
#define NV_DEFINE_SINGLE_PROCFS_FILE(name, open_callback, close_callback) \
|
||||
static int nv_procfs_open_##name( \
|
||||
struct inode *inode, \
|
||||
@@ -114,6 +165,7 @@
|
||||
.llseek = seq_lseek, \
|
||||
.release = nv_procfs_release_##name, \
|
||||
};
|
||||
+#endif
|
||||
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
diff --git a/kernel/common/inc/nv-time.h b/kernel/common/inc/nv-time.h
|
||||
index 968b873..f03c7b0 100644
|
||||
--- a/kernel/common/inc/nv-time.h
|
||||
+++ b/kernel/common/inc/nv-time.h
|
||||
@@ -27,7 +27,12 @@
|
||||
|
||||
#include <linux/ktime.h>
|
||||
|
||||
-static inline void nv_gettimeofday(struct timeval *tv)
|
||||
+struct nv_timeval {
|
||||
+ __kernel_long_t tv_sec;
|
||||
+ __kernel_suseconds_t tv_usec;
|
||||
+};
|
||||
+
|
||||
+static inline void nv_gettimeofday(struct nv_timeval *tv)
|
||||
{
|
||||
#ifdef NV_DO_GETTIMEOFDAY_PRESENT
|
||||
do_gettimeofday(tv);
|
||||
@@ -36,7 +41,7 @@ static inline void nv_gettimeofday(struct timeval *tv)
|
||||
|
||||
ktime_get_real_ts64(&now);
|
||||
|
||||
- *tv = (struct timeval) {
|
||||
+ *tv = (struct nv_timeval) {
|
||||
.tv_sec = now.tv_sec,
|
||||
.tv_usec = now.tv_nsec/1000,
|
||||
};
|
||||
diff --git a/kernel/conftest.sh b/kernel/conftest.sh
|
||||
index 57d85a4..4eb703f 100755
|
||||
--- a/kernel/conftest.sh
|
||||
+++ b/kernel/conftest.sh
|
||||
@@ -806,6 +806,46 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_FILE_OPERATIONS_HAS_IOCTL" "" "types"
|
||||
;;
|
||||
|
||||
+ proc_ops)
|
||||
+ CODE="
|
||||
+ #include <linux/proc_fs.h>
|
||||
+ int conftest_proc_ops(void) {
|
||||
+ return offsetof(struct proc_ops, proc_open);
|
||||
+ }"
|
||||
+
|
||||
+ compile_check_conftest "$CODE" "NV_HAVE_PROC_OPS" "" "types"
|
||||
+ ;;
|
||||
+
|
||||
+ ktime_get_raw_ts64)
|
||||
+ #
|
||||
+ # Determine if the ktime_get_raw_ts64() function is present.
|
||||
+ #
|
||||
+ CODE="
|
||||
+ #include <linux/ktime.h>
|
||||
+ int conftest_ktime_get_raw_ts64(void) {
|
||||
+ struct timespec64 ts = {0};
|
||||
+
|
||||
+ ktime_get_raw_ts64(&ts64);
|
||||
+ }"
|
||||
+
|
||||
+ compile_check_conftest "$CODE" "NV_KTIME_GET_RAW_TS64_PRESENT" "" "functions"
|
||||
+ ;;
|
||||
+
|
||||
+ ktime_get_real_ts64)
|
||||
+ #
|
||||
+ # Determine if the ktime_get_real_ts64() function is present.
|
||||
+ #
|
||||
+ CODE="
|
||||
+ #include <linux/ktime.h>
|
||||
+ int conftest_ktime_get_raw_ts64(void) {
|
||||
+ struct timespec64 ts = {0};
|
||||
+
|
||||
+ ktime_get_real_ts64(&ts64);
|
||||
+ }"
|
||||
+
|
||||
+ compile_check_conftest "$CODE" "NV_KTIME_GET_REAL_TS64_PRESENT" "" "functions"
|
||||
+ ;;
|
||||
+
|
||||
sg_alloc_table)
|
||||
#
|
||||
# sg_alloc_table_from_pages added by commit efc42bc98058
|
||||
diff --git a/kernel/nvidia-modeset/nvidia-modeset-linux.c b/kernel/nvidia-modeset/nvidia-modeset-linux.c
|
||||
index 0ca2c7d..8902143 100644
|
||||
--- a/kernel/nvidia-modeset/nvidia-modeset-linux.c
|
||||
+++ b/kernel/nvidia-modeset/nvidia-modeset-linux.c
|
||||
@@ -266,7 +266,7 @@ void NVKMS_API_CALL nvkms_usleep(NvU64 usec)
|
||||
|
||||
NvU64 NVKMS_API_CALL nvkms_get_usec(void)
|
||||
{
|
||||
- struct timeval tv;
|
||||
+ struct nv_timeval tv;
|
||||
|
||||
nv_gettimeofday(&tv);
|
||||
|
||||
diff --git a/kernel/nvidia-uvm/uvm_linux.h b/kernel/nvidia-uvm/uvm_linux.h
|
||||
index 30a9dea..1a20eff 100644
|
||||
--- a/kernel/nvidia-uvm/uvm_linux.h
|
||||
+++ b/kernel/nvidia-uvm/uvm_linux.h
|
||||
@@ -301,7 +301,16 @@ static inline uint64_t NV_DIV64(uint64_t dividend, uint64_t divisor, uint64_t *r
|
||||
}
|
||||
#endif
|
||||
|
||||
-#if defined(CLOCK_MONOTONIC_RAW)
|
||||
+#if defined(NV_KTIME_GET_RAW_TS64_PRESENT)
|
||||
+static inline NvU64 NV_GETTIME(void)
|
||||
+{
|
||||
+ struct timespec64 ts;
|
||||
+
|
||||
+ ktime_get_raw_ts64(&ts);
|
||||
+
|
||||
+ return (ts.tv_sec * 1000000000ULL + ts.tv_nsec);
|
||||
+}
|
||||
+#elif defined(CLOCK_MONOTONIC_RAW)
|
||||
/* Return a nanosecond-precise value */
|
||||
static inline NvU64 NV_GETTIME(void)
|
||||
{
|
||||
@@ -317,7 +326,7 @@ static inline NvU64 NV_GETTIME(void)
|
||||
* available non-GPL symbols. */
|
||||
static inline NvU64 NV_GETTIME(void)
|
||||
{
|
||||
- struct timeval tv = {0};
|
||||
+ struct nv_timeval tv = {0};
|
||||
|
||||
nv_gettimeofday(&tv);
|
||||
|
||||
diff --git a/kernel/nvidia/linux_nvswitch.c b/kernel/nvidia/linux_nvswitch.c
|
||||
index 1d2c1bc..0a0b4e8 100644
|
||||
--- a/kernel/nvidia/linux_nvswitch.c
|
||||
+++ b/kernel/nvidia/linux_nvswitch.c
|
||||
@@ -1578,10 +1578,17 @@ nvswitch_os_get_platform_time
|
||||
void
|
||||
)
|
||||
{
|
||||
+#if defined(NV_KTIME_GET_REAL_TS64_PRESENT)
|
||||
+ struct timespec64 ts64;
|
||||
+
|
||||
+ ktime_get_real_ts64(&ts64);
|
||||
+ return ((NvU64)(ts64.tv_sec * NSEC_PER_SEC) + ts64.tv_nsec);
|
||||
+#else
|
||||
struct timespec ts;
|
||||
|
||||
getnstimeofday(&ts);
|
||||
return ((NvU64) timespec_to_ns(&ts));
|
||||
+#endif
|
||||
}
|
||||
|
||||
void
|
||||
diff --git a/kernel/nvidia/nv-procfs.c b/kernel/nvidia/nv-procfs.c
|
||||
index 064d727..a7308d3 100644
|
||||
--- a/kernel/nvidia/nv-procfs.c
|
||||
+++ b/kernel/nvidia/nv-procfs.c
|
||||
@@ -452,6 +452,15 @@ done:
|
||||
return ((status < 0) ? status : (int)count);
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_registry_fops = {
|
||||
+ .proc_open = nv_procfs_open_registry,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_registry,
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_registry_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_registry,
|
||||
@@ -460,6 +469,7 @@ static struct file_operations nv_procfs_registry_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = nv_procfs_close_registry,
|
||||
};
|
||||
+#endif
|
||||
|
||||
#if defined(CONFIG_PM)
|
||||
static int
|
||||
@@ -531,6 +541,15 @@ nv_procfs_open_suspend_depth(
|
||||
return single_open(file, nv_procfs_show_suspend_depth, NULL);
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_suspend_depth_fops = {
|
||||
+ .proc_open = nv_procfs_open_suspend_depth,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_suspend_depth,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_suspend_depth_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_suspend_depth,
|
||||
@@ -539,6 +558,7 @@ static struct file_operations nv_procfs_suspend_depth_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release
|
||||
};
|
||||
+#endif
|
||||
|
||||
static int
|
||||
nv_procfs_show_suspend(
|
||||
@@ -613,6 +633,15 @@ nv_procfs_open_suspend(
|
||||
return single_open(file, nv_procfs_show_suspend, NULL);
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_suspend_fops = {
|
||||
+ .proc_open = nv_procfs_open_suspend,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_suspend,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_suspend_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_suspend,
|
||||
@@ -622,6 +651,7 @@ static struct file_operations nv_procfs_suspend_fops = {
|
||||
.release = single_release
|
||||
};
|
||||
#endif
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Forwards error to nv_log_error which exposes data to vendor callback
|
||||
@@ -724,12 +754,20 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_exercise_error_forwarding_fops = {
|
||||
+ .proc_open = nv_procfs_open_exercise_error_forwarding,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_release = nv_procfs_close_exercise_error_forwarding,
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_exercise_error_forwarding_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_exercise_error_forwarding,
|
||||
.write = nv_procfs_write_file,
|
||||
.release = nv_procfs_close_exercise_error_forwarding,
|
||||
};
|
||||
+#endif
|
||||
|
||||
static int
|
||||
nv_procfs_read_unbind_lock(
|
||||
@@ -851,6 +889,15 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static struct proc_ops nv_procfs_unbind_lock_fops = {
|
||||
+ .proc_open = nv_procfs_open_unbind_lock,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_unbind_lock,
|
||||
+};
|
||||
+#else
|
||||
static struct file_operations nv_procfs_unbind_lock_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_unbind_lock,
|
||||
@@ -859,6 +906,7 @@ static struct file_operations nv_procfs_unbind_lock_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = nv_procfs_close_unbind_lock,
|
||||
};
|
||||
+#endif
|
||||
|
||||
static const char*
|
||||
numa_status_describe(nv_numa_status_t state)
|
||||
@@ -1187,6 +1235,22 @@ done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+#if defined(NV_HAVE_PROC_OPS)
|
||||
+static const struct proc_ops nv_procfs_numa_status_fops = {
|
||||
+ .proc_open = nv_procfs_open_numa_status,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_write = nv_procfs_write_file,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_numa_status,
|
||||
+};
|
||||
+
|
||||
+static const struct proc_ops nv_procfs_offline_pages_fops = {
|
||||
+ .proc_open = nv_procfs_open_offline_pages,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = nv_procfs_close_offline_pages,
|
||||
+};
|
||||
+#else
|
||||
static const struct file_operations nv_procfs_numa_status_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = nv_procfs_open_numa_status,
|
||||
@@ -1203,6 +1267,7 @@ static const struct file_operations nv_procfs_offline_pages_fops = {
|
||||
.llseek = seq_lseek,
|
||||
.release = nv_procfs_close_offline_pages,
|
||||
};
|
||||
+#endif
|
||||
|
||||
static int
|
||||
nv_procfs_read_text_file(
|
||||
diff --git a/kernel/nvidia/nvidia.Kbuild b/kernel/nvidia/nvidia.Kbuild
|
||||
index 5ec3e65..339a757 100644
|
||||
--- a/kernel/nvidia/nvidia.Kbuild
|
||||
+++ b/kernel/nvidia/nvidia.Kbuild
|
||||
@@ -150,6 +150,9 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_swiotlb_dma_ops
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += acpi_op_remove
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += outer_flush_all
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += file_operations
|
||||
+NV_CONFTEST_TYPE_COMPILE_TESTS += proc_ops
|
||||
+NV_CONFTEST_TYPE_COMPILE_TESTS += ktime_get_raw_ts64
|
||||
+NV_CONFTEST_TYPE_COMPILE_TESTS += ktime_get_real_ts64
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += file_inode
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += kuid_t
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops
|
||||
diff --git a/kernel/nvidia/nvlink_linux.c b/kernel/nvidia/nvlink_linux.c
|
||||
index c84b36a..54fe244 100644
|
||||
--- a/kernel/nvidia/nvlink_linux.c
|
||||
+++ b/kernel/nvidia/nvlink_linux.c
|
||||
@@ -513,8 +513,8 @@ int NVLINK_API_CALL nvlink_memcmp(const void *s1, const void *s2, NvLength size)
|
||||
|
||||
static NvBool nv_timer_less_than
|
||||
(
|
||||
- const struct timeval *a,
|
||||
- const struct timeval *b
|
||||
+ const struct nv_timeval *a,
|
||||
+ const struct nv_timeval *b
|
||||
)
|
||||
{
|
||||
return (a->tv_sec == b->tv_sec) ? (a->tv_usec < b->tv_usec)
|
||||
@@ -523,9 +523,9 @@ static NvBool nv_timer_less_than
|
||||
|
||||
static void nv_timeradd
|
||||
(
|
||||
- const struct timeval *a,
|
||||
- const struct timeval *b,
|
||||
- struct timeval *result
|
||||
+ const struct nv_timeval *a,
|
||||
+ const struct nv_timeval *b,
|
||||
+ struct nv_timeval *result
|
||||
)
|
||||
{
|
||||
result->tv_sec = a->tv_sec + b->tv_sec;
|
||||
@@ -539,9 +539,9 @@ static void nv_timeradd
|
||||
|
||||
static void nv_timersub
|
||||
(
|
||||
- const struct timeval *a,
|
||||
- const struct timeval *b,
|
||||
- struct timeval *result
|
||||
+ const struct nv_timeval *a,
|
||||
+ const struct nv_timeval *b,
|
||||
+ struct nv_timeval *result
|
||||
)
|
||||
{
|
||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||
@@ -561,7 +561,7 @@ void NVLINK_API_CALL nvlink_sleep(unsigned int ms)
|
||||
unsigned long us;
|
||||
unsigned long jiffies;
|
||||
unsigned long mdelay_safe_msec;
|
||||
- struct timeval tm_end, tm_aux;
|
||||
+ struct nv_timeval tm_end, tm_aux;
|
||||
|
||||
nv_gettimeofday(&tm_aux);
|
||||
|
||||
diff --git a/kernel/nvidia/os-interface.c b/kernel/nvidia/os-interface.c
|
||||
index 07f1b77..239be58 100644
|
||||
--- a/kernel/nvidia/os-interface.c
|
||||
+++ b/kernel/nvidia/os-interface.c
|
||||
@@ -463,7 +463,7 @@ NV_STATUS NV_API_CALL os_get_current_time(
|
||||
NvU32 *useconds
|
||||
)
|
||||
{
|
||||
- struct timeval tm;
|
||||
+ struct nv_timeval tm;
|
||||
|
||||
nv_gettimeofday(&tm);
|
||||
|
||||
@@ -477,9 +477,15 @@ NV_STATUS NV_API_CALL os_get_current_time(
|
||||
|
||||
void NV_API_CALL os_get_current_tick(NvU64 *nseconds)
|
||||
{
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
|
||||
+ struct timespec64 ts;
|
||||
+
|
||||
+ jiffies_to_timespec64(jiffies, &ts);
|
||||
+#else
|
||||
struct timespec ts;
|
||||
|
||||
jiffies_to_timespec(jiffies, &ts);
|
||||
+#endif
|
||||
|
||||
*nseconds = ((NvU64)ts.tv_sec * NSEC_PER_SEC + (NvU64)ts.tv_nsec);
|
||||
}
|
||||
@@ -549,7 +555,7 @@ NV_STATUS NV_API_CALL os_delay_us(NvU32 MicroSeconds)
|
||||
unsigned long usec;
|
||||
|
||||
#ifdef NV_CHECK_DELAY_ACCURACY
|
||||
- struct timeval tm1, tm2;
|
||||
+ struct nv_timeval tm1, tm2;
|
||||
|
||||
nv_gettimeofday(&tm1);
|
||||
#endif
|
||||
@@ -589,9 +595,9 @@ NV_STATUS NV_API_CALL os_delay(NvU32 MilliSeconds)
|
||||
unsigned long MicroSeconds;
|
||||
unsigned long jiffies;
|
||||
unsigned long mdelay_safe_msec;
|
||||
- struct timeval tm_end, tm_aux;
|
||||
+ struct nv_timeval tm_end, tm_aux;
|
||||
#ifdef NV_CHECK_DELAY_ACCURACY
|
||||
- struct timeval tm_start;
|
||||
+ struct nv_timeval tm_start;
|
||||
#endif
|
||||
|
||||
nv_gettimeofday(&tm_aux);
|
||||
@@ -1954,7 +1960,7 @@ static NV_STATUS NV_API_CALL _os_ipmi_receive_resp
|
||||
{
|
||||
struct ipmi_recv_msg *rx_msg;
|
||||
int err_no;
|
||||
- struct timeval tv;
|
||||
+ struct nv_timeval tv;
|
||||
NvU64 start_time;
|
||||
|
||||
nv_gettimeofday(&tv);
|
23
patches/x11-drivers/nvidia-drivers-440.82-r3/patch.diff
Normal file
23
patches/x11-drivers/nvidia-drivers-440.82-r3/patch.diff
Normal file
@ -0,0 +1,23 @@
|
||||
diff --git a/kernel/conftest.sh b/kernel/conftest.sh
|
||||
index 8f807a1..af29636 100755
|
||||
--- a/kernel/conftest.sh
|
||||
+++ b/kernel/conftest.sh
|
||||
@@ -143,6 +143,7 @@ test_headers() {
|
||||
FILES="$FILES video/nv_internal.h"
|
||||
FILES="$FILES asm/book3s/64/hash-64k.h"
|
||||
FILES="$FILES asm/set_memory.h"
|
||||
+ FILES="$FILES asm/pgtable.h"
|
||||
FILES="$FILES asm/prom.h"
|
||||
FILES="$FILES asm/powernv.h"
|
||||
FILES="$FILES asm/tlbflush.h"
|
||||
@@ -466,6 +467,9 @@ compile_test() {
|
||||
# It does not exist on all architectures.
|
||||
#
|
||||
CODE="
|
||||
+ #if defined(NV_ASM_PGTABLE_H_PRESENT)
|
||||
+ #include <asm/pgtable.h>
|
||||
+ #endif
|
||||
#if defined(NV_ASM_SET_MEMORY_H_PRESENT)
|
||||
#include <asm/set_memory.h>
|
||||
#else
|
||||
|
@ -0,0 +1,738 @@
|
||||
From 7808631e7a9a605d5fe7a1077129c658d9ec47fc Mon Sep 17 00:00:00 2001
|
||||
From: Maxime Coste <mawww@kakoune.org>
|
||||
Date: Tue, 22 Oct 2019 22:46:49 +1100
|
||||
Subject: [PATCH] Add support for BGRA glyphs display and scaling
|
||||
|
||||
Display is done using an XRender Picture, as XRender
|
||||
glyphs are incompatible with BGRA rendering due to
|
||||
their use of the glyph bitmap as a mask.
|
||||
|
||||
Scaling is done by averaging all relevant pixel, which gives
|
||||
much better result than nearest pixel sampling while staying
|
||||
simple enough and not too computationally expensive.
|
||||
|
||||
This enables color emoji rendering support.
|
||||
|
||||
Fixes: #6
|
||||
|
||||
Signed-off-by: Maxime Coste <mawww@kakoune.org>
|
||||
---
|
||||
src/xftfreetype.c | 18 ++++-
|
||||
src/xftglyphs.c | 200 ++++++++++++++++++++++++++++++++++++++++++----
|
||||
src/xftint.h | 2 +
|
||||
src/xftrender.c | 168 ++++++++++++++++++++++++--------------
|
||||
4 files changed, 307 insertions(+), 81 deletions(-)
|
||||
|
||||
diff --git a/src/xftfreetype.c b/src/xftfreetype.c
|
||||
index a3b8332..a639a03 100644
|
||||
--- a/src/xftfreetype.c
|
||||
+++ b/src/xftfreetype.c
|
||||
@@ -514,7 +514,7 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
|
||||
/*
|
||||
* Compute glyph load flags
|
||||
*/
|
||||
- fi->load_flags = FT_LOAD_DEFAULT;
|
||||
+ fi->load_flags = FT_LOAD_DEFAULT | FT_LOAD_COLOR;
|
||||
|
||||
#ifndef XFT_EMBEDDED_BITMAP
|
||||
#define XFT_EMBEDDED_BITMAP "embeddedbitmap"
|
||||
@@ -766,6 +766,7 @@ XftFontOpenInfo (Display *dpy,
|
||||
FcChar32 hash_value;
|
||||
FcChar32 rehash_value;
|
||||
FcBool antialias;
|
||||
+ FcBool color;
|
||||
int max_glyph_memory;
|
||||
int alloc_size;
|
||||
int ascent, descent, height;
|
||||
@@ -822,12 +823,16 @@ XftFontOpenInfo (Display *dpy,
|
||||
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
|
||||
antialias = FcFalse;
|
||||
|
||||
+ color = FT_HAS_COLOR(face) ? FcTrue : FcFalse;
|
||||
+
|
||||
/*
|
||||
* Find the appropriate picture format
|
||||
*/
|
||||
if (fi->render)
|
||||
{
|
||||
- if (antialias)
|
||||
+ if (color)
|
||||
+ format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
|
||||
+ else if (antialias)
|
||||
{
|
||||
switch (fi->rgba) {
|
||||
case FC_RGBA_RGB:
|
||||
@@ -842,9 +847,7 @@ XftFontOpenInfo (Display *dpy,
|
||||
}
|
||||
}
|
||||
else
|
||||
- {
|
||||
format = XRenderFindStandardFormat (dpy, PictStandardA1);
|
||||
- }
|
||||
|
||||
if (!format)
|
||||
goto bail2;
|
||||
@@ -959,6 +962,13 @@ XftFontOpenInfo (Display *dpy,
|
||||
* which doesn't happen in XftFontInfoFill
|
||||
*/
|
||||
font->info.antialias = antialias;
|
||||
+
|
||||
+ /*
|
||||
+ * Set color value, which is only known once the
|
||||
+ * font was loaded
|
||||
+ */
|
||||
+ font->info.color = color;
|
||||
+
|
||||
/*
|
||||
* bump XftFile reference count
|
||||
*/
|
||||
diff --git a/src/xftglyphs.c b/src/xftglyphs.c
|
||||
index 4b5fb82..af2e3c1 100644
|
||||
--- a/src/xftglyphs.c
|
||||
+++ b/src/xftglyphs.c
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include FT_SYNTHESIS_H
|
||||
|
||||
+#include FT_GLYPH_H
|
||||
+
|
||||
/*
|
||||
* Validate the memory info for a font
|
||||
*/
|
||||
@@ -78,9 +80,11 @@ _XftFontValidateMemory (Display *dpy, XftFont *public)
|
||||
static int
|
||||
_compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
FT_GlyphSlot slot,
|
||||
- FT_Render_Mode mode )
|
||||
+ FT_Render_Mode mode,
|
||||
+ FT_Matrix* matrix )
|
||||
{
|
||||
FT_Bitmap* ftbit;
|
||||
+ FT_Vector vector;
|
||||
int width, height, pitch;
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
@@ -88,9 +92,18 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
|
||||
// compute the size of the final bitmap
|
||||
ftbit = &slot->bitmap;
|
||||
-
|
||||
width = ftbit->width;
|
||||
height = ftbit->rows;
|
||||
+
|
||||
+ if ( matrix && mode == FT_RENDER_MODE_NORMAL )
|
||||
+ {
|
||||
+ vector.x = ftbit->width;
|
||||
+ vector.y = ftbit->rows;
|
||||
+ FT_Vector_Transform(&vector, matrix);
|
||||
+
|
||||
+ width = vector.x;
|
||||
+ height = vector.y;
|
||||
+ }
|
||||
pitch = (width+3) & ~3;
|
||||
|
||||
switch ( ftbit->pixel_mode )
|
||||
@@ -112,6 +125,10 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
}
|
||||
break;
|
||||
|
||||
+ case FT_PIXEL_MODE_BGRA:
|
||||
+ pitch = width * 4;
|
||||
+ break;
|
||||
+
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
if ( mode != FT_RENDER_MODE_LCD )
|
||||
return -1;
|
||||
@@ -142,6 +159,105 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
return pitch * height;
|
||||
}
|
||||
|
||||
+/* this functions converts the glyph bitmap found in a FT_GlyphSlot
|
||||
+ * into a different format while scaling by applying the given matrix
|
||||
+ * (see _compute_xrender_bitmap_size)
|
||||
+ *
|
||||
+ * you should call this function after _compute_xrender_bitmap_size
|
||||
+ *
|
||||
+ * target :: target bitmap descriptor. Note that its 'buffer' pointer
|
||||
+ * must point to memory allocated by the caller
|
||||
+ *
|
||||
+ * source :: the source bitmap descriptor
|
||||
+ *
|
||||
+ * matrix :: the scaling matrix to apply
|
||||
+ */
|
||||
+static void
|
||||
+_scaled_fill_xrender_bitmap( FT_Bitmap* target,
|
||||
+ FT_Bitmap* source,
|
||||
+ const FT_Matrix* matrix )
|
||||
+{
|
||||
+ unsigned char* src_buf = source->buffer;
|
||||
+ unsigned char* dst_line = target->buffer;
|
||||
+ int src_pitch = source->pitch;
|
||||
+ int width = target->width;
|
||||
+ int height = target->rows;
|
||||
+ int pitch = target->pitch;
|
||||
+ int h;
|
||||
+ FT_Vector vector;
|
||||
+ FT_Matrix inverse = *matrix;
|
||||
+ int sampling_width;
|
||||
+ int sampling_height;
|
||||
+ int sample_count;
|
||||
+
|
||||
+ if ( src_pitch < 0 )
|
||||
+ src_buf -= src_pitch*(source->rows-1);
|
||||
+
|
||||
+ FT_Matrix_Invert(&inverse);
|
||||
+
|
||||
+ /* compute how many source pixels a target pixel spans */
|
||||
+ vector.x = 1;
|
||||
+ vector.y = 1;
|
||||
+ FT_Vector_Transform(&vector, &inverse);
|
||||
+ sampling_width = vector.x / 2;
|
||||
+ sampling_height = vector.y / 2;
|
||||
+ sample_count = (2 * sampling_width + 1) * (2 * sampling_height + 1);
|
||||
+
|
||||
+ for ( h = height; h > 0; h--, dst_line += pitch )
|
||||
+ {
|
||||
+ int x;
|
||||
+
|
||||
+ for ( x = 0; x < width; x++ )
|
||||
+ {
|
||||
+ unsigned char* src;
|
||||
+
|
||||
+#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
|
||||
+
|
||||
+ /* compute target pixel location in source space */
|
||||
+ vector.x = (x * 0x10000) + 0x10000 / 2;
|
||||
+ vector.y = ((height - h) * 0x10000) + 0x10000 / 2;
|
||||
+ FT_Vector_Transform(&vector, &inverse);
|
||||
+ vector.x = CLAMP(FT_RoundFix(vector.x) / 0x10000, 0, source->width - 1);
|
||||
+ vector.y = CLAMP(FT_RoundFix(vector.y) / 0x10000, 0, source->rows - 1);
|
||||
+
|
||||
+ switch ( source->pixel_mode )
|
||||
+ {
|
||||
+ case FT_PIXEL_MODE_MONO: /* convert mono to 8-bit gray, scale using nearest pixel */
|
||||
+ src = src_buf + (vector.y * src_pitch);
|
||||
+ if ( src[(vector.x >> 3)] & (0x80 >> (vector.x & 7)) )
|
||||
+ dst_line[x] = 0xff;
|
||||
+ break;
|
||||
+
|
||||
+ case FT_PIXEL_MODE_GRAY: /* scale using nearest pixel */
|
||||
+ src = src_buf + (vector.y * src_pitch);
|
||||
+ dst_line[x] = src[vector.x];
|
||||
+ break;
|
||||
+
|
||||
+ case FT_PIXEL_MODE_BGRA: /* scale by averaging all relevant source pixels, keep BGRA format */
|
||||
+ {
|
||||
+ int sample_x, sample_y;
|
||||
+ int bgra[4] = {};
|
||||
+ for (sample_y = - sampling_height; sample_y < sampling_height + 1; ++sample_y)
|
||||
+ {
|
||||
+ int src_y = CLAMP(vector.y + sample_y, 0, source->rows - 1);
|
||||
+ src = src_buf + (src_y * src_pitch);
|
||||
+ for (sample_x = - sampling_width; sample_x < sampling_width + 1; ++sample_x)
|
||||
+ {
|
||||
+ int src_x = CLAMP(vector.x + sample_x, 0, source->width - 1);
|
||||
+ for (int i = 0; i < 4; ++i)
|
||||
+ bgra[i] += src[src_x * 4 + i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < 4; ++i)
|
||||
+ dst_line[4 * x + i] = bgra[i] / sample_count;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* this functions converts the glyph bitmap found in a FT_GlyphSlot
|
||||
* into a different format (see _compute_xrender_bitmap_size)
|
||||
*
|
||||
@@ -244,6 +360,11 @@ _fill_xrender_bitmap( FT_Bitmap* target,
|
||||
}
|
||||
break;
|
||||
|
||||
+ case FT_PIXEL_MODE_BGRA: /* Preserve BGRA format */
|
||||
+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
|
||||
+ memcpy( dstLine, srcLine, width * 4 );
|
||||
+ break;
|
||||
+
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
if ( !bgr )
|
||||
{
|
||||
@@ -365,6 +486,8 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
FT_Vector vector;
|
||||
FT_Face face;
|
||||
FT_Render_Mode mode = FT_RENDER_MODE_MONO;
|
||||
+ FcBool transform;
|
||||
+ FcBool glyph_transform;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
@@ -374,6 +497,8 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
if (!face)
|
||||
return;
|
||||
|
||||
+ if (font->info.color)
|
||||
+ mode = FT_RENDER_MODE_NORMAL;
|
||||
if (font->info.antialias)
|
||||
{
|
||||
switch (font->info.rgba) {
|
||||
@@ -390,6 +515,8 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
|
||||
+ transform = font->info.transform && mode != FT_RENDER_MODE_MONO;
|
||||
+
|
||||
while (nglyph--)
|
||||
{
|
||||
glyphindex = *glyphs++;
|
||||
@@ -440,7 +567,7 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
/*
|
||||
* Compute glyph metrics from FreeType information
|
||||
*/
|
||||
- if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
+ if (transform)
|
||||
{
|
||||
/*
|
||||
* calculate the true width by transforming all four corners.
|
||||
@@ -487,7 +614,7 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
* Clip charcell glyphs to the bounding box
|
||||
* XXX transformed?
|
||||
*/
|
||||
- if (font->info.spacing >= FC_CHARCELL && !font->info.transform)
|
||||
+ if (font->info.spacing >= FC_CHARCELL && !transform)
|
||||
{
|
||||
if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
|
||||
{
|
||||
@@ -519,18 +646,20 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
|
||||
+ glyph_transform = transform;
|
||||
if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
{
|
||||
error = FT_Render_Glyph( face->glyph, mode );
|
||||
if (error)
|
||||
continue;
|
||||
+ glyph_transform = False;
|
||||
}
|
||||
|
||||
FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
|
||||
|
||||
if (font->info.spacing >= FC_MONO)
|
||||
{
|
||||
- if (font->info.transform)
|
||||
+ if (transform)
|
||||
{
|
||||
if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
|
||||
{
|
||||
@@ -613,14 +742,27 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
|
||||
- size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
|
||||
+ size = _compute_xrender_bitmap_size( &local, glyphslot, mode, glyph_transform ? &font->info.matrix : NULL );
|
||||
if ( size < 0 )
|
||||
continue;
|
||||
|
||||
xftg->metrics.width = local.width;
|
||||
xftg->metrics.height = local.rows;
|
||||
- xftg->metrics.x = - glyphslot->bitmap_left;
|
||||
- xftg->metrics.y = glyphslot->bitmap_top;
|
||||
+ if (transform)
|
||||
+ {
|
||||
+ vector.x = - glyphslot->bitmap_left;
|
||||
+ vector.y = glyphslot->bitmap_top;
|
||||
+
|
||||
+ FT_Vector_Transform(&vector, &font->info.matrix);
|
||||
+
|
||||
+ xftg->metrics.x = vector.x;
|
||||
+ xftg->metrics.y = vector.y;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ xftg->metrics.x = - glyphslot->bitmap_left;
|
||||
+ xftg->metrics.y = glyphslot->bitmap_top;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* If the glyph is relatively large (> 1% of server memory),
|
||||
@@ -645,9 +787,12 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
|
||||
local.buffer = bufBitmap;
|
||||
|
||||
- _fill_xrender_bitmap( &local, glyphslot, mode,
|
||||
- (font->info.rgba == FC_RGBA_BGR ||
|
||||
- font->info.rgba == FC_RGBA_VBGR ) );
|
||||
+ if (mode == FT_RENDER_MODE_NORMAL && glyph_transform)
|
||||
+ _scaled_fill_xrender_bitmap(&local, &glyphslot->bitmap, &font->info.matrix);
|
||||
+ else
|
||||
+ _fill_xrender_bitmap( &local, glyphslot, mode,
|
||||
+ (font->info.rgba == FC_RGBA_BGR ||
|
||||
+ font->info.rgba == FC_RGBA_VBGR ) );
|
||||
|
||||
/*
|
||||
* Copy or convert into local buffer.
|
||||
@@ -662,6 +807,7 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
*/
|
||||
glyph = (Glyph) glyphindex;
|
||||
|
||||
+ xftg->picture = 0;
|
||||
xftg->glyph_memory = size + sizeof (XftGlyph);
|
||||
if (font->format)
|
||||
{
|
||||
@@ -685,15 +831,35 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
}
|
||||
- else if ( mode != FT_RENDER_MODE_NORMAL )
|
||||
+ else if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA || mode != FT_RENDER_MODE_NORMAL)
|
||||
{
|
||||
/* invert ARGB <=> BGRA */
|
||||
if (ImageByteOrder (dpy) != XftNativeByteOrder ())
|
||||
XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
|
||||
}
|
||||
- XRenderAddGlyphs (dpy, font->glyphset, &glyph,
|
||||
- &xftg->metrics, 1,
|
||||
- (char *) bufBitmap, size);
|
||||
+
|
||||
+ if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
|
||||
+ {
|
||||
+ Pixmap pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), local.width, local.rows, 32);
|
||||
+ GC gc = XCreateGC(dpy, pixmap, 0, NULL);
|
||||
+ XImage image = {
|
||||
+ local.width, local.rows, 0, ZPixmap, (char *)bufBitmap,
|
||||
+ dpy->byte_order, dpy->bitmap_unit, dpy->bitmap_bit_order, 32,
|
||||
+ 32, local.width * 4 - local.pitch, 32,
|
||||
+ 0, 0, 0
|
||||
+ };
|
||||
+
|
||||
+ XInitImage(&image);
|
||||
+ XPutImage(dpy, pixmap, gc, &image, 0, 0, 0, 0, local.width, local.rows);
|
||||
+ xftg->picture = XRenderCreatePicture(dpy, pixmap, font->format, 0, NULL);
|
||||
+
|
||||
+ XFreeGC(dpy, gc);
|
||||
+ XFreePixmap(dpy, pixmap);
|
||||
+ }
|
||||
+ else
|
||||
+ XRenderAddGlyphs (dpy, font->glyphset, &glyph,
|
||||
+ &xftg->metrics, 1,
|
||||
+ (char *) bufBitmap, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -744,7 +910,9 @@ XftFontUnloadGlyphs (Display *dpy,
|
||||
{
|
||||
if (font->format)
|
||||
{
|
||||
- if (font->glyphset)
|
||||
+ if (xftg->picture)
|
||||
+ XRenderFreePicture(dpy, xftg->picture);
|
||||
+ else if (font->glyphset)
|
||||
{
|
||||
glyphBuf[nused++] = (Glyph) glyphindex;
|
||||
if (nused == sizeof (glyphBuf) / sizeof (glyphBuf[0]))
|
||||
diff --git a/src/xftint.h b/src/xftint.h
|
||||
index c06ac3c..b263520 100644
|
||||
--- a/src/xftint.h
|
||||
+++ b/src/xftint.h
|
||||
@@ -85,6 +85,7 @@ typedef struct _XftGlyph {
|
||||
XGlyphInfo metrics;
|
||||
void *bitmap;
|
||||
unsigned long glyph_memory;
|
||||
+ Picture picture;
|
||||
} XftGlyph;
|
||||
|
||||
/*
|
||||
@@ -134,6 +135,7 @@ struct _XftFontInfo {
|
||||
FT_F26Dot6 xsize, ysize; /* pixel size */
|
||||
FcBool antialias; /* doing antialiasing */
|
||||
FcBool embolden; /* force emboldening */
|
||||
+ FcBool color; /* contains color glyphs */
|
||||
int rgba; /* subpixel order */
|
||||
int lcd_filter; /* lcd filter */
|
||||
FT_Matrix matrix; /* glyph transformation matrix */
|
||||
diff --git a/src/xftrender.c b/src/xftrender.c
|
||||
index b280c03..9a789cb 100644
|
||||
--- a/src/xftrender.c
|
||||
+++ b/src/xftrender.c
|
||||
@@ -25,6 +25,35 @@
|
||||
#define NUM_LOCAL 1024
|
||||
#define NUM_ELT_LOCAL 128
|
||||
|
||||
+/*
|
||||
+ * Dispatch glyph drawing to the correct XRenderCompositeString function
|
||||
+ */
|
||||
+static void
|
||||
+_XftCompositeString (Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat* format, GlyphSet glyphset, int srcx, int srcy, int dstx, int dsty, int charwidth, unsigned int* chars, int nchars)
|
||||
+{
|
||||
+ if (nchars == 0)
|
||||
+ return;
|
||||
+
|
||||
+ switch (charwidth) {
|
||||
+ case 1:
|
||||
+ default:
|
||||
+ XRenderCompositeString8 (dpy, op,
|
||||
+ src, dst, format, glyphset,
|
||||
+ srcx, srcy, dstx, dsty, (char*)chars, nchars);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ XRenderCompositeString16(dpy, op,
|
||||
+ src, dst, format, glyphset,
|
||||
+ srcx, srcy, dstx, dsty, (unsigned short*)chars, nchars);
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ XRenderCompositeString32(dpy, op,
|
||||
+ src, dst, format, glyphset,
|
||||
+ srcx, srcy, dstx, dsty, (unsigned int*)chars, nchars);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Use the Render extension to draw the glyphs
|
||||
*/
|
||||
@@ -43,12 +72,14 @@ XftGlyphRender (Display *dpy,
|
||||
int nglyphs)
|
||||
{
|
||||
XftFontInt *font = (XftFontInt *) pub;
|
||||
- int i;
|
||||
+ int i, j;
|
||||
FT_UInt missing[XFT_NMISSING];
|
||||
int nmissing;
|
||||
FT_UInt g, max;
|
||||
int size, width;
|
||||
+ int dstx, dsty;
|
||||
Glyph wire;
|
||||
+ XftGlyph* glyph;
|
||||
char *char8;
|
||||
unsigned short *char16;
|
||||
unsigned int *char32;
|
||||
@@ -100,43 +131,75 @@ XftGlyphRender (Display *dpy,
|
||||
if (!chars)
|
||||
goto bail1;
|
||||
}
|
||||
+ dstx = x;
|
||||
+ dsty = y;
|
||||
char8 = (char *) chars;
|
||||
char16 = (unsigned short *) chars;
|
||||
char32 = (unsigned int *) chars;
|
||||
- for (i = 0; i < nglyphs; i++)
|
||||
+ for (i = 0, j = 0; i < nglyphs; i++)
|
||||
{
|
||||
wire = (Glyph) glyphs[i];
|
||||
if (wire >= font->num_glyphs || !font->glyphs[wire])
|
||||
wire = 0;
|
||||
- switch (width) {
|
||||
- case 1: char8[i] = (char) wire; break;
|
||||
- case 2: char16[i] = (unsigned short) wire; break;
|
||||
- case 4: char32[i] = (unsigned long) wire; break;
|
||||
+ glyph = font->glyphs[wire];
|
||||
+ if (glyph->picture)
|
||||
+ {
|
||||
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
|
||||
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, dstx, dsty - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
|
||||
+ x = dstx = dstx + glyph->metrics.xOff;
|
||||
+ x = dsty = dsty + glyph->metrics.yOff;
|
||||
+ j = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ switch (width) {
|
||||
+ case 1: char8[j] = (char) wire; break;
|
||||
+ case 2: char16[j] = (unsigned short) wire; break;
|
||||
+ case 4: char32[j] = (unsigned long) wire; break;
|
||||
+ }
|
||||
+ dstx += glyph->metrics.xOff;
|
||||
+ dsty += glyph->metrics.yOff;
|
||||
+ ++j;
|
||||
}
|
||||
}
|
||||
- switch (width) {
|
||||
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
|
||||
+ if (chars != char_local)
|
||||
+ free (chars);
|
||||
+bail1:
|
||||
+ if (glyphs_loaded)
|
||||
+ _XftFontManageMemory (dpy, pub);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Dispatch glyph drawing to the correct XRenderCompositeText function
|
||||
+ */
|
||||
+static void
|
||||
+_XftCompositeText (Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat* format, int srcx, int srcy, int dstx, int dsty, int eltwidth, XGlyphElt8* elts, int nelt)
|
||||
+{
|
||||
+ if (nelt == 0)
|
||||
+ return;
|
||||
+
|
||||
+ switch (eltwidth) {
|
||||
case 1:
|
||||
default:
|
||||
- XRenderCompositeString8 (dpy, op,
|
||||
- src, dst, font->format, font->glyphset,
|
||||
- srcx, srcy, x, y, char8, nglyphs);
|
||||
+ XRenderCompositeText8 (dpy, op,
|
||||
+ src, dst, format,
|
||||
+ srcx, srcy, dstx, dsty,
|
||||
+ (XGlyphElt8*)elts, nelt);
|
||||
break;
|
||||
case 2:
|
||||
- XRenderCompositeString16(dpy, op,
|
||||
- src, dst, font->format, font->glyphset,
|
||||
- srcx, srcy, x, y, char16, nglyphs);
|
||||
+ XRenderCompositeText16(dpy, op,
|
||||
+ src, dst, format,
|
||||
+ srcx, srcy, dstx, dsty,
|
||||
+ (XGlyphElt16*)elts, nelt);
|
||||
break;
|
||||
case 4:
|
||||
- XRenderCompositeString32(dpy, op,
|
||||
- src, dst, font->format, font->glyphset,
|
||||
- srcx, srcy, x, y, char32, nglyphs);
|
||||
+ XRenderCompositeText32(dpy, op,
|
||||
+ src, dst, format,
|
||||
+ srcx, srcy, dstx, dsty,
|
||||
+ (XGlyphElt32*)elts, nelt);
|
||||
break;
|
||||
}
|
||||
- if (chars != char_local)
|
||||
- free (chars);
|
||||
-bail1:
|
||||
- if (glyphs_loaded)
|
||||
- _XftFontManageMemory (dpy, pub);
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
@@ -251,9 +314,10 @@ XftGlyphSpecRender (Display *dpy,
|
||||
g = 0;
|
||||
/*
|
||||
* check to see if the glyph is placed where it would
|
||||
- * fall using the normal spacing
|
||||
+ * fall using the normal spacing and if it would render
|
||||
+ * as a XRender glyph
|
||||
*/
|
||||
- if ((glyph = font->glyphs[g]))
|
||||
+ if ((glyph = font->glyphs[g]) && !glyph->picture)
|
||||
{
|
||||
if (x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
@@ -267,7 +331,7 @@ XftGlyphSpecRender (Display *dpy,
|
||||
}
|
||||
|
||||
elts = elts_local;
|
||||
- if (nelt > NUM_ELT_LOCAL)
|
||||
+ if (!font->info.color && nelt > NUM_ELT_LOCAL)
|
||||
{
|
||||
elts = malloc (nelt * sizeof (XGlyphElt8));
|
||||
if (!elts)
|
||||
@@ -275,7 +339,7 @@ XftGlyphSpecRender (Display *dpy,
|
||||
}
|
||||
|
||||
/*
|
||||
- * Generate the list of glyph elts
|
||||
+ * Generate the list of glyph elts or render color glyphs
|
||||
*/
|
||||
nelt = 0;
|
||||
x = y = 0;
|
||||
@@ -289,6 +353,11 @@ XftGlyphSpecRender (Display *dpy,
|
||||
g = 0;
|
||||
if ((glyph = font->glyphs[g]))
|
||||
{
|
||||
+ if (glyph->picture)
|
||||
+ {
|
||||
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, glyphs[i].x, glyphs[i].y - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
|
||||
+ continue;
|
||||
+ }
|
||||
if (!i || x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
if (n)
|
||||
@@ -320,23 +389,9 @@ XftGlyphSpecRender (Display *dpy,
|
||||
elts[nelt].nchars = n;
|
||||
nelt++;
|
||||
}
|
||||
- switch (width) {
|
||||
- case 1:
|
||||
- XRenderCompositeText8 (dpy, op, src, dst, font->format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- elts, nelt);
|
||||
- break;
|
||||
- case 2:
|
||||
- XRenderCompositeText16 (dpy, op, src, dst, font->format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt16 *) elts, nelt);
|
||||
- break;
|
||||
- case 4:
|
||||
- XRenderCompositeText32 (dpy, op, src, dst, font->format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt32 *) elts, nelt);
|
||||
- break;
|
||||
- }
|
||||
+ _XftCompositeText(dpy, op, src, dst, font->format,
|
||||
+ srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
+ width, elts, nelt);
|
||||
|
||||
if (elts != elts_local)
|
||||
free (elts);
|
||||
@@ -535,7 +590,7 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
* check to see if the glyph is placed where it would
|
||||
* fall using the normal spacing
|
||||
*/
|
||||
- if ((glyph = font->glyphs[g]))
|
||||
+ if ((glyph = font->glyphs[g]) && !glyph->picture)
|
||||
{
|
||||
if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
@@ -560,7 +615,7 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
}
|
||||
|
||||
/*
|
||||
- * Generate the list of glyph elts
|
||||
+ * Generate the list of glyph elts and render color glyphs
|
||||
*/
|
||||
nelt = 0;
|
||||
x = y = 0;
|
||||
@@ -578,6 +633,11 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
g = 0;
|
||||
if ((glyph = font->glyphs[g]))
|
||||
{
|
||||
+ if (glyph->picture)
|
||||
+ {
|
||||
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, glyphs[i].x, glyphs[i].y - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
|
||||
+ continue;
|
||||
+ }
|
||||
if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
if (n)
|
||||
@@ -610,23 +670,9 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
elts[nelt].nchars = n;
|
||||
nelt++;
|
||||
}
|
||||
- switch (width) {
|
||||
- case 1:
|
||||
- XRenderCompositeText8 (dpy, op, src, dst, format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- elts, nelt);
|
||||
- break;
|
||||
- case 2:
|
||||
- XRenderCompositeText16 (dpy, op, src, dst, format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt16 *) elts, nelt);
|
||||
- break;
|
||||
- case 4:
|
||||
- XRenderCompositeText32 (dpy, op, src, dst, format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt32 *) elts, nelt);
|
||||
- break;
|
||||
- }
|
||||
+ _XftCompositeText(dpy, op, src, dst, format,
|
||||
+ srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
+ width, elts, nelt);
|
||||
|
||||
if (elts != elts_local)
|
||||
free (elts);
|
||||
--
|
||||
2.26.2
|
||||
|
738
patches/x11-libs/libXft/emojifont.patch
Normal file
738
patches/x11-libs/libXft/emojifont.patch
Normal file
@ -0,0 +1,738 @@
|
||||
From 7808631e7a9a605d5fe7a1077129c658d9ec47fc Mon Sep 17 00:00:00 2001
|
||||
From: Maxime Coste <mawww@kakoune.org>
|
||||
Date: Tue, 22 Oct 2019 22:46:49 +1100
|
||||
Subject: [PATCH] Add support for BGRA glyphs display and scaling
|
||||
|
||||
Display is done using an XRender Picture, as XRender
|
||||
glyphs are incompatible with BGRA rendering due to
|
||||
their use of the glyph bitmap as a mask.
|
||||
|
||||
Scaling is done by averaging all relevant pixel, which gives
|
||||
much better result than nearest pixel sampling while staying
|
||||
simple enough and not too computationally expensive.
|
||||
|
||||
This enables color emoji rendering support.
|
||||
|
||||
Fixes: #6
|
||||
|
||||
Signed-off-by: Maxime Coste <mawww@kakoune.org>
|
||||
---
|
||||
src/xftfreetype.c | 18 ++++-
|
||||
src/xftglyphs.c | 200 ++++++++++++++++++++++++++++++++++++++++++----
|
||||
src/xftint.h | 2 +
|
||||
src/xftrender.c | 168 ++++++++++++++++++++++++--------------
|
||||
4 files changed, 307 insertions(+), 81 deletions(-)
|
||||
|
||||
diff --git a/src/xftfreetype.c b/src/xftfreetype.c
|
||||
index a3b8332..a639a03 100644
|
||||
--- a/src/xftfreetype.c
|
||||
+++ b/src/xftfreetype.c
|
||||
@@ -514,7 +514,7 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
|
||||
/*
|
||||
* Compute glyph load flags
|
||||
*/
|
||||
- fi->load_flags = FT_LOAD_DEFAULT;
|
||||
+ fi->load_flags = FT_LOAD_DEFAULT | FT_LOAD_COLOR;
|
||||
|
||||
#ifndef XFT_EMBEDDED_BITMAP
|
||||
#define XFT_EMBEDDED_BITMAP "embeddedbitmap"
|
||||
@@ -766,6 +766,7 @@ XftFontOpenInfo (Display *dpy,
|
||||
FcChar32 hash_value;
|
||||
FcChar32 rehash_value;
|
||||
FcBool antialias;
|
||||
+ FcBool color;
|
||||
int max_glyph_memory;
|
||||
int alloc_size;
|
||||
int ascent, descent, height;
|
||||
@@ -822,12 +823,16 @@ XftFontOpenInfo (Display *dpy,
|
||||
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
|
||||
antialias = FcFalse;
|
||||
|
||||
+ color = FT_HAS_COLOR(face) ? FcTrue : FcFalse;
|
||||
+
|
||||
/*
|
||||
* Find the appropriate picture format
|
||||
*/
|
||||
if (fi->render)
|
||||
{
|
||||
- if (antialias)
|
||||
+ if (color)
|
||||
+ format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
|
||||
+ else if (antialias)
|
||||
{
|
||||
switch (fi->rgba) {
|
||||
case FC_RGBA_RGB:
|
||||
@@ -842,9 +847,7 @@ XftFontOpenInfo (Display *dpy,
|
||||
}
|
||||
}
|
||||
else
|
||||
- {
|
||||
format = XRenderFindStandardFormat (dpy, PictStandardA1);
|
||||
- }
|
||||
|
||||
if (!format)
|
||||
goto bail2;
|
||||
@@ -959,6 +962,13 @@ XftFontOpenInfo (Display *dpy,
|
||||
* which doesn't happen in XftFontInfoFill
|
||||
*/
|
||||
font->info.antialias = antialias;
|
||||
+
|
||||
+ /*
|
||||
+ * Set color value, which is only known once the
|
||||
+ * font was loaded
|
||||
+ */
|
||||
+ font->info.color = color;
|
||||
+
|
||||
/*
|
||||
* bump XftFile reference count
|
||||
*/
|
||||
diff --git a/src/xftglyphs.c b/src/xftglyphs.c
|
||||
index 4b5fb82..af2e3c1 100644
|
||||
--- a/src/xftglyphs.c
|
||||
+++ b/src/xftglyphs.c
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include FT_SYNTHESIS_H
|
||||
|
||||
+#include FT_GLYPH_H
|
||||
+
|
||||
/*
|
||||
* Validate the memory info for a font
|
||||
*/
|
||||
@@ -78,9 +80,11 @@ _XftFontValidateMemory (Display *dpy, XftFont *public)
|
||||
static int
|
||||
_compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
FT_GlyphSlot slot,
|
||||
- FT_Render_Mode mode )
|
||||
+ FT_Render_Mode mode,
|
||||
+ FT_Matrix* matrix )
|
||||
{
|
||||
FT_Bitmap* ftbit;
|
||||
+ FT_Vector vector;
|
||||
int width, height, pitch;
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
@@ -88,9 +92,18 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
|
||||
// compute the size of the final bitmap
|
||||
ftbit = &slot->bitmap;
|
||||
-
|
||||
width = ftbit->width;
|
||||
height = ftbit->rows;
|
||||
+
|
||||
+ if ( matrix && mode == FT_RENDER_MODE_NORMAL )
|
||||
+ {
|
||||
+ vector.x = ftbit->width;
|
||||
+ vector.y = ftbit->rows;
|
||||
+ FT_Vector_Transform(&vector, matrix);
|
||||
+
|
||||
+ width = vector.x;
|
||||
+ height = vector.y;
|
||||
+ }
|
||||
pitch = (width+3) & ~3;
|
||||
|
||||
switch ( ftbit->pixel_mode )
|
||||
@@ -112,6 +125,10 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
}
|
||||
break;
|
||||
|
||||
+ case FT_PIXEL_MODE_BGRA:
|
||||
+ pitch = width * 4;
|
||||
+ break;
|
||||
+
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
if ( mode != FT_RENDER_MODE_LCD )
|
||||
return -1;
|
||||
@@ -142,6 +159,105 @@ _compute_xrender_bitmap_size( FT_Bitmap* target,
|
||||
return pitch * height;
|
||||
}
|
||||
|
||||
+/* this functions converts the glyph bitmap found in a FT_GlyphSlot
|
||||
+ * into a different format while scaling by applying the given matrix
|
||||
+ * (see _compute_xrender_bitmap_size)
|
||||
+ *
|
||||
+ * you should call this function after _compute_xrender_bitmap_size
|
||||
+ *
|
||||
+ * target :: target bitmap descriptor. Note that its 'buffer' pointer
|
||||
+ * must point to memory allocated by the caller
|
||||
+ *
|
||||
+ * source :: the source bitmap descriptor
|
||||
+ *
|
||||
+ * matrix :: the scaling matrix to apply
|
||||
+ */
|
||||
+static void
|
||||
+_scaled_fill_xrender_bitmap( FT_Bitmap* target,
|
||||
+ FT_Bitmap* source,
|
||||
+ const FT_Matrix* matrix )
|
||||
+{
|
||||
+ unsigned char* src_buf = source->buffer;
|
||||
+ unsigned char* dst_line = target->buffer;
|
||||
+ int src_pitch = source->pitch;
|
||||
+ int width = target->width;
|
||||
+ int height = target->rows;
|
||||
+ int pitch = target->pitch;
|
||||
+ int h;
|
||||
+ FT_Vector vector;
|
||||
+ FT_Matrix inverse = *matrix;
|
||||
+ int sampling_width;
|
||||
+ int sampling_height;
|
||||
+ int sample_count;
|
||||
+
|
||||
+ if ( src_pitch < 0 )
|
||||
+ src_buf -= src_pitch*(source->rows-1);
|
||||
+
|
||||
+ FT_Matrix_Invert(&inverse);
|
||||
+
|
||||
+ /* compute how many source pixels a target pixel spans */
|
||||
+ vector.x = 1;
|
||||
+ vector.y = 1;
|
||||
+ FT_Vector_Transform(&vector, &inverse);
|
||||
+ sampling_width = vector.x / 2;
|
||||
+ sampling_height = vector.y / 2;
|
||||
+ sample_count = (2 * sampling_width + 1) * (2 * sampling_height + 1);
|
||||
+
|
||||
+ for ( h = height; h > 0; h--, dst_line += pitch )
|
||||
+ {
|
||||
+ int x;
|
||||
+
|
||||
+ for ( x = 0; x < width; x++ )
|
||||
+ {
|
||||
+ unsigned char* src;
|
||||
+
|
||||
+#define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
|
||||
+
|
||||
+ /* compute target pixel location in source space */
|
||||
+ vector.x = (x * 0x10000) + 0x10000 / 2;
|
||||
+ vector.y = ((height - h) * 0x10000) + 0x10000 / 2;
|
||||
+ FT_Vector_Transform(&vector, &inverse);
|
||||
+ vector.x = CLAMP(FT_RoundFix(vector.x) / 0x10000, 0, source->width - 1);
|
||||
+ vector.y = CLAMP(FT_RoundFix(vector.y) / 0x10000, 0, source->rows - 1);
|
||||
+
|
||||
+ switch ( source->pixel_mode )
|
||||
+ {
|
||||
+ case FT_PIXEL_MODE_MONO: /* convert mono to 8-bit gray, scale using nearest pixel */
|
||||
+ src = src_buf + (vector.y * src_pitch);
|
||||
+ if ( src[(vector.x >> 3)] & (0x80 >> (vector.x & 7)) )
|
||||
+ dst_line[x] = 0xff;
|
||||
+ break;
|
||||
+
|
||||
+ case FT_PIXEL_MODE_GRAY: /* scale using nearest pixel */
|
||||
+ src = src_buf + (vector.y * src_pitch);
|
||||
+ dst_line[x] = src[vector.x];
|
||||
+ break;
|
||||
+
|
||||
+ case FT_PIXEL_MODE_BGRA: /* scale by averaging all relevant source pixels, keep BGRA format */
|
||||
+ {
|
||||
+ int sample_x, sample_y;
|
||||
+ int bgra[4] = {};
|
||||
+ for (sample_y = - sampling_height; sample_y < sampling_height + 1; ++sample_y)
|
||||
+ {
|
||||
+ int src_y = CLAMP(vector.y + sample_y, 0, source->rows - 1);
|
||||
+ src = src_buf + (src_y * src_pitch);
|
||||
+ for (sample_x = - sampling_width; sample_x < sampling_width + 1; ++sample_x)
|
||||
+ {
|
||||
+ int src_x = CLAMP(vector.x + sample_x, 0, source->width - 1);
|
||||
+ for (int i = 0; i < 4; ++i)
|
||||
+ bgra[i] += src[src_x * 4 + i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < 4; ++i)
|
||||
+ dst_line[4 * x + i] = bgra[i] / sample_count;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* this functions converts the glyph bitmap found in a FT_GlyphSlot
|
||||
* into a different format (see _compute_xrender_bitmap_size)
|
||||
*
|
||||
@@ -244,6 +360,11 @@ _fill_xrender_bitmap( FT_Bitmap* target,
|
||||
}
|
||||
break;
|
||||
|
||||
+ case FT_PIXEL_MODE_BGRA: /* Preserve BGRA format */
|
||||
+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
|
||||
+ memcpy( dstLine, srcLine, width * 4 );
|
||||
+ break;
|
||||
+
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
if ( !bgr )
|
||||
{
|
||||
@@ -365,6 +486,8 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
FT_Vector vector;
|
||||
FT_Face face;
|
||||
FT_Render_Mode mode = FT_RENDER_MODE_MONO;
|
||||
+ FcBool transform;
|
||||
+ FcBool glyph_transform;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
@@ -374,6 +497,8 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
if (!face)
|
||||
return;
|
||||
|
||||
+ if (font->info.color)
|
||||
+ mode = FT_RENDER_MODE_NORMAL;
|
||||
if (font->info.antialias)
|
||||
{
|
||||
switch (font->info.rgba) {
|
||||
@@ -390,6 +515,8 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
|
||||
+ transform = font->info.transform && mode != FT_RENDER_MODE_MONO;
|
||||
+
|
||||
while (nglyph--)
|
||||
{
|
||||
glyphindex = *glyphs++;
|
||||
@@ -440,7 +567,7 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
/*
|
||||
* Compute glyph metrics from FreeType information
|
||||
*/
|
||||
- if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
+ if (transform)
|
||||
{
|
||||
/*
|
||||
* calculate the true width by transforming all four corners.
|
||||
@@ -487,7 +614,7 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
* Clip charcell glyphs to the bounding box
|
||||
* XXX transformed?
|
||||
*/
|
||||
- if (font->info.spacing >= FC_CHARCELL && !font->info.transform)
|
||||
+ if (font->info.spacing >= FC_CHARCELL && !transform)
|
||||
{
|
||||
if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
|
||||
{
|
||||
@@ -519,18 +646,20 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
|
||||
+ glyph_transform = transform;
|
||||
if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
|
||||
{
|
||||
error = FT_Render_Glyph( face->glyph, mode );
|
||||
if (error)
|
||||
continue;
|
||||
+ glyph_transform = False;
|
||||
}
|
||||
|
||||
FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
|
||||
|
||||
if (font->info.spacing >= FC_MONO)
|
||||
{
|
||||
- if (font->info.transform)
|
||||
+ if (transform)
|
||||
{
|
||||
if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT)
|
||||
{
|
||||
@@ -613,14 +742,27 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
|
||||
- size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
|
||||
+ size = _compute_xrender_bitmap_size( &local, glyphslot, mode, glyph_transform ? &font->info.matrix : NULL );
|
||||
if ( size < 0 )
|
||||
continue;
|
||||
|
||||
xftg->metrics.width = local.width;
|
||||
xftg->metrics.height = local.rows;
|
||||
- xftg->metrics.x = - glyphslot->bitmap_left;
|
||||
- xftg->metrics.y = glyphslot->bitmap_top;
|
||||
+ if (transform)
|
||||
+ {
|
||||
+ vector.x = - glyphslot->bitmap_left;
|
||||
+ vector.y = glyphslot->bitmap_top;
|
||||
+
|
||||
+ FT_Vector_Transform(&vector, &font->info.matrix);
|
||||
+
|
||||
+ xftg->metrics.x = vector.x;
|
||||
+ xftg->metrics.y = vector.y;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ xftg->metrics.x = - glyphslot->bitmap_left;
|
||||
+ xftg->metrics.y = glyphslot->bitmap_top;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* If the glyph is relatively large (> 1% of server memory),
|
||||
@@ -645,9 +787,12 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
|
||||
local.buffer = bufBitmap;
|
||||
|
||||
- _fill_xrender_bitmap( &local, glyphslot, mode,
|
||||
- (font->info.rgba == FC_RGBA_BGR ||
|
||||
- font->info.rgba == FC_RGBA_VBGR ) );
|
||||
+ if (mode == FT_RENDER_MODE_NORMAL && glyph_transform)
|
||||
+ _scaled_fill_xrender_bitmap(&local, &glyphslot->bitmap, &font->info.matrix);
|
||||
+ else
|
||||
+ _fill_xrender_bitmap( &local, glyphslot, mode,
|
||||
+ (font->info.rgba == FC_RGBA_BGR ||
|
||||
+ font->info.rgba == FC_RGBA_VBGR ) );
|
||||
|
||||
/*
|
||||
* Copy or convert into local buffer.
|
||||
@@ -662,6 +807,7 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
*/
|
||||
glyph = (Glyph) glyphindex;
|
||||
|
||||
+ xftg->picture = 0;
|
||||
xftg->glyph_memory = size + sizeof (XftGlyph);
|
||||
if (font->format)
|
||||
{
|
||||
@@ -685,15 +831,35 @@ XftFontLoadGlyphs (Display *dpy,
|
||||
}
|
||||
}
|
||||
}
|
||||
- else if ( mode != FT_RENDER_MODE_NORMAL )
|
||||
+ else if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA || mode != FT_RENDER_MODE_NORMAL)
|
||||
{
|
||||
/* invert ARGB <=> BGRA */
|
||||
if (ImageByteOrder (dpy) != XftNativeByteOrder ())
|
||||
XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
|
||||
}
|
||||
- XRenderAddGlyphs (dpy, font->glyphset, &glyph,
|
||||
- &xftg->metrics, 1,
|
||||
- (char *) bufBitmap, size);
|
||||
+
|
||||
+ if (glyphslot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
|
||||
+ {
|
||||
+ Pixmap pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), local.width, local.rows, 32);
|
||||
+ GC gc = XCreateGC(dpy, pixmap, 0, NULL);
|
||||
+ XImage image = {
|
||||
+ local.width, local.rows, 0, ZPixmap, (char *)bufBitmap,
|
||||
+ dpy->byte_order, dpy->bitmap_unit, dpy->bitmap_bit_order, 32,
|
||||
+ 32, local.width * 4 - local.pitch, 32,
|
||||
+ 0, 0, 0
|
||||
+ };
|
||||
+
|
||||
+ XInitImage(&image);
|
||||
+ XPutImage(dpy, pixmap, gc, &image, 0, 0, 0, 0, local.width, local.rows);
|
||||
+ xftg->picture = XRenderCreatePicture(dpy, pixmap, font->format, 0, NULL);
|
||||
+
|
||||
+ XFreeGC(dpy, gc);
|
||||
+ XFreePixmap(dpy, pixmap);
|
||||
+ }
|
||||
+ else
|
||||
+ XRenderAddGlyphs (dpy, font->glyphset, &glyph,
|
||||
+ &xftg->metrics, 1,
|
||||
+ (char *) bufBitmap, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -744,7 +910,9 @@ XftFontUnloadGlyphs (Display *dpy,
|
||||
{
|
||||
if (font->format)
|
||||
{
|
||||
- if (font->glyphset)
|
||||
+ if (xftg->picture)
|
||||
+ XRenderFreePicture(dpy, xftg->picture);
|
||||
+ else if (font->glyphset)
|
||||
{
|
||||
glyphBuf[nused++] = (Glyph) glyphindex;
|
||||
if (nused == sizeof (glyphBuf) / sizeof (glyphBuf[0]))
|
||||
diff --git a/src/xftint.h b/src/xftint.h
|
||||
index c06ac3c..b263520 100644
|
||||
--- a/src/xftint.h
|
||||
+++ b/src/xftint.h
|
||||
@@ -85,6 +85,7 @@ typedef struct _XftGlyph {
|
||||
XGlyphInfo metrics;
|
||||
void *bitmap;
|
||||
unsigned long glyph_memory;
|
||||
+ Picture picture;
|
||||
} XftGlyph;
|
||||
|
||||
/*
|
||||
@@ -134,6 +135,7 @@ struct _XftFontInfo {
|
||||
FT_F26Dot6 xsize, ysize; /* pixel size */
|
||||
FcBool antialias; /* doing antialiasing */
|
||||
FcBool embolden; /* force emboldening */
|
||||
+ FcBool color; /* contains color glyphs */
|
||||
int rgba; /* subpixel order */
|
||||
int lcd_filter; /* lcd filter */
|
||||
FT_Matrix matrix; /* glyph transformation matrix */
|
||||
diff --git a/src/xftrender.c b/src/xftrender.c
|
||||
index b280c03..9a789cb 100644
|
||||
--- a/src/xftrender.c
|
||||
+++ b/src/xftrender.c
|
||||
@@ -25,6 +25,35 @@
|
||||
#define NUM_LOCAL 1024
|
||||
#define NUM_ELT_LOCAL 128
|
||||
|
||||
+/*
|
||||
+ * Dispatch glyph drawing to the correct XRenderCompositeString function
|
||||
+ */
|
||||
+static void
|
||||
+_XftCompositeString (Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat* format, GlyphSet glyphset, int srcx, int srcy, int dstx, int dsty, int charwidth, unsigned int* chars, int nchars)
|
||||
+{
|
||||
+ if (nchars == 0)
|
||||
+ return;
|
||||
+
|
||||
+ switch (charwidth) {
|
||||
+ case 1:
|
||||
+ default:
|
||||
+ XRenderCompositeString8 (dpy, op,
|
||||
+ src, dst, format, glyphset,
|
||||
+ srcx, srcy, dstx, dsty, (char*)chars, nchars);
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ XRenderCompositeString16(dpy, op,
|
||||
+ src, dst, format, glyphset,
|
||||
+ srcx, srcy, dstx, dsty, (unsigned short*)chars, nchars);
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ XRenderCompositeString32(dpy, op,
|
||||
+ src, dst, format, glyphset,
|
||||
+ srcx, srcy, dstx, dsty, (unsigned int*)chars, nchars);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Use the Render extension to draw the glyphs
|
||||
*/
|
||||
@@ -43,12 +72,14 @@ XftGlyphRender (Display *dpy,
|
||||
int nglyphs)
|
||||
{
|
||||
XftFontInt *font = (XftFontInt *) pub;
|
||||
- int i;
|
||||
+ int i, j;
|
||||
FT_UInt missing[XFT_NMISSING];
|
||||
int nmissing;
|
||||
FT_UInt g, max;
|
||||
int size, width;
|
||||
+ int dstx, dsty;
|
||||
Glyph wire;
|
||||
+ XftGlyph* glyph;
|
||||
char *char8;
|
||||
unsigned short *char16;
|
||||
unsigned int *char32;
|
||||
@@ -100,43 +131,75 @@ XftGlyphRender (Display *dpy,
|
||||
if (!chars)
|
||||
goto bail1;
|
||||
}
|
||||
+ dstx = x;
|
||||
+ dsty = y;
|
||||
char8 = (char *) chars;
|
||||
char16 = (unsigned short *) chars;
|
||||
char32 = (unsigned int *) chars;
|
||||
- for (i = 0; i < nglyphs; i++)
|
||||
+ for (i = 0, j = 0; i < nglyphs; i++)
|
||||
{
|
||||
wire = (Glyph) glyphs[i];
|
||||
if (wire >= font->num_glyphs || !font->glyphs[wire])
|
||||
wire = 0;
|
||||
- switch (width) {
|
||||
- case 1: char8[i] = (char) wire; break;
|
||||
- case 2: char16[i] = (unsigned short) wire; break;
|
||||
- case 4: char32[i] = (unsigned long) wire; break;
|
||||
+ glyph = font->glyphs[wire];
|
||||
+ if (glyph->picture)
|
||||
+ {
|
||||
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
|
||||
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, dstx, dsty - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
|
||||
+ x = dstx = dstx + glyph->metrics.xOff;
|
||||
+ x = dsty = dsty + glyph->metrics.yOff;
|
||||
+ j = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ switch (width) {
|
||||
+ case 1: char8[j] = (char) wire; break;
|
||||
+ case 2: char16[j] = (unsigned short) wire; break;
|
||||
+ case 4: char32[j] = (unsigned long) wire; break;
|
||||
+ }
|
||||
+ dstx += glyph->metrics.xOff;
|
||||
+ dsty += glyph->metrics.yOff;
|
||||
+ ++j;
|
||||
}
|
||||
}
|
||||
- switch (width) {
|
||||
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset, srcx, srcy, x, y, width, chars, j);
|
||||
+ if (chars != char_local)
|
||||
+ free (chars);
|
||||
+bail1:
|
||||
+ if (glyphs_loaded)
|
||||
+ _XftFontManageMemory (dpy, pub);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Dispatch glyph drawing to the correct XRenderCompositeText function
|
||||
+ */
|
||||
+static void
|
||||
+_XftCompositeText (Display *dpy, int op, Picture src, Picture dst, XRenderPictFormat* format, int srcx, int srcy, int dstx, int dsty, int eltwidth, XGlyphElt8* elts, int nelt)
|
||||
+{
|
||||
+ if (nelt == 0)
|
||||
+ return;
|
||||
+
|
||||
+ switch (eltwidth) {
|
||||
case 1:
|
||||
default:
|
||||
- XRenderCompositeString8 (dpy, op,
|
||||
- src, dst, font->format, font->glyphset,
|
||||
- srcx, srcy, x, y, char8, nglyphs);
|
||||
+ XRenderCompositeText8 (dpy, op,
|
||||
+ src, dst, format,
|
||||
+ srcx, srcy, dstx, dsty,
|
||||
+ (XGlyphElt8*)elts, nelt);
|
||||
break;
|
||||
case 2:
|
||||
- XRenderCompositeString16(dpy, op,
|
||||
- src, dst, font->format, font->glyphset,
|
||||
- srcx, srcy, x, y, char16, nglyphs);
|
||||
+ XRenderCompositeText16(dpy, op,
|
||||
+ src, dst, format,
|
||||
+ srcx, srcy, dstx, dsty,
|
||||
+ (XGlyphElt16*)elts, nelt);
|
||||
break;
|
||||
case 4:
|
||||
- XRenderCompositeString32(dpy, op,
|
||||
- src, dst, font->format, font->glyphset,
|
||||
- srcx, srcy, x, y, char32, nglyphs);
|
||||
+ XRenderCompositeText32(dpy, op,
|
||||
+ src, dst, format,
|
||||
+ srcx, srcy, dstx, dsty,
|
||||
+ (XGlyphElt32*)elts, nelt);
|
||||
break;
|
||||
}
|
||||
- if (chars != char_local)
|
||||
- free (chars);
|
||||
-bail1:
|
||||
- if (glyphs_loaded)
|
||||
- _XftFontManageMemory (dpy, pub);
|
||||
}
|
||||
|
||||
_X_EXPORT void
|
||||
@@ -251,9 +314,10 @@ XftGlyphSpecRender (Display *dpy,
|
||||
g = 0;
|
||||
/*
|
||||
* check to see if the glyph is placed where it would
|
||||
- * fall using the normal spacing
|
||||
+ * fall using the normal spacing and if it would render
|
||||
+ * as a XRender glyph
|
||||
*/
|
||||
- if ((glyph = font->glyphs[g]))
|
||||
+ if ((glyph = font->glyphs[g]) && !glyph->picture)
|
||||
{
|
||||
if (x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
@@ -267,7 +331,7 @@ XftGlyphSpecRender (Display *dpy,
|
||||
}
|
||||
|
||||
elts = elts_local;
|
||||
- if (nelt > NUM_ELT_LOCAL)
|
||||
+ if (!font->info.color && nelt > NUM_ELT_LOCAL)
|
||||
{
|
||||
elts = malloc (nelt * sizeof (XGlyphElt8));
|
||||
if (!elts)
|
||||
@@ -275,7 +339,7 @@ XftGlyphSpecRender (Display *dpy,
|
||||
}
|
||||
|
||||
/*
|
||||
- * Generate the list of glyph elts
|
||||
+ * Generate the list of glyph elts or render color glyphs
|
||||
*/
|
||||
nelt = 0;
|
||||
x = y = 0;
|
||||
@@ -289,6 +353,11 @@ XftGlyphSpecRender (Display *dpy,
|
||||
g = 0;
|
||||
if ((glyph = font->glyphs[g]))
|
||||
{
|
||||
+ if (glyph->picture)
|
||||
+ {
|
||||
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, glyphs[i].x, glyphs[i].y - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
|
||||
+ continue;
|
||||
+ }
|
||||
if (!i || x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
if (n)
|
||||
@@ -320,23 +389,9 @@ XftGlyphSpecRender (Display *dpy,
|
||||
elts[nelt].nchars = n;
|
||||
nelt++;
|
||||
}
|
||||
- switch (width) {
|
||||
- case 1:
|
||||
- XRenderCompositeText8 (dpy, op, src, dst, font->format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- elts, nelt);
|
||||
- break;
|
||||
- case 2:
|
||||
- XRenderCompositeText16 (dpy, op, src, dst, font->format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt16 *) elts, nelt);
|
||||
- break;
|
||||
- case 4:
|
||||
- XRenderCompositeText32 (dpy, op, src, dst, font->format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt32 *) elts, nelt);
|
||||
- break;
|
||||
- }
|
||||
+ _XftCompositeText(dpy, op, src, dst, font->format,
|
||||
+ srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
+ width, elts, nelt);
|
||||
|
||||
if (elts != elts_local)
|
||||
free (elts);
|
||||
@@ -535,7 +590,7 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
* check to see if the glyph is placed where it would
|
||||
* fall using the normal spacing
|
||||
*/
|
||||
- if ((glyph = font->glyphs[g]))
|
||||
+ if ((glyph = font->glyphs[g]) && !glyph->picture)
|
||||
{
|
||||
if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
@@ -560,7 +615,7 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
}
|
||||
|
||||
/*
|
||||
- * Generate the list of glyph elts
|
||||
+ * Generate the list of glyph elts and render color glyphs
|
||||
*/
|
||||
nelt = 0;
|
||||
x = y = 0;
|
||||
@@ -578,6 +633,11 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
g = 0;
|
||||
if ((glyph = font->glyphs[g]))
|
||||
{
|
||||
+ if (glyph->picture)
|
||||
+ {
|
||||
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None, dst, 0, 0, 0, 0, glyphs[i].x, glyphs[i].y - glyph->metrics.y, glyph->metrics.width, glyph->metrics.height);
|
||||
+ continue;
|
||||
+ }
|
||||
if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
|
||||
{
|
||||
if (n)
|
||||
@@ -610,23 +670,9 @@ XftGlyphFontSpecRender (Display *dpy,
|
||||
elts[nelt].nchars = n;
|
||||
nelt++;
|
||||
}
|
||||
- switch (width) {
|
||||
- case 1:
|
||||
- XRenderCompositeText8 (dpy, op, src, dst, format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- elts, nelt);
|
||||
- break;
|
||||
- case 2:
|
||||
- XRenderCompositeText16 (dpy, op, src, dst, format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt16 *) elts, nelt);
|
||||
- break;
|
||||
- case 4:
|
||||
- XRenderCompositeText32 (dpy, op, src, dst, format,
|
||||
- srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
- (XGlyphElt32 *) elts, nelt);
|
||||
- break;
|
||||
- }
|
||||
+ _XftCompositeText(dpy, op, src, dst, format,
|
||||
+ srcx, srcy, glyphs[0].x, glyphs[0].y,
|
||||
+ width, elts, nelt);
|
||||
|
||||
if (elts != elts_local)
|
||||
free (elts);
|
||||
--
|
||||
2.26.2
|
||||
|
Reference in New Issue
Block a user