1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-18 13:54:36 -05:00

WIP: Port window stuff to xcb

Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
This commit is contained in:
Quentin Glidic 2016-02-21 19:42:32 +01:00
parent 6bb1d4b1a2
commit 2ef950eab9
12 changed files with 192 additions and 167 deletions

View file

@ -87,7 +87,7 @@ GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11])
PKG_CHECK_MODULES([x11], [x11 x11-xcb])
PKG_CHECK_MODULES([xinerama], [xinerama])
PKG_CHECK_MODULES([pango], [pango pangocairo])
PKG_CHECK_MODULES([cairo], [cairo cairo-xlib])
PKG_CHECK_MODULES([cairo], [cairo cairo-xcb])
PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0])

View file

@ -28,7 +28,7 @@ void i3_support_focus_window ( Window id );
* @returns TRUE when i3 is running, FALSE when not.
*/
int i3_support_initialize ( Display *display );
int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection );
/**
* Cleanup.

View file

@ -142,7 +142,7 @@ void textbox_insert ( textbox *tb, int pos, char *str, int slen );
* before any of the textbox_ functions is called.
* Clean with textbox_cleanup()
*/
void textbox_setup ( Display *display );
void textbox_setup ( void );
/**
* Cleanup the allocated colors and fonts by textbox_setup().

View file

@ -90,7 +90,7 @@ void rofi_view_update ( RofiViewState *state );
*
* Enables fake transparancy on this view.
*/
void rofi_view_setup_fake_transparency ( Display *display, RofiViewState *state );
void rofi_view_setup_fake_transparency ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, RofiViewState *state );
/**
* @param state The handle to the view

View file

@ -1,6 +1,7 @@
#ifndef X11_ROFI_HELPER_H
#define X11_ROFI_HELPER_H
#include <cairo.h>
#include <xcb/xcb.h>
#include "xkb.h"
@ -27,7 +28,7 @@ int window_get_prop ( Display *display, Window w, Atom prop,
char* window_get_text_prop ( Display *display, Window w, Atom atom );
int window_get_atom_prop ( Display *display, Window w, Atom atom, Atom *list, int count );
void window_set_atom_prop ( Display *display, Window w, Atom prop, Atom *atoms, int count );
void window_set_atom_prop ( Display *display, Window w, Atom atom, Atom *atoms, int count );
int window_get_cardinal_prop ( Display *display, Window w, Atom atom, unsigned long *list,
int count );
@ -134,13 +135,16 @@ void x11_set_window_opacity ( Display *display, Window box, unsigned int opacity
*/
void x11_setup ( Display *display, xkb_stuff *xkb );
extern xcb_depth_t *depth;
extern xcb_visualtype_t *visual;
extern xcb_colormap_t map;
extern xcb_depth_t *root_depth;
extern xcb_visualtype_t *root_visual;
/**
* @param display Connection to the X server.
*
* This function tries to create a 32bit TrueColor colormap.
* If this fails, it falls back to the default for the connected display.
*/
void create_visual_and_colormap ( Display *display );
void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen );
typedef struct
{
@ -153,11 +157,11 @@ typedef struct
*
* Allocate a pixel value for an X named color
*/
Color color_get ( Display *display, const char *const name, const char * const defn );
Color color_get ( const char *const name );
void color_background ( Display *display, cairo_t *d );
void color_border ( Display *display, cairo_t *d );
void color_separator ( Display *display, cairo_t *d );
void color_background ( cairo_t *d );
void color_border ( cairo_t *d );
void color_separator ( cairo_t *d );
void color_cache_reset ( void );
void x11_helper_set_cairo_rgba ( cairo_t *d, Color col );

View file

@ -74,6 +74,7 @@ typedef struct
long hint_flags;
} client;
// TODO
extern xcb_connection_t *xcb_connection;
extern Display *display;
// window lists
typedef struct
@ -387,7 +388,7 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd )
x11_cache_create ();
// Check for i3
pd->config_i3_mode = i3_support_initialize ( display );
pd->config_i3_mode = i3_support_initialize ( display, xcb_connection );
// Get the active window so we can highlight this.
if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) )

View file

@ -113,20 +113,21 @@ void i3_support_focus_window ( Window id )
close ( s );
}
int i3_support_initialize ( Display *display )
int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection )
{
// If we where initialized, clean this first.
i3_support_free_internals ();
// Get atom for I3_SOCKET_PATH
Atom i3_sp_atom = XInternAtom ( display, "I3_SOCKET_PATH", False );
if ( i3_sp_atom != None ) {
// Get atom for I3_SOCKET_PATH
xcb_intern_atom_cookie_t cookie = xcb_intern_atom ( xcb_connection, FALSE, strlen ( "I3_SOCKET_PATH" ), "I3_SOCKET_PATH" );
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply ( xcb_connection, cookie, NULL );
if ( reply != NULL ) {
// Get the default screen.
Screen *screen = DefaultScreenOfDisplay ( display );
// Find the root window (each X has one.).
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
// Get the i3 path property.
i3_socket_path = window_get_text_prop ( display, root, i3_sp_atom );
i3_socket_path = window_get_text_prop ( display, root, reply->atom );
}
// If we find it, go into i3 mode.
return ( i3_socket_path != NULL ) ? TRUE : FALSE;

View file

@ -139,8 +139,8 @@ static int setup ()
int pfd = create_pid_file ( pidfile );
if ( pfd >= 0 ) {
// Request truecolor visual.
create_visual_and_colormap ( display );
textbox_setup ( display );
x11_create_visual_and_colormap ( xcb_connection, xcb_screen );
textbox_setup ();
}
return pfd;
}

View file

@ -98,7 +98,7 @@ void scrollbar_draw ( scrollbar *sb, cairo_t *draw )
// Cap length;
height = MIN ( bh - y + 1, ( height ) );
// Redraw base window
color_separator ( display, draw );
color_separator ( draw );
cairo_rectangle ( draw, sb->widget.x + config.line_margin, sb->widget.y + y, sb->widget.w - config.line_margin, height );
cairo_fill ( draw );

View file

@ -621,11 +621,7 @@ int textbox_keypress ( textbox *tb, char *pad, int pad_len, unsigned int modstat
/***
* Font setup.
*/
static void parse_color ( Display *display, char *bg, Color *col )
{
*col = color_get ( display, bg, "white" );
}
static void textbox_parse_string ( Display *display, const char *str, RowColor *color )
static void textbox_parse_string ( const char *str, RowColor *color )
{
if ( str == NULL ) {
return;
@ -638,50 +634,50 @@ static void textbox_parse_string ( Display *display, const char *str, RowColor
switch ( index )
{
case 0:
parse_color ( display, g_strstrip ( token ), &( color->bg ) );
color->bg = color_get ( g_strstrip ( token ) );
break;
case 1:
parse_color ( display, g_strstrip ( token ), &( color->fg ) );
color->fg = color_get ( g_strstrip ( token ) );
break;
case 2:
parse_color ( display, g_strstrip ( token ), &( color->bgalt ) );
color->bgalt = color_get ( g_strstrip ( token ) );
break;
case 3:
parse_color ( display, g_strstrip ( token ), &( color->hlbg ) );
color->hlbg = color_get ( g_strstrip ( token ) );
break;
case 4:
parse_color ( display, g_strstrip ( token ), &( color->hlfg ) );
color->hlfg = color_get ( g_strstrip ( token ) );
break;
}
index++;
}
g_free ( cstr );
}
void textbox_setup ( Display *display )
void textbox_setup ( void )
{
if ( config.color_enabled ) {
textbox_parse_string ( display, config.color_normal, &( colors[NORMAL] ) );
textbox_parse_string ( display, config.color_urgent, &( colors[URGENT] ) );
textbox_parse_string ( display, config.color_active, &( colors[ACTIVE] ) );
textbox_parse_string ( config.color_normal, &( colors[NORMAL] ) );
textbox_parse_string ( config.color_urgent, &( colors[URGENT] ) );
textbox_parse_string ( config.color_active, &( colors[ACTIVE] ) );
}
else {
parse_color ( display, config.menu_bg, &( colors[NORMAL].bg ) );
parse_color ( display, config.menu_fg, &( colors[NORMAL].fg ) );
parse_color ( display, config.menu_bg_alt, &( colors[NORMAL].bgalt ) );
parse_color ( display, config.menu_hlfg, &( colors[NORMAL].hlfg ) );
parse_color ( display, config.menu_hlbg, &( colors[NORMAL].hlbg ) );
colors[NORMAL].bg = color_get ( config.menu_bg );
colors[NORMAL].fg = color_get ( config.menu_fg );
colors[NORMAL].bgalt = color_get ( config.menu_bg_alt );
colors[NORMAL].hlfg = color_get ( config.menu_hlfg );
colors[NORMAL].hlbg = color_get ( config.menu_hlbg );
parse_color ( display, config.menu_bg_urgent, &( colors[URGENT].bg ) );
parse_color ( display, config.menu_fg_urgent, &( colors[URGENT].fg ) );
parse_color ( display, config.menu_bg_alt, &( colors[URGENT].bgalt ) );
parse_color ( display, config.menu_hlfg_urgent, &( colors[URGENT].hlfg ) );
parse_color ( display, config.menu_hlbg_urgent, &( colors[URGENT].hlbg ) );
colors[URGENT].bg = color_get ( config.menu_bg_urgent );
colors[URGENT].fg = color_get ( config.menu_fg_urgent );
colors[URGENT].bgalt = color_get ( config.menu_bg_alt );
colors[URGENT].hlfg = color_get ( config.menu_hlfg_urgent );
colors[URGENT].hlbg = color_get ( config.menu_hlbg_urgent );
parse_color ( display, config.menu_bg_active, &( colors[ACTIVE].bg ) );
parse_color ( display, config.menu_fg_active, &( colors[ACTIVE].fg ) );
parse_color ( display, config.menu_bg_alt, &( colors[ACTIVE].bgalt ) );
parse_color ( display, config.menu_hlfg_active, &( colors[ACTIVE].hlfg ) );
parse_color ( display, config.menu_hlbg_active, &( colors[ACTIVE].hlbg ) );
colors[ACTIVE].bg = color_get ( config.menu_bg_active );
colors[ACTIVE].fg = color_get ( config.menu_fg_active );
colors[ACTIVE].bgalt = color_get ( config.menu_bg_alt );
colors[ACTIVE].hlfg = color_get ( config.menu_hlfg_active );
colors[ACTIVE].hlbg = color_get ( config.menu_hlbg_active );
}
}

View file

@ -46,7 +46,7 @@
#include <sys/types.h>
#include <cairo.h>
#include <cairo-xlib.h>
#include <cairo-xcb.h>
#define SN_API_NOT_YET_FROZEN
#include <libsn/sn.h>
@ -68,17 +68,17 @@
// What todo with these.
extern Display *display;
extern xcb_connection_t *xcb_connection;
extern xcb_screen_t *xcb_screen;
extern SnLauncheeContext *sncontext;
GThreadPool *tpool = NULL;
RofiViewState *current_active_menu = NULL;
Window main_window = None;
xcb_window_t main_window = XCB_WINDOW_NONE;
cairo_surface_t *surface = NULL;
cairo_surface_t *fake_bg = NULL;
cairo_t *draw = NULL;
Colormap map = None;
XVisualInfo vinfo;
static char * get_matching_state ( void )
{
@ -408,7 +408,7 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *event, xkb
if ( state->w != xce->width || state->h != xce->height ) {
state->w = xce->width;
state->h = xce->height;
cairo_xlib_surface_set_size ( surface, state->w, state->h );
cairo_xcb_surface_set_size ( surface, state->w, state->h );
rofi_view_resize ( state );
}
}
@ -488,22 +488,31 @@ static void check_is_ascii ( thread_state *t, G_GNUC_UNUSED gpointer user_data )
g_mutex_unlock ( t->mutex );
}
static Window __create_window ( Display *display, MenuFlags menu_flags )
static Window __create_window ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, MenuFlags menu_flags )
{
XSetWindowAttributes attr;
attr.colormap = map;
attr.border_pixel = 0;
attr.background_pixel = 0;
uint32_t selmask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
uint32_t selval[] =
{ 0,
0,
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_BUTTON_1_MOTION,map };
Window box = XCreateWindow ( display, DefaultRootWindow ( display ), 0, 0, 200, 100, 0, vinfo.depth, InputOutput,
vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr );
XSelectInput (
display,
xcb_window_t box = xcb_generate_id ( xcb_connection );
xcb_create_window ( xcb_connection,
depth->depth,
box,
KeyReleaseMask | KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask | FocusChangeMask |
Button1MotionMask );
xcb_screen->root,
0,
0,
200,
100,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
visual->visual_id,
selmask,
selval );
surface = cairo_xlib_surface_create ( display, box, vinfo.visual, 200, 100 );
surface = cairo_xcb_surface_create ( xcb_connection, box, visual, 200, 100 );
// Create a drawable.
draw = cairo_create ( surface );
g_assert ( draw != NULL );
@ -894,17 +903,17 @@ void rofi_view_update ( RofiViewState *state )
-(double) ( state->y - state->mon.y ) );
cairo_paint ( d );
cairo_set_operator ( d, CAIRO_OPERATOR_OVER );
color_background ( display, d );
color_background ( d );
cairo_paint ( d );
}
}
else {
// Paint the background.
color_background ( display, d );
color_background ( d );
cairo_paint ( d );
}
TICK_N ( "Background" );
color_border ( display, d );
color_border ( d );
if ( config.menu_bw > 0 ) {
cairo_save ( d );
@ -935,7 +944,7 @@ void rofi_view_update ( RofiViewState *state )
if ( state->message_tb ) {
textbox_draw ( state->message_tb, d );
}
color_separator ( display, d );
color_separator ( d );
if ( strcmp ( config.separator_style, "none" ) ) {
if ( strcmp ( config.separator_style, "dash" ) == 0 ) {
@ -1243,16 +1252,14 @@ void rofi_view_finalize ( RofiViewState *state )
state->finalize ( state );
}
}
void rofi_view_setup_fake_transparency ( Display *display, RofiViewState *state )
void rofi_view_setup_fake_transparency ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, RofiViewState *state )
{
if ( fake_bg == NULL ) {
Window root = DefaultRootWindow ( display );
int screen = DefaultScreen ( display );
cairo_surface_t *s = cairo_xlib_surface_create ( display,
root,
DefaultVisual ( display, screen ),
DisplayWidth ( display, screen ),
DisplayHeight ( display, screen ) );
cairo_surface_t *s = cairo_xcb_surface_create ( xcb_connection,
xcb_screen->root,
root_visual,
xcb_screen->width_in_pixels,
xcb_screen->height_in_pixels );
fake_bg = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, state->mon.w, state->mon.h );
cairo_t *dr = cairo_create ( fake_bg );
@ -1532,9 +1539,8 @@ RofiViewState *rofi_view_create ( Mode *sw,
}
TICK_N ( "Grab keyboard" );
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
XWindowAttributes attr;
if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) {
main_window = __create_window ( display, menu_flags );
if ( main_window == 0 ) {
main_window = __create_window ( xcb_connection, xcb_screen, menu_flags );
if ( sncontext != NULL ) {
sn_launchee_context_setup_window ( sncontext, main_window );
}
@ -1544,7 +1550,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
monitor_active ( display, &( state->mon ) );
TICK_N ( "Get active monitor" );
if ( config.fake_transparency ) {
rofi_view_setup_fake_transparency ( display, state );
rofi_view_setup_fake_transparency ( xcb_connection, xcb_screen, state );
}
// we need this at this point so we can get height.
@ -1643,12 +1649,14 @@ RofiViewState *rofi_view_create ( Mode *sw,
( mode == state->sw ) ? HIGHLIGHT : NORMAL, mode_get_name ( mode ) );
}
}
uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
uint32_t vals[] = { state->x, state->y, state->w, state->h };
// Display it.
XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h );
cairo_xlib_surface_set_size ( surface, state->w, state->h );
XMapRaised ( display, main_window );
XFlush ( display );
xcb_configure_window ( xcb_connection, main_window, mask, vals );
cairo_xcb_surface_set_size ( surface, state->w, state->h );
xcb_map_window ( xcb_connection, main_window );
xcb_flush ( xcb_connection );
// if grabbing keyboard failed, fall through
state->selected = 0;
@ -1695,12 +1703,11 @@ void rofi_view_error_dialog ( const char *msg, int markup )
// Get active monitor size.
monitor_active ( display, &( state->mon ) );
if ( config.fake_transparency ) {
rofi_view_setup_fake_transparency ( display, state );
rofi_view_setup_fake_transparency ( xcb_connection, xcb_screen, state );
}
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
XWindowAttributes attr;
if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) {
main_window = __create_window ( display, MENU_NORMAL );
if ( main_window == 0 ) {
main_window = __create_window ( xcb_connection, xcb_screen, MENU_NORMAL );
}
rofi_view_calculate_window_and_element_width ( state );
@ -1715,11 +1722,14 @@ void rofi_view_error_dialog ( const char *msg, int markup )
state->h = state->line_height + ( state->border ) * 2;
// Move the window to the correct x,y position.
uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
uint32_t vals[] = { state->x, state->y, state->w, state->h };
xcb_configure_window ( xcb_connection, main_window, mask, vals );
calculate_window_position ( state );
XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h );
cairo_xlib_surface_set_size ( surface, state->w, state->h );
cairo_xcb_surface_set_size ( surface, state->w, state->h );
// Display it.
XMapRaised ( display, main_window );
xcb_map_window ( xcb_connection, main_window );
if ( sncontext != NULL ) {
sn_launchee_context_complete ( sncontext );
@ -1741,15 +1751,14 @@ void rofi_view_cleanup ()
cairo_surface_destroy ( surface );
surface = NULL;
}
if ( main_window != None ) {
XUnmapWindow ( display, main_window );
XDestroyWindow ( display, main_window );
main_window = None;
if ( main_window != XCB_WINDOW_NONE ) {
xcb_unmap_window ( xcb_connection, main_window );
xcb_destroy_window ( xcb_connection, main_window );
main_window = XCB_WINDOW_NONE;
}
if ( map != None ) {
XFreeColormap ( display, map );
map = None;
if ( map != XCB_COLORMAP_NONE ) {
xcb_free_colormap ( xcb_connection, map );
map = XCB_COLORMAP_NONE;
}
}
void rofi_view_workers_initialize ( void )

View file

@ -34,6 +34,7 @@
#include <glib.h>
#include <cairo.h>
#include <xcb/xcb.h>
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
@ -68,12 +69,15 @@ enum
NUM_X11MOD
};
xcb_depth_t *depth = NULL;
xcb_visualtype_t *visual = NULL;
xcb_colormap_t map = XCB_COLORMAP_NONE;
xcb_depth_t *root_depth = NULL;
xcb_visualtype_t *root_visual = NULL;
Atom netatoms[NUM_NETATOMS];
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
static unsigned int x11_mod_masks[NUM_X11MOD];
extern Colormap map;
// retrieve a property of any type from a window
int window_get_prop ( Display *display, Window w, Atom prop, Atom *type, int *items, void *buffer, unsigned int bytes )
{
@ -523,71 +527,81 @@ void x11_setup ( Display *display, xkb_stuff *xkb )
x11_create_frequently_used_atoms ( display );
}
extern XVisualInfo vinfo;
int truecolor = FALSE;
void create_visual_and_colormap ( Display *display )
void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen )
{
int screen = DefaultScreen ( display );
// Try to create TrueColor map
if ( XMatchVisualInfo ( display, screen, 32, TrueColor, &vinfo ) ) {
// Visual found, lets try to create map.
map = XCreateColormap ( display, DefaultRootWindow ( display ), vinfo.visual, AllocNone );
truecolor = TRUE;
xcb_depth_iterator_t depth_iter;
for ( depth_iter = xcb_screen_allowed_depths_iterator ( xcb_screen ); depth_iter.rem; xcb_depth_next ( &depth_iter ) ) {
xcb_depth_t *d = depth_iter.data;
xcb_visualtype_iterator_t visual_iter;
for ( visual_iter = xcb_depth_visuals_iterator ( d ); visual_iter.rem; xcb_visualtype_next ( &visual_iter ) ) {
xcb_visualtype_t *v = visual_iter.data;
if ( ( d->depth == 32 ) && ( v->_class == XCB_VISUAL_CLASS_TRUE_COLOR ) ) {
depth = d;
visual = v;
}
// Failed to create map.
// Use the defaults then.
if ( map == None ) {
truecolor = FALSE;
// Two fields we use.
vinfo.visual = DefaultVisual ( display, screen );
vinfo.depth = DefaultDepth ( display, screen );
map = DefaultColormap ( display, screen );
if ( xcb_screen->root_visual == v->visual_id ) {
root_depth = d;
root_visual = v;
}
}
}
if ( visual != NULL ) {
xcb_void_cookie_t c;
xcb_generic_error_t *e;
map = xcb_generate_id ( xcb_connection );
c = xcb_create_colormap_checked ( xcb_connection, XCB_COLORMAP_ALLOC_NONE, map, xcb_screen->root, visual->visual_id );
e = xcb_request_check ( xcb_connection, c );
if ( e ) {
depth = NULL;
visual = NULL;
free ( e );
}
}
Color color_get ( Display *display, const char *const name, const char * const defn )
if ( visual == NULL ) {
depth = root_depth;
visual = root_visual;
map = xcb_screen->default_colormap;
}
}
Color color_get ( const char *const name )
{
char *copy = g_strdup ( name );
char *cname = g_strstrip ( copy );
XColor color = { 0, 0, 0, 0, 0, 0 };
XColor def;
union
{
struct
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
};
uint32_t pixel;
} color = {
.r = 0xff,
.g = 0xff,
.b = 0xff,
.a = 0xff,
};
// Special format.
if ( strncmp ( cname, "argb:", 5 ) == 0 ) {
color.pixel = strtoul ( &cname[5], NULL, 16 );
color.red = ( ( color.pixel & 0x00FF0000 ) >> 16 ) * 256;
color.green = ( ( color.pixel & 0x0000FF00 ) >> 8 ) * 256;
color.blue = ( ( color.pixel & 0x000000FF ) ) * 256;
if ( !truecolor ) {
// This will drop alpha part.
Status st = XAllocColor ( display, map, &color );
if ( st == None ) {
fprintf ( stderr, "Failed to parse color: '%s'\n", cname );
st = XAllocNamedColor ( display, map, defn, &color, &def );
if ( st == None ) {
fprintf ( stderr, "Failed to allocate fallback color\n" );
exit ( EXIT_FAILURE );
}
}
}
}
else {
Status st = XAllocNamedColor ( display, map, cname, &color, &def );
if ( st == None ) {
fprintf ( stderr, "Failed to parse color: '%s'\n", cname );
st = XAllocNamedColor ( display, map, defn, &color, &def );
if ( st == None ) {
fprintf ( stderr, "Failed to allocate fallback color\n" );
exit ( EXIT_FAILURE );
}
}
else if ( strncmp ( cname, "#", 1 ) == 0 ) {
color.pixel = strtoul ( &cname[1], NULL, 16 );
color.a = 0xff;
}
g_free ( copy );
Color ret = {
.red = color.red / 65535.0,
.green = color.green / 65535.0,
.blue = color.blue / 65535.0,
.alpha = ( ( color.pixel & 0xFF000000 ) >> 24 ) / 255.0,
.red = color.r / 255.0,
.green = color.g / 255.0,
.blue = color.b / 255.0,
.alpha = color.a / 255.0,
};
return ret;
}
@ -619,16 +633,16 @@ void color_cache_reset ( void )
color_cache[BORDER].set = FALSE;
color_cache[SEPARATOR].set = FALSE;
}
void color_background ( Display *display, cairo_t *d )
void color_background ( cairo_t *d )
{
if ( !color_cache[BACKGROUND].set ) {
if ( !config.color_enabled ) {
color_cache[BACKGROUND].color = color_get ( display, config.menu_bg, "black" );
color_cache[BACKGROUND].color = color_get ( config.menu_bg );
}
else {
gchar **vals = g_strsplit ( config.color_window, ",", 3 );
if ( vals != NULL && vals[0] != NULL ) {
color_cache[BACKGROUND].color = color_get ( display, vals[0], "black" );
color_cache[BACKGROUND].color = color_get ( vals[0] );
}
g_strfreev ( vals );
}
@ -638,16 +652,16 @@ void color_background ( Display *display, cairo_t *d )
x11_helper_set_cairo_rgba ( d, color_cache[BACKGROUND].color );
}
void color_border ( Display *display, cairo_t *d )
void color_border ( cairo_t *d )
{
if ( !color_cache[BORDER].set ) {
if ( !config.color_enabled ) {
color_cache[BORDER].color = color_get ( display, config.menu_bc, "white" );
color_cache[BORDER].color = color_get ( config.menu_bc );
}
else {
gchar **vals = g_strsplit ( config.color_window, ",", 3 );
if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) {
color_cache[BORDER].color = color_get ( display, vals[1], "white" );
color_cache[BORDER].color = color_get ( vals[1] );
}
g_strfreev ( vals );
}
@ -656,19 +670,19 @@ void color_border ( Display *display, cairo_t *d )
x11_helper_set_cairo_rgba ( d, color_cache[BORDER].color );
}
void color_separator ( Display *display, cairo_t *d )
void color_separator ( cairo_t *d )
{
if ( !color_cache[SEPARATOR].set ) {
if ( !config.color_enabled ) {
color_cache[SEPARATOR].color = color_get ( display, config.menu_bc, "white" );
color_cache[SEPARATOR].color = color_get ( config.menu_bc );
}
else {
gchar **vals = g_strsplit ( config.color_window, ",", 3 );
if ( vals != NULL && vals[0] != NULL && vals[1] != NULL && vals[2] != NULL ) {
color_cache[SEPARATOR].color = color_get ( display, vals[2], "white" );
color_cache[SEPARATOR].color = color_get ( vals[2] );
}
else if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) {
color_cache[SEPARATOR].color = color_get ( display, vals[1], "white" );
color_cache[SEPARATOR].color = color_get ( vals[1] );
}
g_strfreev ( vals );
}