mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2024-12-29 13:03:37 +01:00
167 lines
4.2 KiB
C
167 lines
4.2 KiB
C
//---------------------------------------------------------------------------//
|
|
// ==>/[_]\ fxlink: A community communication tool for CASIO calculators. //
|
|
// |:::| Made by Lephe' as part of the fxSDK. //
|
|
// \___/ License: MIT <https://opensource.org/licenses/MIT> //
|
|
//---------------------------------------------------------------------------//
|
|
|
|
#include "../fxlink.h"
|
|
#include <fxlink/filter.h>
|
|
#include <fxlink/logging.h>
|
|
#include <fxlink/protocol.h>
|
|
#include <fxlink/devices.h>
|
|
#include <fxlink/tooling/libpng.h>
|
|
#include <fxlink/tooling/sdl2.h>
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
static void handle_new_message(struct fxlink_device *fdev,
|
|
struct fxlink_message *msg)
|
|
{
|
|
char const *path = ".";
|
|
|
|
if(fxlink_message_is_fxlink_image(msg)) {
|
|
struct fxlink_message_image_header *img = msg->data;
|
|
char *filename = fxlink_gen_file_name(path, msg->type, ".png");
|
|
|
|
struct fxlink_message_image_raw *raw =
|
|
fxlink_message_image_decode(msg);
|
|
if(raw) {
|
|
fxlink_libpng_save_raw(raw, filename);
|
|
fxlink_message_image_raw_free(raw);
|
|
hlog("calculators %s", fxlink_device_id(fdev));
|
|
log_("saved image (%dx%d, format=%d) to '%s'\n",
|
|
img->width, img->height, img->pixel_format, filename);
|
|
}
|
|
free(filename);
|
|
return;
|
|
}
|
|
|
|
if(fxlink_message_is_fxlink_text(msg)) {
|
|
char const *str = msg->data;
|
|
|
|
if(options.verbose)
|
|
printf("------------------\n");
|
|
fwrite(str, 1, msg->size, stdout);
|
|
if(str[msg->size - 1] != '\n') {
|
|
if(!options.verbose)
|
|
printf("\e[30;47m%%\e[0m");
|
|
printf("\n");
|
|
}
|
|
if(options.verbose) {
|
|
printf("------------------\n");
|
|
}
|
|
if(options.verbose) {
|
|
for(size_t i = 0; i < msg->size; i++) {
|
|
printf(" %02x", str[i]);
|
|
if((i & 15) == 15 || i == msg->size - 1)
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
if(options.log_file)
|
|
fwrite(str, 1, msg->size, options.log_file);
|
|
return;
|
|
}
|
|
|
|
if(fxlink_message_is_fxlink_video(msg)) {
|
|
struct fxlink_message_image_raw *raw =
|
|
fxlink_message_image_decode(msg);
|
|
if(raw) {
|
|
fxlink_sdl2_display_raw(raw);
|
|
fxlink_message_image_raw_free(raw);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* Default to saving to a blob */
|
|
static char combined_type[48];
|
|
sprintf(combined_type, "%.16s-%.16s", msg->application, msg->type);
|
|
|
|
char *filename = fxlink_gen_file_name(path, combined_type, ".bin");
|
|
FILE *fp = fopen(filename, "wb");
|
|
if(!fp) {
|
|
elog("could not save to '%s': %m\n", filename);
|
|
return;
|
|
}
|
|
|
|
fwrite(msg->data, 1, msg->size, fp);
|
|
fclose(fp);
|
|
|
|
log_("saved blob to '%s'\n", filename);
|
|
free(filename);
|
|
}
|
|
|
|
int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
|
libusb_context *ctx)
|
|
{
|
|
/* Wait for a device to be connected */
|
|
fxlink_filter_clean_libusb(filter);
|
|
filter->intf_fxlink = true;
|
|
|
|
struct fxlink_device *fdev = fxlink_device_find_wait(ctx, filter, delay);
|
|
if(!fdev) {
|
|
printf("No device found.\n");
|
|
return 1;
|
|
}
|
|
if(!fxlink_device_claim_fxlink(fdev)) {
|
|
fxlink_device_cleanup(fdev);
|
|
free(fdev);
|
|
return 1;
|
|
}
|
|
|
|
hlog("interactive");
|
|
log_("connected to %s\n", fxlink_device_id(fdev));
|
|
|
|
/* Buffer used to receive messages */
|
|
static uint8_t buffer[2048];
|
|
/* Current message */
|
|
struct fxlink_transfer *tr = NULL;
|
|
|
|
while(1) {
|
|
fxlink_sdl2_handle_events();
|
|
|
|
int transferred = -1;
|
|
int rc = libusb_bulk_transfer(fdev->dh, fdev->comm->ep_bulk_IN, buffer,
|
|
sizeof buffer, &transferred, 500 /* ms */);
|
|
|
|
if(rc == LIBUSB_ERROR_NO_DEVICE) {
|
|
hlog("interactive");
|
|
log_("disconnected, leaving\n");
|
|
break;
|
|
}
|
|
else if(rc && rc != LIBUSB_ERROR_TIMEOUT) {
|
|
elog_libusb(rc, "bulk transfer failed on %s",
|
|
fxlink_device_id(fdev));
|
|
continue;
|
|
}
|
|
if(transferred <= 0)
|
|
continue;
|
|
|
|
/* Either start a new message or continue an unfinished one */
|
|
if(tr == NULL)
|
|
tr = fxlink_transfer_make_IN(buffer, transferred);
|
|
else
|
|
fxlink_transfer_receive(tr, buffer, transferred);
|
|
|
|
if(tr && fxlink_transfer_complete(tr)) {
|
|
struct fxlink_message *msg = fxlink_transfer_finish_IN(tr);
|
|
if(msg) {
|
|
handle_new_message(fdev, msg);
|
|
fxlink_message_free(msg, true);
|
|
}
|
|
tr = NULL;
|
|
}
|
|
}
|
|
|
|
/* Warning for unfinished transfer */
|
|
if(tr) {
|
|
wlog("unfinished transfer interrupted by disconnection\n");
|
|
fxlink_transfer_free(tr);
|
|
}
|
|
|
|
fxlink_device_cleanup(fdev);
|
|
free(fdev);
|
|
return 0;
|
|
}
|