Mercurial > vim
comparison src/os_win32.c @ 10571:b726d3ea70bc v8.0.0175
patch 8.0.0175: setting language on MS-Windows does not always work
commit https://github.com/vim/vim/commit/972c3b8f1b50e2f887a397c324af99eb354aad0b
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jan 12 21:44:49 2017 +0100
patch 8.0.0175: setting language on MS-Windows does not always work
Problem: Setting language in gvim on MS-Windows does not work when
libintl.dll is dynamically linked with msvcrt.dll.
Solution: Use putenv() from libintl as well. (Ken Takata, closes #1082)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 12 Jan 2017 21:45:04 +0100 |
parents | 56cb9538386c |
children | c96534dd2b2f |
comparison
equal
deleted
inserted
replaced
10570:33f9dbbfb7e5 | 10571:b726d3ea70bc |
---|---|
423 } | 423 } |
424 } | 424 } |
425 return dll; | 425 return dll; |
426 } | 426 } |
427 | 427 |
428 #if defined(DYNAMIC_ICONV) || defined(DYNAMIC_GETTEXT) || defined(PROTO) | |
429 /* | |
430 * Get related information about 'funcname' which is imported by 'hInst'. | |
431 * If 'info' is 0, return the function address. | |
432 * If 'info' is 1, return the module name which the function is imported from. | |
433 */ | |
434 static void * | |
435 get_imported_func_info(HINSTANCE hInst, const char *funcname, int info) | |
436 { | |
437 PBYTE pImage = (PBYTE)hInst; | |
438 PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)hInst; | |
439 PIMAGE_NT_HEADERS pPE; | |
440 PIMAGE_IMPORT_DESCRIPTOR pImpDesc; | |
441 PIMAGE_THUNK_DATA pIAT; /* Import Address Table */ | |
442 PIMAGE_THUNK_DATA pINT; /* Import Name Table */ | |
443 PIMAGE_IMPORT_BY_NAME pImpName; | |
444 | |
445 if (pDOS->e_magic != IMAGE_DOS_SIGNATURE) | |
446 return NULL; | |
447 pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew); | |
448 if (pPE->Signature != IMAGE_NT_SIGNATURE) | |
449 return NULL; | |
450 pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage | |
451 + pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] | |
452 .VirtualAddress); | |
453 for (; pImpDesc->FirstThunk; ++pImpDesc) | |
454 { | |
455 if (!pImpDesc->OriginalFirstThunk) | |
456 continue; | |
457 pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk); | |
458 pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk); | |
459 for (; pIAT->u1.Function; ++pIAT, ++pINT) | |
460 { | |
461 if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal)) | |
462 continue; | |
463 pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage | |
464 + (UINT_PTR)(pINT->u1.AddressOfData)); | |
465 if (strcmp((char *)pImpName->Name, funcname) == 0) | |
466 { | |
467 switch (info) | |
468 { | |
469 case 0: | |
470 return (void *)pIAT->u1.Function; | |
471 case 1: | |
472 return (void *)(pImage + pImpDesc->Name); | |
473 default: | |
474 return NULL; | |
475 } | |
476 } | |
477 } | |
478 } | |
479 return NULL; | |
480 } | |
481 | |
482 /* | |
483 * Get the module handle which 'funcname' in 'hInst' is imported from. | |
484 */ | |
485 HINSTANCE | |
486 find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname) | |
487 { | |
488 char *modulename; | |
489 | |
490 modulename = (char *)get_imported_func_info(hInst, funcname, 1); | |
491 if (modulename != NULL) | |
492 return GetModuleHandleA(modulename); | |
493 return NULL; | |
494 } | |
495 | |
496 /* | |
497 * Get the address of 'funcname' which is imported by 'hInst' DLL. | |
498 */ | |
499 void * | |
500 get_dll_import_func(HINSTANCE hInst, const char *funcname) | |
501 { | |
502 return get_imported_func_info(hInst, funcname, 0); | |
503 } | |
504 #endif | |
505 | |
428 #if defined(DYNAMIC_GETTEXT) || defined(PROTO) | 506 #if defined(DYNAMIC_GETTEXT) || defined(PROTO) |
429 # ifndef GETTEXT_DLL | 507 # ifndef GETTEXT_DLL |
430 # define GETTEXT_DLL "libintl.dll" | 508 # define GETTEXT_DLL "libintl.dll" |
431 # define GETTEXT_DLL_ALT "libintl-8.dll" | 509 # define GETTEXT_DLL_ALT "libintl-8.dll" |
432 # endif | 510 # endif |
434 static char *null_libintl_gettext(const char *); | 512 static char *null_libintl_gettext(const char *); |
435 static char *null_libintl_ngettext(const char *, const char *, unsigned long n); | 513 static char *null_libintl_ngettext(const char *, const char *, unsigned long n); |
436 static char *null_libintl_textdomain(const char *); | 514 static char *null_libintl_textdomain(const char *); |
437 static char *null_libintl_bindtextdomain(const char *, const char *); | 515 static char *null_libintl_bindtextdomain(const char *, const char *); |
438 static char *null_libintl_bind_textdomain_codeset(const char *, const char *); | 516 static char *null_libintl_bind_textdomain_codeset(const char *, const char *); |
517 static int null_libintl_putenv(const char *); | |
439 | 518 |
440 static HINSTANCE hLibintlDLL = NULL; | 519 static HINSTANCE hLibintlDLL = NULL; |
441 char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext; | 520 char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext; |
442 char *(*dyn_libintl_ngettext)(const char *, const char *, unsigned long n) | 521 char *(*dyn_libintl_ngettext)(const char *, const char *, unsigned long n) |
443 = null_libintl_ngettext; | 522 = null_libintl_ngettext; |
444 char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain; | 523 char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain; |
445 char *(*dyn_libintl_bindtextdomain)(const char *, const char *) | 524 char *(*dyn_libintl_bindtextdomain)(const char *, const char *) |
446 = null_libintl_bindtextdomain; | 525 = null_libintl_bindtextdomain; |
447 char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *) | 526 char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *) |
448 = null_libintl_bind_textdomain_codeset; | 527 = null_libintl_bind_textdomain_codeset; |
528 int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv; | |
449 | 529 |
450 int | 530 int |
451 dyn_libintl_init(void) | 531 dyn_libintl_init(void) |
452 { | 532 { |
453 int i; | 533 int i; |
461 {"ngettext", (FARPROC*)&dyn_libintl_ngettext}, | 541 {"ngettext", (FARPROC*)&dyn_libintl_ngettext}, |
462 {"textdomain", (FARPROC*)&dyn_libintl_textdomain}, | 542 {"textdomain", (FARPROC*)&dyn_libintl_textdomain}, |
463 {"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain}, | 543 {"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain}, |
464 {NULL, NULL} | 544 {NULL, NULL} |
465 }; | 545 }; |
546 HINSTANCE hmsvcrt; | |
466 | 547 |
467 /* No need to initialize twice. */ | 548 /* No need to initialize twice. */ |
468 if (hLibintlDLL) | 549 if (hLibintlDLL) |
469 return 1; | 550 return 1; |
470 /* Load gettext library (libintl.dll) */ | 551 /* Load gettext library (libintl.dll) */ |
505 "bind_textdomain_codeset"); | 586 "bind_textdomain_codeset"); |
506 if (dyn_libintl_bind_textdomain_codeset == NULL) | 587 if (dyn_libintl_bind_textdomain_codeset == NULL) |
507 dyn_libintl_bind_textdomain_codeset = | 588 dyn_libintl_bind_textdomain_codeset = |
508 null_libintl_bind_textdomain_codeset; | 589 null_libintl_bind_textdomain_codeset; |
509 | 590 |
591 /* _putenv() function for the libintl.dll is optional. */ | |
592 hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv"); | |
593 if (hmsvcrt != NULL) | |
594 dyn_libintl_putenv = (void *)GetProcAddress(hmsvcrt, "_putenv"); | |
595 if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == putenv) | |
596 dyn_libintl_putenv = null_libintl_putenv; | |
597 | |
510 return 1; | 598 return 1; |
511 } | 599 } |
512 | 600 |
513 void | 601 void |
514 dyn_libintl_end(void) | 602 dyn_libintl_end(void) |
519 dyn_libintl_gettext = null_libintl_gettext; | 607 dyn_libintl_gettext = null_libintl_gettext; |
520 dyn_libintl_ngettext = null_libintl_ngettext; | 608 dyn_libintl_ngettext = null_libintl_ngettext; |
521 dyn_libintl_textdomain = null_libintl_textdomain; | 609 dyn_libintl_textdomain = null_libintl_textdomain; |
522 dyn_libintl_bindtextdomain = null_libintl_bindtextdomain; | 610 dyn_libintl_bindtextdomain = null_libintl_bindtextdomain; |
523 dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset; | 611 dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset; |
612 dyn_libintl_putenv = null_libintl_putenv; | |
524 } | 613 } |
525 | 614 |
526 /*ARGSUSED*/ | 615 /*ARGSUSED*/ |
527 static char * | 616 static char * |
528 null_libintl_gettext(const char *msgid) | 617 null_libintl_gettext(const char *msgid) |
558 /*ARGSUSED*/ | 647 /*ARGSUSED*/ |
559 static char * | 648 static char * |
560 null_libintl_textdomain(const char *domainname) | 649 null_libintl_textdomain(const char *domainname) |
561 { | 650 { |
562 return NULL; | 651 return NULL; |
652 } | |
653 | |
654 /*ARGSUSED*/ | |
655 int | |
656 null_libintl_putenv(const char *envstring) | |
657 { | |
658 return 0; | |
563 } | 659 } |
564 | 660 |
565 #endif /* DYNAMIC_GETTEXT */ | 661 #endif /* DYNAMIC_GETTEXT */ |
566 | 662 |
567 /* This symbol is not defined in older versions of the SDK or Visual C++ */ | 663 /* This symbol is not defined in older versions of the SDK or Visual C++ */ |
4779 } | 4875 } |
4780 | 4876 |
4781 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) | 4877 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO) |
4782 static HANDLE | 4878 static HANDLE |
4783 job_io_file_open( | 4879 job_io_file_open( |
4784 char_u *fname, | 4880 char_u *fname, |
4785 DWORD dwDesiredAccess, | 4881 DWORD dwDesiredAccess, |
4786 DWORD dwShareMode, | 4882 DWORD dwShareMode, |
4787 LPSECURITY_ATTRIBUTES lpSecurityAttributes, | 4883 LPSECURITY_ATTRIBUTES lpSecurityAttributes, |
4788 DWORD dwCreationDisposition, | 4884 DWORD dwCreationDisposition, |
4789 DWORD dwFlagsAndAttributes) | 4885 DWORD dwFlagsAndAttributes) |
4790 { | 4886 { |
4791 HANDLE h; | 4887 HANDLE h; |
4792 # ifdef FEAT_MBYTE | 4888 # ifdef FEAT_MBYTE |
4793 WCHAR *wn = NULL; | 4889 WCHAR *wn = NULL; |
4794 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 4890 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) |
4795 { | 4891 { |
4796 wn = enc_to_utf16(fname, NULL); | 4892 wn = enc_to_utf16(fname, NULL); |
4797 if (wn != NULL) | 4893 if (wn != NULL) |
4798 { | 4894 { |
4799 h = CreateFileW(wn, dwDesiredAccess, dwShareMode, | 4895 h = CreateFileW(wn, dwDesiredAccess, dwShareMode, |
4800 lpSecurityAttributes, dwCreationDisposition, | 4896 lpSecurityAttributes, dwCreationDisposition, |
4801 dwFlagsAndAttributes, NULL); | 4897 dwFlagsAndAttributes, NULL); |
4802 vim_free(wn); | 4898 vim_free(wn); |
4803 } | 4899 } |
4804 } | 4900 } |
4805 if (wn == NULL) | 4901 if (wn == NULL) |
4806 # endif | 4902 # endif |
4807 h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode, | 4903 h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode, |
4808 lpSecurityAttributes, dwCreationDisposition, | 4904 lpSecurityAttributes, dwCreationDisposition, |
4809 dwFlagsAndAttributes, NULL); | 4905 dwFlagsAndAttributes, NULL); |
4810 return h; | 4906 return h; |
4811 } | 4907 } |
4812 | 4908 |
4813 void | 4909 void |
4814 mch_start_job(char *cmd, job_T *job, jobopt_T *options) | 4910 mch_start_job(char *cmd, job_T *job, jobopt_T *options) |