Subversion Repositories filter_foundry

Rev

Rev 300 | Rev 407 | 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;
  139.         int nXAdjust = 0, nYAdjust = 0, nPluginWidth, nPluginHeight, nMonitorWorkWidth, nMonitorWorkHeight;
  140.  
  141.         hMonitor = _MonitorFromRect(rcPlugin, _MONITOR_DEFAULTTONEAREST);
  142.         if (hMonitor == NULL) return;
  143.  
  144.         grMonitorInfo.cbSize = sizeof(grMonitorInfo);
  145.         if (!_GetMonitorInfoA(hMonitor, &grMonitorInfo)) return;
  146.         rcMonitorWork = grMonitorInfo.rcWork;
  147.  
  148.         // Don't let the window exit the left/right borders of the monitor
  149.         nPluginWidth = rcPlugin->right - rcPlugin->left;
  150.         nMonitorWorkWidth = rcMonitorWork.right - rcMonitorWork.left;
  151.         if (nPluginWidth > nMonitorWorkWidth) {
  152.                 // Window larger than screen width. Decrease the width!
  153.                 rcPlugin->left = rcMonitorWork.left;
  154.                 rcPlugin->right = rcMonitorWork.right;
  155.         }
  156.         else if (rcPlugin->left < rcMonitorWork.left) {
  157.                 nXAdjust = rcMonitorWork.left - rcPlugin->left;
  158.         }
  159.         else if (rcPlugin->right > rcMonitorWork.right) {
  160.                 nXAdjust = rcMonitorWork.right  - rcPlugin->right;
  161.         }
  162.  
  163.         // Don't let the window exit the top/bottom borders of the monitor
  164.         nPluginHeight = rcPlugin->bottom - rcPlugin->top;
  165.         nMonitorWorkHeight = rcMonitorWork.bottom - rcMonitorWork.top;
  166.         if (nPluginHeight > nMonitorWorkHeight) {
  167.                 // Window larger than screen height. Decrease the height!
  168.                 rcPlugin->top = rcMonitorWork.top;
  169.                 rcPlugin->bottom = rcMonitorWork.bottom;
  170.         }
  171.         else if (rcPlugin->top < rcMonitorWork.top) {
  172.                 nYAdjust = rcMonitorWork.top - rcPlugin->top;
  173.         }
  174.         else if (rcPlugin->bottom > rcMonitorWork.bottom) {
  175.                 nYAdjust = rcMonitorWork.bottom - rcPlugin->bottom;
  176.         }
  177.  
  178.         OffsetRect(rcPlugin, nXAdjust, nYAdjust);
  179. }
  180.  
  181. /*
  182. * Centers a window to the center of its parent form but avoids
  183. * being spread across two screens.
  184. */
  185. void centre_window(HWND hwnd) {
  186.         RECT rcParent, rcWindowOriginal, rcPlugin;
  187.         HWND hParent;
  188.        
  189.         hParent = GetParent(hwnd);
  190.         if (hParent == NULL) hParent = GetDesktopWindow();
  191.  
  192.         if (!GetWindowRect(hParent, &rcParent)) return;
  193.         if (!GetWindowRect(hwnd, &rcWindowOriginal)) return;
  194.  
  195.         rcPlugin.left =
  196.                 rcParent.left
  197.                 + (rcParent.right - rcParent.left) / 2
  198.                 - (rcWindowOriginal.right - rcWindowOriginal.left) / 2;
  199.         rcPlugin.top =
  200.                 rcParent.top
  201.                 + (rcParent.bottom - rcParent.top) / 2
  202.                 - (rcWindowOriginal.bottom - rcWindowOriginal.top) / 2;
  203.         rcPlugin.right =
  204.                 rcPlugin.left + rcWindowOriginal.right - rcWindowOriginal.left;
  205.         rcPlugin.bottom =
  206.                 rcPlugin.top + rcWindowOriginal.bottom - rcWindowOriginal.top;
  207.  
  208.         // Avoid that the window is spread across two screens
  209.         _doMonitorAdjustments(&rcPlugin);
  210.  
  211.         MoveWindow(hwnd,
  212.                 rcPlugin.left,
  213.                 rcPlugin.top,
  214.                 /*width=*/rcPlugin.right - rcPlugin.left,
  215.                 /*height=*/rcPlugin.bottom - rcPlugin.top,
  216.                 TRUE);
  217. }
  218.  
  219.