mirror of https://github.com/roytam1/kmeleon.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
487 lines
14 KiB
487 lines
14 KiB
/* |
|
* Copyright (C) 2001 Jeff Doozan |
|
* |
|
* This program is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation; either version 2, or (at your option) |
|
* any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program; if not, write to the Free Software |
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
|
|
* Patch to add multiple window support thanks to Ulf Erikson |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "fullscreen.h" |
|
#include "resource.h" |
|
#include "..\..\app\KmeleonConst.h" |
|
#include "utils.h" |
|
#define PLUGIN_NAME "Fullscreen Plugin" |
|
|
|
#define WIN32_LEAN_AND_MEAN |
|
#include <windows.h> |
|
#include <commctrl.h> |
|
// #include <afxres.h> |
|
#include <stdlib.h> |
|
#include <shellapi.h> |
|
|
|
#define KMELEON_PLUGIN_EXPORTS |
|
#include "kmeleon_plugin.h" |
|
#include "LocalesUtils.h" |
|
#include "mozilla.h" |
|
|
|
#include "mozilla/ChaosMode.h" // ChaosMode hack |
|
|
|
Locale* gLoc; |
|
|
|
int Load(); |
|
void Create(HWND parent); |
|
void CreateTab(HWND parent, HWND tab); |
|
void DestroyTab(HWND parent, HWND tab); |
|
void SwitchTab(HWND parent, HWND tab); |
|
void Config(HWND parent); |
|
void Quit(); |
|
void DoMenu(HMENU menu, char *param); |
|
void DoRebar(HWND rebarWnd); |
|
void Destroy(HWND hWnd); |
|
|
|
long DoMessage(const char *to, const char *from, const char *subject, long data1, long data2); |
|
|
|
kmeleonPlugin kPlugin = { |
|
KMEL_PLUGIN_VER, |
|
PLUGIN_NAME, |
|
DoMessage |
|
}; |
|
|
|
kmeleonFunctions *kFuncs; |
|
|
|
long DoMessage(const char *to, const char *from, const char *subject, long data1, long data2) |
|
{ |
|
if (to[0] == '*' || stricmp(to, kPlugin.dllname) == 0) { |
|
if (stricmp(subject, "Load") == 0) { |
|
Load(); |
|
} |
|
else if (strcmp(subject, "Create") == 0) { |
|
Create((HWND)data1); |
|
} |
|
else if (strcmp(subject, "CreateTab") == 0) { |
|
CreateTab((HWND)data1, (HWND)data2); |
|
} |
|
else if (strcmp(subject, "DestroyTab") == 0) { |
|
DestroyTab((HWND)data1, (HWND)data2); |
|
} |
|
else if (strcmp(subject, "SwitchTab") == 0) { |
|
SwitchTab((HWND)data1, (HWND)data2); |
|
} |
|
else if (strcmp(subject, "Config") == 0) { |
|
Config((HWND)data1); |
|
} |
|
else if (strcmp(subject, "Quit") == 0) { |
|
Quit(); |
|
} |
|
else if (strcmp(subject, "DoMenu") == 0) { |
|
DoMenu((HMENU)data1, (char *)data2); |
|
} |
|
else if (strcmp(subject, "DoRebar") == 0) { |
|
DoRebar((HWND)data1); |
|
} |
|
else if (strcmp(subject, "DoAccel") == 0) { |
|
*(int *)data2 = DoAccel((char *)data1); |
|
} |
|
else if (strcmp(subject, "Destroy") == 0) { |
|
Destroy((HWND)data1); |
|
} |
|
else if (strcmp(subject, "DoLocale") == 0) { |
|
if (gLoc) delete gLoc; |
|
gLoc = Locale::kmInit(&kPlugin); |
|
} |
|
else return 0; |
|
|
|
return 1; |
|
} |
|
return 0; |
|
} |
|
|
|
|
|
BOOL bHideReBar=1, bHideStatusBar=1, bAutoFullscreen=0, bHideTaskbar=1, bHideTabsBar = 1; |
|
|
|
HINSTANCE ghInstance; |
|
|
|
RECT rectFullScreenWindowRect; |
|
INT id_fullscreen; |
|
|
|
struct fullscreen { |
|
HWND hWnd; |
|
HWND hReBar, hStatusBar, hTabsBar; |
|
BOOL bMaximized; |
|
BOOL bReBarVisible, bStatusBarVisible, bTabsBarVisible; |
|
|
|
WINDOWPLACEMENT wpOld; |
|
BOOL bFullScreen; |
|
BOOL bDomFullScreen; |
|
CDomEventListener* listener; |
|
|
|
struct fullscreen *next; |
|
}; |
|
typedef struct fullscreen FS; |
|
|
|
static FS *root; |
|
|
|
static FS *create_FS(HWND hWnd) { |
|
FS *ptr = (FS*)calloc(1, sizeof(struct fullscreen)); |
|
if (ptr) { |
|
ptr->hWnd = hWnd; |
|
ptr->next = root; |
|
root = ptr; |
|
} |
|
ptr->listener = new CDomEventListener(hWnd); |
|
return ptr; |
|
} |
|
|
|
static FS *find_FS(HWND hWnd) { |
|
FS *ptr = root; |
|
while (ptr && ptr->hWnd != hWnd) |
|
ptr = ptr->next; |
|
return ptr; |
|
} |
|
|
|
static void remove_FS(HWND hWnd) { |
|
|
|
FS *prev = NULL, *ptr = root; |
|
while (ptr && (ptr->hWnd != hWnd)) { |
|
prev = ptr; |
|
ptr = ptr->next; |
|
} |
|
|
|
if (ptr) { |
|
if (prev) |
|
prev->next = ptr->next; |
|
else |
|
root = ptr->next; |
|
|
|
free(ptr); |
|
} |
|
} |
|
|
|
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { |
|
switch (ul_reason_for_call) { |
|
case DLL_PROCESS_ATTACH: |
|
ghInstance = (HINSTANCE) hModule; |
|
case DLL_THREAD_ATTACH: |
|
case DLL_THREAD_DETACH: |
|
case DLL_PROCESS_DETACH: |
|
break; |
|
} |
|
return TRUE; |
|
} |
|
|
|
|
|
void HideClutter(HWND hWndParent, FS *fs) { |
|
fs->hReBar = FindWindowEx(hWndParent, NULL, REBARCLASSNAME, NULL); |
|
fs->hStatusBar = FindWindowEx(hWndParent, NULL, STATUSCLASSNAME, NULL); |
|
fs->hTabsBar = FindWindowEx(hWndParent, NULL, REBARCLASSNAME, _T("TabsBar")); |
|
|
|
if (fs->bFullScreen) { |
|
WINDOWPLACEMENT wp; |
|
wp.length = sizeof(wp); |
|
GetWindowPlacement(hWndParent, &wp); |
|
fs->bMaximized = (wp.showCmd == SW_SHOWMAXIMIZED); |
|
if (fs->hReBar) { |
|
fs->bReBarVisible = IsWindowVisible(fs->hReBar); // save intitial visibility state |
|
ShowWindow(fs->hReBar, !fs->bDomFullScreen && !bHideReBar); // hide/unhide rebar |
|
} |
|
if (fs->hStatusBar) { |
|
fs->bStatusBarVisible = IsWindowVisible(fs->hStatusBar); |
|
ShowWindow(fs->hStatusBar, !fs->bDomFullScreen && !bHideStatusBar); |
|
} |
|
if (fs->hTabsBar) { |
|
fs->bTabsBarVisible = IsWindowVisible(fs->hTabsBar); |
|
ShowWindow(fs->hTabsBar, !fs->bDomFullScreen && !bHideTabsBar); |
|
} |
|
} |
|
else { |
|
if (fs->hReBar) ShowWindow(fs->hReBar, fs->bReBarVisible); |
|
if (fs->hStatusBar) ShowWindow(fs->hStatusBar, fs->bStatusBarVisible); |
|
if (fs->hTabsBar) ShowWindow(fs->hTabsBar, fs->bTabsBarVisible); |
|
} |
|
} |
|
|
|
void SetFullScreen(HWND hWnd, int fullscreen = -1, bool domFullscreen = false) |
|
{ |
|
WINDOWPLACEMENT wpNew; |
|
|
|
FS *fs = find_FS(hWnd); |
|
if (!fs) fs = create_FS(hWnd); |
|
|
|
if (fullscreen != -1 && (fs->bFullScreen == fullscreen)) |
|
return; |
|
|
|
if (!fs->bFullScreen) { |
|
fs->bDomFullScreen = domFullscreen; |
|
kPlugin.kFuncs->GetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.hide_rebar", &bHideReBar, (void *)&bHideReBar); |
|
kPlugin.kFuncs->GetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.hide_statusbar", &bHideStatusBar, (void *)&bHideStatusBar); |
|
kPlugin.kFuncs->GetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.auto", &bAutoFullscreen, (void *)&bAutoFullscreen); |
|
kPlugin.kFuncs->GetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.hide_taskbar", &bHideTaskbar, (void *)&bHideTaskbar); |
|
kPlugin.kFuncs->GetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.hide_tabsbar", &bHideTabsBar, (void *)&bHideTabsBar); |
|
|
|
RECT rectWindow; |
|
RECT rectDesktop; |
|
|
|
fs->bFullScreen=TRUE; |
|
|
|
fs->wpOld.length = sizeof (fs->wpOld); |
|
GetWindowPlacement(hWnd, &fs->wpOld); |
|
|
|
GetWindowRect(GetDesktopWindow(), &rectDesktop ); |
|
rectWindow = rectDesktop; |
|
|
|
APPBARDATA abd; |
|
abd.cbSize = sizeof(abd); |
|
UINT uState = (UINT) SHAppBarMessage(ABM_GETSTATE, &abd); |
|
|
|
if ((uState & ABS_ALWAYSONTOP) && !(uState & ABS_AUTOHIDE)) |
|
{ |
|
BOOL fResult = (BOOL) SHAppBarMessage(ABM_GETTASKBARPOS, &abd); |
|
if (!bHideTaskbar) |
|
{ |
|
// Idiotic try to get the taskbar position |
|
if (abd.rc.top - rectDesktop.top > 10) |
|
rectWindow.bottom = abd.rc.top; |
|
else if (rectDesktop.right - abd.rc.right > 10) |
|
rectWindow.right -= abd.rc.right - abd.rc.left; |
|
//rectWindow.left = abd.rc.right; |
|
else if (rectDesktop.bottom - abd.rc.bottom > 10) |
|
//rectWindow.top = abd.rc.bottom; |
|
rectWindow.bottom -= abd.rc.bottom - abd.rc.top; |
|
else |
|
rectWindow.right = abd.rc.left; |
|
} |
|
|
|
else if (abd.rc.left <= 1 && abd.rc.top <= 1) |
|
{ |
|
if (abd.rc.right >= rectDesktop.right) { |
|
rectWindow.top -= (abd.rc.bottom-abd.rc.top); |
|
rectWindow.bottom -= abd.rc.bottom - abd.rc.top ; |
|
} |
|
else if (abd.rc.bottom >= rectDesktop.bottom) { |
|
rectWindow.left -= (abd.rc.right-abd.rc.left); |
|
rectWindow.right -= abd.rc.right - abd.rc.left ; |
|
} |
|
} |
|
} |
|
|
|
AdjustWindowRectEx(&rectWindow, GetWindowLong(hWnd, GWL_STYLE), (GetMenu(hWnd)?true:false), GetWindowLong(hWnd, GWL_EXSTYLE)); |
|
|
|
/* rectWindow.top -= 1; |
|
rectWindow.left -= 1; |
|
rectWindow.bottom += 1; |
|
rectWindow.right += 1;*/ |
|
|
|
rectFullScreenWindowRect = rectWindow; |
|
wpNew = fs->wpOld; |
|
|
|
if (fs->wpOld.showCmd!=SW_SHOWMINIMIZED) |
|
wpNew.showCmd = SW_SHOWNORMAL; |
|
wpNew.rcNormalPosition = rectWindow; |
|
|
|
HideClutter(hWnd, fs); |
|
} |
|
else { |
|
fs->bDomFullScreen = false; |
|
fs->bFullScreen=FALSE; |
|
wpNew = fs->wpOld; |
|
HideClutter(hWnd, fs); |
|
if (fs->bMaximized) ShowWindow(hWnd, SW_MAXIMIZE); |
|
} |
|
if (!domFullscreen) |
|
kPlugin.kFuncs->SetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.last", &fs->bFullScreen, false); |
|
SetWindowPlacement (hWnd, &wpNew); |
|
return; |
|
} |
|
|
|
|
|
int Load(){ |
|
gLoc = Locale::kmInit(&kPlugin); |
|
id_fullscreen = kPlugin.kFuncs->GetCommandIDs(1); |
|
return true; |
|
} |
|
|
|
WNDPROC KMeleonWndProc; |
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); |
|
|
|
void Create(HWND hWndParent) { |
|
KMeleonWndProc = (WNDPROC) GetWindowLong(hWndParent, GWL_WNDPROC); |
|
SetWindowLong(hWndParent, GWL_WNDPROC, (LONG)WndProc); |
|
BOOL bLast = FALSE; |
|
kPlugin.kFuncs->GetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.last", &bLast, (void *)&bLast); |
|
if (bAutoFullscreen || bLast) |
|
PostMessage(hWndParent, WM_COMMAND, id_fullscreen, 0); |
|
} |
|
|
|
void CreateTab(HWND hWndParent, HWND hTab) { |
|
FS *fs = find_FS(hWndParent); |
|
if (!fs) fs = create_FS(hWndParent); |
|
fs->listener->Init(hTab); |
|
fs->listener->CancelFullScreen(); |
|
} |
|
|
|
void DestroyTab(HWND hWndParent, HWND hTab) { |
|
FS *fs = find_FS(hWndParent); |
|
if (!fs) return; |
|
//fs->listener->CancelFullScreen(); |
|
fs->listener->Done(hTab); |
|
if (fs->bDomFullScreen) |
|
SetFullScreen(hWndParent, 0); |
|
} |
|
|
|
void SwitchTab(HWND hWndOldTab, HWND hTab) { |
|
HWND hWndParent = ::GetParent(hTab); |
|
FS *fs = find_FS(hWndParent); |
|
if (!fs) return; |
|
fs->listener->CancelFullScreen(); |
|
} |
|
|
|
|
|
void Config(HWND hWndParent) { |
|
gLoc->DialogBoxParam(MAKEINTRESOURCE(IDD_PREFS), hWndParent, (DLGPROC)DlgProc, (LPARAM)NULL); |
|
} |
|
|
|
void Quit(){ |
|
while (root) |
|
remove_FS(root->hWnd); |
|
delete gLoc; |
|
} |
|
|
|
void DoMenu(HMENU menu, char *param) { |
|
if (*param) { |
|
char *action = param; |
|
char *string = strchr(param, ','); |
|
if (string) { |
|
*string = 0; |
|
string = SkipWhiteSpace(string+1); |
|
} |
|
else |
|
string = action; |
|
AppendMenuA(menu, MF_STRING, id_fullscreen, string); |
|
} |
|
else AppendMenuA(menu, MF_STRING, id_fullscreen, kPlugin.kFuncs->Translate("&Full Screen")); |
|
} |
|
|
|
int DoAccel(char *param) { |
|
return id_fullscreen; |
|
} |
|
|
|
void DoRebar(HWND rebarWnd) { |
|
} |
|
|
|
void Destroy(HWND hWnd) { |
|
if (find_FS(hWnd)) |
|
remove_FS(hWnd); |
|
} |
|
|
|
// Subclassed window function |
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ |
|
|
|
switch (message) { |
|
case WM_GETMINMAXINFO: |
|
|
|
FS *fs; |
|
fs = find_FS(hWnd); |
|
if (!fs) break; |
|
|
|
if (fs->bFullScreen) { |
|
MINMAXINFO *lpMMI; |
|
|
|
lpMMI = (MINMAXINFO FAR *) lParam; |
|
|
|
lpMMI->ptMaxSize.y = rectFullScreenWindowRect.bottom - rectFullScreenWindowRect.top; |
|
lpMMI->ptMaxTrackSize.y = lpMMI->ptMaxSize.y; |
|
lpMMI->ptMaxSize.x = rectFullScreenWindowRect.right - rectFullScreenWindowRect.left; |
|
lpMMI->ptMaxTrackSize.x = lpMMI->ptMaxSize.x; |
|
return false; |
|
} |
|
break; |
|
|
|
case WM_COMMAND: |
|
WORD command = LOWORD(wParam); |
|
if (command == id_fullscreen) { |
|
SetFullScreen(hWnd); |
|
return 0; |
|
} |
|
break; |
|
} |
|
|
|
return CallWindowProc(KMeleonWndProc, hWnd, message, wParam, lParam); |
|
} |
|
|
|
|
|
// Preferences Dialog function |
|
BOOL CALLBACK DlgProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { |
|
|
|
switch (uMsg) { |
|
case WM_INITDIALOG: |
|
SendDlgItemMessage(hWnd, IDC_HIDEREBAR, BM_SETCHECK, bHideReBar, 0); |
|
SendDlgItemMessage(hWnd, IDC_HIDESTATUSBAR, BM_SETCHECK, bHideStatusBar, 0); |
|
SendDlgItemMessage(hWnd, IDC_AUTOFULLSCREEN, BM_SETCHECK, bAutoFullscreen, 0); |
|
SendDlgItemMessage(hWnd, IDC_HIDETASKBAR, BM_SETCHECK, bHideTaskbar, 0); |
|
break; |
|
case WM_COMMAND: |
|
switch(HIWORD(wParam)) { |
|
case BN_CLICKED: |
|
switch (LOWORD(wParam)) { |
|
case IDOK: |
|
bHideReBar = SendDlgItemMessage(hWnd, IDC_HIDEREBAR, BM_GETCHECK, 0, 0); |
|
bHideStatusBar = SendDlgItemMessage(hWnd, IDC_HIDESTATUSBAR, BM_GETCHECK, 0, 0); |
|
bAutoFullscreen = SendDlgItemMessage(hWnd, IDC_AUTOFULLSCREEN, BM_GETCHECK, 0, 0); |
|
bHideTaskbar = SendDlgItemMessage(hWnd, IDC_HIDETASKBAR, BM_GETCHECK, 0, 0); |
|
kPlugin.kFuncs->SetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.hide_rebar", &bHideReBar, false); |
|
kPlugin.kFuncs->SetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.hide_statusbar", &bHideStatusBar, false); |
|
kPlugin.kFuncs->SetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.auto", &bAutoFullscreen, false); |
|
kPlugin.kFuncs->SetPreference(PREF_BOOL, "kmeleon.plugins.fullscreen.hide_taskbar", &bHideTaskbar, false); |
|
case IDCANCEL: |
|
SendMessage(hWnd, WM_CLOSE, 0, 0); |
|
} |
|
} |
|
break; |
|
case WM_CLOSE: |
|
EndDialog(hWnd, (LPARAM)NULL); |
|
break; |
|
default: |
|
return FALSE; |
|
} |
|
return TRUE; |
|
} |
|
|
|
// function mutilation protection |
|
extern "C" { |
|
|
|
KMELEON_PLUGIN kmeleonPlugin *GetKmeleonPlugin() { |
|
return &kPlugin; |
|
} |
|
|
|
//KMELEON_PLUGIN int DrawBitmap(DRAWITEMSTRUCT *dis) { |
|
//} |
|
|
|
} |
|
|
|
#if 1 //ChaosMode hack |
|
namespace mozilla { |
|
namespace detail { |
|
|
|
Atomic<uint32_t> gChaosModeCounter(0); |
|
ChaosFeature gChaosFeatures = None; |
|
|
|
} /* namespace detail */ |
|
} /* namespace mozilla */ |
|
#endif
|
|
|