📄 desktop.c
字号:
//
// desktop.c: The Desktop module.
//
// Copyright (C) 1999, Wei Yongming.
//
// Current maintainer: Wei Yongming.
/*
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Library General Public
** License as published by the Free Software Foundation; either
** version 2 of the License, or (at your option) any later version.
**
** This library 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
** Library General Public License for more details.
**
** You should have received a copy of the GNU Library General Public
** License along with this library; if not, write to the Free
** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
** MA 02111-1307, USA
*/
// Create date: 1999.04.19
//
// Modify records:
//
// Who When Where For What Status
//-----------------------------------------------------------------------------
// Wei Yongming 1999.9.11 Tsinghua WS_DISABLED done
// Wei Yongming 1999.9.28 Tsinghua Remove collector thread done
// Wei Yongming 1999.9.28 Tsinghua Timer module to desktop done
// Wei Yongming 1999.10.28 Tsinghua Desktop Menu done
//
// TODO:
//
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/time.h>
#include <errno.h>
#include <string.h>
#include <vgakeyboard.h>
#include <unistd.h>
#include <termios.h>
#include "common.h"
#include "cliprect.h"
#include "gdi.h"
#include "cursor.h"
#include "event.h"
#include "window.h"
#include "internals.h"
#include "misc.h"
#include "menu.h"
#include "fixstr.h"
#include "timer.h"
#include "ctrlclass.h"
#include "accelkey.h"
#include "main.h"
#include "vcswitch.h"
#ifdef _MULFONT
#include "cfont.h"
#endif
#ifdef _DEBUG
#include "msgstr.h"
#endif
#ifndef lint
static char fileid[] = "$Id: desktop.c,v 1.2 2000/04/20 03:18:23 weiym Exp $";
#endif
/******************************* extern data *********************************/
extern int timer_counter;
/******************************* static data *********************************/
static pthread_t desktop, parsor, timer;
static int DesktopProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam);
/********************* Window management support *****************************/
MSGQUEUE DskMsgs;
RECT sg_rcScr;
FREECLIPRECTLIST sg_FreeInvRectList;
static FREECLIPRECTLIST sg_FreeClipRectList;
static PMAINWIN pActiveMainWnd;
static HWND hCaptureWnd;
static ZORDERINFO MainWinZOrder;
static ZORDERINFO TopMostWinZOrder;
static PTRACKMENUINFO sg_ptmi;
static HWND sg_hIMEWnd;
static HWND sg_hCaretWnd;
static UINT sg_uCaretBTime;
static GCRINFO sg_ScrGCRInfo;
static void InitWndManagementInfo(void)
{
InitMainWinMetrics();
hCaptureWnd = HWND_DESKTOP;
pActiveMainWnd = NULL;
sg_ptmi = NULL;
sg_hIMEWnd = HWND_DESKTOP;
sg_hCaretWnd = HWND_DESKTOP;
sg_rcScr.left = sg_rcScr.top = 0;
sg_rcScr.right = GetGDCapability (HDC_SCREEN, GDCAP_MAXX) + 1;
sg_rcScr.bottom = GetGDCapability (HDC_SCREEN, GDCAP_MAXY) + 1;
InitClipRgn (&sg_ScrGCRInfo.crgn, &sg_FreeClipRectList);
SetClipRgn (&sg_ScrGCRInfo.crgn, &sg_rcScr);
pthread_mutex_init (&sg_ScrGCRInfo.lock, NULL);
sg_ScrGCRInfo.age = 0;
}
BITMAP SystemBitmap[SYSBMP_ITEM_NUMBER];
HICON LargeSystemIcon [SYSICO_ITEM_NUMBER] = {0};
HICON SmallSystemIcon [SYSICO_ITEM_NUMBER] = {0};
BOOL InitDesktop ()
{
int i;
int nIconNr;
char szValue [12];
/*
* Load system bitmaps here.
*/
if (!LoadSystemBitmap (SystemBitmap, "minimize")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 1, "maximize")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 2, "restore")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 3, "close")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 4, "arrowup")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 5, "arrowupd")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 6, "arrowdown")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 7, "arrowdownd")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 8, "arrowleft")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 9, "arrowleftd")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 10, "arrowright")) return FALSE;
if (!LoadSystemBitmap (SystemBitmap + 11, "arrowrightd")) return FALSE;
/*
* Load system icons here.
*/
if( GetValueFromEtcFile(ETCFILEPATH, "iconinfo", "iconnumber",
szValue, 10) < 0 )
return FALSE;
nIconNr = atoi(szValue);
if (nIconNr <= 0)
return FALSE;
nIconNr = nIconNr < SYSICO_ITEM_NUMBER ? nIconNr : SYSICO_ITEM_NUMBER;
for (i = 0; i < nIconNr; i++) {
sprintf(szValue, "icon%d", i);
SmallSystemIcon [i] = LoadSystemIcon (szValue, 1);
LargeSystemIcon [i] = LoadSystemIcon (szValue, 0);
if (SmallSystemIcon [i] == 0
|| LargeSystemIcon [i] == 0)
return FALSE;
}
// Init Window Management information.
InitWndManagementInfo();
return TRUE;
}
void TerminateDesktop ()
{
int i;
for (i=0; i<SYSBMP_ITEM_NUMBER; i++)
UnloadBitmap (SystemBitmap + i);
for (i=0; i<SYSICO_ITEM_NUMBER; i++) {
if (SmallSystemIcon [i])
DestroyIcon (SmallSystemIcon [i]);
if (LargeSystemIcon [i])
DestroyIcon (LargeSystemIcon [i]);
}
}
PGCRINFO GetGCRgnInfo(HWND hWnd)
{
PMAINWIN pWin;
if (hWnd == HWND_DESKTOP)
return &sg_ScrGCRInfo;
pWin = GetMainWindow (hWnd);
return &pWin->GCRInfo;
}
inline void DesktopSetActiveWindow(PMAINWIN pWin)
{
if (sg_hIMEWnd != HWND_DESKTOP && pWin) {
if (pWin->dwExStyle & WS_EX_IMECOMPOSE)
SendNotifyMessage (sg_hIMEWnd, MSG_IME_OPEN, 0, 0);
else
SendNotifyMessage (sg_hIMEWnd, MSG_IME_CLOSE, 0, 0);
SendNotifyMessage (sg_hIMEWnd, MSG_IME_SETTARGET, (WPARAM)pWin, 0);
}
pActiveMainWnd = pWin;
}
static HWND DesktopSetCapture(HWND hwnd)
{
HWND hTemp;
hTemp = hCaptureWnd;
hCaptureWnd = hwnd;
return hTemp;
}
/************************* ZOrder operation **********************************/
static void InitZOrderInfo(PZORDERINFO pZOrderInfo, HWND hHost)
{
pZOrderInfo->nNumber = 0;
pZOrderInfo->hWnd = hHost;
pZOrderInfo->pTopMost = NULL;
}
// When show an invisible new main window,
// call this function to update all other windows' GCRInfo.
//
// Window functions which lead to calling this function:
// ShowWindow: show an invisible main window with a SW_SHOW parameter.
//
// this main window is a normal main window.
static void dskUpdateGCRInfoOnShowNewMainWin(MAINWIN* pWin)
{
PZORDERNODE pNode;
PGCRINFO pGCRInfo;
PMAINWIN pTemp;
// this main window's GCR Info
pGCRInfo = &pWin->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
// clip by all top most windows
pNode = TopMostWinZOrder.pTopMost;
while (pNode)
{
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
// update all main windows' global clip region under this window.
// pWin is the top most window.
pNode = MainWinZOrder.pTopMost->pNext;
while (pNode)
{
if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pWin->left));
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pNode = pNode->pNext;
}
// update desktop's global clip region.
pthread_mutex_lock (&sg_ScrGCRInfo.lock);
SubtractClipRect (&sg_ScrGCRInfo.crgn, (PRECT)(&pWin->left));
sg_ScrGCRInfo.age ++;
pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
}
// this main window is a top most window.
static void dskUpdateGCRInfoOnShowNewMainWinEx(MAINWIN* pWin)
{
PZORDERNODE pNode;
PGCRINFO pGCRInfo;
// update all top most windows' global clip region under this window.
// pWin is the top most window.
pNode = TopMostWinZOrder.pTopMost->pNext;
while (pNode)
{
if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pWin->left));
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pNode = pNode->pNext;
}
// update all normal main windows' global clip region
pNode = MainWinZOrder.pTopMost;
while (pNode)
{
if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pWin->left));
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pNode = pNode->pNext;
}
// update desktop's global clip region.
pthread_mutex_lock (&sg_ScrGCRInfo.lock);
SubtractClipRect (&sg_ScrGCRInfo.crgn, (PRECT)(&pWin->left));
sg_ScrGCRInfo.age ++;
pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
}
// When show a main window, all main windows which are covered by
// this showing main window will be updated.
//
// Window functions which lead to calling this function:
// ShowWindow: show an invisible main window with a SW_SHOW parameter.
//
// this is a normal main window.
static void dskUpdateGCRInfoOnShowMainWin(MAINWIN* pWin)
{
PMAINWIN pTemp;
PZORDERNODE pNode;
PGCRINFO pGCRInfo;
RECT rcWin, rcTemp;
// update this showing window's clip region info.
pGCRInfo = &pWin->GCRInfo;
IntersectRect (&rcTemp, (PRECT)(&pWin->left), &sg_rcScr);
pthread_mutex_lock (&pGCRInfo->lock);
SetClipRgn (&pGCRInfo->crgn, &rcTemp);
// clip by all top most windows
pNode = TopMostWinZOrder.pTopMost;
while (pNode)
{
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
// clip by all normal windows which cover this showing window.
pNode = MainWinZOrder.pTopMost;
while (pNode)
{
if (pNode->hWnd == (HWND)pWin)
break;
pTemp = (PMAINWIN)(pNode->hWnd);
if (pTemp->dwStyle & WS_VISIBLE)
SubtractClipRect (&pGCRInfo->crgn, (PRECT)(&pTemp->left));
pNode = pNode->pNext;
}
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
// where is the showing window?
pNode = MainWinZOrder.pTopMost;
while (pNode)
{
if (pNode->hWnd == (HWND)pWin)
break;
pNode = pNode->pNext;
}
// the showing main window's rect
memcpy (&rcWin, &pWin->left, sizeof(RECT));
// clip all main windows covered by this showing window.
pNode = pNode->pNext;
while (pNode)
{
if (((PMAINWIN)(pNode->hWnd))->dwStyle & WS_VISIBLE) {
pGCRInfo = &((PMAINWIN)(pNode->hWnd))->GCRInfo;
pthread_mutex_lock (&pGCRInfo->lock);
SubtractClipRect (&pGCRInfo->crgn, &rcWin);
pGCRInfo->age ++;
pthread_mutex_unlock (&pGCRInfo->lock);
}
pNode = pNode->pNext;
}
// update desktop's global clip region.
pthread_mutex_lock (&sg_ScrGCRInfo.lock);
SubtractClipRect (&sg_ScrGCRInfo.crgn, &rcWin);
sg_ScrGCRInfo.age ++;
pthread_mutex_unlock (&sg_ScrGCRInfo.lock);
}
// this window is a main window with WS_EX style
static void dskUpdateGCRInfoOnShowMainWinEx(MAINWIN* pWin)
{
PMAINWIN pTemp;
PZORDERNODE pNode;
PGCRINFO pGCRInfo;
RECT rcWin, rcTemp;
// update this showing window's clip region info.
pGCRInfo = &pWin->GCRInfo;
IntersectRect (&rcTemp, (PRECT)(&pWin->left), &sg_rcScr);
pthread_mutex_lock (&pGCRInfo->lock);
SetClipRgn (&pGCRInfo->crgn, &rcTemp);
// clip by all top most windows which cover this showing window.
pNode = TopMostWinZOrder.pTopMost;
while (pNode)
{
if (pNode->hWnd == (HWND)pWin)
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -