Пример #1
0
static av_cold int init(AVFilterContext *ctx)
{
    int err;
    DrawTextContext *s = ctx->priv;
    Glyph *glyph;

    if ((err = parse_font(ctx)) < 0)
        return err;

    if (s->textfile) {
        uint8_t *textbuf;
        size_t textbuf_size;

        if (s->text) {
            av_log(ctx, AV_LOG_ERROR,
                   "Both text and text file provided. Please provide only one\n");
            return AVERROR(EINVAL);
        }
        if ((err = av_file_map(s->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {
            av_log(ctx, AV_LOG_ERROR,
                   "The text file '%s' could not be read or is empty\n",
                   s->textfile);
            return err;
        }

        if (textbuf_size > SIZE_MAX - 1 ||
            !(s->text = av_malloc(textbuf_size + 1))) {
            av_file_unmap(textbuf, textbuf_size);
            return AVERROR(ENOMEM);
        }
        memcpy(s->text, textbuf, textbuf_size);
        s->text[textbuf_size] = 0;
        av_file_unmap(textbuf, textbuf_size);
    }

    if (!s->text) {
        av_log(ctx, AV_LOG_ERROR,
               "Either text or a valid file must be provided\n");
        return AVERROR(EINVAL);
    }

    if ((err = av_parse_color(s->fontcolor_rgba, s->fontcolor_string, -1, ctx))) {
        av_log(ctx, AV_LOG_ERROR,
               "Invalid font color '%s'\n", s->fontcolor_string);
        return err;
    }

    if ((err = av_parse_color(s->boxcolor_rgba, s->boxcolor_string, -1, ctx))) {
        av_log(ctx, AV_LOG_ERROR,
               "Invalid box color '%s'\n", s->boxcolor_string);
        return err;
    }

    if ((err = av_parse_color(s->shadowcolor_rgba, s->shadowcolor_string, -1, ctx))) {
        av_log(ctx, AV_LOG_ERROR,
               "Invalid shadow color '%s'\n", s->shadowcolor_string);
        return err;
    }

    if ((err = FT_Init_FreeType(&(s->library)))) {
        av_log(ctx, AV_LOG_ERROR,
               "Could not load FreeType: %s\n", FT_ERRMSG(err));
        return AVERROR(EINVAL);
    }

    /* load the face, and set up the encoding, which is by default UTF-8 */
    if ((err = FT_New_Face(s->library, s->fontfile, 0, &s->face))) {
        av_log(ctx, AV_LOG_ERROR, "Could not load fontface from file '%s': %s\n",
               s->fontfile, FT_ERRMSG(err));
        return AVERROR(EINVAL);
    }
    if ((err = FT_Set_Pixel_Sizes(s->face, 0, s->fontsize))) {
        av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n",
               s->fontsize, FT_ERRMSG(err));
        return AVERROR(EINVAL);
    }

    s->use_kerning = FT_HAS_KERNING(s->face);

    /* load the fallback glyph with code 0 */
    load_glyph(ctx, NULL, 0);

    /* set the tabsize in pixels */
    if ((err = load_glyph(ctx, &glyph, ' ') < 0)) {
        av_log(ctx, AV_LOG_ERROR, "Could not set tabsize.\n");
        return err;
    }
    s->tabsize *= glyph->advance;

#if !HAVE_LOCALTIME_R
    av_log(ctx, AV_LOG_WARNING, "strftime() expansion unavailable!\n");
#endif

    return 0;
}
Пример #2
0
status
ws_create_font(FontObj f, DisplayObj d)
{ WsFont wsf = alloc(sizeof(ws_font));
#ifdef __WINDOWS__
  int widths[FONTTABLESIZE];
#else
  short widths[FONTTABLESIZE];
#endif
  HDC hdc;
  HFONT old;
  int n;
  TEXTMETRIC tm;
  int stock;

  if ( sscanf(strName(f->x_name), STOCKFMT, &stock) == 1 )
  { wsf->hfont      = GetStockObject(stock);
    wsf->from_stock = TRUE;
  } else
  { LOGFONT lfont;
    Real  scale  = getClassVariableValueObject(f, NAME_scale);
    float fscale = (scale ? valReal(scale) : 1.4);

    memset(&lfont, 0, sizeof(lfont));
    lfont.lfHeight          = (int)((float) valInt(f->points) * fscale);
    lfont.lfWeight          = (f->style == NAME_bold ? FW_BOLD : FW_NORMAL);
    lfont.lfItalic          = ((f->style == NAME_italic ||
				f->style == NAME_oblique) ? 1 : 0);
    lfont.lfPitchAndFamily  = (f->family == NAME_screen  ? FIXED_PITCH
							 : DEFAULT_PITCH);
    lfont.lfPitchAndFamily |= (f->family == NAME_helvetica ? FF_SWISS :
			       f->family == NAME_times     ? FF_ROMAN :
			       f->family == NAME_screen    ? FF_MODERN :
							     FF_DONTCARE);

    if ( f->family == NAME_symbol )
      strcpy(lfont.lfFaceName, "symbol");

    if ( instanceOfObject(f->x_name, ClassCharArray) )
    { strcpy(lfont.lfFaceName, strName(f->family));

      parse_font(strName(f->x_name), &lfont);
    } else
    { lfont.lfOutPrecision  = OUT_TT_ONLY_PRECIS;
      lfont.lfQuality	    = PROOF_QUALITY;
    }

    if ( !(wsf->hfont = CreateFontIndirect(&lfont)) )
    { Cprintf("Failed to create logical font; replacing with stock font\n");

      if ( f->family == NAME_screen )
      { if ( f->style == NAME_bold )
	  stock = SYSTEM_FIXED_FONT;
	else
	  stock = ANSI_FIXED_FONT;
      } else
      { if ( f->style == NAME_bold )
	  stock = SYSTEM_FONT;
	else
	  stock = ANSI_VAR_FONT;
      }

      wsf->hfont      = GetStockObject(stock);
      wsf->from_stock = TRUE;
    } else
      wsf->from_stock = FALSE;
  }

  wsf->widths     = alloc(FONTTABLESIZE * sizeof(cwidth));
  assign(f, iswide, OFF);

  hdc = GetDC(NULL);
  old = SelectObject(hdc, wsf->hfont);
  GetCharWidth(hdc, 0, FONTTABLESIZE-1, widths);
  for(n=0; n<FONTTABLESIZE; n++)
    wsf->widths[n] = widths[n];
  GetTextMetrics(hdc, &tm);
  wsf->ascent  = tm.tmAscent + tm.tmExternalLeading;
  wsf->descent = tm.tmDescent;
/*if ( !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && f->family != NAME_win )
    Cprintf("%s (%s/%s): not a TrueType font\n",
	    pp(f), pp(f->family), pp(f->style));
*/
  if ( isDefault(f->x_name) )
  { char buf[256];

    if ( GetTextFace(hdc, sizeof(buf), buf) )
      assign(f, x_name, CtoName(buf));
  }
  SelectObject(hdc, old);
  ReleaseDC(NULL, hdc);

  if ( wsf->widths['i'] == wsf->widths['w'] )
    assign(f, fixed_width, ON);
  else
    assign(f, fixed_width, OFF);

  registerXrefObject(f, d, wsf);

  succeed;
}
Пример #3
0
int fswc_grab(fswebcam_config_t *config)
{
	uint32_t frame;
	uint32_t x, y;
	avgbmp_t *abitmap, *pbitmap;
	gdImage *image, *original;
	uint8_t modified;
	src_t src;
	
	/* Record the start time. */
	config->start = time(NULL);
	
	/* Set source options... */
	memset(&src, 0, sizeof(src));
	src.input      = config->input;
	src.tuner      = config->tuner;
	src.frequency  = config->frequency;
	src.delay      = config->delay;
	src.timeout    = 10; /* seconds */
	src.use_read   = config->use_read;
	src.list       = config->list;
	src.palette    = config->palette;
	src.width      = config->width;
	src.height     = config->height;
	src.fps        = config->fps;
	src.option     = config->option;
	
	HEAD("--- Opening %s...", config->device);
	
	if(src_open(&src, config->device) == -1) return(-1);
	
	/* The source may have adjusted the width and height we passed
	 * to it. Update the main config to match. */
	config->width  = src.width;
	config->height = src.height;
	
	/* Allocate memory for the average bitmap buffer. */
	abitmap = calloc(config->width * config->height * 3, sizeof(avgbmp_t));
	if(!abitmap)
	{
		ERROR("Out of memory.");
		return(-1);
	}
	
	if(config->frames == 1) HEAD("--- Capturing frame...");
	else HEAD("--- Capturing %i frames...", config->frames);
	
	if(config->skipframes == 1) MSG("Skipping frame...");
	else if(config->skipframes > 1) MSG("Skipping %i frames...", config->skipframes);
	
	/* Grab (and do nothing with) the skipped frames. */
	for(frame = 0; frame < config->skipframes; frame++)
		if(src_grab(&src) == -1) break;
	
	/* If frames where skipped, inform when normal capture begins. */
	if(config->skipframes) MSG("Capturing %i frames...", config->frames);
	
	/* Grab the requested number of frames. */
	for(frame = 0; frame < config->frames; frame++)
	{
		if(src_grab(&src) == -1) break;
		
		if(!frame && config->dumpframe)
		{
			/* Dump the raw data from the first frame to file. */
			FILE *f;
			
			MSG("Dumping raw frame to '%s'...", config->dumpframe);
			
			f = fopen(config->dumpframe, "wb");
			if(!f) ERROR("fopen: %s", strerror(errno));
			else
			{
				fwrite(src.img, 1, src.length, f);
				fclose(f);
			}
		}
		
		/* Add frame to the average bitmap. */
		switch(src.palette)
		{
		case SRC_PAL_PNG:
			fswc_add_image_png(&src, abitmap);
			break;
		case SRC_PAL_JPEG:
		case SRC_PAL_MJPEG:
			fswc_add_image_jpeg(&src, abitmap);
			break;
		case SRC_PAL_S561:
			fswc_add_image_s561(abitmap, src.img, src.length, src.width, src.height, src.palette);
			break;
		case SRC_PAL_RGB32:
			fswc_add_image_rgb32(&src, abitmap);
			break;
		case SRC_PAL_BGR32:
			fswc_add_image_bgr32(&src, abitmap);
			break;
		case SRC_PAL_RGB24:
			fswc_add_image_rgb24(&src, abitmap);
			break;
		case SRC_PAL_BGR24:
			fswc_add_image_bgr24(&src, abitmap);
			break;
		case SRC_PAL_BAYER:
		case SRC_PAL_SGBRG8:
		case SRC_PAL_SGRBG8:
			fswc_add_image_bayer(abitmap, src.img, src.length, src.width, src.height, src.palette);
			break;
		case SRC_PAL_YUYV:
		case SRC_PAL_UYVY:
			fswc_add_image_yuyv(&src, abitmap);
			break;
		case SRC_PAL_YUV420P:
			fswc_add_image_yuv420p(&src, abitmap);
			break;
		case SRC_PAL_NV12MB:
			fswc_add_image_nv12mb(&src, abitmap);
			break;
		case SRC_PAL_RGB565:
			fswc_add_image_rgb565(&src, abitmap);
			break;
		case SRC_PAL_RGB555:
			fswc_add_image_rgb555(&src, abitmap);
			break;
		case SRC_PAL_Y16:
			fswc_add_image_y16(&src, abitmap);
			break;
		case SRC_PAL_GREY:
			fswc_add_image_grey(&src, abitmap);
			break;
		}
	}
	
	/* We are now finished with the capture card. */
	src_close(&src);
	
	/* Fail if no frames where captured. */
	if(!frame)
	{
		ERROR("No frames captured.");
		free(abitmap);
		return(-1);
	}
	
	HEAD("--- Processing captured image...");
	
	/* Copy the average bitmap image to a gdImage. */
	original = gdImageCreateTrueColor(config->width, config->height);
	if(!original)
	{
		ERROR("Out of memory.");
		free(abitmap);
		return(-1);
	}
	
	pbitmap = abitmap;
	for(y = 0; y < config->height; y++)
		for(x = 0; x < config->width; x++)
		{
			int px = x;
			int py = y;
			int colour;
			
			colour  = (*(pbitmap++) / config->frames) << 16;
			colour += (*(pbitmap++) / config->frames) << 8;
			colour += (*(pbitmap++) / config->frames);
			
			gdImageSetPixel(original, px, py, colour);
		}
	
	free(abitmap);
	
	/* Make a copy of the original image. */
	image = fswc_gdImageDuplicate(original);
	if(!image)
	{
		ERROR("Out of memory.");
		gdImageDestroy(image);
		return(-1);
	}
	
	/* Set the default values for this run. */
	if(config->font) free(config->font);
	if(config->title) free(config->title);
	if(config->subtitle) free(config->subtitle);
	if(config->timestamp) free(config->timestamp);
	if(config->info) free(config->info);
	if(config->underlay) free(config->underlay);
	if(config->overlay) free(config->overlay);
	if(config->filename) free(config->filename);
	
	config->banner       = BOTTOM_BANNER;
	config->bg_colour    = 0x40263A93;
	config->bl_colour    = 0x00FF0000;
	config->fg_colour    = 0x00FFFFFF;
	config->font         = strdup("sans");
	config->fontsize     = 10;
	config->shadow       = 1;
	config->title        = NULL;
	config->subtitle     = NULL;
	config->timestamp    = strdup("%Y-%m-%d %H:%M (%Z)");
	config->info         = NULL;
	config->underlay     = NULL;
	config->overlay      = NULL;
	config->filename     = NULL;
	config->format       = FORMAT_JPEG;
	config->compression  = -1;
	
	modified = 1;
	
	/* Run through the jobs list. */
	for(x = 0; x < config->jobs; x++)
	{
		uint16_t id   = config->job[x]->id;
		char *options = config->job[x]->options;
		
		switch(id)
		{
		case 1: /* A non-option argument: a filename. */
		case OPT_SAVE:
			fswc_output(config, options, image);
			modified = 0;
			break;
		case OPT_EXEC:
			fswc_exec(config, options);
			break;
		case OPT_REVERT:
			modified = 1;
			gdImageDestroy(image);
			image = fswc_gdImageDuplicate(original);
			break;
		case OPT_FLIP:
			modified = 1;
			image = fx_flip(image, options);
			break;
		case OPT_CROP:
			modified = 1;
			image = fx_crop(image, options);
			break;
		case OPT_SCALE:
			modified = 1;
			image = fx_scale(image, options);
			break;
		case OPT_ROTATE:
			modified = 1;
			image = fx_rotate(image, options);
			break;
		case OPT_DEINTERLACE:
			modified = 1;
			image = fx_deinterlace(image, options);
			break;
		case OPT_INVERT:
			modified = 1;
			image = fx_invert(image, options);
			break;
		case OPT_GREYSCALE:
			modified = 1;
			image = fx_greyscale(image, options);
			break;
		case OPT_SWAPCHANNELS:
			modified = 1;
			image = fx_swapchannels(image, options);
			break;
		case OPT_NO_BANNER:
			modified = 1;
			MSG("Disabling banner.");
			config->banner = NO_BANNER;
			break;
		case OPT_TOP_BANNER:
			modified = 1;
			MSG("Putting banner at the top.");
			config->banner = TOP_BANNER;
			break;
		case OPT_BOTTOM_BANNER:
			modified = 1;
			MSG("Putting banner at the bottom.");
			config->banner = BOTTOM_BANNER;
			break;
		case OPT_BG_COLOUR:
			modified = 1;
			MSG("Setting banner background colour to %s.", options);
			if(sscanf(options, "#%X", &config->bg_colour) != 1)
				WARN("Bad background colour: %s", options);
			break;
		case OPT_BL_COLOUR:
			modified = 1;
			MSG("Setting banner line colour to %s.", options);
			if(sscanf(options, "#%X", &config->bl_colour) != 1)
				WARN("Bad line colour: %s", options);
			break;
		case OPT_FG_COLOUR:
			modified = 1;
			MSG("Setting banner text colour to %s.", options);
			if(sscanf(options, "#%X", &config->fg_colour) != 1)
				WARN("Bad text colour: %s", options);
			break;
		case OPT_FONT:
			modified = 1;
			MSG("Setting font to %s.", options);
			if(parse_font(options, &config->font, &config->fontsize))
				WARN("Bad font: %s", options);
			break;
		case OPT_NO_SHADOW:
			modified = 1;
			MSG("Disabling text shadow.");
			config->shadow = 0;
			break;
		case OPT_SHADOW:
			modified = 1;
			MSG("Enabling text shadow.");
			config->shadow = 1;
			break;
		case OPT_TITLE:
			modified = 1;
			MSG("Setting title \"%s\".", options);
			if(config->title) free(config->title);
			config->title = strdup(options);
			break;
		case OPT_NO_TITLE:
			modified = 1;
			MSG("Clearing title.");
			if(config->title) free(config->title);
			config->title = NULL;
			break;
		case OPT_SUBTITLE:
			modified = 1;
			MSG("Setting subtitle \"%s\".", options);
			if(config->subtitle) free(config->subtitle);
			config->subtitle = strdup(options);
			break;
		case OPT_NO_SUBTITLE:
			modified = 1;
			MSG("Clearing subtitle.");
			if(config->subtitle) free(config->subtitle);
			config->subtitle = NULL;
			break;
		case OPT_TIMESTAMP:
			modified = 1;
			MSG("Setting timestamp \"%s\".", options);
			if(config->timestamp) free(config->timestamp);
			config->timestamp = strdup(options);
			break;
		case OPT_NO_TIMESTAMP:
			modified = 1;
			MSG("Clearing timestamp.");
			if(config->timestamp) free(config->timestamp);
			config->timestamp = NULL;
			break;
		case OPT_INFO:
			modified = 1;
			MSG("Setting info text \"%s\".", options);
			if(config->info) free(config->info);
			config->info = strdup(options);
			break;
		case OPT_NO_INFO:
			modified = 1;
			MSG("Clearing info text.");
			if(config->info) free(config->info);
			config->info = NULL;
			break;
		case OPT_UNDERLAY:
			modified = 1;
			MSG("Setting underlay image: %s", options);
			if(config->underlay) free(config->underlay);
			config->underlay = strdup(options);
			break;
		case OPT_NO_UNDERLAY:
			modified = 1;
			MSG("Clearing underlay.");
			if(config->underlay) free(config->underlay);
			config->underlay = NULL;
			break;
		case OPT_OVERLAY:
			modified = 1;
			MSG("Setting overlay image: %s", options);
			if(config->overlay) free(config->overlay);
			config->overlay = strdup(options);
			break;
		case OPT_NO_OVERLAY:
			modified = 1;
			MSG("Clearing overlay image.");
			if(config->overlay) free(config->overlay);
			config->overlay = NULL;
			break;
		case OPT_JPEG:
			modified = 1;
			MSG("Setting output format to JPEG, quality %i", atoi(options));
			config->format = FORMAT_JPEG;
			config->compression = atoi(options);
			break;
		case OPT_PNG:
			modified = 1;
			MSG("Setting output format to PNG, quality %i", atoi(options));
			config->format = FORMAT_PNG;
			config->compression = atoi(options);
			break;
		}
	}
	
	gdImageDestroy(image);
	gdImageDestroy(original);
	
	if(modified) WARN("There are unsaved changes to the image.");
	
	return(0);
}
Пример #4
0
static void ipc_parse_config(struct config *config, const char *payload) {
	json_object *bar_config = json_tokener_parse(payload);
	json_object *markup, *mode, *hidden_bar, *position, *status_command;
	json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers;
	json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs;
#ifdef ENABLE_TRAY
	json_object *tray_output, *icon_theme, *tray_padding, *activate_button, *context_button;
	json_object *secondary_button;
	json_object_object_get_ex(bar_config, "tray_output", &tray_output);
	json_object_object_get_ex(bar_config, "icon_theme", &icon_theme);
	json_object_object_get_ex(bar_config, "tray_padding", &tray_padding);
	json_object_object_get_ex(bar_config, "activate_button", &activate_button);
	json_object_object_get_ex(bar_config, "context_button", &context_button);
	json_object_object_get_ex(bar_config, "secondary_button", &secondary_button);
#endif
	json_object_object_get_ex(bar_config, "mode", &mode);
	json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar);
	json_object_object_get_ex(bar_config, "position", &position);
	json_object_object_get_ex(bar_config, "status_command", &status_command);
	json_object_object_get_ex(bar_config, "font", &font);
	json_object_object_get_ex(bar_config, "bar_height", &bar_height);
	json_object_object_get_ex(bar_config, "wrap_scroll", &wrap_scroll);
	json_object_object_get_ex(bar_config, "workspace_buttons", &workspace_buttons);
	json_object_object_get_ex(bar_config, "strip_workspace_numbers", &strip_workspace_numbers);
	json_object_object_get_ex(bar_config, "binding_mode_indicator", &binding_mode_indicator);
	json_object_object_get_ex(bar_config, "verbose", &verbose);
	json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol);
	json_object_object_get_ex(bar_config, "colors", &colors);
	json_object_object_get_ex(bar_config, "outputs", &outputs);
	json_object_object_get_ex(bar_config, "pango_markup", &markup);

	if (status_command) {
		free(config->status_command);
		config->status_command = strdup(json_object_get_string(status_command));
	}

	if (position) {
		config->position = parse_position(json_object_get_string(position));
	}

	if (font) {
		free(config->font);
		config->font = parse_font(json_object_get_string(font));
	}

	if (sep_symbol) {
		free(config->sep_symbol);
		config->sep_symbol = strdup(json_object_get_string(sep_symbol));
	}

	if (strip_workspace_numbers) {
		config->strip_workspace_numbers = json_object_get_boolean(strip_workspace_numbers);
	}

	if (binding_mode_indicator) {
		config->binding_mode_indicator = json_object_get_boolean(binding_mode_indicator);
	}

	if (wrap_scroll) {
		config->wrap_scroll = json_object_get_boolean(wrap_scroll);
	}

	if (workspace_buttons) {
		config->workspace_buttons = json_object_get_boolean(workspace_buttons);
	}

	if (bar_height) {
		config->height = json_object_get_int(bar_height);
	}

	if (markup) {
		config->pango_markup = json_object_get_boolean(markup);
	}

#ifdef ENABLE_TRAY
	if (tray_output) {
		free(config->tray_output);
		config->tray_output = strdup(json_object_get_string(tray_output));
	}

	if (icon_theme) {
		free(config->icon_theme);
		config->icon_theme = strdup(json_object_get_string(icon_theme));
	}

	if (tray_padding) {
		config->tray_padding = json_object_get_int(tray_padding);
	}

	if (activate_button) {
		config->activate_button = json_object_get_int(activate_button);
	}

	if (context_button) {
		config->context_button = json_object_get_int(context_button);
	}

	if (secondary_button) {
		config->secondary_button = json_object_get_int(secondary_button);
	}
#endif

	// free previous outputs list
	int i;
	for (i = 0; i < config->outputs->length; ++i) {
		free(config->outputs->items[i]);
	}
	list_free(config->outputs);
	config->outputs = create_list();

	if (outputs) {
		int length = json_object_array_length(outputs);
		json_object *output;
		const char *output_str;
		for (i = 0; i < length; ++i) {
			output = json_object_array_get_idx(outputs, i);
			output_str = json_object_get_string(output);
			if (strcmp("*", output_str) == 0) {
				config->all_outputs = true;
				break;
			}
			list_add(config->outputs, strdup(output_str));
		}
	} else {
		config->all_outputs = true;
	}

	if (colors) {
		json_object *background, *statusline, *separator;
		json_object *focused_background, *focused_statusline, *focused_separator;
		json_object *focused_workspace_border, *focused_workspace_bg, *focused_workspace_text;
		json_object *inactive_workspace_border, *inactive_workspace_bg, *inactive_workspace_text;
		json_object *active_workspace_border, *active_workspace_bg, *active_workspace_text;
		json_object *urgent_workspace_border, *urgent_workspace_bg, *urgent_workspace_text;
		json_object *binding_mode_border, *binding_mode_bg, *binding_mode_text;
		json_object_object_get_ex(colors, "background", &background);
		json_object_object_get_ex(colors, "statusline", &statusline);
		json_object_object_get_ex(colors, "separator", &separator);
		json_object_object_get_ex(colors, "focused_background", &focused_background);
		json_object_object_get_ex(colors, "focused_statusline", &focused_statusline);
		json_object_object_get_ex(colors, "focused_separator", &focused_separator);
		json_object_object_get_ex(colors, "focused_workspace_border", &focused_workspace_border);
		json_object_object_get_ex(colors, "focused_workspace_bg", &focused_workspace_bg);
		json_object_object_get_ex(colors, "focused_workspace_text", &focused_workspace_text);
		json_object_object_get_ex(colors, "active_workspace_border", &active_workspace_border);
		json_object_object_get_ex(colors, "active_workspace_bg", &active_workspace_bg);
		json_object_object_get_ex(colors, "active_workspace_text", &active_workspace_text);
		json_object_object_get_ex(colors, "inactive_workspace_border", &inactive_workspace_border);
		json_object_object_get_ex(colors, "inactive_workspace_bg", &inactive_workspace_bg);
		json_object_object_get_ex(colors, "inactive_workspace_text", &inactive_workspace_text);
		json_object_object_get_ex(colors, "urgent_workspace_border", &urgent_workspace_border);
		json_object_object_get_ex(colors, "urgent_workspace_bg", &urgent_workspace_bg);
		json_object_object_get_ex(colors, "urgent_workspace_text", &urgent_workspace_text);
		json_object_object_get_ex(colors, "binding_mode_border", &binding_mode_border);
		json_object_object_get_ex(colors, "binding_mode_bg", &binding_mode_bg);
		json_object_object_get_ex(colors, "binding_mode_text", &binding_mode_text);
		if (background) {
			config->colors.background = parse_color(json_object_get_string(background));
		}

		if (statusline) {
			config->colors.statusline = parse_color(json_object_get_string(statusline));
		}

		if (separator) {
			config->colors.separator = parse_color(json_object_get_string(separator));
		}

		if (focused_background) {
			config->colors.focused_background = parse_color(json_object_get_string(focused_background));
		}

		if (focused_statusline) {
			config->colors.focused_statusline = parse_color(json_object_get_string(focused_statusline));
		}

		if (focused_separator) {
			config->colors.focused_separator = parse_color(json_object_get_string(focused_separator));
		}

		if (focused_workspace_border) {
			config->colors.focused_workspace.border = parse_color(json_object_get_string(focused_workspace_border));
		}

		if (focused_workspace_bg) {
			config->colors.focused_workspace.background = parse_color(json_object_get_string(focused_workspace_bg));
		}

		if (focused_workspace_text) {
			config->colors.focused_workspace.text = parse_color(json_object_get_string(focused_workspace_text));
		}

		if (active_workspace_border) {
			config->colors.active_workspace.border = parse_color(json_object_get_string(active_workspace_border));
		}

		if (active_workspace_bg) {
			config->colors.active_workspace.background = parse_color(json_object_get_string(active_workspace_bg));
		}

		if (active_workspace_text) {
			config->colors.active_workspace.text = parse_color(json_object_get_string(active_workspace_text));
		}

		if (inactive_workspace_border) {
			config->colors.inactive_workspace.border = parse_color(json_object_get_string(inactive_workspace_border));
		}

		if (inactive_workspace_bg) {
			config->colors.inactive_workspace.background = parse_color(json_object_get_string(inactive_workspace_bg));
		}

		if (inactive_workspace_text) {
			config->colors.inactive_workspace.text = parse_color(json_object_get_string(inactive_workspace_text));
		}

		if (binding_mode_border) {
			config->colors.binding_mode.border = parse_color(json_object_get_string(binding_mode_border));
		}

		if (binding_mode_bg) {
			config->colors.binding_mode.background = parse_color(json_object_get_string(binding_mode_bg));
		}

		if (binding_mode_text) {
			config->colors.binding_mode.text = parse_color(json_object_get_string(binding_mode_text));
		}
	}

	json_object_put(bar_config);
}