diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fcd67e4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,38 @@
+*.o
+*.a
+*.lib
+*.ncb
+*.pdb
+*.suo
+*.idb
+*.user
+*.sdf
+*.opensdf
+moc_*.cpp
+qrc_*.cpp
+ui_*.h
+.*.swp
+.DS_Store
+*~
+/editor/Makefile*
+/editor/editor.vcproj
+/editor/editor.sln
+/editor/debug/
+/editor/release/
+/editor/editor/
+/editor/editor.app/
+/example_bass/example_bass
+/example_bass/Debug Client/
+/example_bass/Debug/
+/example_bass/Release Client/
+/example_bass/Release/
+/example_bass/x64/
+/example_bass/include/
+/example_bass/lib/
+/lib/Debug Client/
+/lib/Debug/
+/lib/Release Client/
+/lib/Release/
+/lib/x64/
+/packages/
+build-*
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..fb36f62
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+language: c
+
+os:
+ - linux
+ - osx
+
+before_script:
+ - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install qt; fi
+
+script: make
diff --git a/COPYING b/COPYING
index d46968d..a2d288f 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (C) 2007-2008 Erik Faye-Lund and Egbert Teeselink
+Copyright (C) 2007 Contributors
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/Makefile b/Makefile
index 0a97efa..efd88b4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,10 @@
# default target
all:
+.PHONY: all clean editor
+
+QMAKE ?= qmake
+
# default build flags
CFLAGS = -g -O2 -Wall
@@ -13,31 +17,57 @@ ifdef COMSPEC
SDL_LIBS = -lSDL
LDLIBS += -lws2_32
else
- OPENGL_LIBS = -lGL -lGLU
+ UNAME_S := $(shell uname -s)
+
+ ifeq ($(UNAME_S), Linux)
+ CPPFLAGS += -DUSE_GETADDRINFO
+ OPENGL_LIBS = -lGL -lGLU
+ else ifeq ($(UNAME_S), Darwin)
+ CPPFLAGS += -DUSE_GETADDRINFO
+ OPENGL_LIBS = -framework OpenGL
+ else
+ OPENGL_LIBS = -lGL -lGLU
+ endif
+
SDL_CFLAGS = $(shell sdl-config --cflags)
SDL_LIBS = $(shell sdl-config --libs)
LDLIBS += -lm
endif
-SYNC_OBJS = \
- sync/data.o \
- sync/device.o \
- sync/track.o
+LIB_OBJS = \
+ lib/device.o \
+ lib/track.o
-all: lib/librocket.a
+all: lib/librocket.a lib/librocket-player.a editor
-bin/example_bass$X: CPPFLAGS += -Iexample_bass/include
-bin/example_bass$X: CXXFLAGS += $(SDL_CFLAGS)
-bin/example_bass$X: LDLIBS += -Lexample_bass/lib -lbass
-bin/example_bass$X: LDLIBS += $(OPENGL_LIBS) $(SDL_LIBS)
+example_bass/%$X: CPPFLAGS += -Iexample_bass/include
+example_bass/%$X: CXXFLAGS += $(SDL_CFLAGS)
+example_bass/%$X: LDLIBS += -Lexample_bass/lib -lbass
+example_bass/%$X: LDLIBS += $(OPENGL_LIBS) $(SDL_LIBS)
clean:
- $(RM) -rf $(SYNC_OBJS) lib bin
+ $(RM) $(LIB_OBJS) lib/librocket.a lib/librocket-player.a
+ $(RM) example_bass/example_bass$X example_bass/example_bass-player$X
+ if test -e editor/Makefile; then $(MAKE) -C editor clean; fi;
+ $(RM) editor/editor editor/Makefile
-lib/librocket.a: $(SYNC_OBJS)
- @mkdir -p lib
+lib/librocket.a: $(LIB_OBJS)
$(AR) $(ARFLAGS) $@ $^
-bin/example_bass$X: example_bass/example_bass.cpp lib/librocket.a
- @mkdir -p bin
+%.player.o : %.c
+ $(COMPILE.c) -DSYNC_PLAYER $(OUTPUT_OPTION) $<
+
+lib/librocket-player.a: $(LIB_OBJS:.o=.player.o)
+ $(AR) $(ARFLAGS) $@ $^
+
+example_bass/example_bass$X: example_bass/example_bass.cpp lib/librocket.a
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@
+
+example_bass/example_bass-player$X: example_bass/example_bass.cpp lib/librocket-player.a
+ $(LINK.cpp) -DSYNC_PLAYER $^ $(LOADLIBES) $(LDLIBS) -o $@
+
+editor/Makefile: editor/editor.pro
+ cd editor && $(QMAKE) editor.pro -o Makefile
+
+editor: editor/Makefile
+ $(MAKE) -C editor
diff --git a/README b/README
deleted file mode 100644
index 87d979f..0000000
--- a/README
+++ /dev/null
@@ -1,91 +0,0 @@
-GNU Rocket
-==========
-GNU Rocket is an intuitive new way of... bah, whatever. It's a sync-tracker,
-a tool for synchronizing music and visuals in demoscene productions. It
-consists of a GUI editor that runs on Microsoft Windows, and an ANSI C
-library that can either communicate with the editor over a network socket,
-or play back an exported data-set.
-
-Compile Editor
---------------
-GNU Rocket compiles using Microsoft Visual Studio 2008. Open editor.sln and
-select "Build" -> "Build Solution" from the menu to build the editor.
-
-Compile Example
----------------
-GNU Rocket contains an example client called example_bass. This is a simple
-OpenGL, SDL 1.2 and BASS audio library application, that demonstrates how to
-use the GNU Rocket API.
-
-Before compiling the example, you need to make sure you have recent
-SDL and BASS libraries and includes. These can be downloaded from the
-following web-sites:
-
-http://www.libsdl.org/
-http://www.un4seen.com/
-
-The header files and libraries can be installed local to the project by
-copying all .lib-files to the example_bass/lib/, all .h files to
-example_bass/inclide/, and all .dll files to the example_bass/.
-
-Once the prerequisites are installed, the example can be compiled much like
-the editor; by opening examples.sln and selecting "Build" -> "Build Solution"
-from the menu.
-
-Using the editor
-----------------
-The GNU Rocket editor is laid out like a music-tracker; tracks (or columns)
-and rows. Each track represents a separate "variable" in the demo, over the
-entire time-domain of the demo. Each row represents a specific point in time,
-and consists of a set of key-frames. The key-frames are interpolated over time
-according to their interpolation modes.
-
-Interpolation modes
--------------------
-Each key-frame has an interpolation mode associated with it, and that
-interpolation mode is valid until the next key-frame is reached. The different
-interpolation modes are the following:
-
-* Step : This is the simplest mode, and always returns the key's value.
-* Linear : This does a linear interpolation between the current and the next
- key's values.
-* Smooth : This interpolates in a smooth fashion, the exact function is what
- is usually called "smoothstep". Do not confuse this mode with
- splines; this only interpolates smoothly between two different
- values, it does not try to calculate tangents or any such things.
-* Ramp : This is similar to "Linear", but additionally applies an
- exponentiation of the interpolation factor.
-
-Keyboard shortcuts
--------------------
-Some of the GNU Rocket editor's features are available through the menu and
-some keyboard shortcut. Here's a list of the supported keyboard shortcuts:
-
-Up/Down/Left/Right Move cursor
-PgUp/PgDn Move cursor 16 rows up/down
-Home/End Move cursor to begining/end
-Ctrl+Left/Right Move track
-Enter Enter key-frame value
-Del Delete key-frame
-i Enumerate interpolation mode
-k Toggle bookmark
-Alt+PgUp/PgDn Go to prev/next bookmark
-Space Pause/Resume demo
-Shift+Up/Down/Left/Right Select
-Ctrl+C Copy
-Ctrl+V Paste
-Ctrl+Z Undo
-Shift+Ctrl+Z Redo
-Ctrl+B Bias keyframes
-Shift+Ctrl+Up/Down Quick-bias by +/- 0.1
-Ctrl+Up/Down Quick-bias by +/- 1
-Ctrl+PgUp/PgDn Quick-bias by +/- 10
-Shift+Ctrl+PgUp/PgDn Quick-bias by +/- 100
-
-Bugs and feed-back
-------------------
-Please report bugs or other feed-back to the GNU Rocket mailing list:
-rocket-users@lists.sourceforge.net
-
-Patches or technical questions can be sent to the developer-list:
-rocket-developers@lists.sourceforge.net
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f119a1b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,92 @@
+GNU Rocket
+==========
+
+[](https://ci.appveyor.com/project/kusma/rocket/branch/master)
+[](https://travis-ci.org/kusma/rocket)
+
+GNU Rocket is an intuitive new way of... bah, whatever. It's a sync-tracker,
+a tool for synchronizing music and visuals in demoscene productions. It
+consists of a GUI editor (using Qt), and an ANSI C library that can either
+communicate with the editor over a network socket, or play back an exported
+data-set.
+
+Compile Editor
+--------------
+The GNU Rocket editor uses qmake as a build-system abstraction, which can
+be used to output Makefiles, Visual Studio project files or can be built
+directly from QtCreator. See the qmake documentation for details.
+
+Compile Example
+---------------
+GNU Rocket contains an example client called example\_bass. This is a simple
+OpenGL, SDL 1.2 and BASS audio library application, that demonstrates how to
+use the GNU Rocket API.
+
+Before compiling the example, you need to make sure you have recent [SDL](http://www.libsdl.org/)
+and [BASS](http://www.un4seen.com/) libraries and includes.
+
+The header files and libraries can be installed local to the project by
+copying all .lib-files to the example\_bass/lib/, all .h files to
+example\_bass/include/, and all .dll files to the example\_bass/.
+
+Once the prerequisites are installed, the example can be compiled either by
+opening examples.sln and selecting "Build" -> "Build Solution" from Visual
+Studio 2008, or by doing "make example_bass/example_bass" on Unix-base
+systems.
+
+Using the editor
+----------------
+The GNU Rocket editor is laid out like a music-tracker; tracks (or columns)
+and rows. Each track represents a separate "variable" in the demo, over the
+entire time-domain of the demo. Each row represents a specific point in time,
+and consists of a set of key frames. The key frames are interpolated over time
+according to their interpolation modes.
+
+Interpolation modes
+-------------------
+Each key frame has an interpolation mode associated with it, and that
+interpolation mode is valid until the next key frame is reached. The different
+interpolation modes are the following:
+
+* Step : This is the simplest mode, and always returns the key's value.
+* Linear : This does a linear interpolation between the current and the next
+ key's values.
+* Smooth : This interpolates in a smooth fashion, the exact function is what
+ is usually called "smoothstep". Do not confuse this mode with
+ splines; this only interpolates smoothly between two different
+ values, it does not try to calculate tangents or any such things.
+* Ramp : This is similar to "Linear", but additionally applies an
+ exponentiation of the interpolation factor.
+
+Keyboard shortcuts
+-------------------
+Some of the GNU Rocket editor's features are available through the menu and
+some keyboard shortcut. Here's a list of the supported keyboard shortcuts:
+
+| Shortcut | Action |
+|:-------------------------|:-----------------------------|
+| Up/Down/Left/Right | Move cursor |
+| PgUp/PgDn | Move cursor 16 rows up/down |
+| Home/End | Move cursor to begining/end |
+| Ctrl+Left/Right | Move track |
+| Enter | Enter key frame value |
+| Del | Delete key frame |
+| i | Enumerate interpolation mode |
+| k | Toggle bookmark |
+| Alt+PgUp/PgDn | Go to prev/next bookmark |
+| Space | Pause/Resume demo |
+| Shift+Up/Down/Left/Right | Select |
+| Ctrl+C | Copy |
+| Ctrl+V | Paste |
+| Ctrl+Z | Undo |
+| Shift+Ctrl+Z | Redo |
+| Ctrl+B | Bias key frames |
+| Shift+Ctrl+Up/Down | Quick-bias by +/- 0.1 |
+| Ctrl+Up/Down | Quick-bias by +/- 1 |
+| Ctrl+PgUp/PgDn | Quick-bias by +/- 10 |
+| Shift+Ctrl+PgUp/PgDn | Quick-bias by +/- 100 |
+
+Bugs and feedback
+------------------
+Please report bugs or other feedback to the GNU Rocket mailing list:
+gnu-rocket@googlegroups.com
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..89a0795
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,48 @@
+version: '{build}'
+
+environment:
+ matrix:
+ - platform: x64
+ cc: VS2013
+ QTDIR: C:\Qt\5.5\msvc2013_64
+ - platform: Win32
+ cc: VS2013
+ QTDIR: C:\Qt\5.5\msvc2013
+
+configuration:
+ - Release
+
+cache:
+ - packages -> **\packages.config
+
+install:
+ - nuget restore examples.vs2013.sln
+ # download and install bass
+ - curl -fsS -o bass24.zip http://www.un4seen.com/files/bass24.zip
+ - 7z x -obass24 bass24.zip > NUL
+ - mkdir example_bass\lib
+ - mkdir example_bass\lib64
+ - mkdir example_bass\include
+ - copy bass24\c\bass.lib example_bass\lib
+ - copy bass24\c\x64\bass.lib example_bass\lib64
+ - copy bass24\c\bass.h example_bass\include
+
+before_build:
+ - set PATH=%QTDIR%\bin;%PATH%
+
+build_script:
+ - msbuild examples.vs2013.sln
+ - msbuild examples.vs2013.sln /property:Configuration="Release Client"
+ - cd editor
+ - qmake -tp vc editor.pro
+ - msbuild
+
+after_build:
+ - mkdir staging
+ - cd staging
+ - copy ..\release\editor.exe .
+ - windeployqt --release editor.exe
+
+artifacts:
+ - path: editor\staging
+ name: editor
diff --git a/contrib/DotRocket/DotRocket/DotRocket.cpp b/contrib/DotRocket/DotRocket/DotRocket.cpp
index 5f2a913..79f9563 100644
--- a/contrib/DotRocket/DotRocket/DotRocket.cpp
+++ b/contrib/DotRocket/DotRocket/DotRocket.cpp
@@ -4,21 +4,22 @@
#include "DotRocket.h"
-#include "../../../sync/sync.h"
-#include "../../../sync/track.h"
+#include "../../../lib/sync.h"
+#include "../../../lib/track.h"
using System::Runtime::InteropServices::Marshal;
using DotRocket::Track;
using DotRocket::PlayerDevice;
-private ref class PlayerTrack: public Track {
+private ref class PlayerTrack: public Track
+{
const sync_track *track;
public:
PlayerTrack(const sync_track *track): track(track) {}
- virtual float GetValue(double time) override
+ virtual double GetValue(double time) override
{
return sync_get_val(track, time);
- };
+ }
};
PlayerDevice::PlayerDevice(System::String ^name)
diff --git a/contrib/DotRocket/DotRocket/DotRocket.h b/contrib/DotRocket/DotRocket/DotRocket.h
index 3625fd7..1df3d9c 100644
--- a/contrib/DotRocket/DotRocket/DotRocket.h
+++ b/contrib/DotRocket/DotRocket/DotRocket.h
@@ -3,7 +3,6 @@
#pragma once
struct sync_device;
-struct sync_track;
using namespace System;
using namespace System::Collections::Generic;
@@ -13,7 +12,7 @@ namespace DotRocket
public ref class Track abstract
{
public:
- virtual float GetValue(double time) = 0;
+ virtual double GetValue(double time) = 0;
};
public delegate void PauseEventHandler(bool flag);
diff --git a/contrib/DotRocket/DotRocket/DotRocket.vcproj b/contrib/DotRocket/DotRocket/DotRocket.vcproj
index f3a1cda..054e191 100644
--- a/contrib/DotRocket/DotRocket/DotRocket.vcproj
+++ b/contrib/DotRocket/DotRocket/DotRocket.vcproj
@@ -59,7 +59,7 @@
/>
using DotRocket::Track;
using DotRocket::Device;
using DotRocket::ClientDevice;
-private ref class ClientTrack: public Track {
+private ref class ClientTrack: public Track
+{
const sync_track *track;
public:
ClientTrack(const sync_track *track) : track(track) {}
- virtual float GetValue(double time) override
+ virtual double GetValue(double time) override
{
return sync_get_val(track, time);
+ }
+};
+
+namespace
+{
+ class DeviceReference
+ {
+ public:
+ DeviceReference(Device ^dev) : dev(dev) {}
+ Device ^GetDevice() { return dev; }
+ private:
+ gcroot dev;
};
-};
-
-ref class Callbacks {
-public:
- static Device ^DeviceCurrenltyBeingProcessed = nullptr;
-};
-
-void cb_pause(void *arg, int row)
-{
- Callbacks::DeviceCurrenltyBeingProcessed->Pause(row);
}
-void cb_set_row(void *arg, int row)
+static void cb_pause(void *arg, int flag)
{
- Callbacks::DeviceCurrenltyBeingProcessed->SetRow(row);
+ ((DeviceReference *)arg)->GetDevice()->Pause(!!flag);
}
-int cb_is_playing(void *arg)
+static void cb_set_row(void *arg, int row)
{
- return !!Callbacks::DeviceCurrenltyBeingProcessed->IsPlaying();
+ ((DeviceReference *)arg)->GetDevice()->SetRow(row);
}
-sync_cb callbacks[] = {
+static int cb_is_playing(void *arg)
+{
+ return ((DeviceReference *)arg)->GetDevice()->IsPlaying();
+}
+
+static sync_cb callbacks[] = {
cb_pause,
cb_set_row,
cb_is_playing
@@ -76,13 +85,13 @@ ClientDevice::!ClientDevice()
bool ClientDevice::Connect(System::String^ host, unsigned short port)
{
char *chost = (char *)(void *)Marshal::StringToHGlobalAnsi(host);
- int result = sync_connect((sync_device *)device, chost, port);
+ int result = sync_connect(device, chost, port);
Marshal::FreeHGlobal((System::IntPtr)chost);
return !result;
}
bool ClientDevice::Update(int row)
{
- Callbacks::DeviceCurrenltyBeingProcessed = this;
- return !sync_update(device, row, callbacks, device);
+ DeviceReference devref(this);
+ return !sync_update(device, row, callbacks, &devref);
}
diff --git a/contrib/DotRocket/DotRocketClient/DotRocketClient.h b/contrib/DotRocket/DotRocketClient/DotRocketClient.h
index d9ecf87..35f118e 100644
--- a/contrib/DotRocket/DotRocketClient/DotRocketClient.h
+++ b/contrib/DotRocket/DotRocketClient/DotRocketClient.h
@@ -3,13 +3,14 @@
#pragma once
struct sync_device;
-struct sync_track;
using namespace System;
using namespace System::Collections::Generic;
-namespace DotRocket {
- public ref class ClientDevice: public Device {
+namespace DotRocket
+{
+ public ref class ClientDevice: public Device
+ {
protected:
sync_device *device;
Dictionary ^tracks;
diff --git a/contrib/DotRocket/DotRocketClient/DotRocketClient.vcproj b/contrib/DotRocket/DotRocketClient/DotRocketClient.vcproj
index 660b426..c9c1175 100644
--- a/contrib/DotRocket/DotRocketClient/DotRocketClient.vcproj
+++ b/contrib/DotRocket/DotRocketClient/DotRocketClient.vcproj
@@ -59,7 +59,7 @@
/>
-#define ID_FILE_NEW 0xE100
-#define ID_FILE_OPEN 0xE101
-#define ID_FILE_SAVE 0xE103
-#define ID_FILE_SAVE_AS 0xE104
-#define ID_EDIT_CLEAR 0xE120
-#define ID_EDIT_COPY 0xE122
-#define ID_EDIT_CUT 0xE123
-#define ID_EDIT_PASTE 0xE125
-#define ID_EDIT_SELECT_ALL 0xE12A
-#define ID_EDIT_UNDO 0xE12B
-#define ID_EDIT_REDO 0xE12C
diff --git a/editor/appicon.icns b/editor/appicon.icns
new file mode 100644
index 0000000..fff9e92
Binary files /dev/null and b/editor/appicon.icns differ
diff --git a/editor/clientsocket.cpp b/editor/clientsocket.cpp
index 3e47624..95df10d 100644
--- a/editor/clientsocket.cpp
+++ b/editor/clientsocket.cpp
@@ -1,47 +1,177 @@
#include "clientsocket.h"
-#include "../sync/track.h"
+#include "syncdocument.h"
-#include
-#include
+#include
+#include
-void ClientSocket::sendSetKeyCommand(const std::string &trackName, const struct track_key &key)
+bool WebSocket::readFrame(QByteArray &buf)
+{
+ unsigned char header[2];
+ if (!TcpSocket::recv((char *)header, 2))
+ return false;
+
+ // int flags = header[0] >> 4;
+ int opcode = header[0] & 0xF;
+ int masked = header[1] >> 7;
+ int payload_len = header[1] & 0x7f;
+
+ if (payload_len == 126) {
+ quint16 tmp;
+ if (!TcpSocket::recv((char *)&tmp, 2))
+ return false;
+ payload_len = qFromBigEndian(tmp);
+ } else if (payload_len == 127) {
+ // dude, that's one crazy big payload! let's bail!
+ return false;
+ }
+
+ unsigned char mask[4] = { 0 };
+ if (masked) {
+ if (!TcpSocket::recv((char *)mask, sizeof(mask)))
+ return false;
+ }
+
+ buf.resize(payload_len);
+ if (payload_len > 0) {
+ if (!TcpSocket::recv(buf.data(), payload_len))
+ return false;
+ }
+
+ for (int i = 0; i < payload_len; ++i)
+ buf[i] = buf[i] ^ mask[i & 3];
+
+ switch (opcode) {
+ case 9:
+ // got ping, send pong!
+ sendFrame(10, buf.data(), buf.length(), true);
+ buf.clear();
+ return true;
+
+ case 8:
+ // close
+ disconnect();
+ buf.clear();
+ return false;
+ }
+
+ return true;
+}
+
+bool WebSocket::recv(char *buffer, int length)
+{
+ if (!connected())
+ return false;
+ while (length) {
+ while (!buf.length() && !readFrame(buf))
+ return false;
+
+ int bytes = qMin(buf.length(), length);
+ memcpy(buffer, buf.data(), bytes);
+ buf.remove(0, bytes);
+ buffer += bytes;
+ length -= bytes;
+ }
+ return true;
+}
+
+bool WebSocket::sendFrame(int opcode, const char *payloadData, size_t payloadLength, bool endOfMessage)
+{
+ unsigned char header[2];
+ header[0] = (endOfMessage ? 0x80 : 0) | (unsigned char)opcode;
+ header[1] = payloadLength < 126 ? (unsigned char)(payloadLength) : 126;
+ if (!TcpSocket::send((const char *)header, 2, false))
+ return false;
+
+ if (payloadLength >= 126) {
+ Q_ASSERT(payloadLength < 0xffff);
+ quint16 tmp = qToBigEndian((quint16)(payloadLength));
+ if (!TcpSocket::send((const char *)&tmp, 2, false))
+ return false;
+ }
+
+ firstFrame = endOfMessage;
+ return TcpSocket::send(payloadData, payloadLength, endOfMessage);
+}
+
+WebSocket *WebSocket::upgradeFromHttp(QTcpSocket *socket)
+{
+ QByteArray key;
+ for (;;) {
+ QByteArray line;
+ for (;;) {
+ char ch;
+ if (socket->read(&ch, 1) != 1)
+ return NULL;
+
+ if (ch == '\n')
+ break;
+ if (ch != '\r')
+ line.push_back(ch);
+ }
+
+ const char *prefix = "Sec-WebSocket-Key: ";
+ if (line.startsWith(prefix))
+ key = line.right(line.length() - int(strlen(prefix)));
+ else if (!line.length())
+ break;
+ }
+
+ if (!key.length())
+ return NULL;
+
+ key.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
+
+ QCryptographicHash hash(QCryptographicHash::Sha1);
+ hash.addData(key.data(), key.size());
+
+ QString response = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ";
+ response.append(hash.result().toBase64());
+ response.append("\r\n\r\n");
+
+ socket->write(response.toUtf8().constData(), response.length());
+
+ return new WebSocket(socket);
+}
+
+
+void ClientSocket::sendSetKeyCommand(const QString &trackName, const SyncTrack::TrackKey &key)
{
if (!connected() ||
clientTracks.count(trackName) == 0)
return;
- uint32_t track = htonl(clientTracks[trackName]);
- uint32_t row = htonl(key.row);
+ quint32 track = qToBigEndian((quint32)clientTracks[trackName]);
+ quint32 row = qToBigEndian((quint32)key.row);
union {
float f;
- uint32_t i;
+ quint32 i;
} v;
v.f = key.value;
- v.i = htonl(v.i);
+ v.i = qToBigEndian(v.i);
- assert(key.type < KEY_TYPE_COUNT);
+ Q_ASSERT(key.type < SyncTrack::TrackKey::KEY_TYPE_COUNT);
unsigned char cmd = SET_KEY;
- send((char *)&cmd, 1, 0);
- send((char *)&track, sizeof(track), 0);
- send((char *)&row, sizeof(row), 0);
- send((char *)&v.i, sizeof(v.i), 0);
- send((char *)&key.type, 1, 0);
+ send((char *)&cmd, 1, false);
+ send((char *)&track, sizeof(track), false);
+ send((char *)&row, sizeof(row), false);
+ send((char *)&v.i, sizeof(v.i), false);
+ send((char *)&key.type, 1, true);
}
-void ClientSocket::sendDeleteKeyCommand(const std::string &trackName, int row)
+void ClientSocket::sendDeleteKeyCommand(const QString &trackName, int row)
{
if (!connected() ||
clientTracks.count(trackName) == 0)
return;
- uint32_t track = htonl(int(clientTracks[trackName]));
- row = htonl(row);
+ quint32 track = qToBigEndian((quint32)clientTracks[trackName]);
+ row = qToBigEndian((quint32)row);
unsigned char cmd = DELETE_KEY;
- send((char *)&cmd, 1, 0);
- send((char *)&track, sizeof(int), 0);
- send((char *)&row, sizeof(int), 0);
+ send((char *)&cmd, 1, false);
+ send((char *)&track, sizeof(int), false);
+ send((char *)&row, sizeof(int), true);
}
void ClientSocket::sendSetRowCommand(int row)
@@ -50,9 +180,9 @@ void ClientSocket::sendSetRowCommand(int row)
return;
unsigned char cmd = SET_ROW;
- row = htonl(row);
- send((char *)&cmd, 1, 0);
- send((char *)&row, sizeof(int), 0);
+ row = qToBigEndian((quint32)row);
+ send((char *)&cmd, 1, false);
+ send((char *)&row, sizeof(int), true);
}
void ClientSocket::sendPauseCommand(bool pause)
@@ -61,9 +191,8 @@ void ClientSocket::sendPauseCommand(bool pause)
return;
unsigned char cmd = PAUSE, flag = pause;
- send((char *)&cmd, 1, 0);
- send((char *)&flag, 1, 0);
- clientPaused = pause;
+ send((char *)&cmd, 1, false);
+ send((char *)&flag, 1, true);
}
void ClientSocket::sendSaveCommand()
@@ -72,5 +201,5 @@ void ClientSocket::sendSaveCommand()
return;
unsigned char cmd = SAVE_TRACKS;
- send((char *)&cmd, 1, 0);
+ send((char *)&cmd, 1, true);
}
diff --git a/editor/clientsocket.h b/editor/clientsocket.h
index f8f82e6..b3f9d36 100644
--- a/editor/clientsocket.h
+++ b/editor/clientsocket.h
@@ -1,63 +1,178 @@
-#include "../sync/base.h"
-#include