/* ************************************************************************** */ /* _____ _ */ /* p7screen/main.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: p7utils | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ /* Last updated: 2017/01/16 23:55:55 |___/ */ /* */ /* ************************************************************************** */ #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 */ int 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); }