Tue, 26 May 2015 11:41:58 +0300
Allow compilation on Windows/MinGW
CMakeLists.txt | file | annotate | diff | comparison | revisions | |
sources/colors.h | file | annotate | diff | comparison | revisions | |
sources/format.h | file | annotate | diff | comparison | revisions | |
sources/interface.cpp | file | annotate | diff | comparison | revisions | |
sources/main.cpp | file | annotate | diff | comparison | revisions | |
sources/main.h | file | annotate | diff | comparison | revisions | |
sources/network/ipaddress.cpp | file | annotate | diff | comparison | revisions | |
sources/network/rconsession.cpp | file | annotate | diff | comparison | revisions | |
sources/network/udpsocket.cpp | file | annotate | diff | comparison | revisions |
--- a/CMakeLists.txt Fri May 15 21:43:21 2015 +0300 +++ b/CMakeLists.txt Tue May 26 11:41:58 2015 +0300 @@ -1,4 +1,5 @@ cmake_minimum_required (VERSION 2.4) +cmake_policy (SET CMP0003 NEW) project (zfc9000) add_library (huffman STATIC @@ -24,12 +25,26 @@ set (CURSES_NEED_NCURSES, True) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -W -Wall") -find_package (Curses) + +if (NOT WIN32) + find_package (Curses) +endif() + +if (MINGW) + set (CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static") +endif() + include_directories (${CURSES_INCUDE_DIRS}) include_directories (${CMAKE_CURRENT_BINARY_DIR}) include_directories (huffman) add_executable (${PROJECT_NAME} ${SOURCE_FILES}) -target_link_libraries (${PROJECT_NAME} ${CURSES_LIBRARIES} huffman) +target_link_libraries (${PROJECT_NAME} huffman) + +if (NOT WIN32) + target_link_libraries (${PROJECT_NAME} ${CURSES_LIBRARIES}) +else() + target_link_libraries (${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR}/pdcurses.a wsock32 ws2_32) +endif() add_custom_target (make_hginfo_h COMMAND python
--- a/sources/colors.h Fri May 15 21:43:21 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -#pragma once \ No newline at end of file
--- a/sources/format.h Fri May 15 21:43:21 2015 +0300 +++ b/sources/format.h Tue May 26 11:41:58 2015 +0300 @@ -33,25 +33,22 @@ #include "basics.h" #include "geometry.h" -#define FORMAT_OVERLOAD(...) \ - inline String make_format_argument (__VA_ARGS__ a) - // ------------------------------------------------------------------------------------------------- // -FORMAT_OVERLOAD (String) { return a; } -FORMAT_OVERLOAD (char) { return String (a); } -FORMAT_OVERLOAD (short int) { return String::from_number (a); } -FORMAT_OVERLOAD (int) { return String::from_number (a); } -FORMAT_OVERLOAD (long int) { return String::from_number (a); } -FORMAT_OVERLOAD (double) { return String::from_number (a); } -FORMAT_OVERLOAD (unsigned short int) { return String::from_number (a); } -FORMAT_OVERLOAD (unsigned int) { return String::from_number (a); } -FORMAT_OVERLOAD (unsigned long int) { return String::from_number (a); } -FORMAT_OVERLOAD (const char*) { return a; } -FORMAT_OVERLOAD (std::nullptr_t) { (void) a; return "<null pointer>"; } -FORMAT_OVERLOAD (bool) { return a ? "true" : "false"; } +inline String make_format_argument (String a) { return a; } +inline String make_format_argument (char a) { return String (a); } +inline String make_format_argument (short a) { return String::from_number (a); } +inline String make_format_argument (int a) { return String::from_number (a); } +inline String make_format_argument (long a) { return String::from_number (a); } +inline String make_format_argument (double a) { return String::from_number (a); } +inline String make_format_argument (unsigned short a) { return String::from_number (a); } +inline String make_format_argument (unsigned int a) { return String::from_number (a); } +inline String make_format_argument (unsigned long a) { return String::from_number (a); } +inline String make_format_argument (const char* a) { return a; } +inline String make_format_argument (std::nullptr_t) { return "<null pointer>"; } +inline String make_format_argument (bool a) { return a ? "true" : "false"; } -FORMAT_OVERLOAD (const void*) +inline String make_format_argument (const void* a) { String result; result.sprintf ("%p", a); @@ -59,7 +56,7 @@ } template<typename T, typename C> -FORMAT_OVERLOAD (const Container<T, C>&) +inline String make_format_argument (const Container<T, C>& a) { String result; @@ -80,7 +77,7 @@ return result; } -FORMAT_OVERLOAD (Color) +inline String make_format_argument (Color a) { static const char* colorstrings[] = { @@ -97,17 +94,17 @@ return "???"; } -FORMAT_OVERLOAD (Position) +inline String make_format_argument (const Position& a) { return String ("(") + a.x + ", " + a.y + ")"; } -FORMAT_OVERLOAD (Size) +inline String make_format_argument (const Size& a) { return String ("(") + a.width + "x" + a.height + ")"; } -FORMAT_OVERLOAD (Rectangle) +inline String make_format_argument (const Rectangle& a) { String result; result.sprintf ("{(%d, %d), (%dx%d)}", a.x, a.y, a.width, a.height); @@ -118,7 +115,7 @@ // // Formats the given string with the given args. // -FUNCTION format_args (const String& fmtstr, const Vector<String>& args) -> String; +String format_args (const String& fmtstr, const Vector<String>& args); // ------------------------------------------------------------------------------------------------- //
--- a/sources/interface.cpp Fri May 15 21:43:21 2015 +0300 +++ b/sources/interface.cpp Tue May 26 11:41:58 2015 +0300 @@ -41,7 +41,7 @@ // int Interface::color_pair (Color fg, Color bg) { - return COLOR_PAIR ((int (fg) * NUM_COLORS) + int (bg)); + return COLOR_PAIR (1 + (int (fg) * NUM_COLORS) + int (bg)); } // ------------------------------------------------------------------------------------------------- @@ -143,26 +143,46 @@ Interface::Interface() : Session (this) { - ::initscr(); - ::start_color(); - ::raw(); +#ifdef XCURSES + ::Xinitscr(argc, argv); +#else + ::initscr(); +#endif + + ::cbreak(); ::keypad (stdscr, true); ::noecho(); ::refresh(); ::timeout (0); - ::use_default_colors(); InputHistory.clear(); InputHistory << ""; OutputLines.clear(); OutputLines << ColoredLine(); Title = format (APPNAME " %1 (%2)", full_version_string(), changeset_date_string()); - for (int i = 0; i < NUM_COLORS; ++i) - for (int j = 0; j < NUM_COLORS; ++j) + if (::has_colors()) { - init_pair ((i * NUM_COLORS + j), - (i == DEFAULT) ? -1 : i, - (j == DEFAULT) ? -1 : j); + ::start_color(); + ::use_default_colors(); + + int defaultFg = (use_default_colors() == OK) ? -1 : COLOR_WHITE; + int defaultBg = (use_default_colors() == OK) ? -1 : COLOR_BLACK; + + // Initialize color pairs + for (int i = 0; i < NUM_COLORS; ++i) + for (int j = 0; j < NUM_COLORS; ++j) + { + int pairnum = 1 + (i * NUM_COLORS + j); + int fg = (i == DEFAULT) ? defaultFg : i; + int bg = (j == DEFAULT) ? defaultBg : j; + + if (::init_pair (pairnum, fg, bg) == ERR) + print ("Unable to initialize color pair %1 (%2, %3)\n", pairnum, fg, bg); + } + } + else + { + print ("This terminal does not appear to support colors.\n"); } render_full(); @@ -602,6 +622,9 @@ { int ch = ::getch(); + if (ch < 0) + return; + if (ch == KEY_RESIZE) { ::clear(); @@ -702,6 +725,7 @@ break; case KEY_BACKSPACE: + case '\b': if (CursorPosition > 0) { mutable_current_input().remove_at (--CursorPosition);
--- a/sources/main.cpp Fri May 15 21:43:21 2015 +0300 +++ b/sources/main.cpp Tue May 26 11:41:58 2015 +0300 @@ -28,9 +28,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "main.h" + +#ifndef _WIN32 +# include <sys/select.h> +#else +# include <winsock2.h> +#endif + #include <time.h> -#include <sys/select.h> -#include "main.h" #include "network/rconsession.h" #include "huffman.h" #include "interface.h" @@ -40,6 +46,19 @@ FUNCTION main (int argc, char* argv[]) -> int { +#ifdef _WIN32 + FreeConsole(); + + WSADATA wsaData; + int result = WSAStartup (MAKEWORD (2, 2), &wsaData); + + if (result != 0) + { + fprintf (stderr, "WSAStartup failed: %d\n", result); + return 1; + } +#endif + HUFFMAN_Construct(); if (argc != 1 and argc != 3)
--- a/sources/main.h Fri May 15 21:43:21 2015 +0300 +++ b/sources/main.h Tue May 26 11:41:58 2015 +0300 @@ -29,7 +29,7 @@ */ #pragma once -#include <ncurses.h> +#include <curses.h> #include "basics.h" #include "mystring.h" #include "geometry.h"
--- a/sources/network/ipaddress.cpp Fri May 15 21:43:21 2015 +0300 +++ b/sources/network/ipaddress.cpp Tue May 26 11:41:58 2015 +0300 @@ -28,13 +28,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "ipaddress.h" + +#ifndef _WIN32 +# include <netinet/in.h> +# include <netdb.h> +#else +# include <winsock2.h> +# include <ws2tcpip.h> +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> -#include <netinet/in.h> -#include <netdb.h> -#include "ipaddress.h" + +#ifdef _WIN32 +using AddrInfo = ADDRINFOA; +#else +using AddrInfo = struct addrinfo; +#endif // ----------------------------------------------------------------------------- // @@ -168,8 +181,8 @@ STATIC METHOD IPAddress::resolve (String node) -> IPAddress { - addrinfo hints; - addrinfo* lookup; + AddrInfo hints; + AddrInfo* lookup; memset (&hints, 0, sizeof hints); hints.ai_family = AF_INET;
--- a/sources/network/rconsession.cpp Fri May 15 21:43:21 2015 +0300 +++ b/sources/network/rconsession.cpp Tue May 26 11:41:58 2015 +0300 @@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <time.h> #include "rconsession.h" #include "../interface.h" @@ -41,7 +42,7 @@ { if (not m_socket.set_blocking (false)) { - print_to (stderr, "unable to set socket as non-blocking: %s\n", + print_to (stderr, "unable to set socket as non-blocking: %1\n", m_socket.error_string().chars()); exit (EXIT_FAILURE); }
--- a/sources/network/udpsocket.cpp Fri May 15 21:43:21 2015 +0300 +++ b/sources/network/udpsocket.cpp Tue May 26 11:41:58 2015 +0300 @@ -28,17 +28,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/socket.h> +#include "udpsocket.h" + +#ifndef _WIN32 +# include <sys/socket.h> +# include <netinet/in.h> +#else +# include <winsock2.h> +# include <ws2tcpip.h> +#endif + #include <sys/types.h> #include <sys/time.h> -#include <netinet/in.h> #include <string.h> #include <fcntl.h> #include <unistd.h> -#include "udpsocket.h" #include "../huffman/huffman.h" -static unsigned char g_huffmanBuffer[131072]; +static char g_huffmanBuffer[131072]; // ----------------------------------------------------------------------------- // @@ -54,9 +61,9 @@ // ------------------------------------------------------------------------------------------------- // -METHOD -UDPSocket::set_blocking (bool a) -> bool +bool UDPSocket::set_blocking (bool a) { +#ifndef _WIN32 int flags = fcntl (m_socket, F_GETFL, 0); int newflags = a ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); @@ -67,6 +74,17 @@ } return true; +#else + unsigned long mode = a ? 0 : 1; + + if (ioctlsocket (m_socket, FIONBIO, &mode) != 0) + { + m_error = strerror (errno); + return false; + } + + return true; +#endif } // ------------------------------------------------------------------------------------------------- @@ -91,8 +109,7 @@ // ------------------------------------------------------------------------------------------------- // -METHOD -UDPSocket::read (Datagram& datagram) -> bool +bool UDPSocket::read (Datagram& datagram) { sockaddr_in claddr; socklen_t socklen = sizeof claddr; @@ -109,7 +126,8 @@ unsigned char decodedPacket[MAX_DATAGRAM_LENGTH]; int decodedLength = sizeof decodedPacket; - HUFFMAN_Decode (g_huffmanBuffer, decodedPacket, length, &decodedLength); + HUFFMAN_Decode (reinterpret_cast<unsigned char*> (g_huffmanBuffer), + decodedPacket, length, &decodedLength); datagram.from.host = ntohl (claddr.sin_addr.s_addr); datagram.from.port = ntohs (claddr.sin_port); datagram.data = Bytestream (decodedPacket, decodedLength); @@ -122,7 +140,8 @@ UDPSocket::send (const IPAddress& address, const Bytestream& data) -> bool { int encodedlength = sizeof g_huffmanBuffer; - HUFFMAN_Encode (data.data(), g_huffmanBuffer, data.written_length(), &encodedlength); + HUFFMAN_Encode (data.data(), reinterpret_cast<unsigned char*> (g_huffmanBuffer), + data.written_length(), &encodedlength); sockaddr_in claddr = address.to_sockaddr_in(); int res = ::sendto (m_socket, g_huffmanBuffer, encodedlength, 0, reinterpret_cast<sockaddr*> (&claddr), sizeof claddr);