cake
/
p7utils
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
p7utils/src/p7screen/main.c

168 lines
5.2 KiB
C

/* ************************************************************************** */
/* _____ _ */
/* p7screen/main.c |_ _|__ _ _| |__ ___ _ _ */
/* | Project: p7utils | |/ _ \| | | | '_ \ / _ \ | | | */
/* | | (_) | |_| | | | | __/ |_| | */
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
/* Last updated: 2017/01/16 23:55:55 |___/ */
/* */
/* ************************************************************************** */
#include "main.h"
#include <string.h>
#include <libp7.h>
#include <SDL.h>
/* ************************************************************************** */
/* Error messages */
/* ************************************************************************** */
/* Couldn't initialize connexion to calculator. */
static const char error_noconnexion[] =
"Could not connect to the calculator.\n"
"- Is it plugged in and in PROJ mode?\n"
"- Have you tried unplugging, plugging and selecting Projector on pop-up?\n"
"- Have you tried changing the cable?\n";
/* Calculator was found but program wasn't allowed to communicate with it. */
static const char error_noaccess[] =
"Could not get access to the calculator.\n"
"Install the appropriate udev rule, or run as root.\n";
/* The calculator acted in a weird way. */
static const char error_unplanned[] =
"The calculator didn't act as planned.\n"
"Stop receive mode on calculator and start it again before re-running " \
QUOTE(BIN) ".\n"
"Error was: %s\n";
/* ************************************************************************** */
/* Globals */
/* ************************************************************************** */
/* The z00m (omG) */
static int zoom;
/* ************************************************************************** */
/* Auxiliary functions */
/* ************************************************************************** */
/**
* display_callback:
* The main callback for screen streaming.
*
* @arg w the width of the received image
* @arg h the height of the received image
* @arg pixels the image data
* @return if reception should continue
*/
static int display_callback(int w, int h, uint32_t **pixels)
{
/* create screen if there isn't one */
static SDL_Surface *screen = NULL;
static int saved_w = 0, saved_h = 0;
if (!screen || saved_w != w || saved_h != h) {
/* create the window */
if (!(screen = SDL_SetVideoMode(w * zoom, h * zoom, 32,
SDL_SWSURFACE | SDL_DOUBLEBUF))) {
log("Couldn't set video mode: %s\n", SDL_GetError());
return (0);
}
SDL_WM_SetCaption("P7screen", NULL);
/* save data and display message */
saved_w = w; saved_h = h;
puts("Turn off your calculator (SHIFT+AC) when you have finished.");
}
/* edit screen */
/* - lock it - */
SDL_LockSurface(screen);
/* - copy - */
uint32_t *px = (uint32_t*)screen->pixels;
int linesize = w * zoom;
for (int y = 0; y < h; y++) {
uint32_t *refline = px;
for (int x = 0; x < w; x++) {
uint32_t pixel = pixels[y][x];
for (int zx = 0; zx < zoom; zx++)
*px++ = pixel;
}
for (int zy = 1; zy < zoom; zy++) {
memcpy(px, refline, linesize * sizeof(uint32_t));
px += linesize;
}
}
/* - unlock it - */
SDL_UnlockSurface(screen);
/* update screen */
SDL_Flip(screen);
/* check if user has pressed escape or cross */
SDL_Event event;
SDL_PollEvent(&event);
if ((event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)
|| event.type == SDL_QUIT)
return (0);
/* continue! */
return (1);
}
/* ************************************************************************** */
/* Main function */
/* ************************************************************************** */
/**
* main:
* Entry point of the program.
*
* @arg ac arguments count
* @arg av arguments values
* @return if it worked (0 if OK)
*/
int main(int ac, char **av)
{
/* parse args */
const char *com;
if (parse_args(ac, av, &com, &zoom))
return (0);
/* Initialize libp7 */
p7_handle_t *handle = NULL; int err;
if (com) err = p7_cominit(&handle, 0, com);
else err = p7_init(&handle, 0);
if (err) {
/* display error */
switch (err) {
case p7_error_nocalc: log(error_noconnexion); break;
case p7_error_noaccess: log(error_noaccess); break;
default: log(error_unplanned, p7_strerror(err)); break;
}
/* return */
return (1);
}
/* Initialize SDL */
if (SDL_Init(SDL_INIT_VIDEO)) {
log("Failed to initialize SDL: %s\n", SDL_GetError());
return (3);
}
atexit(SDL_Quit);
/* receive screen */
if ((err = p7_getscreen(handle, &display_callback))
&& err != p7_error_nocalc) {
switch (err) {
case p7_error_timeout: log(error_noconnexion); break;
default: log(error_unplanned, p7_strerror(err)); break;
}
return (1);
}
/* close */
p7_exit(handle);
/* everything went well */
return (0);
}