void RemoteWindowDataSoftware::clear() {
	lock();
	memset(data(), 0, m_pitch * m_height);
	unlock();
	bool oldDirectRendering = m_directRendering;
	m_directRendering = false;
	sendWindowUpdate(0, 0, m_width, m_height);
	m_directRendering = oldDirectRendering;
}
void RemoteWindowDataSoftware::crossAppSceneActive(CardWebApp* cardWebApp, int appBufWidth, int appBufHeight) {
	int tx = 0;
	int ty = 0;
	int tw = appBufWidth;
	int th = appBufHeight;

	//TODO: is this lock necessary?
	lock();

	cardWebApp->paint(m_context, m_surface, tx, ty, tw, th, tx, ty, tw, th);

	sendWindowUpdate(tx, ty, tw, th);

	unlock();

	m_channel->sendAsyncMessage(new ViewHost_SceneTransitionRun(key(), "zoom-fade-push"));
}
void RemoteWindowDataSoftware::runSceneTransition(CardWebApp* cardWebApp, const char* transitionType,
		bool isPop, int appBufWidth, int appBufHeight) {
	int tx = 0;
	int ty = 0;
	int tw = appBufWidth;
	int th = appBufHeight;

	lock();

	cardWebApp->paint(m_context, m_surface, tx, ty, tw, th, tx, ty, tw, th);

	sendWindowUpdate(tx, ty, tw, th);

	unlock();

	std::string transitionName = transitionType;
	if (isPop)
		transitionName += "-pop";
	else
		transitionName += "-push";

	m_channel->sendAsyncMessage(new ViewHost_SceneTransitionRun(key(), transitionName));
}
Exemplo n.º 4
0
	ServerProtocol *ServerHttp2::process()
	{
		struct Request req;
		req.timeout = std::chrono::milliseconds(15000);
		req.protocol_variant = Transfer::ProtocolVariant::HTTP_2;

		Http2::ConnectionData conn;

		sendEmptySettings(
			this->sock,
			req.timeout,
			conn,
			Http2::FrameFlag::EMPTY
		);

		if (getClientPreface(this->sock, req.timeout) == false) {
			constexpr uint32_t last_stream_id = 0;

			goAway(
				this->sock,
				req.timeout,
				conn,
				last_stream_id,
				Http2::ErrorCode::PROTOCOL_ERROR
			);

			return this;
		}

		conn.client_settings = Http2::ConnectionSettings::defaultSettings();
		conn.server_settings = Http2::ConnectionSettings::defaultSettings();

		std::vector<char> buf(conn.server_settings.max_frame_size);

		std::unordered_map<uint32_t, Http2::IncStream> streams {
			{ 0, Http2::IncStream(0, conn) }
		};

		Http2::IncStream &primary = streams.find(0)->second;
		this->stream = &primary;

		size_t streams_process_count = 0;
		uint32_t last_stream_id = 0;

		Http2::FrameMeta meta {};
		long read_size = 0;

		do {
			if (getNextHttp2FrameMeta(this->sock, req.timeout, buf, meta, read_size) == false) {
				break;
			}

			const uint8_t *addr = reinterpret_cast<const uint8_t *>(
				buf.data()
			) + Http2::FRAME_HEADER_SIZE;

			const uint8_t *end = addr + meta.length;

			if (meta.stream_id > last_stream_id) {
				last_stream_id = meta.stream_id;
			}

			Http2::IncStream &stream = getStreamData(streams, meta.stream_id, conn);

			if (Http2::StreamState::CLOSED == stream.state) {
				rstStream(this->sock, req.timeout, stream, Http2::ErrorCode::STREAM_CLOSED);
				continue;
			}

			if (meta.type != Http2::FrameType::CONTINUATION) {
				stream.frame_type = meta.type;
			}

			Http2::ErrorCode result = Http2::ErrorCode::NO_ERROR;

			switch (stream.frame_type)
			{
			case Http2::FrameType::DATA:
			{
				result = parseHttp2Data(meta, stream, addr, end);

				stream.window_size_inc -= meta.length;

				if (stream.reserved)
				{
					DataVariant::DataReceiver *dr = reinterpret_cast<DataVariant::DataReceiver *>(stream.reserved);

					if (stream.window_size_inc - long(conn.server_settings.max_frame_size) <= 0)
					{
						size_t update_size = conn.server_settings.initial_window_size +
							(dr->full_size - dr->recv_total) - size_t(stream.window_size_inc);

						if (update_size > Http2::MAX_WINDOW_UPDATE) {
							update_size = Http2::MAX_WINDOW_UPDATE;
						}

						sendWindowUpdate(this->sock, req.timeout, stream, uint32_t(update_size) );
						sendWindowUpdate(this->sock, req.timeout, primary, uint32_t(update_size) );

						stream.window_size_inc += update_size;
					}
				}

				break;
			}

			case Http2::FrameType::HEADERS:
			{
				result = parseHttp2Headers(meta, stream, addr, end);

				if (meta.flags & Http2::FrameFlag::END_HEADERS)
				{
					Transfer::request_data *rd = static_cast<Transfer::request_data *>(&stream);

					stream.reserved = createDataReceiver(rd, this->settings.variants);

					if (stream.reserved) {
						DataVariant::DataReceiver *dr = reinterpret_cast<DataVariant::DataReceiver *>(stream.reserved);
						dr->reserved = new std::string();
					}
				}

				break;
			}

			case Http2::FrameType::PRIORITY:
				result = Http2::ErrorCode::NO_ERROR;
				break;

			case Http2::FrameType::RST_STREAM:
				result = parseHttp2rstStream(meta, stream, addr, end);
				break;

			case Http2::FrameType::SETTINGS:
			{
				result = parseHttp2Settings(meta, stream, addr, end);

				if (Http2::ErrorCode::NO_ERROR == result && (meta.flags & Http2::FrameFlag::ACK) == false)
				{
					conn.decoding_dynamic_table.changeHeaderTableSize(conn.client_settings.header_table_size);
					conn.decoding_dynamic_table.changeMaxHeaderListSize(conn.client_settings.max_header_list_size);

					sendEmptySettings(this->sock, req.timeout, conn, Http2::FrameFlag::ACK);
				}

				break;
			}

			case Http2::FrameType::PUSH_PROMISE:
				result = Http2::ErrorCode::NO_ERROR;
				break;

			case Http2::FrameType::PING:
			{
				result = parseHttp2Ping(meta);

				if (Http2::ErrorCode::NO_ERROR == result && (meta.flags & Http2::FrameFlag::ACK) == false)
				{
					const uint64_t ping_data = *reinterpret_cast<const uint64_t *>(addr);
					ping(this->sock, req.timeout, conn, ping_data);
				}

				break;
			}

			case Http2::FrameType::GOAWAY:
				result = parseHttp2GoAway(meta, stream, addr, end);
				break;

			case Http2::FrameType::WINDOW_UPDATE:
				result = parseHttp2WindowUpdate(meta, stream, addr, end);
				break;

			default:
				result = Http2::ErrorCode::PROTOCOL_ERROR;
				break;
			}

			if (result != Http2::ErrorCode::NO_ERROR)
			{
				stream.state = Http2::StreamState::CLOSED;

				rstStream(this->sock, req.timeout, stream, result);

				// TODO: remove closed stream(s) from unordered map
			}
			else if ( (meta.flags & Http2::FrameFlag::END_STREAM) && meta.stream_id != 0)
			{
				stream.reserved = this->sock.get_tls_session();

				sockets.lock();

				sockets.emplace(
					std::tuple<Socket::Socket, Http2::IncStream *> {
						Socket::Socket(this->sock.get_handle() ),
						&stream
					}
				);

				sockets.unlock();

				this->controls.eventProcessQueue->notify();

				++streams_process_count;
			}
		}
		while (Http2::StreamState::CLOSED != primary.state);

		while (conn.sync.completed.load() < streams_process_count) {
			conn.sync.event.wait();
		}

		goAway(
			this->sock,
			req.timeout,
			conn,
			last_stream_id,
			Http2::ErrorCode::NO_ERROR
		);

		for (auto &pair : streams) {
			destroyDataReceiver(pair.second.reserved);
		}

		return this;
	}