Subversion Repositories filter_foundry

Rev

Rev 299 | Rev 301 | 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. Boolean newbitmap(BITMAPREF *ppb,int depth,UIRECT *bounds){
  32.         //char s[0x100];
  33.         if( (*ppb = (BITMAPREF)malloc(sizeof(**ppb))) ){
  34.                 BITMAPINFOHEADER *pbmih = &(*ppb)->bmi.bmiHeader;
  35.  
  36.                 pbmih->biWidth = bounds->right - bounds->left;
  37.                 pbmih->biHeight = bounds->top - bounds->bottom; // negative: top-down!
  38.                 pbmih->biSize = sizeof(BITMAPINFOHEADER);
  39.                 pbmih->biPlanes = 1;
  40.                 pbmih->biBitCount = depth; // blue,green,red; high byte not used
  41.                 pbmih->biCompression = BI_RGB;
  42.                 pbmih->biSizeImage = 0; //(*ppb)->rowbytes * -pbmih->biHeight;
  43.                 pbmih->biXPelsPerMeter =
  44.                 pbmih->biYPelsPerMeter = 0;
  45.                 pbmih->biClrUsed =
  46.                 pbmih->biClrImportant = 0;
  47.  
  48.                 (*ppb)->hbmp = CreateDIBSection(NULL/*hDC*/,&(*ppb)->bmi,DIB_RGB_COLORS,(void**)&(*ppb)->pbits,NULL,0);
  49.  
  50.                 (*ppb)->rowbytes = ((depth * pbmih->biWidth + 31) >> 3) & -4;
  51.  
  52.                 if( (*ppb)->hbmp ){
  53.  
  54.                         /*long i,j,*p;
  55.  
  56.                         char s[0x200];
  57.                         sprintf(s,"newbitmap: biWidth = %d,rowbytes = %d,biHeight = %d,biSize = %d,biBitCount = %d,result = %#x",
  58.                         pbmih->biWidth,(*ppb)->rowbytes,pbmih->biHeight,
  59.                         pbmih->biSize,pbmih->biBitCount,(*ppb)->hbmp );
  60.                         dbg(s);
  61.  
  62.                         // checkerboard test pattern
  63.                         for(j = -pbmih->biHeight,p=(long*)(*ppb)->pbits;j--;p+=(*ppb)->rowbytes/4)
  64.                         for(i=pbmih->biWidth;i--;)
  65.                         p[i] = -( (i^j)&1 ) ;*/
  66.  
  67.                         return true;
  68.                 }else
  69.                         dbg("CreateDIBSection FAILED");
  70.         }
  71.         return false;
  72. }
  73.  
  74. void disposebitmap(BITMAPREF pb){
  75.         if(pb){
  76.                 DeleteObject(pb->hbmp);
  77.                 free(pb);
  78.         }
  79. }
  80.  
  81. typedef struct _tagMONITORINFO
  82. {
  83.         DWORD   cbSize;
  84.         RECT    rcMonitor;
  85.         RECT    rcWork;
  86.         DWORD   dwFlags;
  87. } _MONITORINFO, *_LPMONITORINFO;
  88.  
  89. typedef struct _HMONITOR__* _HMONITOR;
  90.  
  91. typedef BOOL(__stdcall* f_GetMonitorInfoA)(_HMONITOR hMonitor, _LPMONITORINFO lpmi);
  92. BOOL _GetMonitorInfoA(_HMONITOR hMonitor, _LPMONITORINFO lpmi) {
  93.         // Calling dynamically, because Windows 95 does not support GetMonitorInfoA
  94.         HMODULE hLib;
  95.         f_GetMonitorInfoA fGetMonitorInfoA;
  96.         BOOL res;
  97.  
  98.         hLib = LoadLibraryA("USER32.DLL");
  99.         if (!hLib) return 0;
  100.         fGetMonitorInfoA = (f_GetMonitorInfoA)(void*)GetProcAddress(hLib, "GetMonitorInfoA");
  101.         if (fGetMonitorInfoA != 0) {
  102.                 res = fGetMonitorInfoA(hMonitor, lpmi);
  103.                 FreeLibrary(hLib);
  104.                 return res;
  105.         }
  106.         else {
  107.                 return false;
  108.         }
  109. }
  110.  
  111. typedef _HMONITOR(__stdcall* f_MonitorFromRect)(LPCRECT lprc, DWORD dwFlags);
  112. _HMONITOR _MonitorFromRect(LPCRECT lprc, DWORD dwFlags) {
  113.         // Calling dynamically, because Windows 95 does not support MonitorFromRect
  114.         HMODULE hLib;
  115.         f_MonitorFromRect fMonitorFromRect;
  116.         _HMONITOR res;
  117.  
  118.         hLib = LoadLibraryA("USER32.DLL");
  119.         if (!hLib) return 0;
  120.         fMonitorFromRect = (f_MonitorFromRect)(void*)GetProcAddress(hLib, "MonitorFromRect");
  121.         if (fMonitorFromRect != 0) {
  122.                 res = fMonitorFromRect(lprc, dwFlags);
  123.                 FreeLibrary(hLib);
  124.                 return res;
  125.         }
  126.         else {
  127.                 return NULL;
  128.         }
  129. }
  130.  
  131. #define _MONITOR_DEFAULTTONULL       0x00000000
  132. #define _MONITOR_DEFAULTTOPRIMARY    0x00000001
  133. #define _MONITOR_DEFAULTTONEAREST    0x00000002
  134.  
  135. void _doMonitorAdjustments(LPRECT rcPlugin) {
  136.         RECT rcMonitorWork;
  137.         _HMONITOR hMonitor;
  138.         _MONITORINFO grMonitorInfo = { sizeof(grMonitorInfo) };
  139.         int nXAdjust = 0, nYAdjust = 0, nPluginWidth, nPluginHeight, nMonitorWorkWidth, nMonitorWorkHeight;
  140.  
  141.         hMonitor = _MonitorFromRect(rcPlugin, _MONITOR_DEFAULTTONEAREST);
  142.         if (hMonitor == NULL) return;
  143.  
  144.         if (!_GetMonitorInfoA(hMonitor, &grMonitorInfo)) return;
  145.         rcMonitorWork = grMonitorInfo.rcWork;
  146.  
  147.         // Don't let the window exit the left/right borders of the monitor
  148.         nPluginWidth = rcPlugin->right - rcPlugin->left;
  149.         nMonitorWorkWidth = rcMonitorWork.right - rcMonitorWork.left;
  150.         if (nPluginWidth > nMonitorWorkWidth) {
  151.                 // Window larger than screen width. Decrease the width!
  152.                 rcPlugin->left = rcMonitorWork.left;
  153.                 rcPlugin->right = rcMonitorWork.right;
  154.         }
  155.         else if (rcPlugin->left < rcMonitorWork.left) {
  156.                 nXAdjust = rcMonitorWork.left - rcPlugin->left;
  157.         }
  158.         else if (rcPlugin->right > rcMonitorWork.right) {
  159.                 nXAdjust = rcMonitorWork.right  - rcPlugin->right;
  160.         }
  161.  
  162.         // Don't let the window exit the top/bottom borders of the monitor
  163.         nPluginHeight = rcPlugin->bottom - rcPlugin->top;
  164.         nMonitorWorkHeight = rcMonitorWork.bottom - rcMonitorWork.top;
  165.         if (nPluginHeight > nMonitorWorkHeight) {
  166.                 // Window larger than screen height. Decrease the height!
  167.                 rcPlugin->top = rcMonitorWork.top;
  168.                 rcPlugin->bottom = rcMonitorWork.bottom;
  169.         }
  170.         else if (rcPlugin->top < rcMonitorWork.top) {
  171.                 nYAdjust = rcMonitorWork.top - rcPlugin->top;
  172.         }
  173.         else if (rcPlugin->bottom > rcMonitorWork.bottom) {
  174.                 nYAdjust = rcMonitorWork.bottom - rcPlugin->bottom;
  175.         }
  176.  
  177.         OffsetRect(rcPlugin, nXAdjust, nYAdjust);
  178. }
  179.  
  180. /*
  181. * Centers a window to the center of its parent form but avoids
  182. * being spread across two screens.
  183. */
  184. void centre_window(HWND hwnd) {
  185.         RECT rcParent, rcWindowOriginal, rcPlugin;
  186.         HWND hParent;
  187.        
  188.         hParent = GetParent(hwnd);
  189.         if (hParent == NULL) hParent = GetDesktopWindow();
  190.  
  191.         if (!GetWindowRect(hParent, &rcParent)) return;
  192.         if (!GetWindowRect(hwnd, &rcWindowOriginal)) return;
  193.  
  194.         rcPlugin.left =
  195.                 rcParent.left
  196.                 + (rcParent.right - rcParent.left) / 2
  197.                 - (rcWindowOriginal.right - rcWindowOriginal.left) / 2;
  198.         rcPlugin.top =
  199.                 rcParent.top
  200.                 + (rcParent.bottom - rcParent.top) / 2
  201.                 - (rcWindowOriginal.bottom - rcWindowOriginal.top) / 2;
  202.         rcPlugin.right =
  203.                 rcPlugin.left + rcWindowOriginal.right - rcWindowOriginal.left;
  204.         rcPlugin.bottom =
  205.                 rcPlugin.top + rcWindowOriginal.bottom - rcWindowOriginal.top;
  206.  
  207.         // Avoid that the window is spread across two screens
  208.         _doMonitorAdjustments(&rcPlugin);
  209.  
  210.         MoveWindow(hwnd,
  211.                 rcPlugin.left,
  212.                 rcPlugin.top,
  213.                 /*width=*/rcPlugin.right - rcPlugin.left,
  214.                 /*height=*/rcPlugin.bottom - rcPlugin.top,
  215.                 TRUE);
  216. }
  217.  
  218.