mirror of
https://github.com/glest/glest-source.git
synced 2025-08-13 20:03:58 +02:00
Code Restructuring to make mega-glest more standard
This commit is contained in:
@@ -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
|
||||
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
Reference in New Issue
Block a user