WINE/Разработчику/Изображения

Материал из Русский WINE
Перейти к: навигация, поиск
Wackowiki-logo.png Blue Glass Arrow.svg MediaWiki logo.png
Эта страница была автоматически перемещена с old.wiki.etersoft.ru.
Эта страница наверняка требует чистки и улучшения — смело правьте разметку и ссылки.
Просьба по окончанию убрать этот шаблон со страницы.


Проблемы с изображением

Ситуация с DIB

Есть DC. Он связан с устройством, и его обрабатывают функции драйвера (WINEX11).

Созданный на его основе CompatibleDC (memdc), выполняющий все операции над DIB (в памяти), должен обрабатываться функциями DIB Engine.

В gdi32 вызов нужной функции драйвера происходит на основе таблицы с функциями, указатель на которую (dc->funcs) хранится в объекте. Если функция присутствует, она вызывается. Если функции нет, возможно использование альтернативной реализации прямо из gdi32.


Последняя реализация использует хак в SelectObject, которая если вызвана для memdc, подгружает драйвер DIB, его функции попадают в таблицу, и далее для этого объекта вызываются только функции DIB Engine.


Наша цель в этой таблице функций (для memdc) постепенно (по мере разработки) подменять функции драйвера на функции DIB Engine.


CyrilMargorin /11.10.2008 11:48/

Есть ли для этого Test cases? Сегодня к вечеру попробую просмотреть, чтобы понять выше написаное (без кода, описание не совсем понятно).


Кирилл, я уже и потерял связь давно... Может быть спишемся, или в аське/джаббере? JID: lav@im.etersoft.ru


CyrilMargorin /11.10.2008 17:56/

К сожалению, из дома в аське стараюсь не сидеть (ибо она у меня рабочая). Джаббер соответсвует е-мылу: comargo@gmail.com, но тоже забываю включить дома. На работе включена всегда.

Сейчас пока включил.



Некие проблемы с графикой

Проблемы с изображением можно увидеть на

  • Заставке к КОМПАС - падает при запуске без патча
  • Также на этом падает Консультант+ (если запускать с патчем ;))


Ситуация:

1. код около функции BITMAP_Object неверный

2. патч тоже неверный

3. в /wine/dlls/gdi/tests/bitmap.c

должны быть тесты об этом, они тоже неверные (если их исправить, они должны работать на Windows и не работать в wine)



Патч, корректирующий проблему для КОМПАСА

Index: bitmap.c

===================================================================

RCS file: /home/wine/wine/dlls/gdi/bitmap.c,v

retrieving revision 1.7

diff -u -u -r1.7 bitmap.c

--- bitmap.c    13 Apr 2005 16:11:18 -0000      1.7

+++ dlls/gdi/bitmap.c   17 May 2005 18:44:52 -0000

@@ -612,6 +612,7 @@



 /***********************************************************************

  *           BITMAP_GetObject

+ * Fill buffer with BITMAP or DIPSECTION (depends on dib field and count size)

  */

 static INT BITMAP_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )

 {

@@ -621,26 +622,19 @@

     {

         if( !buffer )

             return sizeof(DIBSECTION);

-       if (count < sizeof(DIBSECTION))

-       {

-           if (count > sizeof(BITMAP)) count = sizeof(BITMAP);

-       }

-       else

-       {

-           if (count > sizeof(DIBSECTION)) count = sizeof(DIBSECTION);

-       }

-

-       memcpy( buffer, bmp->dib, count );

-       return count;

-    }

-    else

-    {

-        if( !buffer )

-            return sizeof(BITMAP);

-       if (count > sizeof(BITMAP)) count = sizeof(BITMAP);

-       memcpy( buffer, &bmp->bitmap, count );

-       return count;

+        if (count >= sizeof(DIBSECTION))

+        {

+            count = sizeof(DIBSECTION);

+            memcpy( buffer, bmp->dib, count );

+            return count;

+        }

+        if (count > sizeof(BITMAP)) count = sizeof(BITMAP);

     }

+    if( !buffer )

+        return sizeof(BITMAP);

+    if (count > sizeof(BITMAP)) count = sizeof(BITMAP);

+    memcpy( buffer, &bmp->bitmap, count );

+    return count;

 }


//Похоже надо через таблицу цветов превращать из 24х битовой в 4х битовую....

При этом надо учитывать, что кроме 24х битового дисплея бывает еще и 32 и 16.... а иногда и 8ми.....

В теории можно повнимательней просмотреть код около функции X11_GetDIBits() (или как то так она называется) и еще (скорее всего) необходимо сделать схожие изменения в функции X11_SetBitmapBits...//


CyrilMargorin /10.12.2005 01:38/

Появилась для обсуждение идея, перевести функцию CopyImage с Get/SetBitmapBits на Get/SetDIBits. Попытка сделать это в общем-то была успешна....

Index: dlls/user/cursoricon.c

===================================================================

RCS file: /home/wine/wine/dlls/user/cursoricon.c,v

retrieving revision 1.22

diff -u -r1.22 cursoricon.c

--- dlls/user/cursoricon.c      5 Dec 2005 20:07:34 -0000       1.22

+++ dlls/user/cursoricon.c      9 Dec 2005 22:29:21 -0000

@@ -2322,14 +2322,39 @@



             if (!GetObjectW( hnd, sizeof(bm), &bm )) return 0;

             bm.bmBits = NULL;

-            if ((res = CreateBitmapIndirect(&bm)))

-            {

-                char *buf = HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight );

-                GetBitmapBits( hnd, bm.bmWidthBytes * bm.bmHeight, buf );

-                SetBitmapBits( res, bm.bmWidthBytes * bm.bmHeight, buf );

-                HeapFree( GetProcessHeap(), 0, buf );

-            }

-            return (HICON)res;

+           if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );

+           if (screen_dc)

+           {

+               if((res = CreateCompatibleBitmap(screen_dc,bm.bmWidth,bm.bmHeight)))

+               {

+                   BITMAPINFO* pbmi;

+                   char *buf;

+                   char *bmibuf;

+                   int nColor=0;

+                   if(bm.bmBitsPixel <= 8)

+                       nColor = 1<<bm.bmBitsPixel;

+                   if(bm.bmBitsPixel == 15 || bm.bmBitsPixel == 16)

+                       nColor = 3;

+                   bmibuf = HeapAlloc( GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER)+nColor*sizeof(RGBQUAD));

+                   pbmi = (BITMAPINFO*)bmibuf;

+                   ZeroMemory(pbmi,sizeof(BITMAPINFOHEADER)+nColor*sizeof(RGBQUAD));

+                   pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);

+                   pbmi->bmiHeader.biWidth = bm.bmWidth;

+                   pbmi->bmiHeader.biHeight = bm.bmHeight;

+                   pbmi->bmiHeader.biPlanes = bm.bmPlanes;

+                   pbmi->bmiHeader.biBitCount = bm.bmBitsPixel;

+                   pbmi->bmiHeader.biCompression = BI_RGB;

+                   buf = HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight );

+                   GetDIBits(screen_dc,hnd,0,bm.bmHeight,buf,pbmi,DIB_RGB_COLORS);

+                   SetDIBits(screen_dc,res,0,bm.bmHeight,buf,pbmi,DIB_RGB_COLORS);

+                   HeapFree( GetProcessHeap(), 0, bmibuf );

+                   HeapFree( GetProcessHeap(), 0, buf );

+               }

+               return (HICON)res;

+           }

+           /* In case of error it should return 0

+            */

+           return 0;

         }

         case IMAGE_ICON:

                 return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);



CyrilMargorin /13.02.2006 23:32/

После дальнейшего исследования проблемы с пропавшей заставкой в

Компасе выяснилось, что проблема состоит в том, что функция GetDIBits

возвращает "черную" картинку.

При этом, компиляция wine с выключенной поддержкой Shared Memory

картинку проявило.

Таким образом наткнулись на следующий момент

Есть следующий код:

dlls/x11drv/dib.c функция X11DRV_DIB_GetImageBits

XImage *bmpImage;



   wine_tsx11_lock();

  if (descr->image)

       bmpImage = descr->image;

   else {

       bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,

                                descr->infoWidth, lines, 32, 0 );

       bmpImage->data = calloc( lines, bmpImage->bytes_per_line );

       if(bmpImage->data == NULL) {

           ERR("Out of memory!\n");

           XDestroyImage( bmpImage );

           wine_tsx11_unlock();

           return lines;

       }

   }



#ifdef HAVE_LIBXXSHM

   if (descr->image && descr->useShm)

   {

       int saveRed, saveGreen, saveBlue;



       TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",

                           gdi_display, descr->drawable, bmpImage,

                           descr->xSrc, descr->ySrc, AllPlanes);

       saveRed = bmpImage->red_mask;

       saveBlue= bmpImage->blue_mask;

       saveGreen = bmpImage->green_mask;



       XShmGetImage( gdi_display, descr->drawable, bmpImage,

                     descr->xSrc, descr->ySrc, AllPlanes);



       bmpImage->red_mask = saveRed;

       bmpImage->blue_mask = saveBlue;

       bmpImage->green_mask = saveGreen;

   }

   else

#endif /* HAVE_LIBXXSHM */

   {

       TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",

             gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,

             lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);

       XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,

                     descr->width, lines, AllPlanes, ZPixmap,

                     bmpImage, descr->xDest, descr->yDest );

   }


В случае, если descr->image равен нулю, создается новый XImage, без поддержки Shared Memory, но если был передан параметр useShm, для получения XImage из Pixmap используется функция с поддержкой Shared Memory, которая есстественно не срабатывает в данном случае. (Схожий код исспользуется в X11DRV_DIB_SetImageBits).

Таким образом, первый патч заключается в проверке, создавалася ли XImage локально, или исспользовался внешний?

===================================================================

RCS file: /home/wine/wine/dlls/x11drv/dib.c,v

retrieving revision 1.49

retrieving revision 1.50

diff -u -p -r1.49 -r1.50

--- wine/dlls/x11drv/dib.c	2006/02/13 13:09:31	1.49

+++ wine/dlls/x11drv/dib.c	2006/02/13 13:09:49	1.50

@@ -3626,7 +3626,7 @@ static int X11DRV_DIB_SetImageBits( cons

      descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,

      descr->width, descr->height);

 #ifdef HAVE_LIBXXSHM

-    if (descr->useShm)

+    if (descr->image && descr->useShm)

     {

         XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,

                       descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,

@@ -3670,7 +3670,7 @@ static int X11DRV_DIB_GetImageBits( cons

     }

 

 #ifdef HAVE_LIBXXSHM

-    if (descr->useShm)

+    if (descr->image && descr->useShm)

     {

         int saveRed, saveGreen, saveBlue;
Внимание вопрос: А может быть имеет смысл попытаться создать Shared Memory XImage? Или эта операция недостаточно быстрая и будет тормозить систему
?


Второй момент:

В функции X11DRV_GetDIBits при заполнении структуры X11DRV_DIB_IMAGEBITS_DESCR descr в поле image записывался NULL. Соответственно было изменено на существующий XImage из physBitmap.

RCS file: /home/wine/wine/dlls/x11drv/dib.c,v

retrieving revision 1.48

retrieving revision 1.49

diff -u -p -r1.48 -r1.49

--- wine/dlls/x11drv/dib.c	2005/12/13 18:25:52	1.48

+++ wine/dlls/x11drv/dib.c	2006/02/13 13:09:31	1.49

@@ -4080,7 +4080,7 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *ph

   descr.physDev   = physDev;

   descr.palentry  = palette;

   descr.bits      = bits;

-  descr.image     = NULL;

+  descr.image     = physBitmap->image;

   descr.infoWidth = width;

   descr.lines     = lines;

   descr.depth     = physBitmap->pixmap_depth;
Внимание вопрос: А в функции X11DRV_SetDIBits тоже наверно надо передавать image из physBitmap
?


Оба патча вошли в репозиторий cvs.winehq.org 13 февраля 2006.

Wine
Search.png
Программы работающие в WineСкачатьШкольный Wine
WINE@Etersoft Общие сведенияУстановка на 64-битные ОСОсобенности разработкиПатчи для WINE@EtersoftАдминистративная установкаДополнительные компонентыКак получить WINE@Etersoft?Лицензия на документациюГлоссарийИспользование аппаратных ключей защиты в LinuxДополнительная информация • [ Совместная работа | по CIFSпо NFS ] • Изменение системных ограниченийРегистрация продуктаПошаговая инструкция по установке rpm-пакетовОбращение в службу поддержкиТерминальные решенияУстановка WINE@EtersoftПодписка на обновленияНастройка WINE@EtersoftРазработчикуEnterpriseЧто такое WINE@Etersoft SQLВозможностиСреда для запуска приложений WindowsИспользование WINE@EtersoftFAQ по использованию WINE@EtersoftОсновные командыWINE@Etersoft/LocalЧто такое WINE@Etersoft Local
Программы Запуск БЭСТ 4+Запуск Консультант+ (сетевой версии)ГарантF1Инфо-Бухгалтер 8.xНалогоплательщик ЮЛ
1C Отличия от обычного WineМестоположение базы 1С1C: Предприятие 7.7 в WINEНастройка 1С 7.7 для работы с SQL-серверомУстановка 1С: Предприятия 8.1Установка 1С: Предприятия 8.1 в трёхзвенном режиме
Пользователю
Помощь Использование WinecfgИспользование RegeditПубличный префиксНесколько версийКлючи regedit
Легальность DCOM95IE5DCOMMSXML
Утилиты для работы с Wine WinetricksWineToolsQ4WinePlayOnLinuxIEs4LinuxWine-DoorsSwineWine LauncherLutris
Разработчику
Компоненты WindowsЗапрет отключения защиты программыУправление обработчиком исключенийStraceNTИзмерение скорости функций WinAPIGLУстройство чтения смарт-картПрофилированиеТесты для проверки интерфейсовНаписание тестов в системе WineАутентификация в домене ADРепозиторииПрименение Git-патчей
Помощь Создание патчейНаписание приложения под wineОтправка патчейСборка eterhackСборка wine-public
Отладка Способы отладкиWINEDEBUGWinedbg
Разработка WINE
1CODBCWinHelpКомпасМетодикаТестирование доступаЦветаФайловый диалогТестированиеЛитератураИзображенияWin32ШрифтыФайловые блокировкиСсылкиКлючи защитыRPMWineGeckoListViewУпаковка Wine
Производителю
Родственные проекты
LUKReactOSARWINSSCrossOverKernelEx
Прочее
PageSetupDlgFreeBSDWwr