1 名前:login:Penguin mailto:sage [2017/08/12(土) 21:18:15.22 ID:tNr8ii2i.net] Linux上でWindowsのアプリを動作させるソフトウェア Wineに関する情報交換スレ。 前スレ 今夜も Wine で乾杯! - 20本目 https://mao.2ch.net/test/read.cgi/linux/1455088008/ Wine本家 www.winehq.org/ wiki.winehq.org/ 動作報告Wikiや過去ログなど www.2chlinux.org/index.php?FrontPage ここにパッチをうpするときはgzipやbzip2で圧縮した上で base64などでエンコードしてください。おながいします。 動作報告は>>2 のテンプレ使用を推奨。
369 名前:login:Penguin mailto:sage [2018/02/05(月) 02:08:15.28 ID:O1Pwqk/s.net] とりあえず3.0stableで様子見決め込んでる
370 名前:login:Penguin mailto:sage [2018/02/05(月) 19:21:01.05 ID:Nv69ARvL.net] wine-staging2.21からwine-stable3.0にしたら 負荷とメモリ消費が素晴らしく改善されたから 開発版に手を出しかねてる 3.0で改善されたのか、stagingのものが足を引っ張ってたのか判別つかなくて
371 名前:login:Penguin mailto:sage [2018/02/05(月) 20:00:31.17 ID:EoTMajD6.net] chrootで試せばいい。
372 名前:login:Penguin [2018/02/07(水) 03:18:13.01 ID:EaQ8LavF.net] janeで書き込みてすと
373 名前:login:Penguin mailto:sage [2018/02/07(水) 11:19:50.99 ID:wf+3Oqyn.net] 3.4のときは起動すらしなかったのにな 4.0になったら快調すぎる
374 名前:login:Penguin mailto:sage [2018/02/07(水) 12:09:50.12 ID:obK+oDJv.net] だったらいいんjane
375 名前:login:Penguin mailto:sage [2018/02/07(水) 13:18:45.69 ID:zs43/D2L.net] じゃあコンパイルすっかな
376 名前:login:Penguin mailto:sage [2018/02/08(木) 05:29:46.28 ID:awGx+2l1.net] 結局のところwinehq-stableとwine-stableの差は何なのさ
377 名前:login:Penguin mailto:sage [2018/02/09(金) 02:10:23.04 ID:7CcbsDfN.net] winehq stableが公式サイトで公開されてるやつでwine stableは各ディストリから配布されてるやつだと思ってたけど違うのかな
378 名前:login:Penguin mailto:sage [2018/02/09(金) 09:15:05.20 ID:VkWK7O5C.net] wine-3.1-arm.apk ExaGearより動くかなと期待して入れたんだけど、プログラムが一つも動かない… まだ見てくれだけの未完成品ってこと?
379 名前:login:Penguin mailto:sage [2018/02/09(金) 09:31:45.76 ID:VkWK7O5C.net] あー Windows RT ARMのソフトしか動かないのかこれ
380 名前:login:Penguin mailto:sage [2018/02/09(金) 10:40:32.53 ID:PPTatEc4.net] 違うだろ medaka.2ch.net/test/read.cgi/market/1516899338/
381 名前:login:Penguin mailto:sage [2018/02/09(金) 10:58:50.36 ID:FuNSphmo.net] >>371 マルチポストにつきNG推奨
382 名前:login:Penguin mailto:sage [2018/02/09(金) 11:54:48.43 ID:uGFZgCuz.net] >>372 こいつMac関連のスレ狙ってる?別にそんな事ないのかな
383 名前:login:Penguin mailto:sage [2018/02/10(土) 14:13:46.18 ID:JX1fd7td.net] crossoverのベースになっているwineのバージョンってどこから調べたらいいの? もう3.0ベースになってるのかな
384 名前:login:Penguin [2018/02/10(土) 21:57:09.72 ID:yxHJfpP2.net] >>374 /opt/cxoffice/changelog.txt もしくは https://www.codeweavers.com/products/more-information/changelog 3.0はまだやね
385 名前:login:Penguin mailto:sage [2018/02/10(土) 22:08:14.64 ID:yxHJfpP2.net] ちがったかな $ /opt/cxoffice/bin/wineserver --version wine-2.8-8251-g8a457d1
386 名前:login:Penguin mailto:sage [2018/02/10(土) 23:24:32.73 ID:JX1fd7td.net] >>375-376 ありがとう そっかまだかあ
387 名前:login:Penguin mailto:sage [2018/02/15(木) 16:28:40.72 ID:Adu/G50n.net] ubuntu studio 16.04LTS にwineを入れて、 JaneStyle を使える様にはなった。 書き込みテスト。
388 名前:login:Penguin [2018/02/15(木) 22:20:39.99 ID:feRq4tDS.net] >>369 まじかよ、Elonaさえ動けばいいのに。
389 名前:login:Penguin mailto:sage [2018/02/15(木) 23:40:06.85 ID:XEMKL93X.net] ARM機とかスマホしか持ってないわ これから増えるんかね
390 名前:login:Penguin mailto:sage [2018/02/16(金) 01:05:13.35 ID:+Lqzmf2v.net] 3DSとかもARMじゃないっけ
391 名前:login:Penguin mailto:sage [2018/02/16(金) 08:01:15.26 ID:TwuYLqrN.net] PS VitaもARMだしSwitchもARMだな
392 名前:login:Penguin mailto:sage [2018/02/16(金) 08:03:04.95 ID:8cWV/uet.net] 最近のモバイル端末はだいたいARMだな
393 名前:login:Penguin mailto:sage [2018/02/16(金) 08:03:51.98 ID:8uACRqcY.net] ChromebookもARM機ある
394 名前:login:Penguin mailto:sage [2018/02/16(金) 11:10:06.04 ID:80vLUCQ5.net] WindowsもARM機が再登場する
395 名前:login:Penguin mailto:sage [2018/02/16(金) 12:08:49.84 ID:Q5rpQjEk.net] RTでコケて痛い目にあったからそれはないと思う。 ARMじゃない別のアーキテクチャで出す可能性はあるかも・・・ そしてまたコケるw
396 名前:login:Penguin mailto:sage [2018/02/16(金) 12:24:21.66 ID:Pj9ij8xw.net] >>386 いや出るから HPとASUSがsnapdragon搭載Windows端末を発表済で春に発売予定
397 名前:login:Penguin mailto:sage [2018/02/16(金) 13:41:56.11 ID:QNuqSD5T.net] 売れるとは限らないんだがなぁ x86exeが何となくでも動くだけでいいのにな
398 名前:login:Penguin mailto:sage [2018/02/16(金) 15:27:59.39 ID:80vLUCQ5.net] x86が動くWin10のARMが出る
399 名前:login:Penguin mailto:sage [2018/02/16(金) 16:20:26.93 ID:1h3N4gI+.net] ちょっと調べてから否定しようよ まあいいんだけどさ
400 名前:login:Penguin [2018/02/16(金) 19:29:08.29 ID:XuFK7/QF.net] 古いけど、Ubuntu12.01 への Wine3.0のインストールに成功した。 git のソースから、./configure 途中、Font関連のファイルが見つからないエラーが出たので、 そのFontの「dev版」をapt-getでインストール。 その他、いくつかエラーが出るので、インストールしたりする。 その後、make, make
401 名前:install。 でインストールには成功するが、今まで動いていたWinアプリを起動してみると 日本語で文字化けしてる。wintricks font や regedit などをいじってみたが、 ダメだった。しかし、apt-get remove wineとしたあと、再度、 apt-get install wineとすると、なぜか、すぐに成功した。 wine --versionとすると、なぜか、3.1のままだった。 不思議な事に、文字化けはすっきり解決した状態で、Ver 3.1のWineが動いているらしい。 実際、Windowsとの互換性は明らかに向上した。 [] [ここ壊れてます]
402 名前:login:Penguin [2018/02/16(金) 19:30:26.21 ID:XuFK7/QF.net] 3.1じゃなく、3.0でした。スマソ
403 名前:login:Penguin mailto:sage [2018/02/16(金) 19:37:33.92 ID:XuFK7/QF.net] Wzエディタで、検索やGrepのダイアログのStatic Textの表示が途切れてしまう 不具合があったのが、Wine3.0では修正されている。これは使える。
404 名前:login:Penguin mailto:sage [2018/02/16(金) 23:10:05.44 ID:XuFK7/QF.net] 透明色と MDI Window を組み合わせた自作WindowsアプリをWineで動くように修正中。 MDI Child Widnow のタイトルバーをドラッグすると遅くなるので原因を調査していた。 PreTranslateMessage() にくるメッセージを、自前でWindowに表示していたところ、 システム全体が実質的にハングアップした。マウスは動くが、タスクバーも反応しない。 ちなみに、透明色とMDI Windowの組み合わせが必ず遅くなるわけではない事は、 単純なテストプログラムを作って分かっている。ではなぜ、このプログラムに限っては 遅くなるのかが分からないので調査中だった。
405 名前:login:Penguin mailto:sage [2018/02/17(土) 14:20:45.23 ID:SLFwTllY.net] The Wine development release 3.2 is now available. What's new in this release (see below for details): - Separate implementation of USER controls for ComCtl32 v6. - Multisample texture support in Direct3D. - Support for HID gamepads. - More event support in MSHTML. - Obsolete DOS code removed. - Various bug fixes.
406 名前:login:Penguin mailto:sage [2018/02/17(土) 16:25:52.12 ID:XDWn7PKv.net] 廃れたDOSコードを削除、か
407 名前:login:Penguin mailto:sage [2018/02/17(土) 16:26:50.92 ID:KjUUJ1nJ.net] Wineは、Desktopの直接の子であるような、Win32における「OVERLAPED WINDOW」 的な物しか、XWindow の Window を作らないのだろうか?? Wineのソースをダウンロードして、FIXME(WARNでもいいはずだけど)で実行を調べてみた。 でも、良く分からない。ビルドとmake installに時間がかかるため、大変。 本当はもっと実験したいんだけど、時間的に難しくなる。 ソースを見ると、HWNDの親が Desktopの場合にだけ、XCreateWindowしているように 見える。これが、透明ウィンドウが遅くなる理由かもしれない。LinuxのNativeなWindowの 場合、実験した限り透明にしても速度が余り変わらない。でも、Wineがもし、自前で透明処理 をやっているとなれば遅くなるのも頷けるが。 1つのソースしか修正してないのに、ビルドが始まるまでに数十秒かかる。make installに また数十秒。それに、wineserver -k などにも時間がかかるし。なんか、30年前のビルド環境 みたいだ。
408 名前:login:Penguin mailto:sage [2018/02/17(土) 16:41:42.91 ID:eqmjcJnH.net] >>397 >ソースを見ると どこだかわからんからhttps://source.winehq.org/のリンク貼ってくれ
409 名前:login:Penguin mailto:sage [2018/02/17(土) 17:12:51.37 ID:KjUUJ1nJ.net] >>398 今回に関しては、以下を読んで、git でやってます : https://wiki.winehq.org/Git_Wine_Tutoria home directory (~) にて、 $ git clone git://source.winehq.org/git/wine.git [ret] とすると、wine ディレクトリが作成されるので、 $ cd wine とします。そこで、 $ git config remote.origin.url [ret] と入れて git://source.winehq.org/git/wine.gi と出れば、大
410 名前:フ DL 成功です。 ~/wine/ にソースが DL されており、dlls に Win32 の DLL 群の実装があります。 例えば、user32 などのフォルダがあります。~/wine/server に wine の中枢の プログラムが入っています。CreateWindow などは、dlls の方にありますが、 それを XWindowCreate に橋渡しするのは、server の方です。 オンラインで見たいなら、 https://source.winehq.org/git/wine.git/tree/HEAD:/dlls/user32 の win.c に CreateWindow 系のソースが入っており、 https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/user32/win.c で見られます。win.c の右の「raw」のボタンを押すと、ローカルの Wz エディタ などでも見られます。 [] [ここ壊れてます]
411 名前:login:Penguin [2018/02/17(土) 17:16:25.31 ID:KjUUJ1nJ.net] 5ch からのアクセスは禁止されているらしいので、アドレスバーに上記の URL を コピーしてアクセスしてください。 なお、make が遅い件は、make -j 4 などとして、マルチコア動作するとだいぶ良くなりました。 ただし、その場合、make にバグがあるので精密な神経の持ち主には、ストレスがたまります。
412 名前:login:Penguin mailto:sage [2018/02/17(土) 17:19:14.92 ID:KjUUJ1nJ.net] 動きをトレースしたい場合、TRACE はデフォルトではメッセージが出ず、使い方を調べて ないので、 FIXME( "Yamada Taro, CreateWindowEx, hWND=%08X", hWND ); みたいにやってます。
413 名前:login:Penguin mailto:sage [2018/02/17(土) 17:23:11.12 ID:KjUUJ1nJ.net] makeしたい人は、~/wine にて、 $ ./confiugre $ make -j 4 2>build.log $ make -j 4 install 2>inst.log $ wineserver -k で行けます。ここで、wz エディタを起動してみます。文字化けするようでしたら、 $ apt-get remove wine $ apt-get install wine で直ると思います。これは、一度やれば Ok のようです。
414 名前:login:Penguin mailto:sage [2018/02/17(土) 17:40:09.90 ID:KjUUJ1nJ.net] call set_window_pos() --> wine/dlls/user32/winpos.c --> X11DRV_WindowPosChanging() --> X11DRV_create_win_data() --> dlls/winex11.drv/window.c : static void create_whole_window( struct x11drv_win_data *data ) ---> data->whole_window = XCreateWindow( data->display, root_window, pos.x, pos.y, cx, cy, 0, data->vis.depth, InputOutput, data->vis.visual, mask, &attr ); という流れのようです。
415 名前:login:Penguin mailto:sage [2018/02/17(土) 17:41:22.28 ID:KjUUJ1nJ.net] 以下を見ると、親が、DesktopWindow の時のみ、create_whole_window() が呼び出されている らしいことが分かります。 static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *window_rect, const RECT *client_rect ) { Display *display; struct x11drv_win_data *data; HWND parent; if (!(parent = GetAncestor( hwnd, GA_PARENT ))) return NULL; /* desktop */ /* don't create win data for HWND_MESSAGE windows */ if (parent != GetDesktopWindow() && !GetAncestor( parent, GA_PARENT )) return NULL; if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId()) return NULL; display = thread_init_display(); init_clip_window(); /* make sure the clip window is initialized in this thread */ if (!(data = alloc_win_data( display, hwnd ))) return NULL; data->whole_rect = data->window_rect = *window_rect; data->client_rect = *client_rect; if (parent == GetDesktopWindow()){ create_whole_window( data ); TRACE( "win %p/%lx window %s whole %s client %s\n", hwnd, data->whole_window, wine_dbgstr_rect( &data->window_rect ), wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect( &data->client_rect )); } return data; }
416 名前:login:Penguin mailto:sage [2018/02/17(土) 17:42:23.86 ID:KjUUJ1nJ.net] >>403 の訂正: CreateWindowExW() ---> WIN_CreateWindowEx() call set_window_pos() --> wine/dlls/user32/winpos.c --> X11DRV_WindowPosChanging() --> X11DRV_create_win_data() --> dlls/winex11.drv/window.c : static void create_whole_window( struct x11drv_win_data *data ) ---> data->whole_window = XCreateWindow( data->display, root_window, pos.x, pos.y, cx, cy, 0, data->vis.depth, InputOutput, data->vis.visual, mask, &attr );
417 名前:login:Penguin mailto:sage [2018/02/17(土) 18:08:08.76 ID:KjUUJ1nJ.net] ちなみに、 1. ~/.wine 2. ~/wine は別物です。1は、binary をインストールした際に出来るデフォルトのフォルダ ですよね。2. は、git からソースを持ってきた時にできるディレクトリです。 まずは、バイナリをインストールして動作してから、ソースを持ってきてください。
418 名前:login:Penguin mailto:sage [2018/02/17(土) 18:27:32.24 ID:1JDlaACg.net] 半透明化はWin32API側でどうやっているの? Linuxネイティブなアプリでは? SetLayeredWindowAttributesであれば、user32.dllからUSER_Driverを介してwinex11.drvが呼ばれて、 window.c内のsync_window_opacityで_NET_WM_WINDOW_OPACITYにα値を設定している様子が見て取れる ttps://github.com/wine-mirror/wine/blob/wine-3.2/dlls/winex11.drv/window.c#L435 TRACEで表示しているメッセージを確認するには環境変数WINEDEBUGを使って、 WINEDEBUG=win,x11 みたいにカンマ区切りで指定する。細かくは ttps://wiki.winehq.org/Wine_Developer%27s_Guide/Debug_Logging に書いてある。 あとは、dlls配下の各ディレクトリでもmake && sudo make instlallできるので 特定のDLLファイルしか変更しないのであれば、この方法でビルド時間を短縮できるぞ。
419 名前:login:Penguin mailto:sage [2018/02/17(土) 18:42:48.23 ID:cvAP0C15.net] デバッグ大変だな。めんどくさそう。 仕事じゃないと俺はやらないだろうな。
420 名前:login:Penguin mailto:sage [2018/02/17(土) 19:41:54.60 ID:J9G7l4mf.net] 自分はimm32関連(日本語入力)APIを修正しようとeclipceでコンパイル環境作ったはいいけど ネイティブのウィンドウマネージャ関連の知識不足でソースの意味がわからず寝かせてある・・・
421 名前:login:Penguin mailto:sage [2018/02/17(土) 19:54:02.08 ID:Tf7u8zkg.net] >>407 Linux Nativeアプリの場合、32BIT COLOR にすると、A,R,G,B の 4つの値を ドットの「色」として指定できます。Aがα値です。このようなことは、Windows では出来ないと思います。Windowsの場合、CreateWindowExのdwExStyle に WS_EX_LAYEREDを指定すると透明、半透明が扱えるようになります。 1.完全に「透明になる色」を24BIT値で1色指定できます。この色で描いたドットは、 デスクトップまで透けて見えるようになります。見た目だけではなく、Windowメッ セージも下のWindowに伝達されてしまうことになりますが。 2.ドットごとではなく、Window全体のα値を1つ(1BYTE)だけ指定できます。 ドットごとでは無いので、全体的に透明度が決まってしまいます。 1と2は完全に別の概念です。 LinuxのARGB値は、ドット毎に指定できるので、Windowsの機能を包含していると 言えます。逆に Windowsでは、同じ事は出来ないはずです。
422 名前:login:Penguin mailto:sage [2018/02/17(土) 19:57:46.46 ID:Tf7u8zkg.net] /wine/dlls/winex11.drv/x11drv.h に次のような構造体があり、この whole_window というのが大事らしい: /* x11drv private window data */ struct x11drv_win_data { Display *display; /* display connection for the thread owning the window */ XVisualInfo vis; /* X visual used by this window */ Colormap colormap; /* colormap if non-default visual */ HWND hwnd; /* hwnd that this private data belongs to */ Window whole_window; /* X window for the complete window */ Window client_window; /* X window for the client area */ RECT window_rect; /* USER window rectangle relative to parent */ RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to parent */ XIC xic; /* X input context */ BOOL managed : 1; /* is window managed? */ BOOL mapped : 1; /* is window mapped? (in either normal or iconic state) */ BOOL iconic : 1; /* is window in
423 名前:iconic state? */ BOOL embedded : 1; /* is window an XEMBED client? */ BOOL shaped : 1; /* is window using a custom region shape? */ BOOL layered : 1; /* is window layered and with valid attributes? */ BOOL use_alpha : 1; /* does window use an alpha channel? */ int wm_state; /* current value of the WM_STATE property */ DWORD net_wm_state; /* bit mask of active x11drv_net_wm_state values */ Window embedder; /* window id of embedder */ unsigned long configure_serial; /* serial number of last configure request */ struct window_surface *surface; Pixmap icon_pixmap; Pixmap icon_mask; unsigned long *icon_bits; unsigned int icon_size; }; [] [ここ壊れてます]
424 名前:login:Penguin mailto:sage [2018/02/17(土) 20:00:42.49 ID:Tf7u8zkg.net] >>407 後半の二つ。自分に取っては、かなり貴重な情報です。助かります。
425 名前:login:Penguin mailto:sage [2018/02/17(土) 20:11:22.91 ID:Tf7u8zkg.net] >>407 XWindow で透明化。これはやってみて実際に出来ました: https://stackoverflow.com/questions/39906128/ how-to-create-semi-transparent-white-window-in-xlib 子ウィンドウを入れてみても、ちゃんと出来ました。 ただし、子ウィンドウには、Win32のような、タイトルバーは付ききませんでした。 XWindow に詳しい人によれば、XWindow の Window Manager は、 Win32 の MDI のような事は、サポートしていないらしいです。絶対か どうかは分かりませんが。 実験してみると、子ウィンドウも、親ウィンドウも、ABI で、XMoveWindow でスムーズに動かせました。 ただし、Wineの場合、子ウィンドウに直線や文字が書かれていて、かつ、背景が透明な場合、 スムーズには動かせません。
426 名前:login:Penguin mailto:sage [2018/02/17(土) 21:31:43.98 ID:cvAP0C15.net] Win32APIだけじゃなく、X Windowについても知っておかないといけないのか 面倒臭っ・・・ 普段使ってるだけでずいぶん楽してたんだな。
427 名前:login:Penguin mailto:sage [2018/02/17(土) 22:08:41.04 ID:eqmjcJnH.net] 面白そうだけど時間ねえな…… >>411 を見る限りだとuse_alphaは持ってるけどAlpha値自体はもうX11の構造体にいれてるのかな? まあ遅くなる理由とか検討つかんけど……
428 名前:396 mailto:sage [2018/02/18(日) 01:13:22.20 ID:DznsC7ZZ.net] WINEにおいて、 1. MDIのCMDIChildWndのCViewのCLIENT領域全体(子ウィンドウの 中全体と言ってもよい) に >>410 の1.の色を塗って、完全透明 にしている時は、CMDIChildWndのタイトルバー(子ウィンドウの タイトルバー)をドラッグしても高速に動かせる。 2. 1のCViewの中に、pDC->LineTo()で直線を一本描いた状態にしてから 同じ事をしようとすると、とても遅くなる。 3. 2.は、直線の代わりに pDC->TextOut() で文字を描いても同様に遅く なる。 4. 推定では、Wineは、Win32のCreateWindow系で、Parent Window が Desktop 以外の場合、XWindow の Window を使わず、自前で Parent Window の中に画像を合成して子Windowを模倣している。 5. 4.の様にしている理由は、推定だと Window Manager の種類による 挙動の違いに患わされずに安定して Emulation するためかも知れ ない。 6. その結果、XWindow の ARGB 値による高速な透明処理を利用できな くなり、低速になる。 7. しかし、なるべく低速にならないようにするため、少なくとも、 子ウィンドウの中全体が完全透明な場合については、対策が取ら れており、高速にドラッグできるようになっている。 8. その結果、2, 3 のような条件の時のみ遅くなると推定される。
429 名前:login:Penguin mailto:sage [2018/02/18(日) 01:24:45.49 ID:smHwezpH.net] 推定じゃなくて直接聞いたら?
430 名前:login:Penguin [2018/02/18(日) 01:56:23.18 ID:HH6qVqdM.net] >>417 どうやって?
431 名前:406 mailto:sage [2018/02/18(日) 02:29:31.78 ID:dARugMLm.net] >>416 すまん、ウィンドウの半透明化処理(LWA_ALPHA)と勘違いしてた。 ウィンドウ領域内の特定色で書いた箇所を透過させる場合(LWA_COLORKEY)ね。 ソースを調べたら、WineではX11のShape Extensionを使ってウィンドウの形状を変更することで、 「見た目だけではなく、Windowメッセージも下のWindowに伝達すること」を実現しているようだ。 具体的にはupdate_surface_region()で1ピクセルごとにピクセル値を比較して、 XShapeCombineRectanglesに指定する矩形領域を作っている。 ttps://github.com/wine-mirror/wine/blob/2936f3f9bb9dc01c595498a821d6adb6775b62cc/dlls/winex11.drv/bitblt.c#L1616 415の2.,3.の条件だと遅くなるとすると、ピクセル値を比較する処理は1.と同じなので、 矩形が大量になったときに、X側で描画性能が低下するのではないかと思うぞ。 StackOverflowの記事はShape Extensionを使っていないので筋違いだ。
432 名前:login:Penguin mailto:sage [2018/02/18(日) 04:20:47.62 ID:HH6qVqdM.net] >>419 なるほど。 1つ質問です。 はっきりとは書いてなかったのですが、>>416 の遅くなる条件であるところの 2,3 の場合 においても、CMainFrame、つまり、アプリケーション全体の Main の Window のタイトルバーを ドラッグした場合は、遅くなりません。いたって高速にドラッグできます。 >>419 が正しいなら、どうして、X は、この場合だけは速く、CMDIChildWnd の場合だけは 遅く動作するのでしょうか???
433 名前:login:Penguin mailto:sage [2018/02/18(日) 04:57:21.33 ID:HH6qVqdM.net] ↓の構造体の dc_rect の矩形が子ウィンドウを模倣するために使われているかも知れません: /* X physical device */ typedef struct { struct gdi_physdev dev; GC gc; /* X Window GC */ Drawable drawable; RECT dc_rect; /* DC rectangle relative to drawable */ RECT *bounds; /* Graphics bounds */ HRGN region; /* Device region (visible region & clip region) */ X_PHYSPEN pen; X_PHYSBRUSH brush; int depth; /* bit depth of the DC */ ColorShifts *color_shifts; /* color shifts of the DC */ int exposures; /* count of graphics exposures operations */ } X11DRV_PDEVICE; BOOL X11DRV_LineTo( PHYSDEV dev, INT x, INT y ) { X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); POINT pt[2]; GetCurrentPositionEx( dev->hdc, &pt[0] ); pt[1].x = x; pt[1].y = y; LPtoDP( dev->hdc, pt, 2 ); add_pen_device_bounds( physDev, pt, 2 ); if (X11DRV_SetupGCForPen( physDev )) XDrawLine(gdi_display, physDev->drawable, physDev->gc, physDev->dc_rect.left + pt[0].x, physDev->dc_rect.top + pt[0].y, physDev->dc_rect.left + pt[1].x, physDev->dc_rect.top + pt[1].y ); return TRUE; }
434 名前:login:Penguin mailto:sage [2018/02/18(日) 05:32:50.78 ID:HH6qVqdM.net] /wine/dlls/user32/painting.c の中の、 // Set the visible region and X11 drawable for the DC associated to a given window. static void update_visible_region( struct dce *dce ) の中に、 USER_Driver->pGetDC( dce->hdc, dce->hwnd, top_win, &win_rect, &top_rect, flags ); とあって、 void CDECL X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect, const RECT *top_rect, DWORD flags ) が呼び出される。引数に hwnd と top、win_rect と top_rect が対になっているらしいことに注意。 この関数の中で、x11drv_escape_set_drawable escape; の escape.dc_rect に、win_rect の top_rect の (left, top) からの相対座標が入れられる。 そして、ExtEscape( hdc, X11DRV_ESCA
435 名前:PE, sizeof(escape), (LPSTR)&escape, 0, NULL ); と ExtEscape() が呼び出される。 escape = X11DRV_ESCAPE; escape.code = X11DRV_SET_DRAWABLE; in_data = &escape; の状態で、 X11DRV_PDEVICE *physDev = get_x11drv_dev( dev ); const struct x11drv_escape_set_drawable *data = in_data; physDev->dc_rect = data->dc_rect; となる。physDev->dc_rect が、>>421 の dc_rect に他ならない。 つまり、HWND hwndのwin_rectの、HWND topの左上座標からの相対座標が、 physDev->dc_rect に入ることになると思われる。hwndの「最上位の親」が topだとすると、topだけが XCreateWindow()された本物のWindowであって、 hwnd は 擬似Windowであるとして辻褄が合う。hwndへの描画は、 実は座標だけを修正して top の(本物の X )Window に書き込まれているだけ かも知れない。 [] [ここ壊れてます]
436 名前:login:Penguin [2018/02/18(日) 12:58:43.05 ID:HH6qVqdM.net] 結論的には、Wine では、完全透明色が設定されている全ての LAYERED_WINDOW に 対して、Idle状態の時か、または、50(ms) 毎に、Windowアプリのメッセージループ の中から自動的に、>>419 の update_surface_region() が呼び出されるようになっ ているらしいです。この条件のWindowがあって、かつ、update_surface_region() の 処理が重い場合に、動作が遅くなる可能性が高いです。Dirty Bitのようなものは、 今のところ見つかっていませんので、何もしなくても常に重くなるのでしょうか。 【詳細】 flush_window_surfaces() なる関数が、定期的に呼び出される。 典型的なタイミングは、PeekMessage() の中からであり、GetMessage()では、 check_for_driver_events() を介して呼び出される。 flush_window_surfaces() の中に次のようなマクロ呼び出しがある : LIST_FOR_EACH_ENTRY( surface, &window_surfaces, struct window_surface, entry ) surface->funcs->flush( surface ); ここで、 /* iterate through the list using a list entry */ #define LIST_FOR_EACH_ENTRY(elem, list, type, field) \ for ((elem) = LIST_ENTRY((list)->next, type, field); \ &(elem)->field != (list); \ (elem) = LIST_ENTRY((elem)->field.next, type, field)) であり、上記は、window_surfaces リストに登録されている全ての window_surface *surface について、window_surface_funcs *funcs の 関数ポインタ flush の関数を呼び出すことになり、結局、 関数 x11drv_surface_flush() が呼び出されることになる。 関数 x11drv_surface_flush() の中に if (surface->is_argb || surface->color_key != CLR_INVALID) update_surface_region( surface ); とある。update_surface_region() は、>>419 に書かれている関数。
437 名前:396=422 mailto:sage [2018/02/18(日) 13:53:01.38 ID:HH6qVqdM.net] 該当の条件の時、新たには何の描画もしていない静止状態でも、Linuxのシステム・モニターで CPUパワーが膨大に消費されていることを確認しました。このことは、>>423 を裏付ける物です。 だとすると、Dirty Bit を導入して、update_surface_region()の頻度を下げれば、この低速化 は修正できる可能性が出てきました。LineTo, TextOut, MoveWindow, SetWindowPos, ShowWindow などを使ったときだけ、DirtyBit を 1にして、1の時だけ update_surface_region() を呼び出し、呼び出した後には 0 にすれば良いのではないかということです。 条件は: 1. WINEを使用して Windowsアプリを走らせていること。 2. アプリ内で CreateWindowEx() のdwExStyle に WS_EX_LAYERED を指定して Windowを作成 済みであること。 3. さらに、SetLayeredWindowAttribute() に LWA_COLORKEY を指定して「完全透明色」を 指定していること。 4. その Window の背景を「完全透明色」で消去していること。 5. その Window 内部に通常色で、LineTo() や TextOut() によって図形や文字を 描いた後であること。 です。 MDIを使っている事や、CMDIChildWnd 動かすかどうかは関係ない様です。 CMainFrame をドラッグした時には遅く感じないのは、その動作についてはシステムが CPU の優先順位を上げているからではないかと思います。
438 名前:396 mailto:sage [2018/02/18(日) 14:19:00.83 ID:HH6qVqdM.net] >>419 さんの指摘は凄く役立ちました。有難うございます。 ただし、こっちの調査不足のせいが大きいのでしょうが、以下の部分は、今回の 結果とは違っていたようです: >416の2.,3.の条件だと遅くなるとすると、ピクセル値を比較する処理は1.と同じなので、 >矩形が大量になったときに、X側で描画性能が低下するのではないかと思うぞ。 「X側の描画性能の低下」が原因ではなく、「ピクセル値を比較する処理」自体が、 実は「静止状態」でも、常時、大幅に増加していた、ということです。 何の変化がないときにでも、百万ピクセルを比較し、ランレングスを導き出す処理を、 原則的には秒間20回もやっています。 また、図形が複雑だと、システムコールを呼び出す回数がランレングスの変化の回数倍 されます。例えば、直線をN本引いた場合、システムコールの回数が原則 3N (倍)になります。 縦方向が500ドットのWindowで、1本の直線を引いた場合、一回の処理で、最低でも 6,000回のシステムコールが呼び出されます。これが秒間20回も行われますので、 最低で、秒間12万回のシステムコールとなります。1回のシステムコールは、5(μs) くらいはどうしてもかかるので、これだけで、0.6(秒)もかかってしまいます。 つまり、1秒間に0.6秒も無駄なシステムコールに時間を取られていると見積もれます。 直線を2本にすると、これだけでCPUがフルパワー状態になります。
439 名前:396 mailto:sage [2018/02/18(日) 14:38:25.11 ID:HH6qVqdM.net] 【厳密化】 1. 多分、6,000回ではなく、4,500回程度でした。 2. 比較処理自体は、図形の複雑さとは無関係にほぼ一定の重さです。 3. 図形が複雑な場合、システムコールの回数が増えます。 4. 横方向の1つのランレングスで、3つのシステムコールが呼ばれます。 5. 図形が何も描かれていない場合、1つのy座標に対して、1つのランレングスです。 6. N 本の直線の場合、大体で言えば、3N 個のランレングスになります。 7. だから、1つのy座標に対し、9N 個のシステムコールが呼ばれることになります。 8. 縦 500 ドットの場合、500*9N = 4500 N 回のシステムコールとなります。 9. よって、中に描かれている直線の本数が増えると、大体 O(N) で処理時間が 増えます。 10. 文字を描いた場合、大体、文字の複雑さに比例して処理時間が増えます。
440 名前:396 mailto:sage [2018/02/18(日) 15:25:59.15 ID:HH6qVqdM.net] >>426 【訂正】 「6.」のランレングスの個数は、3N個ではなく、2N+1 個でした。 お騒がせしました。
441 名前:login:Penguin mailto:sage [2018/02/18(日) 16:08:39.77 ID:dARugMLm.net] >>426 update_surface_regionの方が効率悪そうなので、X側の描画性能が原因と推測した部分は撤回する。 Shape Extensionの仕様を見ると、 矩形領域ではなくマスク用のPixmapを指定する方法も採れるから、 BitBltで効率よくマスクを作ればそっちの方が早くなるかもと思ってみたり。 あと、MDIウィンドウがXのWindowではないことは、xwininfoコマンドの結果でも確認できる。
442 名前:396 mailto:sage [2018/02/18(日) 17:01:36.91 ID:hqeoLLBF.net] >>428 >矩形領域ではなくマスク用のPixmapを指定する方法も採れるから、 >BitBltで効率よくマスクを作ればそっちの方が早くなるかもと思ってみたり。 少なくともその方法だと、図形の複雑さによらずに安定して同じ処理時間で 済みますね。それと当然、BitBlt はハードウェアの補助が得られます。 あと、システムコールも全体で数回しか呼ばなて済みますし。
443 名前:396 mailto:sage [2018/02/19(月) 12:40:07.08 ID:v4nZjJQ1.net] 特定のアプリの場合にだけは、自作の user32.dll.so を読み込ませる事が出来ない。 WINEDLLPATH, WINEPATH を試してみたが、今のところ上手く行かない。
444 名前:396 mailto:sage [2018/02/19(月) 15:28:56.74 ID:v4nZjJQ1.net] 調べてみると、/wine/libs/wine/loader.c の中の build_dll_path() 関数の中で、環境変数 WINEDLLPATH が、読み取られ、: を 0x00に 変えてから、dll_paths[] 配列に : で区切られたそれぞれの文字列 の先頭アドレスを代入している。 しかし、その処理に入る前に、get_dlldir() 関数が NULL 以外を返した場合、 dll_paths[0] にその関数が返した文字列のアドレスを入れてしまう。 そして、実際の get_dlldir() は、"/usr/local/bin/../lib/wine" という文字列を返してくるので、そっちのパスの方が、WINEDLLPATH の優先順位よりも上になってしまう。そして、 /* retrieve the default dll dir */ const char *get_dlldir( const char **default_dlldir ) { *default_dlldir = DLLDIR; return dlldir; } となっているが、DLLDIR が全ての拡張子の全ファイルを全文検索しても どこにも定義されておらず、参照されているのも唯一この関数だけだった。 これだと、WINEDLLPATH で「Override」できないのも当然だけど、 そもそも、DLLDIR がどこで定義されているのかが分からないので 誰かの教えをいただきたいです。
445 名前:login:Penguin mailto:sage [2018/02/19(月) 15:47:21.84 ID:qkc2SRTD.net] 見つかりました。wine/libs/wine/Makefileの中で、 config_EXTRADEFS = \ -DBINDIR='"${bindir}"' \ -DDLLDIR='"${dlldir}"' \ -DLIB_TO_BINDIR=\"`$(MAKEDEP) -R ${libdir} ${bindir}`\" \ -DLIB_TO_DLLDIR=\"`$(MAKEDEP) -R ${libdir} ${dlldir}`\" \ -DBIN_TO_DLLDIR=\"`$(MAKEDEP) -R ${bindir} ${dlldir}`\" \ -DBIN_TO_DATADIR=\"`$(MAKEDEP) -R ${bindir} ${datadir}/wine`\" というのが。単語検索していたのが鬼門でした。
446 名前:396 mailto:sage [2018/02/19(月) 19:22:56.55 ID:WuPPo4Ry.net] loader.c の build_dll_path() の修正と、user32.dll.so の修正を、 自分のアプリだけに適用する事に成功しました。
447 名前:396 mailto:sage [2018/02/20(火) 03:10:39.77 ID:nCkYsCc8.net] surface が NULL ではない場合、xxx->pLineTo() は、X11DRV_LineTo() ではなく、dibdrv_LineTo() が呼び出されるような・・・。
448 名前:396 mailto:sage [2018/02/20(火) 05:59:07.45 ID:nCkYsCc8.net] DirtyBit を使って、例の update_surface_region() は、 描画してないときには全く呼ばれないようにできたんですが、 まだかなり遅いです。何もしてないときにも CPU パワーがかなり消費されています。 その間、update_surface_region() が呼び出されていないことは、FIXME で 表示して確認が取れています。 なお、>>434 は、windrv_LineTo() の方の間違いでした。windrv_LineTo() の場合、 簡単に surface にアクセスできるので、surface に bNeedToUpdate のような フラグを追加して、それを 1 にして dirty bit にしています。 なぜ遅いままなのかは謎です。
449 名前:login:Penguin mailto:sage [2018/02/20(火) 06:05:44.26 ID:AmaI1OSV.net] 2ch(5ch?)は人は多いけど基本的にユーザーレベルの人ばかりだから技術的な書き込みしても反応は鈍いね Qiitaにでも書いてみたらどう?
450 名前:login:Penguin mailto:sage [2018/02/20(火) 18:28:22.71 ID:QMmYbOOf.net] 本家にパッチ投稿もお願いしますw
451 名前:396 mailto:sage [2018/02/20(火) 18:49:16.00 ID:nCkYsCc8.net] 遅い原因の1つは、Onldle の中にあることが分かりました。 1. 必要があって、外部ツールによるファイルの更新チェックをしていたところ、 それがとんでもなく重い事が判明。 2. SetTimer で CMainFrame にタイマーをしかけていると、CMainFrame::OnCmdMsg() が、WM_TIMER メッセージが来る度に、それを何倍にも掛け算した回数だけ呼び 出される事が判明。例えば、秒間 N 回のタイマーを仕掛けると、OnCmdMsg が、 10*N 回 呼び出されるような感じです。タイマーメッセージがくる度に、 メニューなどを更新するためのメッセージが来ているような気がします。 多分、本家 Windows では、タイマーメッセージが来ても、そのような事には ならないんじゃないかと思います。 通常、OnCmdMsg は頻度が低いことが 前提になっているので、その中で多少重い処理をしていると、とんでもなく 重たくなる。 なお、透明色を使っている場合、update_surface_region の中の処理の軽重に よって、描画速度が大幅に変わることも確認しました。 ランレングスを数えてリージョンを add_row している箇所を、単純に何も 数えずに行全体で、1個だけ add_row するように
452 名前:修正してみると、描画が だいぶ速くなりました(透明にはなりませんが。)。 [] [ここ壊れてます]
453 名前:login:Penguin [2018/02/20(火) 18:56:15.10 ID:nCkYsCc8.net] >>437 そうしたいんですが、何かと大変なんです。 1. メールアドレスの登録するのが、Linuxからだと大変。 2. git の仕様が良く分からない。 3. 回線が遅いので、Project を Fork して、git が Tree 全体を アップロードしようとしてしまったりなんかすると大変な事になる。 4. だから、一部のファイルだけを UL したいが、コミュニケーションの 問題から事情を伝えて、そこまで行くかどうか分からない。 5. だから、独自にオーバーライドしようとしたのが、先日からここでも 書いていたことです。loader を修正して、かつ、環境変数を変えて やれば、本家と統合しなくても、部分書き変えのような事が出来る。
454 名前:login:Penguin mailto:sage [2018/02/20(火) 18:59:20.15 ID:TT83z4l8.net] >>439 githubからでもプルリクエスト受け付けてるよ
455 名前:login:Penguin mailto:sage [2018/02/20(火) 19:09:08.87 ID:LN/W3cN7.net] 先にhttps://bugs.winehq.org/に書いた方がいい 報告してあるとパッチ送る時説明が楽になるから
456 名前:login:Penguin mailto:sage [2018/02/20(火) 19:12:23.54 ID:hMkWg0ue.net] 描画が早くなるならありがたい 素のWindowsより異様に遅いゲームとかあるし
457 名前:396 mailto:sage [2018/02/20(火) 20:06:46.63 ID:ErFPSqeX.net] 結論だけ書いておくと、surfaceが非NULLの時の LineTo の実体は、 windrv_LineToで、surface を lock する以外は、dibdrv_LineTo と同じ。 dibdrv_LineToは、bits なるpixel配列に 32BITの色値を書き込む。 実際は汎用性のため、必ずandしてからxorする。SOLIDモードの場合、and値は0。 xor値は、00RRGGBB で、最上位バイトは0。 実際への画面の反映は、定期的に「xxx->flush」なる関数ポインタを介して、 x11drv_surface_flush() を呼び出す事で行う。その中で、議題になっている update_surface_region() も呼ばれる。最後に bits の内容を実画面に反映させる ため、XShmPutImage()または、XPutImage(), XFlush()を行う。 surface->image の pixel バッファは、bits[] 配列と共通らしい。 つまり、Linux の描画関数は全く使わずに自前で画像をpixel配列に合成してから、 定期的に、XPutImage() などで実が面に描き込む、というようなことをやっているらしい。
458 名前:396 mailto:sage [2018/02/21(水) 16:48:35.77 ID:SJPTXnf1.net] update_surface_region() が遅いんだと思って、 XShape の作成を、XShapeCombineRectangles() を使う方式から、 XCreateBitmapFromData() と XShapeCombineMask() を使う方式へと変えた。 すると、1146 x 745 のサイズの Window で、 1. 自前のコードによる 1bit の mask bitmap 作成にかかる時間 : 796 (us) 2. XCreateBitmapFromData() と XShapeCombineMask() にかかる時間 : 38 (us) 3. XShmPutImage() と XFlush() ; x11drv_surface_flush()内 の両方にかかる時間 : 94 (us) 4. MDI Child Wnd をドラッグするときに、x11drv_surface_flush() が 呼び出される時間間隔 : 3〜100 (ms) ---> 秒間 10回〜330回 5. 肉眼で描画が更新されるまでに x11drv_surface_flush() が呼び出される回数 : 数10回 以上あることが多い。 1.〜4. だけみると、高速に処理されている様に見えるけど、5. だけが理解できない。 カウンタを設けて数えてみると、実際に目では更新が起きてないのに、 ちゃんと、1〜3 の全ての関数が数十回も呼び出されている。 ちゃんと「XFlush()」されているのに、なぜだろう????
459 名前:login:Penguin mailto:sage [2018/02/21(水) 17:03:51.93 ID:SJPTXnf1.net] XSync() を追加しても、XShmPutImage() を XPutImage() に修正しても、 何をやっても見た目だけが更新されない。
460 名前:login:Penguin mailto:sage [2018/02/21(水) 17:09:56.25 ID:iuEniYB2.net] >>444 > update_surface_region() が遅いんだと思って、 > XShape の作成を、XShapeCombineRectangles() を使う方式から、 > XCreateBitmapFromData() と XShapeCombineMask() > を使う方式へと変えた。 こうするとなんで速くなるの?
461 名前:396 mailto:sage [2018/02/21(水) 17:35
] [ここ壊れてます]
462 名前::51.39 ID:SJPTXnf1.net mailto: >>446 それは、 >>428-429 の部分と深く関係しています。 [] [ここ壊れてます]
463 名前:login:Penguin mailto:sage [2018/02/21(水) 17:39:34.11 ID:SJPTXnf1.net] X の同期の問題ではなく、MDI Child Wnd の TITLE BAR をドラッグするとき、 なぜか、数秒経ってから、x11drv_surface_flush() がまとめて何十回も呼び出されている 可能性があるかも・・・。 デバッグ表示をリアルタイムで見ていると、見た目が変化する直前までデバッグ表示が 全く出ず、見た目が変化する直前に、どどっと、数十回分の x11drv_surface_flush() がまとめて出てくる、という現象が起きている。
464 名前:login:Penguin mailto:sage [2018/02/21(水) 17:56:34.37 ID:iuEniYB2.net] >>448 flushしてないだけではなく?
465 名前:396 mailto:sage [2018/02/21(水) 17:57:13.78 ID:SJPTXnf1.net] 以下のコードが気になる。 message_count を減少させるのは唯一、wait_message() しか見つからなかった。 後は、check_for_driver_events() の中で単調増加してしまう。 メッセージがたまって初めて、flush_window_surfaces() が呼び出されるような コードにも /* check for driver events if we detect that the app is not properly consuming messages */ static inline void check_for_driver_events( UINT msg ) { if (get_user_thread_info()->message_count > 200) { flush_window_surfaces( FALSE ); USER_Driver->pMsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_ALLINPUT, 0 ); } else if (msg == WM_TIMER || msg == WM_SYSTIMER) { /* driver events should have priority over timers, so make sure we'll check for them soon */ get_user_thread_info()->message_count += 100; } else get_user_thread_info()->message_count++; } static DWORD wait_message( DWORD count, const HANDLE *handles, DWORD timeout, DWORD mask, DWORD flags ) { DWORD ret = USER_Driver->pMsgWaitForMultipleObjectsEx( count, handles, timeout, mask, flags ); if (ret == WAIT_TIMEOUT && !count && !timeout) NtYieldExecution(); if ((mask & QS_INPUT) == QS_INPUT) get_user_thread_info()->message_count = 0; return ret; }
466 名前:396 mailto:sage [2018/02/21(水) 17:58:18.49 ID:SJPTXnf1.net] BOOL WINAPI DECLSPEC_HOTPATCH PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT flags ) { MSG msg; USER_CheckNotLock(); check_for_driver_events( 0 ); if (!peek_message( &msg, hwnd, first, last, flags, 0 )) { DWORD ret; flush_window_surfaces( TRUE ); ret = wow_handlers.wait_message( 0, NULL, 0, QS_ALLINPUT, 0 ); /* if we received driver events, check again for a pending message */ if (ret == WAIT_TIMEOUT || !peek_message( &msg, hwnd, first, last, flags, 0 )) return FALSE; } check_for_driver_events( msg.message ); /* copy back our internal safe copy of message data to msg_out. * msg_out is a variable from the *program*, so it can't be used * internally as it can get "corrupted" by our use of SendMessage() * (back to the program) inside the message handling itself. */ if (!msg_out) { SetLastError( ERROR_NOACCESS ); return FALSE; } *msg_out = msg; return TRUE; }
467 名前:396 mailto:sage [2018/02/21(水) 18:24:27.09 ID:SJPTXnf1.net] >>449 PeekMessage()を回しているだけの時で、メッセージがキューに残り続けている場合、 メッセージを 200回 (100回?) PeekMessage するまでは、flush_window_surfaces() されないコードになっている気がしませんか・・・。
468 名前:login:Penguin [2018/02/21(水) 18:32:33.53 ID:SJPTXnf1.net] GetMessage() の方もほぼ同じような感じかも。。 とにかく、flush_window_surfaces() がとてつもなく長い間、呼ばれないことが あるコードになっている様に見えて、実際、実験してもそう思える。
469 名前:login:Penguin mailto:sage [2018/02/21(水) 18:38:45.85 ID:SJPTXnf1.net] そうか、もともとは、dirty bit 方式じゃないから、flush_window_surfaces() を呼ぶと、 再計算する必要が無いのに必ず再計算されてしまうから、呼び出す頻度を下げるしか 高速化する方法が無いために、そんな風なコードになっているのかもしれない。