Skip to content

Instantly share code, notes, and snippets.

@wormyrocks
Created August 17, 2020 17:50
Show Gist options
  • Save wormyrocks/c6a53b90bf5f43b41509990cca13b0ff to your computer and use it in GitHub Desktop.
Save wormyrocks/c6a53b90bf5f43b41509990cca13b0ff to your computer and use it in GitHub Desktop.
// ShowQuilt example code
// Shiyun (Vanilla) Liu and Evan Kahn, 8/17/2020
//
// Easiest way to build this on any platform is to add this source file to
// HoloPlayCore/examples, and uncomment lines 26-29 in HoloPlayCore/examples/CMakeLists.txt.
//
// Oh and you need a file called quilt.jpg in the same directory from which you run
// the executable. You can download a sample one from: http://eka.hn/quilts/evan.jpg
// (remember to rename it).
//
// If you're integrating this sort of code into your own project, you don't actually
// have to create a file. You can just skip the fread call and pass a pointer to JPG-
// or PNG-encoded data in memory.
// You can find a browser-based playground/debugger for these commands that's much more
// fluent than this code at http://eka.hn/driver-client.html - although it uses the
// WebSocket tunnel to HoloPlay Service rather than the IPC tunnel, because of
// browser permissions.
// Sorry this sample code is so obtuse, the native HoloPlayCore library
// isn't designed to send static quilts as a first priority, and some of the
// decisions around the string and serializer functions are intended to make it
// easier to bind from higher-level languages, but definitely makes things ugly in C.
// Feel free to email me at evan@lookingglassfactory.com if you have questions.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <HoloPlayCore.h>
int ShowQuiltFile(char* filepath, int windowNum)
{
printf("We're trying to open a file at %s.\n", filepath);
char cmd[500];
// open quilt file data
// all of this is far from safe code; be forewarned
char *bin;
size_t binlen = 0;
FILE *f = fopen(filepath, "rb");
if (f != NULL)
{
fseek(f, 0, SEEK_END);
binlen = ftell(f);
fseek(f, 0, SEEK_SET);
bin = (unsigned char *)malloc(binlen);
fread(bin, sizeof(unsigned char), binlen, f);
fseek(f, 0, SEEK_SET);
fclose(f);
printf("file opened!\n");
}else{
printf("no file found at %s. abort\n", filepath);
}
if (binlen == 0)
return 1;
// we're going to construct a "show" message with binary data and file data
// with a quilt image.
// this is really ugly in C, but of course you can use a string type and/or
// JSON serializer, in a different language, to do this all in one line.
printf("we loaded a quilt file, now we're going to package it in the object\
binary field and send it to holoplay service with an associated command.\n");
int end = sprintf(cmd, "{\"show\":{");
end += sprintf(cmd + end, "\"targetDisplay\":%d,", windowNum);
end += sprintf(cmd + end, "\"source\":\"bindata\",\"quilt\":{\"type\":\"image\",\"settings\":{\"vx\":%d,\"vy\":%d", 5, 9);
end += sprintf(cmd + end, ",\"vtotal\":%d", 45);
strcat(cmd, "}}}}");
printf("Here's that command as JSON: %s\n", cmd);
// hpc_SendBlocking will allocate a buffer for the response data
hpc_obj msg_to_send = hpc_MakeObject(cmd, binlen, bin);
hpc_obj *quilt_msg_response = NULL;
hpc_client_error errco = hpc_SendBlocking(msg_to_send, &quilt_msg_response);
int ret = (int)errco;
if (!ret) printf("OK, that worked! Message sent and response received.\n");
else printf("Uh oh, something went wrong sending the message (error code: %d)\n", (int)errco);
char *stringbuf[1000];
size_t len = hpc_ObjAsJson(quilt_msg_response, &stringbuf, 1000);
printf("And here's the response as JSON: %s\n", stringbuf);
printf("Sending the quilt file was %s.\n", (hpc_ObjGetErrorCode(quilt_msg_response) == hpc_ERR_NOERROR ? "successful" : "unsuccessful"));
// clean up objects allocated by HoloPlayCore dll
free(bin);
hpc_DeleteObject(msg_to_send);
hpc_DeleteObject(quilt_msg_response);
return ret;
}
int main(int argc, char **argv)
{
hpc_client_error errco;
if (!(errco = hpc_InitializeApp("quiltdemo", hpc_LICENSE_NONCOMMERCIAL)))
{
printf("Getting initial state message...\n");
char buf[1500];
// we're going to get the current state of the holoplay runtime as a json string
// (this is a wrapper function for the hpc_Send* functions in the code above)
size_t d = hpc_GetStateAsJSON(buf, 1500);
// if we haven't allocated enough space for the string, try again
if (d)
{
char *buf2 = (char *)malloc(d);
size_t c = hpc_GetStateAsJSON(buf2, d);
printf("Initial state message (buffer resized): %s\n", buf2);
free(buf2);
}
else
{
printf("Initial state message: %s\n", buf);
}
// we're never gonna need 1500 characters, this is max like 10, but we're
// reusing the buffer so whatever
hpc_GetHoloPlayServiceVersion(buf, 1500);
printf("HoloPlayService version %s\n", buf);
int num_devices = hpc_GetNumDevices();
printf("%d devices connected.\n", num_devices);
if (num_devices > 0) {
ShowQuiltFile("quilt.jpg", 0);
} else {
printf("HoloPlay Service works fine, but no Looking Glass connected. Done.\n");
}
}
else
{
printf("Error connecting to HoloPlay Service (code %d).\n", errco);
}
hpc_CloseApp();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment