/* ***************************************************************************** * p7screen/main.c -- p7screen main source. * Copyright (C) 2016-2017 Thomas "Cakeisalie5" Touhey * * This file is part of p7utils. * p7utils is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2.0 of the License, * or (at your option) any later version. * * p7utils is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with p7utils; if not, see . * ************************************************************************** */ #include "main.h" #include #include #include /* ************************************************************************** */ /* 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 */ if (parse_args(ac, av, &zoom)) return (0); /* Initialize libp7 */ p7_handle_t *handle = NULL; int err; 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); }