#include #include #include #include #include #include #include #include #include "color.h" int add_color(update_info *color, int key) { XFreeColors(color->display, color->colormap, &color->background.pixel, 1, 0); switch(key){ case X_Q_KEY: color->background.red += color->channel_step; break; case X_W_KEY: color->background.green += color->channel_step; printf("%i\n", color->background.green); break; case X_E_KEY: color->background.blue += color->channel_step; break; case X_A_KEY: color->background.red -= color->channel_step; break; case X_S_KEY: color->background.green -= color->channel_step; break; case X_D_KEY: color->background.blue -= color->channel_step; break; default: printf("what the actual fuck is wrong with your program you cunt\n"); break; } XAllocColor(color->display, color->colormap, &color->background); } int redraw_display(update_info *display_summary, XTextItem *text_prompt, GC *gc, unsigned int textpos_y) { XFreeColors(display_summary->display, display_summary->colormap, &display_summary->foreground.pixel, 1, 0); display_summary->foreground.red = 0xffff - display_summary->background.red; display_summary->foreground.green = 0xffff - display_summary->background.green; display_summary->foreground.blue = 0xffff - display_summary->background.blue; XAllocColor(display_summary->display, display_summary->colormap, &display_summary->foreground); XClearWindow(display_summary->display, display_summary->window); printf("%i\n", display_summary->background.pixel); XSetWindowBackground(display_summary->display, display_summary->window, display_summary->background.pixel); XSetForeground(display_summary->display, *gc, display_summary->foreground.pixel); XDrawText(display_summary->display, display_summary->window, *gc, TEXT_CORNER_OFFSET, textpos_y, text_prompt, 1); } int main(void) { char text_prompt_buffer[PROMPT_BUFSIZE] = "Q/W/E increases R/G/B. A/S/D decreases R/G/B. Enter allows exact value. Press Escape to dismiss."; Display *display; Window window; XEvent event; Colormap colormap; int screen; XColor background_color; XColor foreground_color; XTextItem text_prompt; XGCValues text_prompt_formatting; GC text_prompt_gc; int text_buffer_space; unsigned int color_step; int is_prompt = 0; unsigned int textpos_y; XFontStruct* font; XWindowAttributes win_info; if((display = XOpenDisplay(NULL)) == NULL) { printf("Couldn't open display due to fatal error: %s\n", strerror(errno)); exit(errno); } screen = DefaultScreen(display); //background colormap colormap = DefaultColormap(display, screen); background_color.red = 0; background_color.green = 0; background_color.blue = 0; //text colormap foreground_color.red = 0xffff - background_color.red; foreground_color.green = 0xffff - background_color.green; foreground_color.blue = 0xffff - background_color.blue; XAllocColor(display, colormap, &background_color); XAllocColor(display, colormap, &foreground_color); window = XCreateSimpleWindow(display, RootWindow(display, screen), 10, 10, 1920, 1080, 0, background_color.pixel, background_color.pixel); //last arg is color XMapWindow(display, window); XSelectInput(display, window, KeyPressMask | ExposureMask); XGetWindowAttributes(display, window, &win_info); //TODO: this math is techincly one off in very, very specific scenarios color_step = 0xffff / pow(2, (win_info.depth / 3)) + 0.5; //text struct text_prompt.chars = text_prompt_buffer; text_prompt.nchars = strlen(text_prompt_buffer); text_prompt.delta = 0; //what? text_prompt.font = None; //text formatting struct text_prompt_formatting.foreground = foreground_color.pixel; text_prompt_gc = XCreateGC(display, window, GCForeground | GCLineWidth, &text_prompt_formatting); font = XLoadQueryFont(display, "-*-helvetica-medium-r-normal-*-20-*"); XSetFont(display, text_prompt_gc, font->fid); XGetWindowAttributes(display, window, &win_info); textpos_y = win_info.height - TEXT_CORNER_OFFSET; update_info display_summary = { .window = window, .display = display, .colormap = colormap, .background = background_color, .foreground = foreground_color, .channel_step = color_step }; for(;;) { XNextEvent(display, &event); switch (event.type) { case KeyPress: if(is_prompt) { XClearWindow(display, window); text_buffer_space = PROMPT_BUFSIZE - text_prompt.nchars; switch(event.xkey.keycode) { case X_BACKSPACE: if(text_buffer_space < PROMPT_BUFSIZE) { text_prompt.nchars--; } break; case X_ESCAPE_KEY: text_prompt.nchars = 0; is_prompt = 0; break; case X_ENTER_KEY: text_prompt_buffer[text_prompt.nchars + 1] = '\0'; XFreeColors(display, colormap, background_color.pixel, 1, NULL); XParseColor(display, colormap, text_prompt_buffer, &background_color); background_color.red = 60000; XAllocColor(display, colormap, &background_color); is_prompt = 0; text_prompt.nchars = 0; redraw_display(&display_summary, &text_prompt, &text_prompt_gc, textpos_y); break; default: if(text_buffer_space > 0) { text_prompt.nchars += XLookupString(&event.xkey, text_prompt_buffer + text_prompt.nchars, text_buffer_space, NULL, NULL); } break; } XDrawText(display, window, text_prompt_gc, TEXT_CORNER_OFFSET, textpos_y, &text_prompt, 1); } else { switch(event.xkey.keycode) { case X_ENTER_KEY: is_prompt = 1; text_prompt.nchars = 4; strcpy(text_prompt_buffer, "rgb:"); break; case X_Q_KEY: //if anyone is reading this, on a scale from 1-10, case X_W_KEY: //just how ugly is this? case X_E_KEY: //I don't know why, but it feels gross. case X_A_KEY: //to be fair, most of this code is just for me. case X_S_KEY: //otherwise, it'd be way cleaner. case X_D_KEY: add_color(&display_summary, event.xkey.keycode); break; case X_ESCAPE_KEY: text_prompt.nchars = 0; default: break; } redraw_display(&display_summary, &text_prompt, &text_prompt_gc, textpos_y); } XDrawText(display, window, text_prompt_gc, TEXT_CORNER_OFFSET, textpos_y, &text_prompt, 1); break; case Expose: XGetWindowAttributes(display, window, &win_info); textpos_y = win_info.height - TEXT_CORNER_OFFSET; redraw_display(&display_summary, &text_prompt, &text_prompt_gc, textpos_y); break; default: break; } } return 0; }