2016-12-21 22:56:20 +01:00
|
|
|
/* ************************************************************************** */
|
|
|
|
/* _____ _ */
|
2016-12-22 01:22:29 +01:00
|
|
|
/* p7screen/main.c |_ _|__ _ _| |__ ___ _ _ */
|
|
|
|
/* | Project: p7utils | |/ _ \| | | | '_ \ / _ \ | | | */
|
2016-12-21 22:56:20 +01:00
|
|
|
/* | | (_) | |_| | | | | __/ |_| | */
|
|
|
|
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
2017-01-17 00:46:42 +01:00
|
|
|
/* Last updated: 2017/01/16 23:55:55 |___/ */
|
2016-12-21 22:56:20 +01:00
|
|
|
/* */
|
|
|
|
/* ************************************************************************** */
|
|
|
|
#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"
|
2017-01-11 15:46:18 +01:00
|
|
|
"Stop receive mode on calculator and start it again before re-running " \
|
|
|
|
QUOTE(BIN) ".\n"
|
2016-12-21 22:56:20 +01:00
|
|
|
"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 */
|
2017-02-08 14:04:11 +01:00
|
|
|
const char *com;
|
2017-01-11 22:58:24 +01:00
|
|
|
if (parse_args(ac, av, &com, &zoom))
|
2016-12-21 22:56:20 +01:00
|
|
|
return (0);
|
|
|
|
|
|
|
|
/* Initialize libp7 */
|
2017-01-19 15:25:19 +01:00
|
|
|
p7_handle_t *handle = NULL; int err;
|
2017-01-26 14:36:52 +01:00
|
|
|
if (com) err = p7_cominit(&handle, 0, com);
|
|
|
|
else err = p7_init(&handle, 0);
|
2016-12-21 22:56:20 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-12-27 13:40:57 +01:00
|
|
|
/* Initialize SDL */
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO)) {
|
|
|
|
log("Failed to initialize SDL: %s\n", SDL_GetError());
|
|
|
|
return (3);
|
|
|
|
}
|
|
|
|
atexit(SDL_Quit);
|
|
|
|
|
2016-12-21 22:56:20 +01:00
|
|
|
/* 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 */
|
2017-01-27 00:10:39 +01:00
|
|
|
p7_exit(handle);
|
2016-12-21 22:56:20 +01:00
|
|
|
|
|
|
|
/* everything went well */
|
|
|
|
return (0);
|
|
|
|
}
|