Subversion Repositories filter_foundry

Rev

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

Rev Author Line No. Line
259 daniel-mar 1
/*
268 daniel-mar 2
    This file is part of a common library for Adobe(R) Photoshop(R) plugins
259 daniel-mar 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
268 daniel-mar 6
    it under the terms of the GNU General Public License as published by
259 daniel-mar 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
 
268 daniel-mar 15
    You should have received a copy of the GNU General Public License
259 daniel-mar 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
 
407 daniel-mar 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
 
444 daniel-mar 38
        hLib = LoadLibrary(TEXT("GDI32.DLL"));
407 daniel-mar 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
 
259 daniel-mar 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
 
268 daniel-mar 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;
259 daniel-mar 67
 
407 daniel-mar 68
                (*ppb)->hbmp = _CreateDIBSection(NULL/*hDC*/,&(*ppb)->bmi,DIB_RGB_COLORS,(void**)&(*ppb)->pbits,NULL,0);
268 daniel-mar 69
 
259 daniel-mar 70
                (*ppb)->rowbytes = ((depth * pbmih->biWidth + 31) >> 3) & -4;
71
 
72
                if( (*ppb)->hbmp ){
268 daniel-mar 73
 
259 daniel-mar 74
                        /*long i,j,*p;
268 daniel-mar 75
 
259 daniel-mar 76
                        char s[0x200];
268 daniel-mar 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
 
259 daniel-mar 87
                        return true;
88
                }else
444 daniel-mar 89
                        dbg((TCHAR*)TEXT("CreateDIBSection FAILED"));
259 daniel-mar 90
        }
91
        return false;
92
}
93
 
94
void disposebitmap(BITMAPREF pb){
95
        if(pb){
96
                DeleteObject(pb->hbmp);
97
                free(pb);
98
        }
99
}
100
 
296 daniel-mar 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
 
444 daniel-mar 118
        hLib = LoadLibrary(TEXT("USER32.DLL"));
296 daniel-mar 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
        }
259 daniel-mar 129
}
296 daniel-mar 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
 
444 daniel-mar 138
        hLib = LoadLibrary(TEXT("USER32.DLL"));
296 daniel-mar 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) {
298 daniel-mar 156
        RECT rcMonitorWork;
296 daniel-mar 157
        _HMONITOR hMonitor;
301 daniel-mar 158
        _MONITORINFO grMonitorInfo;
300 daniel-mar 159
        int nXAdjust = 0, nYAdjust = 0, nPluginWidth, nPluginHeight, nMonitorWorkWidth, nMonitorWorkHeight;
160
 
296 daniel-mar 161
        hMonitor = _MonitorFromRect(rcPlugin, _MONITOR_DEFAULTTONEAREST);
162
        if (hMonitor == NULL) return;
163
 
301 daniel-mar 164
        grMonitorInfo.cbSize = sizeof(grMonitorInfo);
298 daniel-mar 165
        if (!_GetMonitorInfoA(hMonitor, &grMonitorInfo)) return;
166
        rcMonitorWork = grMonitorInfo.rcWork;
296 daniel-mar 167
 
298 daniel-mar 168
        // Don't let the window exit the left/right borders of the monitor
300 daniel-mar 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;
298 daniel-mar 174
                rcPlugin->right = rcMonitorWork.right;
296 daniel-mar 175
        }
298 daniel-mar 176
        else if (rcPlugin->left < rcMonitorWork.left) {
300 daniel-mar 177
                nXAdjust = rcMonitorWork.left - rcPlugin->left;
296 daniel-mar 178
        }
298 daniel-mar 179
        else if (rcPlugin->right > rcMonitorWork.right) {
300 daniel-mar 180
                nXAdjust = rcMonitorWork.right  - rcPlugin->right;
296 daniel-mar 181
        }
298 daniel-mar 182
 
183
        // Don't let the window exit the top/bottom borders of the monitor
300 daniel-mar 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!
298 daniel-mar 188
                rcPlugin->top = rcMonitorWork.top;
189
                rcPlugin->bottom = rcMonitorWork.bottom;
296 daniel-mar 190
        }
298 daniel-mar 191
        else if (rcPlugin->top < rcMonitorWork.top) {
300 daniel-mar 192
                nYAdjust = rcMonitorWork.top - rcPlugin->top;
298 daniel-mar 193
        }
194
        else if (rcPlugin->bottom > rcMonitorWork.bottom) {
300 daniel-mar 195
                nYAdjust = rcMonitorWork.bottom - rcPlugin->bottom;
298 daniel-mar 196
        }
300 daniel-mar 197
 
198
        OffsetRect(rcPlugin, nXAdjust, nYAdjust);
296 daniel-mar 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
 
298 daniel-mar 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;
296 daniel-mar 227
 
299 daniel-mar 228
        // Avoid that the window is spread across two screens
296 daniel-mar 229
        _doMonitorAdjustments(&rcPlugin);
230
 
231
        MoveWindow(hwnd,
232
                rcPlugin.left,
233
                rcPlugin.top,
298 daniel-mar 234
                /*width=*/rcPlugin.right - rcPlugin.left,
235
                /*height=*/rcPlugin.bottom - rcPlugin.top,
296 daniel-mar 236
                TRUE);
237
}
238