Compare commits
6 Commits
master
...
tutorial/p
Author | SHA1 | Date | |
---|---|---|---|
|
0acb1e30ca | ||
|
4a6d83d55c | ||
|
8436f2e22e | ||
|
f9aaa78768 | ||
|
428ecf2732 | ||
|
6bca037e01 |
@ -35,6 +35,7 @@ DIST_SUBDIRS = \
|
|||||||
src/guacenc \
|
src/guacenc \
|
||||||
src/guaclog \
|
src/guaclog \
|
||||||
src/pulse \
|
src/pulse \
|
||||||
|
src/protocols/ball \
|
||||||
src/protocols/kubernetes \
|
src/protocols/kubernetes \
|
||||||
src/protocols/rdp \
|
src/protocols/rdp \
|
||||||
src/protocols/ssh \
|
src/protocols/ssh \
|
||||||
@ -43,7 +44,8 @@ DIST_SUBDIRS = \
|
|||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
src/libguac \
|
src/libguac \
|
||||||
src/common
|
src/common \
|
||||||
|
src/protocols/ball
|
||||||
|
|
||||||
if ENABLE_COMMON_SSH
|
if ENABLE_COMMON_SSH
|
||||||
SUBDIRS += src/common-ssh
|
SUBDIRS += src/common-ssh
|
||||||
|
@ -1140,6 +1140,7 @@ AC_CONFIG_FILES([Makefile
|
|||||||
src/guaclog/Makefile
|
src/guaclog/Makefile
|
||||||
src/guaclog/man/guaclog.1
|
src/guaclog/man/guaclog.1
|
||||||
src/pulse/Makefile
|
src/pulse/Makefile
|
||||||
|
src/protocols/ball/Makefile
|
||||||
src/protocols/kubernetes/Makefile
|
src/protocols/kubernetes/Makefile
|
||||||
src/protocols/rdp/Makefile
|
src/protocols/rdp/Makefile
|
||||||
src/protocols/rdp/tests/Makefile
|
src/protocols/rdp/tests/Makefile
|
||||||
|
22
src/protocols/ball/Makefile.am
Normal file
22
src/protocols/ball/Makefile.am
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
AM_FLAGS = -Werror -Wall -pedantic
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libguac-client-ball.la
|
||||||
|
|
||||||
|
noinst_HEADERS = ball.h
|
||||||
|
|
||||||
|
libguac_client_ball_la_SOURCES = \
|
||||||
|
ball.c
|
||||||
|
|
||||||
|
libguac_client_ball_la_CFLAGS = \
|
||||||
|
-Werror -Wall -Iinclude \
|
||||||
|
@LIBGUAC_INCLUDE@
|
||||||
|
|
||||||
|
libguac_client_ball_la_LIBADD = \
|
||||||
|
@COMMON_LTLIB@ \
|
||||||
|
@LIBGUAC_LTLIB@
|
||||||
|
|
||||||
|
libguac_client_ball_la_LDFLAGS = \
|
||||||
|
-version-info 0:0:0
|
224
src/protocols/ball/ball.c
Normal file
224
src/protocols/ball/ball.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ball.h"
|
||||||
|
|
||||||
|
#include <guacamole/client.h>
|
||||||
|
#include <guacamole/layer.h>
|
||||||
|
#include <guacamole/protocol.h>
|
||||||
|
#include <guacamole/socket.h>
|
||||||
|
#include <guacamole/timestamp.h>
|
||||||
|
#include <guacamole/user.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
const char* TUTORIAL_ARGS[] = { NULL };
|
||||||
|
|
||||||
|
|
||||||
|
void* ball_render_thread(void* arg) {
|
||||||
|
|
||||||
|
/* Get data */
|
||||||
|
guac_client* client = (guac_client*) arg;
|
||||||
|
ball_client_data* data = (ball_client_data*) client->data;
|
||||||
|
|
||||||
|
/* Init time of last frame to current time */
|
||||||
|
guac_timestamp last_frame = guac_timestamp_current();
|
||||||
|
|
||||||
|
/* Update ball position as long as client is running */
|
||||||
|
while (client->state == GUAC_CLIENT_RUNNING) {
|
||||||
|
|
||||||
|
/* Default to 30ms frames */
|
||||||
|
int frame_duration = 30;
|
||||||
|
|
||||||
|
/* Lengthen frame duration if client is lagging */
|
||||||
|
int processing_lag = guac_client_get_processing_lag(client);
|
||||||
|
if (processing_lag > frame_duration)
|
||||||
|
frame_duration = processing_lag;
|
||||||
|
|
||||||
|
/* Sleep for duration of frame, then get timestamp */
|
||||||
|
usleep(frame_duration);
|
||||||
|
guac_timestamp current = guac_timestamp_current();
|
||||||
|
|
||||||
|
/* Calculate change in time */
|
||||||
|
int delta_t = current - last_frame;
|
||||||
|
|
||||||
|
/* Update position */
|
||||||
|
data->ball_x += data->ball_velocity_x * delta_t / 1000;
|
||||||
|
data->ball_y += data->ball_velocity_y * delta_t / 1000;
|
||||||
|
|
||||||
|
/* Bounce if necessary */
|
||||||
|
if (data->ball_x < 0) {
|
||||||
|
data->ball_x = -data->ball_x;
|
||||||
|
data->ball_velocity_x = -data->ball_velocity_x;
|
||||||
|
}
|
||||||
|
else if (data->ball_x >= 1024 - 128) {
|
||||||
|
data->ball_x = (2 * (1024 - 128)) - data->ball_x;
|
||||||
|
data->ball_velocity_x = -data->ball_velocity_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->ball_y < 0) {
|
||||||
|
data->ball_y = -data->ball_y;
|
||||||
|
data->ball_velocity_y = -data->ball_velocity_y;
|
||||||
|
}
|
||||||
|
else if (data->ball_y >= 768 - 128) {
|
||||||
|
data->ball_y = (2 * (768 - 128)) - data->ball_y;
|
||||||
|
data->ball_velocity_y = -data->ball_velocity_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
guac_protocol_send_move(client->socket, data->ball,
|
||||||
|
GUAC_DEFAULT_LAYER, data->ball_x, data->ball_y, 0);
|
||||||
|
|
||||||
|
/* End frame and flush socket */
|
||||||
|
guac_client_end_frame(client);
|
||||||
|
guac_socket_flush(client->socket);
|
||||||
|
|
||||||
|
/* Update timestamp */
|
||||||
|
last_frame = current;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ball_join_handler(guac_user* user, int argc, char** argv) {
|
||||||
|
|
||||||
|
/* Get client associated with user */
|
||||||
|
guac_client* client = user->client;
|
||||||
|
|
||||||
|
/* Get ball layer from client data */
|
||||||
|
ball_client_data* data = (ball_client_data*) client->data;
|
||||||
|
guac_layer* ball = data->ball;
|
||||||
|
|
||||||
|
/* Get user-specific socket */
|
||||||
|
guac_socket* socket = user->socket;
|
||||||
|
|
||||||
|
/* Send the display size */
|
||||||
|
guac_protocol_send_size(socket, GUAC_DEFAULT_LAYER, 1024, 768);
|
||||||
|
|
||||||
|
/* Create background tile */
|
||||||
|
guac_layer* texture = guac_client_alloc_buffer(client);
|
||||||
|
|
||||||
|
guac_protocol_send_rect(socket, texture, 0, 0, 64, 64);
|
||||||
|
guac_protocol_send_cfill(socket, GUAC_COMP_OVER, texture,
|
||||||
|
0x88, 0x88, 0x88, 0xFF);
|
||||||
|
|
||||||
|
guac_protocol_send_rect(socket, texture, 0, 0, 32, 32);
|
||||||
|
guac_protocol_send_cfill(socket, GUAC_COMP_OVER, texture,
|
||||||
|
0xDD, 0xDD, 0xDD, 0xFF);
|
||||||
|
|
||||||
|
guac_protocol_send_rect(socket, texture, 32, 32, 32, 32);
|
||||||
|
guac_protocol_send_cfill(socket, GUAC_COMP_OVER, texture,
|
||||||
|
0xDD, 0xDD, 0xDD, 0xFF);
|
||||||
|
|
||||||
|
/* Prepare a curve which covers the entire layer */
|
||||||
|
guac_protocol_send_rect(socket, GUAC_DEFAULT_LAYER,
|
||||||
|
0, 0, 1024, 768);
|
||||||
|
|
||||||
|
/* Fill curve with texture */
|
||||||
|
guac_protocol_send_lfill(socket,
|
||||||
|
GUAC_COMP_OVER, GUAC_DEFAULT_LAYER,
|
||||||
|
texture);
|
||||||
|
|
||||||
|
/* Set up ball layer */
|
||||||
|
guac_protocol_send_size(socket, ball, 128, 128);
|
||||||
|
|
||||||
|
/* Prepare a circular curve */
|
||||||
|
guac_protocol_send_arc(socket, data->ball,
|
||||||
|
64, 64, 62, 0, 6.28, 0);
|
||||||
|
|
||||||
|
guac_protocol_send_close(socket, data->ball);
|
||||||
|
|
||||||
|
/* Draw a 4-pixel black border */
|
||||||
|
guac_protocol_send_cstroke(socket,
|
||||||
|
GUAC_COMP_OVER, data->ball,
|
||||||
|
GUAC_LINE_CAP_ROUND, GUAC_LINE_JOIN_ROUND, 4,
|
||||||
|
0x00, 0x00, 0x00, 0xFF);
|
||||||
|
|
||||||
|
/* Fill the circle with color */
|
||||||
|
guac_protocol_send_cfill(socket,
|
||||||
|
GUAC_COMP_OVER, data->ball,
|
||||||
|
0x00, 0x80, 0x80, 0x80);
|
||||||
|
|
||||||
|
/* Free texture (no longer needed) */
|
||||||
|
guac_client_free_buffer(client, texture);
|
||||||
|
|
||||||
|
/* Mark end-of-frame */
|
||||||
|
guac_protocol_send_sync(socket, client->last_sent_timestamp);
|
||||||
|
|
||||||
|
/* Flush buffer */
|
||||||
|
guac_socket_flush(socket);
|
||||||
|
|
||||||
|
/* User successfully initialized */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ball_free_handler(guac_client* client) {
|
||||||
|
|
||||||
|
ball_client_data* data = (ball_client_data*) client->data;
|
||||||
|
|
||||||
|
/* Wait for render thread to terminate */
|
||||||
|
pthread_join(data->render_thread, NULL);
|
||||||
|
|
||||||
|
/* Free client-level ball layer */
|
||||||
|
guac_client_free_layer(client, data->ball);
|
||||||
|
|
||||||
|
/* Free client-specific data */
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
/* Data successfully freed */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int guac_client_init(guac_client* client) {
|
||||||
|
|
||||||
|
/* Allocate storage for client-specific data */
|
||||||
|
ball_client_data* data = malloc(sizeof(ball_client_data));
|
||||||
|
|
||||||
|
/* Set up client data and handlers */
|
||||||
|
client->data = data;
|
||||||
|
|
||||||
|
/* Allocate layer at the client level */
|
||||||
|
data->ball = guac_client_alloc_layer(client);
|
||||||
|
|
||||||
|
/* This example does not implement any arguments */
|
||||||
|
client->args = TUTORIAL_ARGS;
|
||||||
|
|
||||||
|
/* Client-level handlers */
|
||||||
|
client->join_handler = ball_join_handler;
|
||||||
|
client->free_handler = ball_free_handler;
|
||||||
|
|
||||||
|
/* Start ball at upper left */
|
||||||
|
data->ball_x = 0;
|
||||||
|
data->ball_y = 0;
|
||||||
|
|
||||||
|
/* Move at a reasonable pace to the lower right */
|
||||||
|
data->ball_velocity_x = 200; /* pixels per second */
|
||||||
|
data->ball_velocity_y = 200; /* pixels per second */
|
||||||
|
|
||||||
|
/* Start render thread */
|
||||||
|
pthread_create(&data->render_thread, NULL, ball_render_thread, client);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
42
src/protocols/ball/ball.h
Normal file
42
src/protocols/ball/ball.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BALL_H
|
||||||
|
#define BALL_H
|
||||||
|
|
||||||
|
#include <guacamole/layer.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
typedef struct ball_client_data {
|
||||||
|
|
||||||
|
guac_layer* ball;
|
||||||
|
|
||||||
|
int ball_x;
|
||||||
|
int ball_y;
|
||||||
|
|
||||||
|
int ball_velocity_x;
|
||||||
|
int ball_velocity_y;
|
||||||
|
|
||||||
|
pthread_t render_thread;
|
||||||
|
|
||||||
|
|
||||||
|
} ball_client_data;
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user