Subversion Repositories filter_foundry

Rev

Rev 407 | Rev 492 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     This file is part of a common library for Adobe(R) Photoshop(R) plugins
  3.     Copyright (C) 2002-6 Toby Thain, toby@telegraphics.com.au
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19.  
  20. #include <windows.h>
  21. #include <stdlib.h>
  22.  
  23. #include "ui_compat.h"
  24.  
  25. #include "str.h"
  26. #include "dbg.h"
  27.  
  28. /* see "DIBs and Their Use",
  29.    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dngdi/html/msdn_dibs2.asp */
  30.  
  31. typedef HBITMAP(__stdcall* f_CreateDIBSection)(HDC hdc, CONST BITMAPINFO* pbmi, UINT usage, VOID** ppvBits, HANDLE hSection, DWORD offset);
  32. HBITMAP _CreateDIBSection(HDC hdc, CONST BITMAPINFO* pbmi, UINT usage, VOID** ppvBits, HANDLE hSection, DWORD offset) {
  33.         // Calling dynamically, because Windows NT 3.1 does not support CreateDIBSection
  34.         HMODULE hLib;
  35.         f_CreateDIBSection fCreateDIBSection;
  36.         HBITMAP res;
  37.  
  38.         hLib = LoadLibrary(TEXT("GDI32.DLL"));
  39.         if (!hLib) return 0;
  40.         fCreateDIBSection = (f_CreateDIBSection)(void*)GetProcAddress(hLib, "CreateDIBSection");
  41.         if (fCreateDIBSection != 0) {
  42.                 res = fCreateDIBSection(hdc, pbmi, usage, ppvBits, hSection, offset);
  43.                 FreeLibrary(hLib);
  44.                 return res;
  45.         }
  46.         else {
  47.                 return NULL;
  48.         }
  49. }
  50.  
  51. Boolean newbitmap(BITMAPREF *ppb,int depth,UIRECT *bounds){
  52.         //char s[0x100];
  53.         if( (*ppb = (BITMAPREF)malloc(sizeof(**ppb))) ){
  54.                 BITMAPINFOHEADER *pbmih = &(*ppb)->bmi.bmiHeader;
  55.  
  56.                 pbmih->biWidth = bounds->right - bounds->left;
  57.                 pbmih->biHeight = bounds->top - bounds->bottom; // negative: top-down!
  58.                 pbmih->biSize = sizeof(BITMAPINFOHEADER);
  59.                 pbmih->biPlanes = 1;
  60.                 pbmih->biBitCount = depth; // blue,green,red; high byte not used
  61.                 pbmih->biCompression = BI_RGB;
  62.                 pbmih->biSizeImage = 0; //(*ppb)->rowbytes * -pbmih->biHeight;
  63.                 pbmih->biXPelsPerMeter =
  64.                 pbmih->biYPelsPerMeter = 0;
  65.                 pbmih->biClrUsed =
  66.                 pbmih->biClrImportant = 0;
  67.  
  68.                 (*ppb)->hbmp = _CreateDIBSection(NULL/*hDC*/,&(*ppb)->bmi,DIB_RGB_COLORS,(void**)&(*ppb)->pbits,NULL,0);
  69.  
  70.                 (*ppb)->rowbytes = ((depth * pbmih->biWidth + 31) >> 3) & -4;
  71.  
  72.                 if( (*ppb)->hbmp ){
  73.  
  74.                         /*long i,j,*p;
  75.  
  76.                         char s[0x200];
  77.                         sprintf(s,"newbitmap: biWidth = %d,rowbytes = %d,biHeight = %d,biSize = %d,biBitCount = %d,result = %#x",
  78.                         pbmih->biWidth,(*ppb)->rowbytes,pbmih->biHeight,
  79.                         pbmih->biSize,pbmih->biBitCount,(*ppb)->hbmp );
  80.                         dbg(s);
  81.  
  82.                         // checkerboard test pattern
  83.                         for(j = -pbmih->biHeight,p=(long*)(*ppb)->pbits;j--;p+=(*ppb)->rowbytes/4)
  84.                         for(i=pbmih->biWidth;i--;)
  85.                         p[i] = -( (i^j)&1 ) ;*/
  86.  
  87.                         return true;
  88.                 }else
  89.                         dbg((TCHAR*)TEXT("CreateDIBSection FAILED"));
  90.         }
  91.         return false;
  92. }
  93.  
  94. void disposebitmap(BITMAPREF pb){
  95.         if(pb){
  96.                 DeleteObject(pb->hbmp);
  97.                 free(pb);
  98.         }
  99. }
  100.  
  101. typedef struct _tagMONITORINFO
  102. {
  103.         DWORD   cbSize;
  104.         RECT    rcMonitor;
  105.         RECT    rcWork;
  106.         DWORD   dwFlags;
  107. } _MONITORINFO, *_LPMONITORINFO;
  108.  
  109. typedef struct _HMONITOR__* _HMONITOR;
  110.  
  111. typedef BOOL(__stdcall* f_GetMonitorInfoA)(_HMONITOR hMonitor, _LPMONITORINFO lpmi);
  112. BOOL _GetMonitorInfoA(_HMONITOR hMonitor, _LPMONITORINFO lpmi) {
  113.         // Calling dynamically, because Windows 95 does not support GetMonitorInfoA
  114.         HMODULE hLib;
  115.         f_GetMonitorInfoA fGetMonitorInfoA;
  116.         BOOL res;
  117.  
  118.         hLib = LoadLibrary(TEXT("USER32.DLL"));
  119.         if (!hLib) return 0;
  120.         fGetMonitorInfoA = (f_GetMonitorInfoA)(void*)GetProcAddress(hLib, "GetMonitorInfoA");
  121.         if (fGetMonitorInfoA != 0) {
  122.                 res = fGetMonitorInfoA(hMonitor, lpmi);
  123.                 FreeLibrary(hLib);
  124.                 return res;
  125.         }
  126.         else {
  127.                 return false;
  128.         }
  129. }
  130.  
  131. typedef _HMONITOR(__stdcall* f_MonitorFromRect)(LPCRECT lprc, DWORD dwFlags);
  132. _HMONITOR _MonitorFromRect(LPCRECT lprc, DWORD dwFlags) {
  133.         // Calling dynamically, because Windows 95 does not support MonitorFromRect
  134.         HMODULE hLib;
  135.         f_MonitorFromRect fMonitorFromRect;
  136.         _HMONITOR res;
  137.  
  138.         hLib = LoadLibrary(TEXT("USER32.DLL"));
  139.         if (!hLib) return 0;
  140.         fMonitorFromRect = (f_MonitorFromRect)(void*)GetProcAddress(hLib, "MonitorFromRect");
  141.         if (fMonitorFromRect != 0) {
  142.                 res = fMonitorFromRect(lprc, dwFlags);
  143.                 FreeLibrary(hLib);
  144.                 return res;
  145.         }
  146.         else {
  147.                 return NULL;
  148.         }
  149. }
  150.  
  151. #define _MONITOR_DEFAULTTONULL       0x00000000
  152. #define _MONITOR_DEFAULTTOPRIMARY    0x00000001
  153. #define _MONITOR_DEFAULTTONEAREST    0x00000002
  154.  
  155. void _doMonitorAdjustments(LPRECT rcPlugin) {
  156.         RECT rcMonitorWork;
  157.         _HMONITOR hMonitor;
  158.         _MONITORINFO grMonitorInfo;
  159.         int nXAdjust = 0, nYAdjust = 0, nPluginWidth, nPluginHeight, nMonitorWorkWidth, nMonitorWorkHeight;
  160.  
  161.         hMonitor = _MonitorFromRect(rcPlugin, _MONITOR_DEFAULTTONEAREST);
  162.         if (hMonitor == NULL) return;
  163.  
  164.         grMonitorInfo.cbSize = sizeof(grMonitorInfo);
  165.         if (!_GetMonitorInfoA(hMonitor, &grMonitorInfo)) return;
  166.         rcMonitorWork = grMonitorInfo.rcWork;
  167.  
  168.         // Don't let the window exit the left/right borders of the monitor
  169.         nPluginWidth = rcPlugin->right - rcPlugin->left;
  170.         nMonitorWorkWidth = rcMonitorWork.right - rcMonitorWork.left;
  171.         if (nPluginWidth > nMonitorWorkWidth) {
  172.                 // Window larger than screen width. Decrease the width!
  173.                 rcPlugin->left = rcMonitorWork.left;
  174.                 rcPlugin->right = rcMonitorWork.right;
  175.         }
  176.         else if (rcPlugin->left < rcMonitorWork.left) {
  177.                 nXAdjust = rcMonitorWork.left - rcPlugin->left;
  178.         }
  179.         else if (rcPlugin->right > rcMonitorWork.right) {
  180.                 nXAdjust = rcMonitorWork.right  - rcPlugin->right;
  181.         }
  182.  
  183.         // Don't let the window exit the top/bottom borders of the monitor
  184.         nPluginHeight = rcPlugin->bottom - rcPlugin->top;
  185.         nMonitorWorkHeight = rcMonitorWork.bottom - rcMonitorWork.top;
  186.         if (nPluginHeight > nMonitorWorkHeight) {
  187.                 // Window larger than screen height. Decrease the height!
  188.                 rcPlugin->top = rcMonitorWork.top;
  189.                 rcPlugin->bottom = rcMonitorWork.bottom;
  190.         }
  191.         else if (rcPlugin->top < rcMonitorWork.top) {
  192.                 nYAdjust = rcMonitorWork.top - rcPlugin->top;
  193.         }
  194.         else if (rcPlugin->bottom > rcMonitorWork.bottom) {
  195.                 nYAdjust = rcMonitorWork.bottom - rcPlugin->bottom;
  196.         }
  197.  
  198.         OffsetRect(rcPlugin, nXAdjust, nYAdjust);
  199. }
  200.  
  201. /*
  202. * Centers a window to the center of its parent form but avoids
  203. * being spread across two screens.
  204. */
  205. void centre_window(HWND hwnd) {
  206.         RECT rcParent, rcWindowOriginal, rcPlugin;
  207.         HWND hParent;
  208.        
  209.         hParent = GetParent(hwnd);
  210.         if (hParent == NULL) hParent = GetDesktopWindow();
  211.  
  212.         if (!GetWindowRect(hParent, &rcParent)) return;
  213.         if (!GetWindowRect(hwnd, &rcWindowOriginal)) return;
  214.  
  215.         rcPlugin.left =
  216.                 rcParent.left
  217.                 + (rcParent.right - rcParent.left) / 2
  218.                 - (rcWindowOriginal.right - rcWindowOriginal.left) / 2;
  219.         rcPlugin.top =
  220.                 rcParent.top
  221.                 + (rcParent.bottom - rcParent.top) / 2
  222.                 - (rcWindowOriginal.bottom - rcWindowOriginal.top) / 2;
  223.         rcPlugin.right =
  224.                 rcPlugin.left + rcWindowOriginal.right - rcWindowOriginal.left;
  225.         rcPlugin.bottom =
  226.                 rcPlugin.top + rcWindowOriginal.bottom - rcWindowOriginal.top;
  227.  
  228.         // Avoid that the window is spread across two screens
  229.         _doMonitorAdjustments(&rcPlugin);
  230.  
  231.         MoveWindow(hwnd,
  232.                 rcPlugin.left,
  233.                 rcPlugin.top,
  234.                 /*width=*/rcPlugin.right - rcPlugin.left,
  235.                 /*height=*/rcPlugin.bottom - rcPlugin.top,
  236.                 TRUE);
  237. }
  238.  
  239.