/* textures.c ... */ /* * This example creates an SDL window and renderer, and then draws some * textures to it every frame. * * This code is public domain. Feel free to use it for any purpose! */ #define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ #include #include #include #include #include #include #include #include #include "neko.h" #include "common.h" /* We will use this renderer to draw into this window every frame. */ static SDL_Window *window = NULL; static SDL_Renderer *renderer = NULL; static IMG_Animation *anim; static SDL_Texture **anim_textures; static int current_frame = 1; int WINDOW_WIDTH; int WINDOW_HEIGHT; void set_override_redirect() { Display *dpy = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL); Window xwin = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); XSetWindowAttributes attrs; attrs.override_redirect = True; XChangeWindowAttributes(dpy, xwin, CWOverrideRedirect, &attrs); XFlush(dpy); } void make_window_clickthrough() { Display *dpy = (Display *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL); Window xwin = (Window)SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0); // Make input shape empty → ignores mouse events XRectangle rect; XserverRegion region = XFixesCreateRegion(dpy, &rect, 0); XFixesSetWindowShapeRegion(dpy, xwin, ShapeInput, 0, 0, region); XFixesDestroyRegion(dpy, region); XFlush(dpy); } Uint32 increment_frame(void *userdata, SDL_TimerID timerID, Uint32 interval){ current_frame = (current_frame+1) % anim->count; return(interval); } /* This function runs once at startup. */ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) { char *gif_path = NULL; SDL_SetAppMetadata("systemd", "1.0", "org.kernel.systemd"); if (!SDL_Init(SDL_INIT_VIDEO)) { SDL_Log("Couldn't initialize SDL: %s", SDL_GetError()); return SDL_APP_FAILURE; } // Init window size to fullscreen int num_displays; SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); SDL_Log("Found %d display(s)", num_displays); const SDL_DisplayMode* DisplayMode = SDL_GetCurrentDisplayMode(displays[0]); SDL_free(displays); if(DisplayMode==NULL){ printf("Error could not get display mode"); return 1; } WINDOW_WIDTH = DisplayMode->w; WINDOW_HEIGHT = DisplayMode->h; if (!SDL_CreateWindowAndRenderer("systemd", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_TRANSPARENT | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_BORDERLESS , &window, &renderer)) { SDL_Log("Couldn't create window/renderer: %s", SDL_GetError()); return SDL_APP_FAILURE; } make_window_clickthrough(); set_override_redirect(); neko_init(renderer, window); /* Open the image file */ SDL_asprintf(&gif_path, "%ssample.gif", SDL_GetBasePath()); anim = IMG_LoadAnimation(gif_path); if (!anim) { SDL_Log("Couldn't load %s: %s\n", gif_path, SDL_GetError()); return SDL_APP_FAILURE; } SDL_free(gif_path); /* done with this, the file is loaded. */ int aw = anim->w; int ah = anim->h; anim_textures = (SDL_Texture **)SDL_calloc(anim->count, sizeof(*anim_textures)); if (!anim_textures) { SDL_Log("Couldn't allocate textures\n"); IMG_FreeAnimation(anim); return SDL_APP_FAILURE; } for (int i = 0; i < anim->count; ++i) { anim_textures[i] = SDL_CreateTextureFromSurface(renderer, anim->frames[i]); } SDL_AddTimer(anim->delays[0], increment_frame, NULL); return SDL_APP_CONTINUE; /* carry on with the program! */ } /* This function runs when a new event (mouse input, keypresses, etc) occurs. */ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { if (event->type == SDL_EVENT_QUIT) { return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ } return SDL_APP_CONTINUE; /* carry on with the program! */ } /* This function runs once per frame, and is the heart of the program. */ SDL_AppResult SDL_AppIterate(void *appstate) { SDL_FRect dst_rect; const Uint64 now = SDL_GetTicks(); /* as you can see from this, rendering draws over whatever was drawn before it. */ SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_TRANSPARENT); /* black, full alpha */ SDL_RenderClear(renderer); /* start with a blank canvas. */ neko_render(renderer, window); /* dst_rect.x = WINDOW_HEIGHT/2; dst_rect.y = WINDOW_HEIGHT/2; dst_rect.h = WINDOW_HEIGHT/10; dst_rect.w = WINDOW_HEIGHT/10; SDL_RenderTexture(renderer, anim_textures[current_frame], NULL, &dst_rect); */ SDL_RenderPresent(renderer); /* put it all on the screen! */ return SDL_APP_CONTINUE; /* carry on with the program! */ } /* This function runs once at shutdown. */ void SDL_AppQuit(void *appstate, SDL_AppResult result) { neko_quit(); /* SDL will clean up the window/renderer for us. */ } /* BACKUP SDL_AppIterate const float direction = ((now % 2000) >= 1000) ? 1.0f : -1.0f; const float scale = ((float) (((int) (now % 1000)) - 500) / 500.0f) * direction; dst_rect.x = (100.0f * scale); dst_rect.y = 0.0f; dst_rect.w = (float) texture_width; dst_rect.h = (float) texture_height; SDL_RenderTexture(renderer, texture, NULL, &dst_rect); dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) / 2.0f; dst_rect.y = ((float) (WINDOW_HEIGHT - texture_height)) / 2.0f; dst_rect.w = (float) texture_width/2; dst_rect.h = (float) texture_height/2; SDL_RenderTexture(renderer, texture, NULL, &dst_rect); dst_rect.x = ((float) (WINDOW_WIDTH - texture_width)) - (100.0f * scale); dst_rect.y = (float) (WINDOW_HEIGHT - texture_height); dst_rect.w = (float) texture_width; dst_rect.h = (float) texture_height; */