242 lines
8.2 KiB
C
242 lines
8.2 KiB
C
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <math.h>
|
|
#include <signal.h>
|
|
|
|
#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;
|
|
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);
|
|
printf("Pixel:\t%x\nR:\t%x\nG:\t%x\nB:\t%x\n", color->background->pixel, color->background->red, color->background->green, color->background->blue);
|
|
}
|
|
|
|
void 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);
|
|
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, A/S/D for RGB channels. [Enter] begins rgb prompt, [Space] for 24 bit integers, [Enter] for hex. Seperate channels with \"/\"";
|
|
|
|
char rgb_split_seperations[3][3];
|
|
|
|
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);
|
|
|
|
XFreeColors(display, colormap, &background_color.pixel, 1, 0);
|
|
XParseColor(display, colormap, "rgb:0/0/ff", &background_color);
|
|
XAllocColor(display, colormap, &background_color);
|
|
|
|
XFreeColors(display, colormap, &background_color.pixel, 1, 0);
|
|
XAllocColor(display, colormap, &background_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;
|
|
printf("%i\n", event.xkey.keycode);
|
|
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, 0);
|
|
XParseColor(display, colormap, text_prompt_buffer, &background_color);
|
|
XAllocColor(display, colormap, &background_color);
|
|
is_prompt = 0;
|
|
text_prompt.nchars = 0;
|
|
redraw_display(&display_summary, &text_prompt, &text_prompt_gc, textpos_y);
|
|
break;
|
|
case X_SHIFT_KEY:
|
|
XFreeColors(display, colormap, &background_color.pixel, 1, 0);
|
|
str
|
|
background_color.red =
|
|
background_color.green =
|
|
background_color.blue =
|
|
|
|
printf("Pixel:\t%x\nR:\t%x\nG:\t%x\nB:\t%x\n", background_color.pixel, background_color.red, background_color.green, background_color.blue);
|
|
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_ESCAPE_KEY:
|
|
text_prompt.nchars = 0;
|
|
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;
|
|
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;
|
|
}
|