ちなみに、透明色とMDI Windowの組み合わせが必ず遅くなるわけではない事は、 単純なテストプログラムを作って分かっている。ではなぜ、このプログラムに限っては 遅くなるのかが分からないので調査中だった。 0394login:Penguin2018/02/17(土) 14:20:45.23ID:SLFwTllY 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. 0395login:Penguin2018/02/17(土) 16:25:52.12ID:XDWn7PKv 廃れたDOSコードを削除、か 0396login:Penguin2018/02/17(土) 16:26:50.92ID:KjUUJ1nJ Wineは、Desktopの直接の子であるような、Win32における「OVERLAPED WINDOW」 的な物しか、XWindow の Window を作らないのだろうか?? Wineのソースをダウンロードして、FIXME(WARNでもいいはずだけど)で実行を調べてみた。 でも、良く分からない。ビルドとmake installに時間がかかるため、大変。 本当はもっと実験したいんだけど、時間的に難しくなる。
LinuxのARGB値は、ドット毎に指定できるので、Windowsの機能を包含していると 言えます。逆に Windowsでは、同じ事は出来ないはずです。 0410login:Penguin2018/02/17(土) 19:57:46.46ID:Tf7u8zkg /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 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; }; 0411login:Penguin2018/02/17(土) 20:00:42.49ID:Tf7u8zkg>>406 後半の二つ。自分に取っては、かなり貴重な情報です。助かります。 0412login:Penguin2018/02/17(土) 20:11:22.91ID:Tf7u8zkg>>406 XWindow で透明化。これはやってみて実際に出来ました: https://stackoverflow.com/questions/39906128/ how-to-create-semi-transparent-white-window-in-xlib
はっきりとは書いてなかったのですが、>>415の遅くなる条件であるところの 2,3 の場合 においても、CMainFrame、つまり、アプリケーション全体の Main の Window のタイトルバーを ドラッグした場合は、遅くなりません。いたって高速にドラッグできます。
>>418 が正しいなら、どうして、X は、この場合だけは速く、CMDIChildWnd の場合だけは 遅く動作するのでしょうか??? 0420login:Penguin2018/02/18(日) 04:57:21.33ID:HH6qVqdM ↓の構造体の 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; } 0421login:Penguin2018/02/18(日) 05:32:50.78ID:HH6qVqdM /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 が対になっているらしいことに注意。
/* 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++; }
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; } 04513962018/02/21(水) 18:24:27.09ID:SJPTXnf1>>448 PeekMessage()を回しているだけの時で、メッセージがキューに残り続けている場合、 メッセージを 200回 (100回?) PeekMessage するまでは、flush_window_surfaces() されないコードになっている気がしませんか・・・。 0452login:Penguin2018/02/21(水) 18:32:33.53ID:SJPTXnf1 GetMessage() の方もほぼ同じような感じかも。。
EnterCriticalSection( &surfaces_section ); now = GetTickCount(); if (idle) last_idle = now; /* if not idle, we only flush if there's evidence that the app never goes idle */ else if ((int)(now - last_idle) < 50) goto done;
この最後の関数の中に、次のような、メッセージ・ループがある: if (!GetMessageW( &msg, 0, 0, 0 )) break; if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
/* Exit on button-up, Return, or Esc */ if ((msg.message == WM_LBUTTONUP) || ((msg.message == WM_KEYDOWN) && ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE)) { TranslateMessage( &msg ); DispatchMessageW( &msg ); continue; /* We are not interested in other messages */ } 04663962018/02/22(木) 01:32:06.83ID:9+xI5ulA さらに次のような、枠だけを書くか、実際に動かしてしまうコードが続く :