当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 111 篇帖子 ]  前往页数 1, 2, 3, 4, 5 ... 8  下一页
作者 内容
1 楼 
 文章标题 : 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-22 22:42 
头像

注册: 2006-12-08 10:21
帖子: 1116
送出感谢: 0 次
接收感谢: 0 次
第四页49楼更新,提供了打过提交官方备选的2#补丁的gdi32.dll.so。请大家试用反馈,争取这个补丁被早日融合到wine中!

我每2个星期就要给wine打一次补丁,有点不胜其烦。看了置顶帖的召集很感兴趣,就对目前使用的补丁做了一点分析。我不懂Linux编程,权当抛砖引玉。希望我们的努力能够为Wine官方接受。

首先,我们来看一下那个补丁的详情,依我看来,它并不太脏,只是有一点点脏。

代码:
1    if(lf.lfCharSet == DEFAULT_CHARSET || lf.lfCharSet == ANSI_CHARSET) {
2     int codepage = 936; /* I'm Chinese. Let me do something selfish. */
3      char *env_wdc = getenv("WINE_DEFAULT_CODEPAGE");
4      if(env_wdc != NULL) {
5        codepage = atoi(env_wdc);
6      }
7      FIXME("Dirty hack. Default and ansi charset is translated to getenv(\"WINE_DEFAULT_CODEPAGE\")\n");
8      if(!TranslateCharsetInfo((DWORD*)(INT_PTR)codepage, &csi, TCI_SRCCODEPAGE)) {
9        FIXME("OMG. Even this dirty hack doesn't work.  Let's PRAY.\n");
10       csi.fs.fsCsb[0] = 0;
11     }
12     lf.lfCharSet = csi.ciCharset;
13  } else if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
14      switch(lf.lfCharSet) {
15       case DEFAULT_CHARSET:
16         csi.fs.fsCsb[0] = 0;
17         break;
18      default:
19           FIXME("Untranslated charset %d\n", lf.lfCharSet);
20           csi.fs.fsCsb[0] = 0;
21           break;
22       }
23  }


我们所谈论的补丁是第1行到第13行的else为止的部分。“脏”的地方有2个:

1)默认codepage=936,这个可能对其他非中文用户产生影响。
2)虽然后面定义了WINE_DEFAULT_CODEPAGE,但为时已晚,因为这个分支对所有的lfCharset == DEFAULT_CHARSET和lfCharset == ANSI_CHARSET都做了处理,而不进入WINE原版程序的TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet...)函数。

我的设想是,我们利用WINE_DEFAULT_CODEPAGE这个参数,如果这个参数没有设置,我们依照Wine原始的逻辑处理,如果设置了,我们就依照这个codepage处理。代码如下:

代码:
    int codepage = 0;
    char *env_wdc = getenv("WINE_DEFAULT_CODEPAGE");
    if(env_wdc != NULL)
      codepage = atoi(env_wdc);
    if((codepage != 0) && (lf.lfCharSet == DEFAULT_CHARSET || lf.lfCharSet == ANSI_CHARSET)) {
      FIXME("WINE_DEFAULT_CODEPAGE=%d, overriding lfCharSet\n", codepage);
      if(!TranslateCharsetInfo((DWORD*)(INT_PTR)codepage, &csi, TCI_SRCCODEPAGE)) {
        FIXME("OMG. Even this hack doesn't work.  Let's PRAY.\n");
        csi.fs.fsCsb[0] = 0;
      }
      lf.lfCharSet = csi.ciCharset;
    } else if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
        switch(lf.lfCharSet) {
         case DEFAULT_CHARSET:
           csi.fs.fsCsb[0] = 0;
           break;
         default:
           FIXME("Untranslated charset %d\n", lf.lfCharSet);
           csi.fs.fsCsb[0] = 0;
           break;
       }
    }


这个简单的改动使得只有WINE_DEFAULT_CODEPAGE被设置的情况下,才按照他来TranslateCharsetInfo,这样我觉得就做到了和原来代码的兼容。对于我们中文用户,只要在系统某个文件比如/etc/profile中export WINE_DEFAULT_CODEPAGE=936就可以实现中文兼容了。

不知我这个方案可行否?请Linux编程高手指导。我对Linux程序的理解仅限于当年大学一年级用HPUX学C语言,以及对man page的阅读。至于为什么要lf.lfCharSet = csi.ciCharset;诸如此类的问题,我就比较迷糊了。 :em04


_________________
你爱用不用,没人逼你用--这就是Free的定义?
不,请自重,不要玷污Linux文化。


最后由 xrfang 编辑于 2008-12-16 21:26,总共编辑了 2 次

页首
 用户资料  
 
2 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-23 1:04 
头像

注册: 2006-08-06 16:58
帖子: 618
地址: 北海
送出感谢: 0 次
接收感谢: 1
好啊,顶上!!


_________________
Wine与中文显示补丁的安装
Wine注册表设置


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-23 10:45 
头像

注册: 2006-12-08 10:21
帖子: 1116
送出感谢: 0 次
接收感谢: 0 次
我个人的测试是成功的。但有一个程序,和讯股道,即原来的飞狐交易师,死活显示不正常。希望懂windows font原理的大师解惑,以便大家可以群策群力给出较好的中文解决方案。我个人认为没有必要使用“自动字符集判断”。看看下面两个图:


附件:
文件注释: 设置WINE_DEFAULT_CODEPAGE=936
cp936.png
cp936.png [ 11.65 KiB | 被浏览 12129 次 ]
文件注释: 未设置WINE_DEFAULT_CODEPAGE
cpdef.png
cpdef.png [ 13.4 KiB | 被浏览 12130 次 ]


_________________
你爱用不用,没人逼你用--这就是Free的定义?
不,请自重,不要玷污Linux文化。
页首
 用户资料  
 
4 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-23 11:38 

注册: 2007-12-02 18:12
帖子: 49
送出感谢: 0 次
接收感谢: 0 次
纯支持

第一张图中程序似乎选择了一个不含中文字符的字体


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-23 12:16 
头像

注册: 2005-10-01 21:38
帖子: 964
地址: 湖南邵东流光岭
送出感谢: 0 次
接收感谢: 0 次
飞狐交易师可以在字体设置里选择已有的字体。


_________________
小江恩的博客
http://gann.blog.ifeng.com/


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-23 13:15 
头像

注册: 2006-12-08 10:21
帖子: 1116
送出感谢: 0 次
接收感谢: 0 次
yinliang108 写道:
飞狐交易师可以在字体设置里选择已有的字体。


果真如此!没想到这么简单就可以解决。谢谢楼上和楼上的楼上。


_________________
你爱用不用,没人逼你用--这就是Free的定义?
不,请自重,不要玷污Linux文化。


页首
 用户资料  
 
7 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-23 18:31 

注册: 2007-09-24 16:51
帖子: 62
送出感谢: 0 次
接收感谢: 0 次
怎么使用啊,我不懂编程啊


页首
 用户资料  
 
8 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-24 7:27 
头像

注册: 2006-12-08 10:21
帖子: 1116
送出感谢: 0 次
接收感谢: 0 次
aaawhale 写道:
怎么使用啊,我不懂编程啊


如不懂编程,直接使用置顶贴的文件就可以了 :em09 这个帖子的期望目的在于使这个补丁被wine官方所接受。我们先探讨一个最佳解决方案。


_________________
你爱用不用,没人逼你用--这就是Free的定义?
不,请自重,不要玷污Linux文化。


页首
 用户资料  
 
9 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-25 10:55 

注册: 2008-11-19 18:27
帖子: 13
送出感谢: 0 次
接收感谢: 0 次
这样不行,稍微变换下,等我研究下不过要看WINE如何配置。我对WINE的配置不是很了解。
一会用vc测试下1.1.9的EFAULT_CODEPAGE问题。


页首
 用户资料  
 
10 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-25 11:59 
头像

注册: 2006-12-08 10:21
帖子: 1116
送出感谢: 0 次
接收感谢: 0 次
the_Fm 写道:
这样不行,稍微变换下,等我研究下不过要看WINE如何配置。我对WINE的配置不是很了解。
一会用vc测试下1.1.9的EFAULT_CODEPAGE问题。


我用GCC测试过getenv()没有问题,另外,我自己在用这个修改过的补丁是可以的。不知LS说的不行是什么东西,期待你测试完了以后详加说明...


_________________
你爱用不用,没人逼你用--这就是Free的定义?
不,请自重,不要玷污Linux文化。


页首
 用户资料  
 
11 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-25 13:09 

注册: 2008-11-19 18:27
帖子: 13
送出感谢: 0 次
接收感谢: 0 次
xrfang 写道:
the_Fm 写道:
这样不行,稍微变换下,等我研究下不过要看WINE如何配置。我对WINE的配置不是很了解。
一会用vc测试下1.1.9的EFAULT_CODEPAGE问题。


我用GCC测试过getenv()没有问题,另外,我自己在用这个修改过的补丁是可以的。不知LS说的不行是什么东西,期待你测试完了以后详加说明...


我的理解的dirty不是pageocde在前面设置了的问题。而是对 DEFAULT的修改。所以要读下代码。


页首
 用户资料  
 
12 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-25 18:36 
头像

注册: 2006-12-08 10:21
帖子: 1116
送出感谢: 0 次
接收感谢: 0 次
the_Fm 写道:
xrfang 写道:
the_Fm 写道:
这样不行,稍微变换下,等我研究下不过要看WINE如何配置。我对WINE的配置不是很了解。
一会用vc测试下1.1.9的EFAULT_CODEPAGE问题。


我用GCC测试过getenv()没有问题,另外,我自己在用这个修改过的补丁是可以的。不知LS说的不行是什么东西,期待你测试完了以后详加说明...


我的理解的dirty不是pageocde在前面设置了的问题。而是对 DEFAULT的修改。所以要读下代码。


这就是我说的第二个问题。我改动的代码解决了这个问题--只有特定条件下才修改default


_________________
你爱用不用,没人逼你用--这就是Free的定义?
不,请自重,不要玷污Linux文化。


页首
 用户资料  
 
13 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-26 2:12 

注册: 2006-05-05 2:22
帖子: 16
送出感谢: 0 次
接收感谢: 0 次
什么脏不脏,这个补丁没有找到问题的所在,肯定不会被接受。

需要修正的函数是 GdiGetCodePage,当用DEFAULT_CHARSET或ANSI_CHARSET创建字体、GDI选择这个字体后,GdiGetCodePage应该返回的codepage是936,而现在的返回codepage是有问题的。

等有时间了我来提交一个补丁吧。


xrfang 写道:
我每2个星期就要给wine打一次补丁,有点不胜其烦。看了置顶帖的召集很感兴趣,就对目前使用的补丁做了一点分析。我不懂Linux编程,权当抛砖引玉。希望我们的努力能够为Wine官方接受。

首先,我们来看一下那个补丁的详情,依我看来,它并不太脏,只是有一点点脏。

代码:
1    if(lf.lfCharSet == DEFAULT_CHARSET || lf.lfCharSet == ANSI_CHARSET) {
2     int codepage = 936; /* I'm Chinese. Let me do something selfish. */
3      char *env_wdc = getenv("WINE_DEFAULT_CODEPAGE");
4      if(env_wdc != NULL) {
5        codepage = atoi(env_wdc);
6      }
7      FIXME("Dirty hack. Default and ansi charset is translated to getenv(\"WINE_DEFAULT_CODEPAGE\")\n");
8      if(!TranslateCharsetInfo((DWORD*)(INT_PTR)codepage, &csi, TCI_SRCCODEPAGE)) {
9        FIXME("OMG. Even this dirty hack doesn't work.  Let's PRAY.\n");
10       csi.fs.fsCsb[0] = 0;
11     }
12     lf.lfCharSet = csi.ciCharset;
13  } else if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
14      switch(lf.lfCharSet) {
15       case DEFAULT_CHARSET:
16         csi.fs.fsCsb[0] = 0;
17         break;
18      default:
19           FIXME("Untranslated charset %d\n", lf.lfCharSet);
20           csi.fs.fsCsb[0] = 0;
21           break;
22       }
23  }


我们所谈论的补丁是第1行到第13行的else为止的部分。“脏”的地方有2个:

1)默认codepage=936,这个可能对其他非中文用户产生影响。
2)虽然后面定义了WINE_DEFAULT_CODEPAGE,但为时已晚,因为这个分支对所有的lfCharset == DEFAULT_CHARSET和lfCharset == ANSI_CHARSET都做了处理,而不进入WINE原版程序的TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet...)函数。

我的设想是,我们利用WINE_DEFAULT_CODEPAGE这个参数,如果这个参数没有设置,我们依照Wine原始的逻辑处理,如果设置了,我们就依照这个codepage处理。代码如下:

代码:
    int codepage = 0;
    char *env_wdc = getenv("WINE_DEFAULT_CODEPAGE");
    if(env_wdc != NULL)
      codepage = atoi(env_wdc);
    if((codepage != 0) && (lf.lfCharSet == DEFAULT_CHARSET || lf.lfCharSet == ANSI_CHARSET)) {
      FIXME("WINE_DEFAULT_CODEPAGE=%d, overriding lfCharSet\n", codepage);
      if(!TranslateCharsetInfo((DWORD*)(INT_PTR)codepage, &csi, TCI_SRCCODEPAGE)) {
        FIXME("OMG. Even this hack doesn't work.  Let's PRAY.\n");
        csi.fs.fsCsb[0] = 0;
      }
      lf.lfCharSet = csi.ciCharset;
    } else if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
        switch(lf.lfCharSet) {
         case DEFAULT_CHARSET:
           csi.fs.fsCsb[0] = 0;
           break;
         default:
           FIXME("Untranslated charset %d\n", lf.lfCharSet);
           csi.fs.fsCsb[0] = 0;
           break;
       }
    }


这个简单的改动使得只有WINE_DEFAULT_CODEPAGE被设置的情况下,才按照他来TranslateCharsetInfo,这样我觉得就做到了和原来代码的兼容。对于我们中文用户,只要在系统某个文件比如/etc/profile中export WINE_DEFAULT_CODEPAGE=936就可以实现中文兼容了。

不知我这个方案可行否?请Linux编程高手指导。我对Linux程序的理解仅限于当年大学一年级用HPUX学C语言,以及对man page的阅读。至于为什么要lf.lfCharSet = csi.ciCharset;诸如此类的问题,我就比较迷糊了。 :em04


页首
 用户资料  
 
14 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-26 3:13 
头像

注册: 2007-04-30 2:25
帖子: 429
地址: 湖南湘潭
送出感谢: 0 次
接收感谢: 0 次
等楼上的好消息!!!


_________________
孰能浊静之以徐清,孰能安动之以馀生!
gcell -- http://gcell.blog.163.com/


页首
 用户资料  
 
15 楼 
 文章标题 : Re: 洗干净Wine补丁的尝试,请爱好者和Linux编程高手进
帖子发表于 : 2008-11-27 17:04 
头像

注册: 2006-12-08 10:21
帖子: 1116
送出感谢: 0 次
接收感谢: 0 次
受13楼hzhr大师的启发,我发现只有CharSet==ANSI_CHARSET的时候才有问题,而DEFAULT_CHARSET是没有问题的。于是有了另一个版本的patch,我本人测试通过:
代码:
    if (lf.lfCharSet == ANSI_CHARSET) {
     UINT codepage;
     codepage = GetACP();
      FIXME("lf.lfCharSet == ANSI_CHARSET, using GetACP (%d)\n", codepage);
      if(!TranslateCharsetInfo((DWORD*)(INT_PTR)codepage, &csi, TCI_SRCCODEPAGE)) {
        FIXME("OMG. Even this hack doesn't work.  Let's PRAY.\n");
        csi.fs.fsCsb[0] = 0;
      }
      lf.lfCharSet = csi.ciCharset;
    } else if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
        switch(lf.lfCharSet) {
         case DEFAULT_CHARSET:
           csi.fs.fsCsb[0] = 0;
           break;
         default:
           FIXME("Untranslated charset %d\n", lf.lfCharSet);
           csi.fs.fsCsb[0] = 0;
           break;
       }
    }


这个版本不需要WINE_DEFAULT_CODEPAGE来支持。我想由于用了GetACP(),应该是兼容非中文系统的?

我看了一下GdiGetCodePage函数,这个函数虽然简单,但我没有完全理解,不敢动它,另外,作者或者维护者在里面写了个注释:

/* Hmm, nicely designed api this one! */

既然大师对这个函数如此青睐,我更加未敢造次了!

虽然这个patch不是从根本上解决问题,但我想总比现在这个好些?


_________________
你爱用不用,没人逼你用--这就是Free的定义?
不,请自重,不要玷污Linux文化。


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 111 篇帖子 ]  前往页数 1, 2, 3, 4, 5 ... 8  下一页

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 3 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译