Flasher.cpp
资源名称:vnc3326s.zip [点击查看]
上传用户:sbftbdw
上传日期:2007-01-03
资源大小:379k
文件大小:8k
源码类别:
远程控制编程
开发平台:
Visual C++
- // Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
- //
- // This file is part of the VNC system.
- //
- // The VNC system 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 of the License, 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.
- //
- // If the source code for the VNC system is not available from the place
- // whence you received this file, check http://www.orl.co.uk/vnc or contact
- // the authors on vnc@orl.co.uk for information on obtaining it.
- // Flasher.cpp: implementation of the Flasher class.
- #include "stdhdrs.h"
- #include "vncviewer.h"
- #include "Flasher.h"
- #include "Exception.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- #define FLASHER_CLASS_NAME "VNCviewer Flasher"
- #define FLASHFONTHEIGHT 80
- Flasher::Flasher(int port)
- {
- // Create a dummy window. We don't use it for anything except
- // receiving socket events, so a seperate listening thread would
- // probably be easier!
- WNDCLASSEX wndclass;
- wndclass.cbSize = sizeof(wndclass);
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = Flasher::WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = pApp->m_instance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = (const char *) NULL;
- wndclass.lpszClassName = FLASHER_CLASS_NAME;
- wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- RegisterClassEx(&wndclass);
- m_hwnd = CreateWindow(FLASHER_CLASS_NAME,
- FLASHER_CLASS_NAME,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- 200, 200,
- NULL,
- NULL,
- pApp->m_instance,
- NULL);
- // record which client created this window
- SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this);
- // Select a font for displaying user name
- LOGFONT lf;
- memset(&lf, 0, sizeof(lf));
- lf.lfHeight = FLASHFONTHEIGHT;
- lf.lfWeight = FW_BOLD;
- lf.lfItalic = 1;
- lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
- lf.lfFaceName[0] = ' ';
- m_hfont = CreateFontIndirect(&lf);
- if (m_hfont == NULL) {
- log.Print(1, _T("FAILED TO SELECT FLASHER FONT!n"));
- }
- // Create a listening socket
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = INADDR_ANY;
- m_sock = socket(AF_INET, SOCK_STREAM, 0);
- if (!m_sock) throw WarningException("Error creating Flasher socket");
- try {
- int one = 1, res = 0;
- // If we use the SO_REUSEADDR option then you can run multiple daemons
- // because the bind doesn't return an error. Only one gets the accept,
- // but when that process dies it hands back to another. This may or may
- // not be desirable. We don't use it.
- //int res = setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &one, sizeof(one));
- //if (res == SOCKET_ERROR)
- // throw WarningException("Error setting Flasher socket options");
- res = bind(m_sock, (struct sockaddr *)&addr, sizeof(addr));
- if (res == SOCKET_ERROR)
- throw WarningException("Error binding Flasher socket");
- res = listen(m_sock, 5);
- if (res == SOCKET_ERROR)
- throw WarningException("Error when Flasher tries to listen");
- } catch (...) {
- closesocket(m_sock);
- m_sock = 0;
- throw;
- }
- // Send a message to specified window on an incoming connection
- WSAAsyncSelect (m_sock, m_hwnd, WM_SOCKEVENT, FD_ACCEPT | FD_CLOSE);
- }
- // convert a lower-case ASCII char to a value 0-255
- inline int scalechar(char c) {
- return ( ((c - 'a')+4) & 0x1f ) * 255 / 0x1f;
- }
- // We use this on each screen saver window running
- BOOL CALLBACK KillScreenSaverFunc(HWND hwnd, LPARAM lParam) {
- PostMessage(hwnd, WM_CLOSE, 0, 0);
- return TRUE;
- }
- // Process window messages
- LRESULT CALLBACK Flasher::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
- // This is a static method, so we don't know which instantiation we're
- // dealing with. We use Allen Hadden's (ahadden@taratec.com) suggestion
- // from a newsgroup to get the pseudo-this.
- Flasher *_this = (Flasher *) GetWindowLong(hwnd, GWL_USERDATA);
- switch (iMsg) {
- case WM_CREATE:
- return 0;
- case WM_SOCKEVENT:
- {
- assert(HIWORD(lParam) == 0);
- // A new socket created by accept might send messages to
- // this procedure. We can ignore them.
- if(wParam != _this->m_sock) {
- return 0;
- }
- switch(lParam) {
- case FD_ACCEPT:
- {
- SOCKET hNewSock;
- char username[256];
- hNewSock = accept(_this->m_sock, NULL, NULL);
- // make it blocking
- WSAAsyncSelect(hNewSock, hwnd, 0, 0);
- u_long blk = 0;
- int res = ioctlsocket(hNewSock, FIONBIO, &blk);
- assert(res == 0);
- CloseScreenSaver();
- // Se if the server's sending a user name
- int namelen = recv(hNewSock, username, 250, 0);
- if (namelen >= 0)
- username[namelen] = 0;
- log.Print(2, _T("Flash for '%s'n"), username);
- closesocket(hNewSock);
- // flash
- // Get a DC for the root window
- HDC hrootdc = ::GetDC(NULL);
- HBRUSH holdbrush = (HBRUSH) SelectObject(hrootdc,
- (HBRUSH) GetStockObject(BLACK_BRUSH));
- // Find the size.
- RECT rect;
- GetClipBox(hrootdc, &rect);
- int barwidth = (rect.right - rect.left) / 10;
- int barheight = max(
- (rect.bottom - rect.top) / 10,
- FLASHFONTHEIGHT);
- HFONT oldfont = (HFONT) SelectObject(hrootdc, _this->m_hfont);
- // Flash the screen
- ::Beep(440,50);
- Rectangle(hrootdc, rect.left, rect.top,
- rect.right, barheight);
- Rectangle(hrootdc, rect.left, rect.bottom-barheight,
- rect.right, rect.bottom);
- Rectangle(hrootdc, rect.left, rect.top+barheight,
- barwidth, rect.bottom-barheight);
- Rectangle(hrootdc, rect.right-barwidth, rect.top+barheight,
- rect.right, rect.bottom-barheight);
- RECT topbar;
- SetRect(&topbar, rect.left, rect.top,
- rect.right, barheight);
- int i = 0;
- if (namelen > 0) {
- int oldmode = SetBkMode(hrootdc, TRANSPARENT);
- COLORREF oldcolor = SetTextColor(hrootdc,
- RGB(scalechar(username[0])/(i+1), scalechar(username[1])/(i+1), scalechar(username[2])/(i+1)));
- DrawText(hrootdc, username, -1, &topbar, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- SetTextColor(hrootdc, oldcolor);
- SetBkMode(hrootdc, oldmode);
- }
- GdiFlush();
- SelectObject(hrootdc, holdbrush);
- ::Sleep(1000);
- SelectObject(hrootdc, oldfont);
- InvalidateRect(0, &rect, TRUE);
- ::ReleaseDC(NULL, hrootdc);
- break;
- }
- case FD_CLOSE:
- log.Print(2, _T("Flasher connection closedn"));
- DestroyWindow(hwnd);
- break;
- }
- return 0;
- }
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, iMsg, wParam, lParam);
- }
- void Flasher::CloseScreenSaver() {
- // Which OS are we on?
- OSVERSIONINFO ovi;
- ovi.dwOSVersionInfoSize = sizeof(ovi);
- if (!GetVersionEx(&ovi)) return;
- switch (ovi.dwPlatformId) {
- case VER_PLATFORM_WIN32_WINDOWS:
- {
- // Windows 95
- HWND hsswnd = FindWindow ("WindowsScreenSaverClass", NULL);
- if (hsswnd != NULL)
- PostMessage(hsswnd, WM_CLOSE, 0, 0);
- break;
- }
- case VER_PLATFORM_WIN32_NT:
- {
- // Windows NT
- HDESK hdesk = OpenDesktop(
- TEXT("Screen-saver"),
- 0, FALSE, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS);
- if (hdesk) {
- if (EnumDesktopWindows(hdesk, (WNDENUMPROC) KillScreenSaverFunc, 0)) {
- CloseDesktop(hdesk);
- }
- Sleep(1000);
- }
- }
- }
- }
- Flasher::~Flasher()
- {
- shutdown(m_sock, SD_BOTH);
- closesocket(m_sock);
- if (m_hfont != NULL) DeleteObject(m_hfont);
- }