Code Restructuring to make mega-glest more standard

This commit is contained in:
Mark Vejvoda
2010-03-12 05:20:53 +00:00
parent 7cb4f99ec4
commit 43c3f2457e
399 changed files with 0 additions and 73357 deletions

View File

@@ -1,703 +0,0 @@
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code 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.
#include "socket.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <sstream>
#if defined(HAVE_SYS_IOCTL_H)
#define BSD_COMP /* needed for FIONREAD on Solaris2 */
#include <sys/ioctl.h>
#endif
#if defined(HAVE_SYS_FILIO_H) /* needed for FIONREAD on Solaris 2.5 */
#include <sys/filio.h>
#endif
#include "conversion.h"
using namespace std;
using namespace Shared::Util;
namespace Shared{ namespace Platform{
bool Socket::enableDebugText = true;
// =====================================================
// class Ip
// =====================================================
Ip::Ip(){
bytes[0]= 0;
bytes[1]= 0;
bytes[2]= 0;
bytes[3]= 0;
}
Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3){
bytes[0]= byte0;
bytes[1]= byte1;
bytes[2]= byte2;
bytes[3]= byte3;
}
Ip::Ip(const string& ipString){
int offset= 0;
int byteIndex= 0;
for(byteIndex= 0; byteIndex<4; ++byteIndex){
int dotPos= ipString.find_first_of('.', offset);
bytes[byteIndex]= atoi(ipString.substr(offset, dotPos-offset).c_str());
offset= dotPos+1;
}
}
string Ip::getString() const{
return intToStr(bytes[0]) + "." + intToStr(bytes[1]) + "." + intToStr(bytes[2]) + "." + intToStr(bytes[3]);
}
// ===============================================
// class Socket
// ===============================================
Socket::Socket(int sock){
this->sock= sock;
}
Socket::Socket()
{
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock < 0)
{
throwException("Error creating socket");
}
}
Socket::~Socket()
{
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
disconnectSocket();
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
}
void Socket::disconnectSocket()
{
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
if(sock > 0)
{
if(Socket::enableDebugText) printf("In [%s::%s] calling shutdown and close for socket = %d...\n",__FILE__,__FUNCTION__,sock);
::shutdown(sock,2);
::close(sock);
sock = -1;
}
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
}
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
{
bool bResult = false;
if(socketTriggeredList.size() > 0)
{
/* Watch stdin (fd 0) to see when it has input. */
fd_set rfds;
FD_ZERO(&rfds);
int imaxsocket = 0;
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
itermap != socketTriggeredList.end(); itermap++)
{
int socket = itermap->first;
if(socket > 0)
{
FD_SET(socket, &rfds);
imaxsocket = max(socket,imaxsocket);
}
}
if(imaxsocket > 0)
{
/* Wait up to 0 seconds. */
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
int retval = select(imaxsocket + 1, &rfds, NULL, NULL, &tv);
if(retval < 0)
{
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d errno = %d [%s]",__FILE__,__FUNCTION__,retval,errno,strerror(errno));
fprintf(stderr, "%s", szBuf);
}
else if(retval)
{
bResult = true;
if(Socket::enableDebugText) printf("In [%s::%s] select detected data imaxsocket = %d...\n",__FILE__,__FUNCTION__,imaxsocket);
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
itermap != socketTriggeredList.end(); itermap++)
{
int socket = itermap->first;
if (FD_ISSET(socket, &rfds))
{
if(Socket::enableDebugText) printf("In [%s] FD_ISSET true for socket %d...\n",__FUNCTION__,socket);
itermap->second = true;
}
else
{
itermap->second = false;
}
}
if(Socket::enableDebugText) printf("In [%s::%s] socketTriggeredList->size() = %d\n",__FILE__,__FUNCTION__,socketTriggeredList.size());
}
}
}
return bResult;
}
bool Socket::hasDataToRead()
{
return Socket::hasDataToRead(sock) ;
}
bool Socket::hasDataToRead(int socket)
{
bool bResult = false;
if(socket > 0)
{
fd_set rfds;
struct timeval tv;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(socket, &rfds);
/* Wait up to 0 seconds. */
tv.tv_sec = 0;
tv.tv_usec = 0;
int retval = select(socket + 1, &rfds, NULL, NULL, &tv);
if(retval)
{
if (FD_ISSET(socket, &rfds))
{
bResult = true;
}
}
}
return bResult;
}
int Socket::getDataToRead(){
unsigned long size = 0;
//fd_set rfds;
//struct timeval tv;
//int retval;
/* Watch stdin (fd 0) to see when it has input. */
//FD_ZERO(&rfds);
//FD_SET(sock, &rfds);
/* Wait up to 0 seconds. */
//tv.tv_sec = 0;
//tv.tv_usec = 0;
//retval = select(sock + 1, &rfds, NULL, NULL, &tv);
//if(retval)
if(sock > 0)
{
/* ioctl isn't posix, but the following seems to work on all modern
* unixes */
int err= ioctl(sock, FIONREAD, &size);
if(err < 0 && errno != EAGAIN)
{
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s] ERROR PEEKING SOCKET DATA, err = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,err,errno,strerror(errno));
//throwException(szBuf);
printf("%s",szBuf);
}
else if(err == 0)
{
//if(Socket::enableDebugText) printf("In [%s] ioctl returned = %d, size = %ld\n",__FUNCTION__,err,size);
}
}
return static_cast<int>(size);
}
int Socket::send(const void *data, int dataSize) {
ssize_t bytesSent= 0;
if(sock > 0)
{
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
}
if(bytesSent < 0 && errno != EAGAIN)
{
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s] ERROR WRITING SOCKET DATA, err = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesSent,errno,strerror(errno));
//throwException(szBuf);
printf("%s",szBuf);
}
else if(bytesSent < 0 && errno == EAGAIN)
{
printf("In [%s::%s] #1 EAGAIN during send, trying again...\n",__FILE__,__FUNCTION__);
time_t tStartTimer = time(NULL);
while((bytesSent < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
{
if(Socket::isWritable(true) == true)
{
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
printf("In [%s::%s] #2 EAGAIN during send, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesSent);
}
}
}
if(bytesSent <= 0)
{
int iErr = errno;
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesSent,iErr,strerror(iErr));
printf("%s",szBuf);
//throwException(szBuf);
}
if(Socket::enableDebugText) printf("In [%s::%s] sock = %d, bytesSent = %d\n",__FILE__,__FUNCTION__,sock,bytesSent);
return static_cast<int>(bytesSent);
}
int Socket::receive(void *data, int dataSize)
{
ssize_t bytesReceived = 0;
if(sock > 0)
{
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
}
if(bytesReceived < 0 && errno != EAGAIN)
{
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesReceived,errno,strerror(errno));
//throwException(szBuf);
printf("%s",szBuf);
}
else if(bytesReceived < 0 && errno == EAGAIN)
{
printf("In [%s::%s] #1 EAGAIN during receive, trying again...\n",__FILE__,__FUNCTION__);
time_t tStartTimer = time(NULL);
while((bytesReceived < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
{
if(Socket::isReadable() == true)
{
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
printf("In [%s::%s] #2 EAGAIN during receive, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesReceived);
}
}
}
if(bytesReceived <= 0)
{
int iErr = errno;
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesReceived,iErr,strerror(iErr));
printf("%s",szBuf);
//throwException(szBuf);
}
return static_cast<int>(bytesReceived);
}
int Socket::peek(void *data, int dataSize){
ssize_t err = 0;
if(sock > 0)
{
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
}
if(err < 0 && errno != EAGAIN)
{
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] ERROR PEEKING SOCKET DATA error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,errno,strerror(errno));
//throwException(szBuf);
disconnectSocket();
}
else if(err < 0 && errno == EAGAIN)
{
printf("In [%s::%s] #1 EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__);
time_t tStartTimer = time(NULL);
while((err < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
{
if(Socket::isReadable() == true)
{
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
printf("In [%s::%s] #2 EAGAIN during peek, trying again returned: %d\n",__FILE__,__FUNCTION__,err);
}
}
}
if(err <= 0)
{
int iErr = errno;
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,iErr,strerror(iErr));
printf("%s",szBuf);
//throwException(szBuf);
}
return static_cast<int>(err);
}
void Socket::setBlock(bool block){
int err= fcntl(sock, F_SETFL, block ? 0 : O_NONBLOCK);
if(err<0){
throwException("Error setting I/O mode for socket");
}
}
bool Socket::isReadable()
{
if(sock <= 0) return false;
struct timeval tv;
tv.tv_sec= 0;
tv.tv_usec= 1;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
int i= select(sock+1, &set, NULL, NULL, &tv);
if(i < 0)
{
if(difftime(time(NULL),lastDebugEvent) >= 1)
{
lastDebugEvent = time(NULL);
//throwException("Error selecting socket");
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
printf("%s",szBuf);
}
}
//return (i == 1 && FD_ISSET(sock, &set));
return (i == 1);
}
bool Socket::isWritable(bool waitOnDelayedResponse)
{
if(sock <= 0) return false;
struct timeval tv;
tv.tv_sec= 0;
tv.tv_usec= 1;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
bool result = false;
do
{
int i = select(sock+1, NULL, &set, NULL, &tv);
if(i < 0 )
{
if(difftime(time(NULL),lastDebugEvent) >= 1)
{
lastDebugEvent = time(NULL);
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
printf("%s",szBuf);
}
waitOnDelayedResponse = false;
//throwException("Error selecting socket");
}
else if(i == 0)
{
if(difftime(time(NULL),lastDebugEvent) >= 1)
{
lastDebugEvent = time(NULL);
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] TIMEOUT while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
printf("%s",szBuf);
}
if(waitOnDelayedResponse == false)
{
result = true;
}
}
else
{
result = true;
}
} while(waitOnDelayedResponse == true && result == false);
//return (i == 1 && FD_ISSET(sock, &set));
return result;
}
bool Socket::isConnected()
{
//if the socket is not writable then it is not conencted
if(isWritable(false) == false)
{
return false;
}
//if the socket is readable it is connected if we can read a byte from it
if(isReadable())
{
char tmp;
int err = peek(&tmp, sizeof(tmp));
return (err > 0);
/*
int err = recv(sock, &tmp, sizeof(tmp), MSG_PEEK);
if(err <= 0 && errno != EAGAIN)
{
int iErr = errno;
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking isconnected socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,iErr,strerror(iErr));
printf("%s",szBuf);
return false;
}
else if(err <= 0)
{
int iErr = errno;
//disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] #2 DISCONNECTED SOCKET error while peeking isconnected socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,iErr,strerror(iErr));
printf("%s",szBuf);
}
*/
}
//otherwise the socket is connected
return true;
}
string Socket::getHostName() const {
const int strSize= 256;
char hostname[strSize];
gethostname(hostname, strSize);
return hostname;
}
string Socket::getIp() const{
hostent* info= gethostbyname(getHostName().c_str());
unsigned char* address;
if(info==NULL){
throw runtime_error("Error getting host by name");
}
address= reinterpret_cast<unsigned char*>(info->h_addr_list[0]);
if(address==NULL){
throw runtime_error("Error getting host ip");
}
return
intToStr(address[0]) + "." +
intToStr(address[1]) + "." +
intToStr(address[2]) + "." +
intToStr(address[3]);
}
void Socket::throwException(const string &str){
std::stringstream msg;
msg << str << " (Error: " << strerror(errno) << ")";
throw runtime_error(msg.str());
}
// ===============================================
// class ClientSocket
// ===============================================
void ClientSocket::connect(const Ip &ip, int port)
{
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= inet_addr(ip.getString().c_str());
addr.sin_port= htons(port);
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if(err < 0)
{
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s] #2 Error connecting socket for IP: %s for Port: %d err = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,ip.getString().c_str(),port,err,errno,strerror(errno));
fprintf(stderr, "%s", szBuf);
if (errno == EINPROGRESS)
{
fd_set myset;
struct timeval tv;
int valopt;
socklen_t lon;
fprintf(stderr, "In [%s::%s] EINPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__);
do
{
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO(&myset);
FD_SET(sock, &myset);
err = select(sock+1, NULL, &myset, NULL, &tv);
if (err < 0 && errno != EINTR)
{
sprintf(szBuf, "In [%s::%s] Error connecting %d - [%s]\n",__FILE__,__FUNCTION__,errno, strerror(errno));
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
break;
}
else if (err > 0)
{
// Socket selected for write
lon = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0)
{
sprintf(szBuf, "In [%s::%s] Error in getsockopt() %d - [%s]\n",__FILE__,__FUNCTION__,errno, strerror(errno));
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
break;
}
// Check the value returned...
if (valopt)
{
sprintf(szBuf, "In [%s::%s] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,valopt, strerror(valopt));
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
break;
}
errno = 0;
fprintf(stderr, "In [%s::%s] Apparent recovery for connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
break;
}
else
{
sprintf(szBuf, "In [%s::%s] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__);
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
disconnectSocket();
break;
}
} while (1);
}
if(err < 0)
{
fprintf(stderr, "In [%s::%s] Before END sock = %d, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,sock,err,errno,strerror(errno));
//throwException(szBuf);
disconnectSocket();
}
else
{
fprintf(stderr, "In [%s::%s] Valid recovery for connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
}
}
}
// ===============================================
// class ServerSocket
// ===============================================
void ServerSocket::bind(int port)
{
//sockaddr structure
sockaddr_in addr;
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= INADDR_ANY;
addr.sin_port= htons(port);
int val = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
if(err < 0)
{
char szBuf[1024]="";
sprintf(szBuf, "In [%s::%s] Error binding socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
throwException(szBuf);
}
}
void ServerSocket::listen(int connectionQueueSize)
{
int err= ::listen(sock, connectionQueueSize);
if(err < 0)
{
char szBuf[1024]="";
sprintf(szBuf, "In [%s::%s] Error listening socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
throwException(szBuf);
}
}
Socket *ServerSocket::accept()
{
int newSock= ::accept(sock, NULL, NULL);
if(newSock < 0)
{
char szBuf[1024]="";
if(Socket::enableDebugText) printf(szBuf, "In [%s::%s] Error accepting socket connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,newSock,errno);
if(errno == EAGAIN)
{
return NULL;
}
throwException(szBuf);
}
return new Socket(newSock);
}
}}//end namespace

View File

@@ -1,41 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//
// You can redistribute this code 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
// ==============================================================
#include "factory_repository.h"
namespace Shared{ namespace Platform{
// =====================================================
// class FactoryRepository
// =====================================================
FactoryRepository &FactoryRepository::getInstance() {
static FactoryRepository factoryRepository;
return factoryRepository;
}
GraphicsFactory *FactoryRepository::getGraphicsFactory(const string &name) {
if(name == "OpenGL") {
return &graphicsFactoryGl;
}
throw runtime_error("Unknown graphics factory: " + name);
}
SoundFactory *FactoryRepository::getSoundFactory(const string &name) {
if(name == "OpenAL") {
return &soundFactoryOpenAL;
}
throw runtime_error("Unknown sound factory: " + name);
}
}}//end namespace

View File

@@ -1,122 +0,0 @@
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code 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.
#include "gl_wrap.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <cassert>
#include <SDL.h>
#ifdef X11_AVAILABLE
#include <GL/glx.h>
#endif
#include "opengl.h"
#include "sdl_private.h"
#include "leak_dumper.h"
#include "noimpl.h"
using namespace Shared::Graphics::Gl;
namespace Shared{ namespace Platform{
// ======================================
// class PlatformContextGl
// ======================================
void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits) {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits);
int flags = SDL_OPENGL;
if(Private::shouldBeFullscreen)
flags |= SDL_FULLSCREEN;
int resW = Private::ScreenWidth;
int resH = Private::ScreenHeight;
SDL_Surface* screen = SDL_SetVideoMode(resW, resH, colorBits, flags);
if(screen == 0) {
std::ostringstream msg;
msg << "Couldn't set video mode "
<< resW << "x" << resH << " (" << colorBits
<< "bpp " << stencilBits << " stencil "
<< depthBits << " depth-buffer). SDL Error is: " << SDL_GetError();
throw std::runtime_error(msg.str());
}
}
void PlatformContextGl::end() {
}
void PlatformContextGl::makeCurrent() {
}
void PlatformContextGl::swapBuffers() {
SDL_GL_SwapBuffers();
}
// ======================================
// Global Fcs
// ======================================
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width,
int charCount, FontMetrics &metrics) {
#ifdef X11_AVAILABLE
Display* display = glXGetCurrentDisplay();
if(display == 0) {
throw std::runtime_error("Couldn't create font: display is 0");
}
XFontStruct* fontInfo = XLoadQueryFont(display, type.c_str());
if(!fontInfo) {
throw std::runtime_error("Font not found.");
}
// we need the height of 'a' which sould ~ be half ascent+descent
metrics.setHeight(static_cast<float>
(fontInfo->ascent + fontInfo->descent) / 2);
for(unsigned int i = 0; i < static_cast<unsigned int> (charCount); ++i) {
if(i < fontInfo->min_char_or_byte2 ||
i > fontInfo->max_char_or_byte2) {
metrics.setWidth(i, static_cast<float>(6));
} else {
int p = i - fontInfo->min_char_or_byte2;
metrics.setWidth(i, static_cast<float> (
fontInfo->per_char[p].rbearing
- fontInfo->per_char[p].lbearing));
}
}
glXUseXFont(fontInfo->fid, 0, charCount, base);
XFreeFont(display, fontInfo);
#else
// we badly need a solution portable to more than just glx
NOIMPL;
#endif
}
void createGlFontOutlines(uint32 &base, const string &type, int width,
float depth, int charCount, FontMetrics &metrics) {
NOIMPL;
}
const char *getPlatformExtensions(const PlatformContextGl *pcgl) {
return "";
}
void *getGlProcAddress(const char *procName) {
void* proc = SDL_GL_GetProcAddress(procName);
assert(proc!=NULL);
return proc;
}
}}//end namespace

View File

@@ -1,461 +0,0 @@
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code 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.
#include "platform_util.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <glob.h>
#include <errno.h>
#include <string.h>
#include <SDL.h>
#include "util.h"
#include "conversion.h"
#include "leak_dumper.h"
#include "sdl_private.h"
#include "window.h"
#include "noimpl.h"
#include "checksum.h"
#include "socket.h"
#include <algorithm>
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
namespace Private{
bool shouldBeFullscreen = false;
int ScreenWidth;
int ScreenHeight;
}
// =====================================
// PerformanceTimer
// =====================================
void PerformanceTimer::init(float fps, int maxTimes){
times= 0;
this->maxTimes= maxTimes;
lastTicks= SDL_GetTicks();
updateTicks= static_cast<int>(1000./fps);
}
bool PerformanceTimer::isTime(){
Uint32 thisTicks = SDL_GetTicks();
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
lastTicks+= updateTicks;
times++;
return true;
}
times= 0;
return false;
}
void PerformanceTimer::reset(){
lastTicks= SDL_GetTicks();
}
// =====================================
// Chrono
// =====================================
Chrono::Chrono() {
freq = 1000;
stopped= true;
accumCount= 0;
}
void Chrono::start() {
stopped= false;
startCount = SDL_GetTicks();
}
void Chrono::stop() {
Uint32 endCount;
endCount = SDL_GetTicks();
accumCount += endCount-startCount;
stopped= true;
}
int64 Chrono::getMicros() const {
return queryCounter(1000000);
}
int64 Chrono::getMillis() const {
return queryCounter(1000);
}
int64 Chrono::getSeconds() const {
return queryCounter(1);
}
int64 Chrono::queryCounter(int multiplier) const {
if(stopped) {
return multiplier*accumCount/freq;
} else {
Uint32 endCount;
endCount = SDL_GetTicks();
return multiplier*(accumCount+endCount-startCount)/freq;
}
}
// =====================================
// Misc
// =====================================
//finds all filenames like path and stores them in resultys
void findAll(const string &path, vector<string> &results, bool cutExtension, bool errorOnNotFound) {
results.clear();
std::string mypath = path;
/** Stupid win32 is searching for all files without extension when *. is
* specified as wildcard
*/
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,mypath.c_str());
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
results.push_back(begin);
}
globfree(&globbuf);
if(results.size() == 0 && errorOnNotFound == true) {
throw runtime_error("No files found in: " + mypath);
}
if(cutExtension) {
for (size_t i=0; i<results.size(); ++i){
results.at(i)=cutLastExt(results.at(i));
}
}
}
int isdir(const char *path)
{
struct stat stats;
return stat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
}
bool EndsWith(const string &str, const string& key)
{
size_t keylen = key.length();
size_t strlen = str.length();
if(keylen <= strlen)
return string::npos != str.rfind(key.c_str(),strlen - keylen, keylen);
else
return false;
}
//finds all filenames like path and gets their checksum of all files combined
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum) {
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
/** Stupid win32 is searching for all files without extension when *. is
* specified as wildcard
*/
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
if(isdir(p) == 0)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
checksum.addFile(p);
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
getFolderTreeContentsCheckSumRecursively(string(p) + "/*", filterFileExt, &checksum);
}
globfree(&globbuf);
return checksum.getSum();
}
//finds all filenames like path and gets the checksum of each file
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
vector<std::pair<string,int32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,int32> >() : *recursiveMap);
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
/** Stupid win32 is searching for all files without extension when *. is
* specified as wildcard
*/
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
if(isdir(p) == 0)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
Checksum checksum;
checksum.addFile(p);
checksumFiles.push_back(std::pair<string,int32>(p,checksum.getSum()));
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
/*
const char* begin = p;
for( ; *p != 0; ++p) {
// strip the path component
if(*p == '/')
begin = p+1;
}
*/
checksumFiles = getFolderTreeContentsCheckSumListRecursively(string(p) + "/*", filterFileExt, &checksumFiles);
}
globfree(&globbuf);
return checksumFiles;
}
string extractDirectoryPathFromFile(string filename)
{
return filename.substr( 0, filename.rfind("/")+1 );
}
void createDirectoryPaths(string Path)
{
char DirName[256]="";
const char *path = Path.c_str();
char *dirName = DirName;
while(*path)
{
//if (('\\' == *path) || ('/' == *path))
if ('/' == *path)
{
//if (':' != *(path-1))
{
mkdir(DirName, S_IRWXO);
}
}
*dirName++ = *path++;
*dirName = '\0';
}
mkdir(DirName, S_IRWXO);
}
bool changeVideoMode(int resW, int resH, int colorBits, int ) {
Private::shouldBeFullscreen = true;
return true;
}
void restoreVideoMode() {
}
void message(string message) {
std::cerr << "******************************************************\n";
std::cerr << " " << message << "\n";
std::cerr << "******************************************************\n";
}
bool ask(string message) {
std::cerr << "Confirmation: " << message << "\n";
int res;
std::cin >> res;
return res != 0;
}
void exceptionMessage(const exception &excp) {
std::cerr << "Exception: " << excp.what() << std::endl;
}
int getScreenW() {
return SDL_GetVideoSurface()->w;
}
int getScreenH() {
return SDL_GetVideoSurface()->h;
}
void sleep(int millis) {
SDL_Delay(millis);
}
void showCursor(bool b) {
SDL_ShowCursor(b ? SDL_ENABLE : SDL_DISABLE);
}
bool isKeyDown(int virtualKey) {
char key = static_cast<char> (virtualKey);
const Uint8* keystate = SDL_GetKeyState(0);
// kinda hack and wrong...
if(key >= 0) {
return keystate[key];
}
switch(key) {
case vkAdd:
return keystate[SDLK_PLUS] | keystate[SDLK_KP_PLUS];
case vkSubtract:
return keystate[SDLK_MINUS] | keystate[SDLK_KP_MINUS];
case vkAlt:
return keystate[SDLK_LALT] | keystate[SDLK_RALT];
case vkControl:
return keystate[SDLK_LCTRL] | keystate[SDLK_RCTRL];
case vkShift:
return keystate[SDLK_LSHIFT] | keystate[SDLK_RSHIFT];
case vkEscape:
return keystate[SDLK_ESCAPE];
case vkUp:
return keystate[SDLK_UP];
case vkLeft:
return keystate[SDLK_LEFT];
case vkRight:
return keystate[SDLK_RIGHT];
case vkDown:
return keystate[SDLK_DOWN];
case vkReturn:
return keystate[SDLK_RETURN] | keystate[SDLK_KP_ENTER];
case vkBack:
return keystate[SDLK_BACKSPACE];
default:
std::cerr << "isKeyDown called with unknown key.\n";
break;
}
return false;
}
}}//end namespace

View File

@@ -1,67 +0,0 @@
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code 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.
#include "thread.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "noimpl.h"
namespace Shared{ namespace Platform{
// =====================================
// Threads
// =====================================
void Thread::start() {
thread = SDL_CreateThread(beginExecution, this);
}
void Thread::setPriority(Thread::Priority threadPriority) {
NOIMPL;
}
int Thread::beginExecution(void* data) {
Thread* thread = static_cast<Thread*> (data);
thread->execute();
return 0;
}
void Thread::suspend() {
NOIMPL;
}
void Thread::resume() {
NOIMPL;
}
// =====================================
// Mutex
// =====================================
Mutex::Mutex() {
mutex = SDL_CreateMutex();
if(mutex == 0)
throw std::runtime_error("Couldn't initialize mutex");
}
Mutex::~Mutex() {
SDL_DestroyMutex(mutex);
}
void Mutex::p() {
SDL_mutexP(mutex);
}
void Mutex::v() {
SDL_mutexV(mutex);
}
}}//end namespace

View File

@@ -1,303 +0,0 @@
//This file is part of Glest Shared Library (www.glest.org)
//Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//You can redistribute this code 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.
#include "window.h"
#include <iostream>
#include <stdexcept>
#include <cassert>
#include <cctype>
#include "conversion.h"
#include "platform_util.h"
#include "leak_dumper.h"
#include "sdl_private.h"
#include "noimpl.h"
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
// =======================================
// WINDOW
// =======================================
// ========== STATIC INICIALIZATIONS ==========
// Matze: hack for now...
static Window* global_window = 0;
// ========== PUBLIC ==========
Window::Window() {
memset(lastMouseDown, 0, sizeof(lastMouseDown));
assert(global_window == 0);
global_window = this;
}
Window::~Window() {
assert(global_window == this);
global_window = 0;
}
bool Window::handleEvent() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
try {
switch(event.type) {
case SDL_QUIT:
return false;
case SDL_MOUSEBUTTONDOWN:
global_window->handleMouseDown(event);
break;
case SDL_MOUSEBUTTONUP: {
global_window->eventMouseUp(event.button.x,
event.button.y,getMouseButton(event.button.button));
break;
}
case SDL_MOUSEMOTION: {
MouseState ms;
ms.leftMouse = (event.motion.state & SDL_BUTTON_LMASK) != 0;
ms.rightMouse = (event.motion.state & SDL_BUTTON_RMASK) != 0;
ms.centerMouse = (event.motion.state & SDL_BUTTON_MMASK) != 0;
global_window->eventMouseMove(event.motion.x, event.motion.y, &ms);
break;
}
case SDL_KEYDOWN:
/* handle ALT+Return */
if(event.key.keysym.sym == SDLK_RETURN
&& (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) {
toggleFullscreen();
}
global_window->eventKeyDown(getKey(event.key.keysym));
global_window->eventKeyPress(static_cast<char>(event.key.keysym.unicode));
break;
case SDL_KEYUP:
global_window->eventKeyUp(getKey(event.key.keysym));
break;
}
} catch(std::exception& e) {
std::cerr << "Couldn't process event: " << e.what() << "\n";
}
}
return true;
}
string Window::getText() {
char* c = 0;
SDL_WM_GetCaption(&c, 0);
return string(c);
}
float Window::getAspect() {
return static_cast<float>(getClientH())/getClientW();
}
void Window::setText(string text) {
SDL_WM_SetCaption(text.c_str(), 0);
}
void Window::setSize(int w, int h) {
this->w = w;
this->h = h;
Private::ScreenWidth = w;
Private::ScreenHeight = h;
}
void Window::setPos(int x, int y) {
if(x != 0 || y != 0) {
NOIMPL;
return;
}
}
void Window::minimize() {
NOIMPL;
}
void Window::setEnabled(bool enabled) {
NOIMPL;
}
void Window::setVisible(bool visible) {
NOIMPL;
}
void Window::setStyle(WindowStyle windowStyle) {
if(windowStyle == wsFullscreen)
return;
// NOIMPL;
}
void Window::create() {
// nothing here
}
void Window::destroy() {
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
void Window::toggleFullscreen() {
SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
}
void Window::handleMouseDown(SDL_Event event) {
static const Uint32 DOUBLECLICKTIME = 500;
static const int DOUBLECLICKDELTA = 5;
MouseButton button = getMouseButton(event.button.button);
Uint32 ticks = SDL_GetTicks();
int n = (int) button;
if(ticks - lastMouseDown[n] < DOUBLECLICKTIME
&& abs(lastMouseX[n] - event.button.x) < DOUBLECLICKDELTA
&& abs(lastMouseY[n] - event.button.y) < DOUBLECLICKDELTA) {
eventMouseDown(event.button.x, event.button.y, button);
eventMouseDoubleClick(event.button.x, event.button.y, button);
} else {
eventMouseDown(event.button.x, event.button.y, button);
}
lastMouseDown[n] = ticks;
lastMouseX[n] = event.button.x;
lastMouseY[n] = event.button.y;
}
MouseButton Window::getMouseButton(int sdlButton) {
switch(sdlButton) {
case SDL_BUTTON_LEFT:
return mbLeft;
case SDL_BUTTON_RIGHT:
return mbRight;
case SDL_BUTTON_MIDDLE:
return mbCenter;
default:
throw std::runtime_error("Mouse Button > 3 not handled.");
}
}
char Window::getKey(SDL_keysym keysym) {
switch(keysym.sym) {
case SDLK_PLUS:
case SDLK_KP_PLUS:
return vkAdd;
case SDLK_MINUS:
case SDLK_KP_MINUS:
return vkSubtract;
case SDLK_LALT:
case SDLK_RALT:
return vkAlt;
case SDLK_LCTRL:
case SDLK_RCTRL:
return vkControl;
case SDLK_LSHIFT:
case SDLK_RSHIFT:
return vkShift;
case SDLK_ESCAPE:
return vkEscape;
case SDLK_UP:
return vkUp;
case SDLK_LEFT:
return vkLeft;
case SDLK_RIGHT:
return vkRight;
case SDLK_DOWN:
return vkDown;
case SDLK_RETURN:
case SDLK_KP_ENTER:
return vkReturn;
case SDLK_BACKSPACE:
return vkBack;
case SDLK_0:
return '0';
case SDLK_1:
return '1';
case SDLK_2:
return '2';
case SDLK_3:
return '3';
case SDLK_4:
return '4';
case SDLK_5:
return '5';
case SDLK_6:
return '6';
case SDLK_7:
return '7';
case SDLK_8:
return '8';
case SDLK_9:
return '9';
case SDLK_a:
return 'A';
case SDLK_b:
return 'B';
case SDLK_c:
return 'C';
case SDLK_d:
return 'D';
case SDLK_e:
return 'E';
case SDLK_f:
return 'F';
case SDLK_g:
return 'G';
case SDLK_h:
return 'H';
case SDLK_i:
return 'I';
case SDLK_j:
return 'J';
case SDLK_k:
return 'K';
case SDLK_l:
return 'L';
case SDLK_m:
return 'M';
case SDLK_n:
return 'N';
case SDLK_o:
return 'O';
case SDLK_p:
return 'P';
case SDLK_q:
return 'Q';
case SDLK_r:
return 'R';
case SDLK_s:
return 'S';
case SDLK_t:
return 'T';
case SDLK_u:
return 'U';
case SDLK_v:
return 'V';
case SDLK_w:
return 'W';
case SDLK_x:
return 'X';
case SDLK_y:
return 'Y';
case SDLK_z:
return 'Z';
default:
Uint16 c = keysym.unicode;
if((c & 0xFF80) == 0) {
return toupper(c);
}
break;
}
return 0;
}
}}//end namespace

View File

@@ -1,42 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
//
// You can redistribute this code 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
// ==============================================================
#include "window_gl.h"
#include "gl_wrap.h"
#include "graphics_interface.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
namespace Shared{ namespace Platform{
// =====================================================
// class WindowGl
// =====================================================
void WindowGl::initGl(int colorBits, int depthBits, int stencilBits){
context.setColorBits(colorBits);
context.setDepthBits(depthBits);
context.setStencilBits(stencilBits);
context.init();
}
void WindowGl::makeCurrentGl() {
GraphicsInterface::getInstance().setCurrentContext(&context);
context.makeCurrent();
}
void WindowGl::swapBuffersGl(){
context.swapBuffers();
}
}}//end namespace

View File

@@ -1,46 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "factory_repository.h"
#include "leak_dumper.h"
namespace Shared{ namespace Platform{
// =====================================================
// class FactoryRepository
// =====================================================
FactoryRepository &FactoryRepository::getInstance(){
static FactoryRepository factoryRepository;
return factoryRepository;
}
GraphicsFactory *FactoryRepository::getGraphicsFactory(const string &name){
if(name == "OpenGL"){
return &graphicsFactoryGl;
}
else if(name == "OpenGL2"){
return &graphicsFactoryGl2;
}
throw runtime_error("Unknown graphics factory: " + name);
}
SoundFactory *FactoryRepository::getSoundFactory(const string &name){
if(name == "DirectSound8"){
return &soundFactoryDs8;
}
throw runtime_error("Unknown sound factory: " + name);
}
}}//end namespace

View File

@@ -1,164 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "gl_wrap.h"
#include <cassert>
#include <windows.h>
#include "opengl.h"
#include "leak_dumper.h"
using namespace Shared::Graphics::Gl;
namespace Shared{ namespace Platform{
// =====================================================
// class PlatformContextGl
// =====================================================
void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits){
int iFormat;
PIXELFORMATDESCRIPTOR pfd;
BOOL err;
//Set8087CW($133F);
dch = GetDC(GetActiveWindow());
assert(dch!=NULL);
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize= sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion= 1;
pfd.dwFlags= PFD_GENERIC_ACCELERATED | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType= PFD_TYPE_RGBA;
pfd.cColorBits= colorBits;
pfd.cDepthBits= depthBits;
pfd.iLayerType= PFD_MAIN_PLANE;
pfd.cStencilBits= stencilBits;
iFormat= ChoosePixelFormat(dch, &pfd);
assert(iFormat!=0);
err= SetPixelFormat(dch, iFormat, &pfd);
assert(err);
glch= wglCreateContext(dch);
if(glch==NULL){
throw runtime_error("Error initing OpenGL device context");
}
makeCurrent();
}
void PlatformContextGl::end(){
int makeCurrentError= wglDeleteContext(glch);
assert(makeCurrentError);
}
void PlatformContextGl::makeCurrent(){
int makeCurrentError= wglMakeCurrent(dch, glch);
assert(makeCurrentError);
}
void PlatformContextGl::swapBuffers(){
int swapErr= SwapBuffers(dch);
assert(swapErr);
}
// ======================================
// Global Fcs
// ======================================
void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, int charCount, FontMetrics &metrics){
HFONT font= CreateFont(
size, 0, 0, 0, width, 0, FALSE, FALSE, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
DEFAULT_PITCH, type.c_str());
assert(font!=NULL);
HDC dc= wglGetCurrentDC();
SelectObject(dc, font);
BOOL err= wglUseFontBitmaps(dc, 0, charCount, base);
FIXED one;
one.value= 1;
one.fract= 0;
FIXED zero;
zero.value= 0;
zero.fract= 0;
MAT2 mat2;
mat2.eM11= one;
mat2.eM12= zero;
mat2.eM21= zero;
mat2.eM22= one;
//metrics
GLYPHMETRICS glyphMetrics;
int errorCode= GetGlyphOutline(dc, 'a', GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(errorCode!=GDI_ERROR){
metrics.setHeight(static_cast<float>(glyphMetrics.gmBlackBoxY));
}
for(int i=0; i<charCount; ++i){
int errorCode= GetGlyphOutline(dc, i, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2);
if(errorCode!=GDI_ERROR){
metrics.setWidth(i, static_cast<float>(glyphMetrics.gmCellIncX));
}
}
DeleteObject(font);
assert(err);
}
void createGlFontOutlines(uint32 &base, const string &type, int width, float depth, int charCount, FontMetrics &metrics){
HFONT font= CreateFont(
10, 0, 0, 0, width, 0, FALSE, FALSE, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
DEFAULT_PITCH, type.c_str());
assert(font!=NULL);
GLYPHMETRICSFLOAT *glyphMetrics= new GLYPHMETRICSFLOAT[charCount];
HDC dc= wglGetCurrentDC();
SelectObject(dc, font);
BOOL err= wglUseFontOutlines(dc, 0, charCount, base, 1000, depth, WGL_FONT_POLYGONS, glyphMetrics);
//load metrics
metrics.setHeight(glyphMetrics['a'].gmfBlackBoxY);
for(int i=0; i<charCount; ++i){
metrics.setWidth(i, glyphMetrics[i].gmfCellIncX);
}
DeleteObject(font);
delete [] glyphMetrics;
assert(err);
}
const char *getPlatformExtensions(const PlatformContextGl *pcgl){
typedef const char* (WINAPI * PROCTYPE) (HDC hdc);
PROCTYPE proc= reinterpret_cast<PROCTYPE>(getGlProcAddress("wglGetExtensionsStringARB"));
return proc==NULL? "": proc(pcgl->getHandle());
}
PROC getGlProcAddress(const char *procName){
PROC proc= wglGetProcAddress(procName);
assert(proc!=NULL);
return proc;
}
}}//end namespace

View File

@@ -1,75 +0,0 @@
#include "platform_menu.h"
#include <cassert>
#include "leak_dumper.h"
namespace Shared{ namespace Platform{
int MenuBase::nextId= 1000;
// =====================================================
// class MenuBase
// =====================================================
void MenuBase::init(const string &text){
this->text= text;
id= nextId++;
}
// =====================================================
// class Menu
// =====================================================
void Menu::create(Menu *parent){
handle= CreatePopupMenu();
for(int i= 0; i<children.size(); ++i){
children[i]->create(this);
}
if(parent!=NULL){
BOOL result = AppendMenu(parent->getHandle(), MF_POPUP | MF_STRING, reinterpret_cast<UINT_PTR>(handle), text.c_str());
assert(result);
}
}
void Menu::destroy(){
for(int i= 0; i<children.size(); ++i){
children[i]->destroy();
}
children.clear();
BOOL result = DestroyMenu(handle);
assert(result);
}
// =====================================================
// class MenuItem
// =====================================================
void MenuItem::create(Menu *parent){
isChecked= false;
this->parent = parent;
assert(parent!=NULL);
BOOL result = AppendMenu(parent->getHandle(), MF_STRING, static_cast<UINT>(id), text.c_str());
assert(result);
}
void MenuItem::setChecked(bool checked){
isChecked= checked;
CheckMenuItem(parent->getHandle(), id, checked? MF_CHECKED: MF_UNCHECKED);
}
// =====================================================
// class MenuSeparator
// =====================================================
void MenuSeparator::create(Menu *parent){
assert(parent!=NULL);
BOOL result = AppendMenu(parent->getHandle(), MF_SEPARATOR, static_cast<UINT>(id), NULL);
assert(result);
}
}}//end namespace

View File

@@ -1,482 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "platform_util.h"
#include <io.h>
#include <DbgHelp.h>
#include <cassert>
#include "util.h"
#include "conversion.h"
#include "leak_dumper.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <direct.h>
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
// =====================================================
// class PerformanceTimer
// =====================================================
void PerformanceTimer::init(int fps, int maxTimes){
int64 freq;
if(QueryPerformanceFrequency((LARGE_INTEGER*) &freq)==0){
throw runtime_error("Performance counters not supported");
}
times= 0;
this->maxTimes= maxTimes;
QueryPerformanceCounter((LARGE_INTEGER*) &lastTicks);
updateTicks= freq/fps;
}
bool PerformanceTimer::isTime(){
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
if((thisTicks-lastTicks)>=updateTicks && times<maxTimes){
lastTicks+= updateTicks;
times++;
return true;
}
times= 0;
return false;
}
void PerformanceTimer::reset(){
QueryPerformanceCounter((LARGE_INTEGER*) &thisTicks);
lastTicks= thisTicks;
}
// =====================================================
// class Chrono
// =====================================================
Chrono::Chrono(){
if(!QueryPerformanceFrequency((LARGE_INTEGER*) &freq)){
throw runtime_error("Performance counters not supported");
}
stopped= true;
accumCount= 0;
}
void Chrono::start(){
stopped= false;
QueryPerformanceCounter((LARGE_INTEGER*) &startCount);
}
void Chrono::stop(){
int64 endCount;
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
accumCount+= endCount-startCount;
stopped= true;
}
int64 Chrono::getMicros() const{
return queryCounter(1000000);
}
int64 Chrono::getMillis() const{
return queryCounter(1000);
}
int64 Chrono::getSeconds() const{
return queryCounter(1);
}
int64 Chrono::queryCounter(int multiplier) const{
if(stopped){
return multiplier*accumCount/freq;
}
else{
int64 endCount;
QueryPerformanceCounter((LARGE_INTEGER*) &endCount);
return multiplier*(accumCount+endCount-startCount)/freq;
}
}
// =====================================================
// class PlatformExceptionHandler
// =====================================================
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
HANDLE hFile = CreateFile(
thisPointer->dumpFileName.c_str(),
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation;
lExceptionInformation.ThreadId= GetCurrentThreadId();
lExceptionInformation.ExceptionPointers= pointers;
lExceptionInformation.ClientPointers= false;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&lExceptionInformation,
NULL,
NULL );
thisPointer->handle();
return EXCEPTION_EXECUTE_HANDLER;
}
void PlatformExceptionHandler::install(string dumpFileName){
thisPointer= this;
this->dumpFileName= dumpFileName;
SetUnhandledExceptionFilter(handler);
}
// =====================================================
// class Misc
// =====================================================
//finds all filenames like path and stores them in resultys
void findAll(const string &path, vector<string> &results, bool cutExtension, bool errorOnNotFound){
int i= 0;
struct _finddata_t fi;
intptr_t handle;
char *cstr;
results.clear();
cstr= new char[path.length()+1];
strcpy(cstr, path.c_str());
if((handle=_findfirst(cstr,&fi))!=-1){
do{
if(!(strcmp(".", fi.name)==0 || strcmp("..", fi.name)==0)){
i++;
results.push_back(fi.name);
}
}
while(_findnext(handle, &fi)==0);
}
else if(errorOnNotFound == true){
throw runtime_error("Error opening files: "+ path);
}
if(i==0 && errorOnNotFound == true){
throw runtime_error("No files found: "+ path);
}
if(cutExtension){
for (int i=0; i<results.size(); ++i){
results.at(i)=cutLastExt(results.at(i));
}
}
delete [] cstr;
}
int isdir(const char *path)
{
struct stat stats;
return stat (path, &stats) == 0 && S_ISDIR (stats.st_mode);
}
bool EndsWith(const string &str, const string& key)
{
size_t keylen = key.length();
size_t strlen = str.length();
if(keylen <= strlen)
return string::npos != str.rfind(key.c_str(),strlen - keylen, keylen);
else
return false;
}
//finds all filenames like path and gets their checksum of all files combined
int32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum) {
Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
/* MV - PORT THIS to win32
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
// Stupid win32 is searching for all files without extension when *. is specified as wildcard
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// // strip the path component
// if(*p == '/')
// begin = p+1;
//}
if(isdir(p) == 0)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
checksum.addFile(p);
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// strip the path component
// if(*p == '/')
// begin = p+1;
//}
getFolderTreeContentsCheckSumRecursively(string(p) + "/*", filterFileExt, &checksum);
}
globfree(&globbuf);
*/
return checksum.getSum();
}
//finds all filenames like path and gets the checksum of each file
vector<std::pair<string,int32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,int32> > *recursiveMap) {
vector<std::pair<string,int32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,int32> >() : *recursiveMap);
/* MV - PORT THIS to win32
//if(Socket::enableDebugText) printf("In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
std::string mypath = path;
// Stupid win32 is searching for all files without extension when *. is specified as wildcard
if(mypath.compare(mypath.size() - 2, 2, "*.") == 0) {
mypath = mypath.substr(0, mypath.size() - 2);
mypath += "*";
}
glob_t globbuf;
int res = glob(mypath.c_str(), 0, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// strip the path component
// if(*p == '/')
// begin = p+1;
//}
if(isdir(p) == 0)
{
bool addFile = true;
if(filterFileExt != "")
{
addFile = EndsWith(p, filterFileExt);
}
if(addFile)
{
//if(Socket::enableDebugText) printf("In [%s::%s] adding file [%s]\n",__FILE__,__FUNCTION__,p);
Checksum checksum;
checksum.addFile(p);
checksumFiles.push_back(std::pair<string,int32>(p,checksum.getSum()));
}
}
}
globfree(&globbuf);
// Look recursively for sub-folders
res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
if(res < 0) {
std::stringstream msg;
msg << "Couldn't scan directory '" << mypath << "': " << strerror(errno);
throw runtime_error(msg.str());
}
for(size_t i = 0; i < globbuf.gl_pathc; ++i) {
const char* p = globbuf.gl_pathv[i];
//
//const char* begin = p;
//for( ; *p != 0; ++p) {
// strip the path component
// if(*p == '/')
// begin = p+1;
//}
checksumFiles = getFolderTreeContentsCheckSumListRecursively(string(p) + "/*", filterFileExt, &checksumFiles);
}
globfree(&globbuf);
*/
return checksumFiles;
}
string extractDirectoryPathFromFile(string filename)
{
return filename.substr( 0, filename.rfind("/")+1 );
}
void createDirectoryPaths(string Path)
{
char DirName[256]="";
const char *path = Path.c_str();
char *dirName = DirName;
while(*path)
{
//if (('\\' == *path) || ('/' == *path))
if ('/' == *path)
{
//if (':' != *(path-1))
{
_mkdir(DirName);
}
}
*dirName++ = *path++;
*dirName = '\0';
}
_mkdir(DirName);
}
bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
DEVMODE devMode;
for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
if (devMode.dmPelsWidth== resW &&
devMode.dmPelsHeight== resH &&
devMode.dmBitsPerPel== colorBits){
devMode.dmDisplayFrequency=refreshFrequency;
LONG result= ChangeDisplaySettings(&devMode, 0);
if(result == DISP_CHANGE_SUCCESSFUL){
return true;
}
else{
return false;
}
}
}
return false;
}
void restoreVideoMode(){
int dispChangeErr= ChangeDisplaySettings(NULL, 0);
assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
}
void message(string message){
MessageBox(NULL, message.c_str(), "Message", MB_OK);
}
bool ask(string message){
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
}
void exceptionMessage(const exception &excp){
string message, title;
showCursor(true);
message+= "ERROR(S):\n\n";
message+= excp.what();
title= "Error: Unhandled Exception";
printf("Error detected with text: %s\n",message.c_str());
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
}
int getScreenW(){
return GetSystemMetrics(SM_CXSCREEN);
}
int getScreenH(){
return GetSystemMetrics(SM_CYSCREEN);
}
void sleep(int millis){
Sleep(millis);
}
void showCursor(bool b){
ShowCursor(b);
}
bool isKeyDown(int virtualKey){
return (GetKeyState(virtualKey) & 0x8000) != 0;
}
}}//end namespace

View File

@@ -1,796 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2007 Marti<74>o Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "socket.h"
#include <stdexcept>
#include "conversion.h"
#include "leak_dumper.h"
#include <time.h>
#include <strstream>
#include <algorithm>
#define socklen_t int
using namespace std;
using namespace Shared::Util;
#define MAXHOSTNAME 254
//// Constants /////////////////////////////////////////////////////////
const int kBufferSize = 1024;
//// Statics ///////////////////////////////////////////////////////////
// List of Winsock error constants mapped to an interpretation string.
// Note that this list must remain sorted by the error constants'
// values, because we do a binary search on the list when looking up
// items.
static class ErrorEntry
{
public:
int nID;
const char* pcMessage;
ErrorEntry(int id, const char* pc = 0) : nID(id), pcMessage(pc)
{
}
bool operator<(const ErrorEntry& rhs)
{
return nID < rhs.nID;
}
} gaErrorList[] =
{
ErrorEntry(0, "No error"),
ErrorEntry(WSAEINTR, "Interrupted system call"),
ErrorEntry(WSAEBADF, "Bad file number"),
ErrorEntry(WSAEACCES, "Permission denied"),
ErrorEntry(WSAEFAULT, "Bad address"),
ErrorEntry(WSAEINVAL, "Invalid argument"),
ErrorEntry(WSAEMFILE, "Too many open sockets"),
ErrorEntry(WSAEWOULDBLOCK, "Operation would block"),
ErrorEntry(WSAEINPROGRESS, "Operation now in progress"),
ErrorEntry(WSAEALREADY, "Operation already in progress"),
ErrorEntry(WSAENOTSOCK, "Socket operation on non-socket"),
ErrorEntry(WSAEDESTADDRREQ, "Destination address required"),
ErrorEntry(WSAEMSGSIZE, "Message too long"),
ErrorEntry(WSAEPROTOTYPE, "Protocol wrong type for socket"),
ErrorEntry(WSAENOPROTOOPT, "Bad protocol option"),
ErrorEntry(WSAEPROTONOSUPPORT, "Protocol not supported"),
ErrorEntry(WSAESOCKTNOSUPPORT, "Socket type not supported"),
ErrorEntry(WSAEOPNOTSUPP, "Operation not supported on socket"),
ErrorEntry(WSAEPFNOSUPPORT, "Protocol family not supported"),
ErrorEntry(WSAEAFNOSUPPORT, "Address family not supported"),
ErrorEntry(WSAEADDRINUSE, "Address already in use"),
ErrorEntry(WSAEADDRNOTAVAIL, "Can't assign requested address"),
ErrorEntry(WSAENETDOWN, "Network is down"),
ErrorEntry(WSAENETUNREACH, "Network is unreachable"),
ErrorEntry(WSAENETRESET, "Net connection reset"),
ErrorEntry(WSAECONNABORTED, "Software caused connection abort"),
ErrorEntry(WSAECONNRESET, "Connection reset by peer"),
ErrorEntry(WSAENOBUFS, "No buffer space available"),
ErrorEntry(WSAEISCONN, "Socket is already connected"),
ErrorEntry(WSAENOTCONN, "Socket is not connected"),
ErrorEntry(WSAESHUTDOWN, "Can't send after socket shutdown"),
ErrorEntry(WSAETOOMANYREFS, "Too many references, can't splice"),
ErrorEntry(WSAETIMEDOUT, "Connection timed out"),
ErrorEntry(WSAECONNREFUSED, "Connection refused"),
ErrorEntry(WSAELOOP, "Too many levels of symbolic links"),
ErrorEntry(WSAENAMETOOLONG, "File name too long"),
ErrorEntry(WSAEHOSTDOWN, "Host is down"),
ErrorEntry(WSAEHOSTUNREACH, "No route to host"),
ErrorEntry(WSAENOTEMPTY, "Directory not empty"),
ErrorEntry(WSAEPROCLIM, "Too many processes"),
ErrorEntry(WSAEUSERS, "Too many users"),
ErrorEntry(WSAEDQUOT, "Disc quota exceeded"),
ErrorEntry(WSAESTALE, "Stale NFS file handle"),
ErrorEntry(WSAEREMOTE, "Too many levels of remote in path"),
ErrorEntry(WSASYSNOTREADY, "Network system is unavailable"),
ErrorEntry(WSAVERNOTSUPPORTED, "Winsock version out of range"),
ErrorEntry(WSANOTINITIALISED, "WSAStartup not yet called"),
ErrorEntry(WSAEDISCON, "Graceful shutdown in progress"),
ErrorEntry(WSAHOST_NOT_FOUND, "Host not found"),
ErrorEntry(WSANO_DATA, "No host data of that type was found")
};
bool operator<(const ErrorEntry& rhs1,const ErrorEntry& rhs2)
{
return rhs1.nID < rhs2.nID;
}
const int kNumMessages = sizeof(gaErrorList) / sizeof(ErrorEntry);
//// WSAGetLastErrorMessage ////////////////////////////////////////////
// A function similar in spirit to Unix's perror() that tacks a canned
// interpretation of the value of WSAGetLastError() onto the end of a
// passed string, separated by a ": ". Generally, you should implement
// smarter error handling than this, but for default cases and simple
// programs, this function is sufficient.
//
// This function returns a pointer to an internal static buffer, so you
// must copy the data from this function before you call it again. It
// follows that this function is also not thread-safe.
const char* WSAGetLastErrorMessage(const char* pcMessagePrefix,
int nErrorID /* = 0 */)
{
// Build basic error string
static char acErrorBuffer[256];
std::ostrstream outs(acErrorBuffer, sizeof(acErrorBuffer));
outs << pcMessagePrefix << ": ";
// Tack appropriate canned message onto end of supplied message
// prefix. Note that we do a binary search here: gaErrorList must be
// sorted by the error constant's value.
ErrorEntry* pEnd = gaErrorList + kNumMessages;
ErrorEntry Target(nErrorID ? nErrorID : WSAGetLastError());
ErrorEntry* it = std::lower_bound(gaErrorList, pEnd, Target);
if ((it != pEnd) && (it->nID == Target.nID))
{
outs << it->pcMessage;
}
else
{
// Didn't find error in list, so make up a generic one
outs << "unknown error";
}
outs << " (" << Target.nID << ")";
// Finish error message off and return it.
outs << std::ends;
acErrorBuffer[sizeof(acErrorBuffer) - 1] = '\0';
return acErrorBuffer;
}
namespace Shared{ namespace Platform{
bool Socket::enableDebugText = true;
// =====================================================
// class Ip
// =====================================================
Ip::Ip(){
bytes[0]= 0;
bytes[1]= 0;
bytes[2]= 0;
bytes[3]= 0;
}
Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3){
bytes[0]= byte0;
bytes[1]= byte1;
bytes[2]= byte2;
bytes[3]= byte3;
}
Ip::Ip(const string& ipString){
int offset= 0;
int byteIndex= 0;
for(byteIndex= 0; byteIndex<4; ++byteIndex){
int dotPos= ipString.find_first_of('.', offset);
bytes[byteIndex]= atoi(ipString.substr(offset, dotPos-offset).c_str());
offset= dotPos+1;
}
}
string Ip::getString() const{
return intToStr(bytes[0]) + "." + intToStr(bytes[1]) + "." + intToStr(bytes[2]) + "." + intToStr(bytes[3]);
}
// =====================================================
// class Socket
// =====================================================
Socket::SocketManager Socket::socketManager;
Socket::SocketManager::SocketManager(){
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 0);
WSAStartup(wVersionRequested, &wsaData);
//dont throw exceptions here, this is a static initializacion
printf("Winsock initialized.\n");
}
Socket::SocketManager::~SocketManager(){
WSACleanup();
printf("Winsock cleanup complete.\n");
}
Socket::Socket(SOCKET sock){
this->sock= sock;
}
Socket::Socket(){
sock= socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(sock==INVALID_SOCKET){
throwException("Error creating socket");
}
}
Socket::~Socket()
{
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
disconnectSocket();
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
}
void Socket::disconnectSocket()
{
if(Socket::enableDebugText) printf("In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
if(sock > 0)
{
::shutdown(sock,2);
::closesocket(sock);
sock = -1;
}
if(Socket::enableDebugText) printf("In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
}
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
{
bool bResult = false;
if(socketTriggeredList.size() > 0)
{
/* Watch stdin (fd 0) to see when it has input. */
fd_set rfds;
FD_ZERO(&rfds);
int imaxsocket = 0;
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
itermap != socketTriggeredList.end(); itermap++)
{
int socket = itermap->first;
if(socket > 0)
{
FD_SET(socket, &rfds);
imaxsocket = max(socket,imaxsocket);
}
}
if(imaxsocket > 0)
{
/* Wait up to 0 seconds. */
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
int retval = select(imaxsocket + 1, &rfds, NULL, NULL, &tv);
if(retval < 0)
{
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d WSAGetLastError() = %d",__FILE__,__FUNCTION__,retval,WSAGetLastError());
fprintf(stderr, "%s", szBuf);
}
else if(retval)
{
bResult = true;
if(Socket::enableDebugText) printf("In [%s::%s] select detected data imaxsocket = %d...\n",__FILE__,__FUNCTION__,imaxsocket);
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
itermap != socketTriggeredList.end(); itermap++)
{
int socket = itermap->first;
if (FD_ISSET(socket, &rfds))
{
if(Socket::enableDebugText) printf("In [%s] FD_ISSET true for socket %d...\n",__FUNCTION__,socket);
itermap->second = true;
}
else
{
itermap->second = false;
}
}
if(Socket::enableDebugText) printf("In [%s::%s] socketTriggeredList->size() = %d\n",__FILE__,__FUNCTION__,socketTriggeredList.size());
}
}
}
return bResult;
}
bool Socket::hasDataToRead()
{
return Socket::hasDataToRead(sock) ;
}
bool Socket::hasDataToRead(int socket)
{
bool bResult = false;
if(socket > 0)
{
fd_set rfds;
struct timeval tv;
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(socket, &rfds);
/* Wait up to 0 seconds. */
tv.tv_sec = 0;
tv.tv_usec = 0;
int retval = select(socket + 1, &rfds, NULL, NULL, &tv);
if(retval)
{
if (FD_ISSET(socket, &rfds))
{
bResult = true;
}
}
}
return bResult;
}
int Socket::getDataToRead(){
unsigned long size = 0;
//fd_set rfds;
//struct timeval tv;
//int retval;
/* Watch stdin (fd 0) to see when it has input. */
//FD_ZERO(&rfds);
//FD_SET(sock, &rfds);
/* Wait up to 0 seconds. */
//tv.tv_sec = 0;
//tv.tv_usec = 0;
//retval = select(sock + 1, &rfds, NULL, NULL, &tv);
//if(retval)
if(sock > 0)
{
/* ioctl isn't posix, but the following seems to work on all modern
* unixes */
int err= ioctlsocket(sock, FIONREAD, &size);
if(err < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
{
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s] ERROR PEEKING SOCKET DATA, err = %d WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,err,WSAGetLastError());
printf("%s",szBuf);
//throwException(szBuf);
}
else if(err == 0)
{
//if(Socket::enableDebugText) printf("In [%s] ioctl returned = %d, size = %ld\n",__FUNCTION__,err,size);
}
}
return static_cast<int>(size);
}
int Socket::send(const void *data, int dataSize) {
int bytesSent= 0;
if(sock > 0)
{
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
}
if(bytesSent < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
{
char szBuf[1024]="";
sprintf(szBuf,"In [%s::%s] ERROR WRITING SOCKET DATA, err = %d WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,bytesSent,WSAGetLastError());
//throwException(szBuf);
printf("%s",szBuf);
}
else if(bytesSent < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
{
printf("In [%s::%s] #1 WSAEWOULDBLOCK during send, trying again...\n",__FILE__,__FUNCTION__);
time_t tStartTimer = time(NULL);
while((bytesSent < 0 && WSAGetLastError() == WSAEWOULDBLOCK) && (difftime(time(NULL),tStartTimer) <= 5))
{
if(Socket::isWritable(true) == true)
{
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
printf("In [%s::%s] #2 WSAEWOULDBLOCK during send, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesSent);
}
}
}
if(bytesSent <= 0)
{
int iErr = WSAGetLastError();
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,bytesSent,iErr);
printf("%s",szBuf);
//throwException(szBuf);
}
if(Socket::enableDebugText) printf("In [%s::%s] sock = %d, bytesSent = %d\n",__FILE__,__FUNCTION__,sock,bytesSent);
return static_cast<int>(bytesSent);
}
int Socket::receive(void *data, int dataSize)
{
int bytesReceived = 0;
if(sock > 0)
{
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
}
if(bytesReceived < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
{
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,bytesReceived,WSAGetLastError());
//throwException(szBuf);
printf("%s",szBuf);
}
else if(bytesReceived < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
{
printf("In [%s::%s] #1 WSAEWOULDBLOCK during receive, trying again...\n",__FILE__,__FUNCTION__);
time_t tStartTimer = time(NULL);
while((bytesReceived < 0 && WSAGetLastError() == WSAEWOULDBLOCK) && (difftime(time(NULL),tStartTimer) <= 5))
{
if(Socket::isReadable() == true)
{
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
printf("In [%s::%s] #2 WSAEWOULDBLOCK during receive, trying again returned: %d\n",__FILE__,__FUNCTION__,bytesReceived);
}
}
}
if(bytesReceived <= 0)
{
int iErr = WSAGetLastError();
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,bytesReceived,iErr);
printf("%s",szBuf);
//throwException(szBuf);
}
return static_cast<int>(bytesReceived);
}
int Socket::peek(void *data, int dataSize){
int err = 0;
if(sock > 0)
{
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
}
if(err < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
{
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] ERROR PEEKING SOCKET DATA error while sending socket data, bytesSent = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,err,WSAGetLastError());
//throwException(szBuf);
printf("%s",szBuf);
}
else if(err < 0 && WSAGetLastError() == WSAEWOULDBLOCK)
{
printf("In [%s::%s] #1 WSAEWOULDBLOCK during peek, trying again...\n",__FILE__,__FUNCTION__);
time_t tStartTimer = time(NULL);
while((err < 0 && WSAGetLastError() == WSAEWOULDBLOCK) && (difftime(time(NULL),tStartTimer) <= 5))
{
if(Socket::isReadable() == true)
{
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
printf("In [%s::%s] #2 WSAEWOULDBLOCK during peek, trying again returned: %d\n",__FILE__,__FUNCTION__,err);
}
}
}
if(err <= 0)
{
int iErr = WSAGetLastError();
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking socket data, err = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,err,iErr);
printf("%s",szBuf);
//throwException(szBuf);
}
return static_cast<int>(err);
}
void Socket::setBlock(bool block){
u_long iMode= !
block;
int err= ioctlsocket(sock, FIONBIO, &iMode);
if(err==SOCKET_ERROR)
{
throwException("Error setting I/O mode for socket");
}
}
bool Socket::isReadable()
{
if(sock <= 0) return false;
TIMEVAL tv;
tv.tv_sec= 0;
tv.tv_usec= 1;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
int i= select(sock+1, &set, NULL, NULL, &tv);
if(i==SOCKET_ERROR)
{
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d\n",__FILE__,__FUNCTION__,i,WSAGetLastError());
printf("%s",szBuf);
}
//return (i == 1 && FD_ISSET(sock, &set));
return (i == 1);
}
bool Socket::isWritable(bool waitOnDelayedResponse)
{
if(sock <= 0) return false;
TIMEVAL tv;
tv.tv_sec= 0;
tv.tv_usec= 1;
fd_set set;
FD_ZERO(&set);
FD_SET(sock, &set);
bool result = false;
do
{
int i= select(sock+1, NULL, &set, NULL, &tv);
if(i==SOCKET_ERROR)
{
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] error while selecting socket data, err = %d, errno = %d\n",__FILE__,__FUNCTION__,i,WSAGetLastError());
printf("%s",szBuf);
waitOnDelayedResponse = false;
}
else if(i == 0)
{
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] TIMEOUT while selecting socket data, err = %d, errno = %d\n",__FILE__,__FUNCTION__,i,WSAGetLastError());
printf("%s",szBuf);
if(waitOnDelayedResponse == false)
{
result = true;
}
}
else
{
result = true;
}
} while(waitOnDelayedResponse == true && result == false);
return result;
}
bool Socket::isConnected(){
//if the socket is not writable then it is not conencted
if(isWritable(false) == false)
{
return false;
}
//if the socket is readable it is connected if we can read a byte from it
if(isReadable())
{
char tmp;
int err = peek(&tmp, sizeof(tmp));
return (err > 0);
/*
int err = recv(sock, &tmp, sizeof(tmp), MSG_PEEK);
if(err <= 0 && WSAGetLastError() != WSAEWOULDBLOCK)
{
int iErr = WSAGetLastError();
disconnectSocket();
char szBuf[1024]="";
sprintf(szBuf,"[%s::%s] DISCONNECTED SOCKET error while peeking isconnected socket data, err = %d, WSAGetLastError() = %d\n",__FILE__,__FUNCTION__,err,iErr);
printf("%s",szBuf);
return false;
}
*/
}
//otherwise the socket is connected
return true;
}
string Socket::getHostName() const{
const int strSize= 256;
char hostname[strSize];
gethostname(hostname, strSize);
return hostname;
}
string Socket::getIp() const{
hostent* info= gethostbyname(getHostName().c_str());
unsigned char* address;
if(info==NULL)
{
throwException("Error getting host by name");
}
address= reinterpret_cast<unsigned char*>(info->h_addr_list[0]);
if(address==NULL)
{
throwException("Error getting host ip");
}
return
intToStr(address[0]) + "." +
intToStr(address[1]) + "." +
intToStr(address[2]) + "." +
intToStr(address[3]);
}
void Socket::throwException(const string &str){
throw runtime_error("Network error: " + str+" (Code: " + intToStr(WSAGetLastError())+")");
}
// =====================================================
// class ClientSocket
// =====================================================
void ClientSocket::connect(const Ip &ip, int port)
{
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= inet_addr(ip.getString().c_str());
addr.sin_port= htons(port);
fprintf(stderr, "Connecting to host [%s] on port = %d\n", ip.getString().c_str(),port);
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if(err < 0)
{
char szBuf[1024]="";
sprintf(szBuf,"#2 Error connecting socket for IP: %s for Port: %d err = %d WSAGetLastError() = %d",ip.getString().c_str(),port,err,WSAGetLastError());
fprintf(stderr, "%s\n", WSAGetLastErrorMessage(szBuf));
//fprintf(stderr, "%s", szBuf);
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK)
{
fd_set myset;
struct timeval tv;
int valopt;
socklen_t lon;
fprintf(stderr, "WSAEINPROGRESS or WSAEWOULDBLOCK in connect() - selecting\n");
do {
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO(&myset);
FD_SET(sock, &myset);
err = select(0, NULL, &myset, NULL, &tv);
if (err < 0 && WSAGetLastError() != WSAEWOULDBLOCK && WSAGetLastError() != WSAEWOULDBLOCK)
{
sprintf(szBuf, "Error connecting %d\n", WSAGetLastError());
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
break;
}
else if (err > 0) {
// Socket selected for write
lon = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)(&valopt), &lon) < 0)
{
sprintf(szBuf, "Error in getsockopt() %d\n", WSAGetLastError());
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
break;
}
// Check the value returned...
if (valopt)
{
sprintf(szBuf, "Error in delayed connection() %d\n", valopt);
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
break;
}
fprintf(stderr, "Apparent recovery for connection sock = %d, err = %d, WSAGetLastError() = %d\n",sock,err,WSAGetLastError());
break;
}
else
{
sprintf(szBuf, "Timeout in select() - Cancelling!\n");
//throwException(szBuf);
fprintf(stderr, "%s", szBuf);
disconnectSocket();
break;
}
} while (1);
}
if(err < 0)
{
fprintf(stderr, "In [%s::%s] Before END sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,WSAGetLastError());
//throwException(szBuf);
disconnectSocket();
}
fprintf(stderr, "Valid recovery for connection sock = %d, err = %d, WSAGetLastError() = %d\n",sock,err,WSAGetLastError());
}
else
{
fprintf(stderr, "Connected to host [%s] on port = %d sock = %d err = %d", ip.getString().c_str(),port,err);
}
}
// =====================================================
// class ServerSocket
// =====================================================
void ServerSocket::bind(int port){
//sockaddr structure
sockaddr_in addr;
addr.sin_family= AF_INET;
addr.sin_addr.s_addr= INADDR_ANY;
addr.sin_port= htons(port);
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
if(err==SOCKET_ERROR){
throwException("Error binding socket");
}
}
void ServerSocket::listen(int connectionQueueSize){
int err= ::listen(sock, connectionQueueSize);
if(err==SOCKET_ERROR){
throwException("Error listening socket");
}
}
Socket *ServerSocket::accept(){
SOCKET newSock= ::accept(sock, NULL, NULL);
if(newSock==INVALID_SOCKET){
if(WSAGetLastError()==WSAEWOULDBLOCK){
return NULL;
}
throwException("Error accepting socket connection");
}
return new Socket(newSock);
}
}}//end namespace

View File

@@ -1,66 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "thread.h"
#include "leak_dumper.h"
namespace Shared{ namespace Platform{
// =====================================================
// class Threads
// =====================================================
ThreadId Thread::nextThreadId= threadIdBase;
void Thread::start(){
threadHandle= CreateThread(NULL, 0, beginExecution, this, 0, &nextThreadId);
nextThreadId++;
}
void Thread::setPriority(Thread::Priority threadPriority){
SetThreadPriority(threadHandle, threadPriority);
}
DWORD WINAPI Thread::beginExecution(void *param){
static_cast<Thread*>(param)->execute();
return 0;
}
void Thread::suspend(){
SuspendThread(threadHandle);
}
void Thread::resume(){
ResumeThread(threadHandle);
}
// =====================================================
// class Mutex
// =====================================================
Mutex::Mutex(){
InitializeCriticalSection(&mutex);
}
Mutex::~Mutex(){
DeleteCriticalSection(&mutex);
}
void Mutex::p(){
EnterCriticalSection(&mutex);
}
void Mutex::v(){
LeaveCriticalSection(&mutex);
}
}}//end namespace

View File

@@ -1,396 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "window.h"
#include <cassert>
#include "control.h"
#include "conversion.h"
#include "platform_util.h"
#include "leak_dumper.h"
using namespace Shared::Util;
using namespace std;
namespace Shared{ namespace Platform{
// =====================================================
// class Window
// =====================================================
const DWORD Window::fullscreenStyle= WS_POPUP | WS_OVERLAPPED;
const DWORD Window::windowedFixedStyle= WS_CAPTION | WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_SYSMENU;
const DWORD Window::windowedResizeableStyle= WS_SIZEBOX | WS_CAPTION | WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_SYSMENU;
int Window::nextClassName= 0;
Window::WindowMap Window::createdWindows;
// ===================== PUBLIC ========================
Window::Window(){
handle= 0;
style= windowedFixedStyle;
exStyle= 0;
ownDc= false;
x= 0;
y= 0;
w= 100;
h= 100;
}
Window::~Window(){
if(handle!=0){
DestroyWindow(handle);
handle= 0;
BOOL b= UnregisterClass(className.c_str(), GetModuleHandle(NULL));
assert(b);
}
}
//static
bool Window::handleEvent(){
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message==WM_QUIT){
return false;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
string Window::getText(){
if(handle==0){
return text;
}
char c[255];
SendMessage(handle, WM_GETTEXT, 255, (LPARAM) c);
return string(c);
}
int Window::getClientW(){
RECT r;
GetClientRect(handle, &r);
return r.right;
}
int Window::getClientH(){
RECT r;
GetClientRect(handle, &r);
return r.bottom;
}
float Window::getAspect(){
return static_cast<float>(getClientH())/getClientW();
}
void Window::setText(string text){
this->text= text;
if(handle!=0){
SendMessage(handle, WM_SETTEXT, 0, (LPARAM) text.c_str());
}
}
void Window::setSize(int w, int h){
if(windowStyle != wsFullscreen){
RECT rect;
rect.left= 0;
rect.top= 0;
rect.bottom= h;
rect.right= w;
AdjustWindowRect(&rect, style, FALSE);
w= rect.right-rect.left;
h= rect.bottom-rect.top;
}
this->w= w;
this->h= h;
if(handle!=0){
MoveWindow(handle, x, y, w, h, FALSE);
UpdateWindow(handle);
}
}
void Window::setPos(int x, int y){
this->x= x;
this->y= y;
if(handle!=0){
MoveWindow(handle, x, y, w, h, FALSE);
}
}
void Window::setEnabled(bool enabled){
EnableWindow(handle, static_cast<BOOL>(enabled));
}
void Window::setVisible(bool visible){
if (visible){
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
}
else{
ShowWindow(handle, SW_HIDE);
UpdateWindow(handle);
}
}
void Window::setStyle(WindowStyle windowStyle){
this->windowStyle= windowStyle;
switch(windowStyle){
case wsFullscreen:
style= fullscreenStyle;
exStyle= WS_EX_APPWINDOW;
ownDc= true;
break;
case wsWindowedFixed:
style= windowedFixedStyle;
exStyle= 0;
ownDc= false;
break;
case wsWindowedResizeable:
style= windowedResizeableStyle;
exStyle= 0;
ownDc= false;
break;
}
if(handle!=0){
setVisible(false);
int err= SetWindowLong(handle, GWL_STYLE, style);
assert(err);
setVisible(true);
UpdateWindow(handle);
}
}
void Window::create(){
registerWindow();
createWindow();
}
void Window::minimize(){
ShowWindow(getHandle(), SW_MINIMIZE);
}
void Window::maximize(){
ShowWindow(getHandle(), SW_MAXIMIZE);
}
void Window::restore(){
ShowWindow(getHandle(), SW_RESTORE);
}
void Window::showPopupMenu(Menu *menu, int x, int y){
RECT rect;
GetWindowRect(handle, &rect);
TrackPopupMenu(menu->getHandle(), TPM_LEFTALIGN | TPM_TOPALIGN, rect.left+x, rect.top+y, 0, handle, NULL);
}
void Window::destroy(){
DestroyWindow(handle);
BOOL b= UnregisterClass(className.c_str(), GetModuleHandle(NULL));
assert(b);
handle= 0;
}
// ===================== PRIVATE =======================
LRESULT CALLBACK Window::eventRouter(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
Window *eventWindow;
WindowMap::iterator it;
it= createdWindows.find(hwnd);
if(it==createdWindows.end()){
return DefWindowProc(hwnd, msg, wParam, lParam);
}
eventWindow= it->second;
POINT mousePos;
RECT windowRect;
GetWindowRect(eventWindow->getHandle(), &windowRect);
mousePos.x = LOWORD(lParam) - windowRect.left;
mousePos.y = HIWORD(lParam) -windowRect.top;
ClientToScreen(eventWindow->getHandle(), &mousePos);
switch(msg){
case WM_CREATE:
eventWindow->eventCreate();
break;
case WM_LBUTTONDOWN:
eventWindow->eventMouseDown(mousePos.x, mousePos.y, mbLeft);
break;
case WM_RBUTTONDOWN:
eventWindow->eventMouseDown(mousePos.x, mousePos.y, mbRight);
break;
case WM_LBUTTONUP:
eventWindow->eventMouseUp(mousePos.x, mousePos.y, mbLeft);
break;
case WM_RBUTTONUP:
eventWindow->eventMouseUp(mousePos.x, mousePos.y, mbRight);
break;
case WM_LBUTTONDBLCLK:
eventWindow->eventMouseDoubleClick(mousePos.x, mousePos.y, mbLeft);
break;
case WM_RBUTTONDBLCLK:
eventWindow->eventMouseDoubleClick(mousePos.x, mousePos.y, mbRight);
break;
case WM_MOUSEMOVE:
{
MouseState ms;
ms.leftMouse= (wParam & MK_LBUTTON) ? true : false;
ms.rightMouse= (wParam & MK_RBUTTON) ? true : false;
ms.centerMouse= (wParam & MK_MBUTTON) ? true : false;
eventWindow->eventMouseMove(mousePos.x, mousePos.y, &ms);
}
break;
case WM_KEYDOWN:
eventWindow->eventKeyDown(static_cast<char>(wParam));
break;
case WM_KEYUP:
eventWindow->eventKeyUp(static_cast<char>(wParam));
break;
case WM_CHAR:
eventWindow->eventKeyPress(static_cast<char>(wParam));
break;
case WM_COMMAND:
if(HIWORD(wParam)==0){
eventWindow->eventMenu(LOWORD(wParam));
}
break;
case WM_ACTIVATE:
eventWindow->eventActivate(wParam!=WA_INACTIVE);
break;
case WM_MOVE:
{
RECT rect;
GetWindowRect(eventWindow->getHandle(), &rect);
eventWindow->x= rect.left;
eventWindow->y= rect.top;
eventWindow->w= rect.right-rect.left;
eventWindow->h= rect.bottom-rect.top;
}
break;
case WM_SIZE:
{
RECT rect;
GetWindowRect(eventWindow->getHandle(), &rect);
eventWindow->x= rect.left;
eventWindow->y= rect.top;
eventWindow->w= rect.right-rect.left;
eventWindow->h= rect.bottom-rect.top;
eventWindow->eventResize(static_cast<SizeState>(wParam));
}
break;
case WM_SIZING:
eventWindow->eventResize();
break;
case WM_PAINT:
eventWindow->eventPaint();
break;
case WM_CLOSE:
eventWindow->eventClose();
break;
case WM_DESTROY:
eventWindow->eventDestroy();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int Window::getNextClassName(){
return ++nextClassName;
}
void Window::registerWindow(WNDPROC wndProc){
WNDCLASSEX wc;
this->className= "Window" + intToStr(Window::getNextClassName());
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_DBLCLKS | (ownDc? CS_OWNDC : 0);
wc.lpfnWndProc = wndProc==NULL? eventRouter: wndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = this->className.c_str();
wc.hIconSm = NULL;
int registerClassErr=RegisterClassEx(&wc);
assert(registerClassErr);
}
void Window::createWindow(LPVOID creationData){
handle = CreateWindowEx(
exStyle,
className.c_str(),
text.c_str(),
style,
x, y, w, h,
NULL, NULL, GetModuleHandle(NULL), creationData);
createdWindows.insert(pair<WindowHandle, Window*>(handle, this));
eventRouter(handle, WM_CREATE, 0, 0);
assert(handle != NULL);
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
}
}}//end namespace

View File

@@ -1,44 +0,0 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Marti<74>o Figueroa
//
// You can redistribute this code 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
// ==============================================================
#include "window_gl.h"
#include "gl_wrap.h"
#include "graphics_interface.h"
#include "leak_dumper.h"
using namespace Shared::Graphics;
namespace Shared{ namespace Platform{
// =====================================================
// class WindowGl
// =====================================================
void WindowGl::initGl(int colorBits, int depthBits, int stencilBits){
context.setColorBits(colorBits);
context.setDepthBits(depthBits);
context.setStencilBits(stencilBits);
context.init();
}
void WindowGl::makeCurrentGl(){
GraphicsInterface::getInstance().setCurrentContext(&context);
context.makeCurrent();
}
void WindowGl::swapBuffersGl(){
context.swapBuffers();
}
}}//end namespace