Esempio n. 1
0
char *get_vol(char *buf) {
	long max = 0, min = 0, vol = 0;
	int mute = 0;

	snd_mixer_t *handle;
	snd_mixer_elem_t *pcm_mixer, *mas_mixer;
	snd_mixer_selem_id_t *vol_info, *mute_info;

	snd_mixer_open(&handle, 0);
	snd_mixer_attach(handle, "default");
	snd_mixer_selem_register(handle, NULL, NULL);
	snd_mixer_load(handle);
	snd_mixer_selem_id_malloc(&vol_info);
	snd_mixer_selem_id_malloc(&mute_info);
	snd_mixer_selem_id_set_name(vol_info, VOL_CH);
	snd_mixer_selem_id_set_name(mute_info, VOL_CH);
	pcm_mixer = snd_mixer_find_selem(handle, vol_info);
	mas_mixer = snd_mixer_find_selem(handle, mute_info);
	snd_mixer_selem_get_playback_volume_range((snd_mixer_elem_t *)pcm_mixer, &min, &max);
	snd_mixer_selem_get_playback_volume((snd_mixer_elem_t *)pcm_mixer, SND_MIXER_SCHN_MONO, &vol);
	snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO, &mute);
	sprintf(buf, !(mute) ? VOL_MUTE_S : VOL_S, (int)vol * 100 / (int)max);
	if(vol_info)
		snd_mixer_selem_id_free(vol_info);
	if(mute_info)
		snd_mixer_selem_id_free(mute_info);
	if(handle)
		snd_mixer_close(handle);
	return buf;
}
Esempio n. 2
0
static snd_mixer_elem_t *alsa_init_mixer_channel (const char *name,
		long *vol_min, long *vol_max)
{
	snd_mixer_selem_id_t *sid;
	snd_mixer_elem_t *elem = NULL;
	
	snd_mixer_selem_id_malloc (&sid);
	snd_mixer_selem_id_set_index (sid, 0);
	snd_mixer_selem_id_set_name (sid, name);

	if (!(elem = snd_mixer_find_selem(mixer_handle, sid)))
		error ("Can't find mixer %s", name);
	else if (!snd_mixer_selem_has_playback_volume(elem)) {
		error ("Mixer device has no playback volume (%s).", name);
		elem = NULL;
	}
	else {
		snd_mixer_selem_get_playback_volume_range (elem, vol_min,
				vol_max);
		logit ("Opened mixer (%s), volume range: %ld-%ld", name,
				*vol_min, *vol_max);
	}

	snd_mixer_selem_id_free (sid);

	return elem;
}
Esempio n. 3
0
void asound_set_channel(const gchar * channel)
{
    if(m_mixer == NULL || channel == NULL) {
        return;
    }
    if(g_strcmp0(channel, m_channel) == 0)
        return;

    // Clean up any previously set channels
    g_free(m_channel);
    m_channel = g_strdup(channel);
    if(m_elem)
    {
        snd_mixer_elem_set_callback(m_elem, NULL);
        m_elem = NULL;
    }

    // Setup m_elem using the provided channelname
    snd_mixer_selem_id_t * sid;
    snd_mixer_selem_id_malloc(&sid);
    snd_mixer_selem_id_set_name(sid, channel);
    m_elem = snd_mixer_find_selem(m_mixer, sid);
    if(m_elem != NULL)
    {
        snd_mixer_elem_set_callback(m_elem, asound_elem_event);
        snd_mixer_selem_id_free(sid);
    }
}
Esempio n. 4
0
static snd_mixer_elem_t *find_mixer_elem_by_name(const char *goal_name)
{
	snd_mixer_elem_t *elem;
	snd_mixer_selem_id_t *sid = NULL;

	snd_mixer_selem_id_malloc(&sid);

	for (elem = snd_mixer_first_elem(alsa_mixer_handle); elem;
		 elem = snd_mixer_elem_next(elem)) {

		const char *name;

		snd_mixer_selem_get_id(elem, sid);
		name = snd_mixer_selem_id_get_name(sid);
		d_print("name = %s\n", name);
		d_print("has playback volume = %d\n", snd_mixer_selem_has_playback_volume(elem));
		d_print("has playback switch = %d\n", snd_mixer_selem_has_playback_switch(elem));

		if (strcasecmp(name, goal_name) == 0) {
			if (!snd_mixer_selem_has_playback_volume(elem)) {
				d_print("mixer element `%s' does not have playback volume\n", name);
				elem = NULL;
			}
			break;
		}
	}

	snd_mixer_selem_id_free(sid);
	return elem;
}
Esempio n. 5
0
void
moko_alsa_volume_control_set_element_from_name (MokoAlsaVolumeControl *control,
					       const gchar *name)
{
	MokoAlsaVolumeControlPrivate *priv =
		ALSA_VOLUME_CONTROL_PRIVATE (control);

	if (!priv->device) return;
	
	detach_mixer (control);
	
	if (!name) {
		moko_alsa_volume_control_set_element (control, NULL);
		return;
	}
	
	open_mixer (control);
	if ((snd_mixer_attach (priv->mixer_handle, priv->device) == 0) &&
	    (snd_mixer_selem_register (priv->mixer_handle, NULL, NULL) == 0) &&
	    (snd_mixer_load (priv->mixer_handle) == 0)) {
		snd_mixer_elem_t *elem;
		
		elem = snd_mixer_first_elem (priv->mixer_handle);
		while (elem) {
			const char *elem_name = snd_mixer_selem_get_name (elem);
			if (strcmp (elem_name, name) == 0)
				break;
			elem = snd_mixer_elem_next (elem);
		}
		
		if (!elem) {
			snd_mixer_detach (priv->mixer_handle, priv->device);
			close_mixer (control);
			g_warning ("Mixer element '%s' not found", name);
			attach_mixer (control);
		} else {
			snd_mixer_selem_id_t *id;
			if (snd_mixer_selem_id_malloc (&id) != 0) {
				g_warning ("Unable to allocate element id");
				snd_mixer_detach (
					priv->mixer_handle, priv->device);
				close_mixer (control);
			} else {
				snd_mixer_selem_get_id (elem, id);
				snd_mixer_detach (
					priv->mixer_handle, priv->device);
				close_mixer (control);
				g_debug ("Setting element ID");
				moko_alsa_volume_control_set_element (
					control, id);
				snd_mixer_selem_id_free (id);
			}
		}
	} else
		g_warning ("Unable to open mixer on card '%s'", priv->device);
}
Esempio n. 6
0
int
main(void) {
	Display *dpy;
	struct iwreq wreq;
	snd_mixer_t *handle;
	snd_mixer_elem_t *elem;
	snd_mixer_selem_id_t *vol_info;
	int sockfd, loops = 60;
	char *status, *mpd, *net, *vol, *bat, *clk;

	if(!(dpy = XOpenDisplay(NULL))) {
		fprintf(stderr, "dwmst: cannot open display.\n");
		exit(EXIT_FAILURE);
	}

	memset(&wreq, 0, sizeof(struct iwreq));
	snprintf(wreq.ifr_name, sizeof(WIRELESS_DEVICE), WIRELESS_DEVICE);
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	snd_mixer_open(&handle, 0);
	snd_mixer_attach(handle, "default");
	snd_mixer_selem_register(handle, NULL, NULL);
	snd_mixer_load(handle);
	snd_mixer_selem_id_malloc(&vol_info);
	snd_mixer_selem_id_set_name(vol_info, VOL_CH);
	elem = snd_mixer_find_selem(handle, vol_info);
	if(elem == NULL) {
		fprintf(stderr, "dwmst: can not open device.\n");
		cleanup(dpy, sockfd, handle, vol_info);
		exit(EXIT_FAILURE);
	}

	for(;;sleep(INTERVAL)) {
		if(++loops > 60) {
			loops = 0;
			mpd = get_mpd();
			net = get_net(wreq, sockfd);
			bat = get_bat();
			clk = get_time();
		}
		vol = get_vol(handle, elem);
		status = smprintf("%s  %s  %s  %s  %s", mpd, net, vol, bat, clk);
		setstatus(dpy, status);
		free(vol);
		free(status);
	}

	free(mpd);
	free(net);
	free(bat);
	free(clk);
	cleanup(dpy, sockfd, handle, vol_info);
	exit(EXIT_SUCCESS);
}
Esempio n. 7
0
/* Set volume information */
int alsa_sound(char *stat)
{
	int mute=0, realvol=0, len = 0;
	long vol=0, min=0, max=0;
	snd_mixer_t *handle; /* init alsa */
	snd_mixer_selem_id_t *vol_info; /* init channel with volume info */
	snd_mixer_selem_id_t *mute_info; /* init channel with mute info */

	snd_mixer_open(&handle, 0);
	snd_mixer_attach(handle, "default");
	snd_mixer_selem_register(handle, NULL, NULL);
	snd_mixer_load(handle);
	snd_mixer_selem_id_malloc(&vol_info);
	snd_mixer_selem_id_set_name(vol_info, VOL_CH);
	snd_mixer_elem_t* pcm_mixer = snd_mixer_find_selem(handle, vol_info);
	snd_mixer_selem_get_playback_volume_range(pcm_mixer, &min, &max); /* get volume */
	snd_mixer_selem_get_playback_volume(pcm_mixer, SND_MIXER_SCHN_MONO, &vol);
	snd_mixer_selem_id_malloc(&mute_info);
	snd_mixer_selem_id_set_name(mute_info, VOL_CH);
	snd_mixer_elem_t* mas_mixer = snd_mixer_find_selem(handle, mute_info);
	snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO, &mute); /* get mute state */

	if(mute == 0)
		len = sprintf(stat, VOL_MUTE_STR, 0);
	else
        {
		realvol = (vol*100)/max;
		len = sprintf(stat, VOL_STR, realvol);
        }

	if(vol_info)
		snd_mixer_selem_id_free(vol_info);
	if (mute_info)
		snd_mixer_selem_id_free(mute_info);
	if (handle)
		snd_mixer_close(handle);

	return len;
}
Esempio n. 8
0
static char *
get_vol()
{
        long vol = 0, max = 0, min = 0;
        int mute = 0, realvol = 0;
        snd_mixer_t *handle;
        snd_mixer_elem_t *pcm_mixer, *mas_mixer;
        snd_mixer_selem_id_t *vol_info, *mute_info;
        snd_mixer_open(&handle, 0);
        snd_mixer_attach(handle, SOUNDCARD);
        snd_mixer_selem_register(handle, NULL, NULL);
        snd_mixer_load(handle);
        snd_mixer_selem_id_malloc(&vol_info);
        snd_mixer_selem_id_malloc(&mute_info);
        snd_mixer_selem_id_set_name(vol_info, VOL_CH);
        snd_mixer_selem_id_set_name(mute_info, VOL_CH);
        pcm_mixer = snd_mixer_find_selem(handle, vol_info);
        mas_mixer = snd_mixer_find_selem(handle, mute_info);
        snd_mixer_selem_get_playback_volume_range((snd_mixer_elem_t *)pcm_mixer,
                        &min, &max);
        snd_mixer_selem_get_playback_volume((snd_mixer_elem_t *)pcm_mixer,
                        SND_MIXER_SCHN_MONO, &vol);
        snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO,
                        &mute);
        if (!mute)
                realvol = 0;
        else
                realvol = (vol * 100) / max;

        if (vol_info)
                snd_mixer_selem_id_free(vol_info);
        if (mute_info)
                snd_mixer_selem_id_free(mute_info);
        if (handle)
                snd_mixer_close(handle);

        return smprintf("%d%%", realvol);
}
Esempio n. 9
0
float getvolume(snd_mixer_t *handle, const char* vol_ch)
{
	int mute = 0;
	long vol = 0, max = 0, min = 0;
	snd_mixer_elem_t *pcm_mixer, *max_mixer;
	snd_mixer_selem_id_t *vol_info, *mute_info;

	/*ToDo: maybe move all this to main?*/
	snd_mixer_handle_events(handle);
	snd_mixer_selem_id_malloc(&vol_info);
	snd_mixer_selem_id_malloc(&mute_info);
	snd_mixer_selem_id_set_name(vol_info, vol_ch);
	snd_mixer_selem_id_set_name(mute_info, vol_ch);
	pcm_mixer = snd_mixer_find_selem(handle, vol_info);
	max_mixer = snd_mixer_find_selem(handle, mute_info);
	snd_mixer_selem_get_playback_volume_range(pcm_mixer, &min, &max);
	snd_mixer_selem_get_playback_volume(pcm_mixer, 0, &vol);
	snd_mixer_selem_get_playback_switch(max_mixer, 0, &mute);
	snd_mixer_selem_id_free(vol_info);
	snd_mixer_selem_id_free(mute_info);

    return ((float)vol/(float)max)*100;
}
Esempio n. 10
0
void
moko_alsa_volume_control_set_element (MokoAlsaVolumeControl *control,
				     snd_mixer_selem_id_t *element)
{
	MokoAlsaVolumeControlPrivate *priv =
		ALSA_VOLUME_CONTROL_PRIVATE (control);

	detach_mixer (control);
	if (priv->element) {
		snd_mixer_selem_id_free (priv->element);
		priv->element = NULL;
	}
	
	if (snd_mixer_selem_id_malloc (&priv->element) != 0) {
		g_warning ("Unable to allocate mixer element id");
	} else if (element) {
		snd_mixer_selem_id_copy (priv->element, element);
		g_debug ("Element set");
		attach_mixer (control);
	}
}
void create_mixer_object(struct snd_mixer_selem_regopt *selem_regopt)
{
	int err;

	err = snd_mixer_open(&mixer, 0);
	if (err < 0)
		fatal_alsa_error(_("cannot open mixer"), err);

	mixer_device_name = cstrdup(selem_regopt->device);
	err = snd_mixer_selem_register(mixer, selem_regopt, NULL);
	if (err < 0)
		fatal_alsa_error(_("cannot open mixer"), err);

	snd_mixer_set_callback(mixer, mixer_callback);

	err = snd_mixer_load(mixer);
	if (err < 0)
		fatal_alsa_error(_("cannot load mixer controls"), err);

	err = snd_mixer_selem_id_malloc(&current_selem_id);
	if (err < 0)
		fatal_error("out of memory");
}
Esempio n. 12
0
char *
get_volume(void)
{
    snd_mixer_t *handle;
    snd_mixer_elem_t *elem;
    snd_mixer_selem_id_t *s_elem;

    snd_mixer_open(&handle, 0);
    snd_mixer_attach(handle, "default");
    snd_mixer_selem_register(handle, NULL, NULL);
    snd_mixer_load(handle);
    snd_mixer_selem_id_malloc(&s_elem);
    snd_mixer_selem_id_set_name(s_elem, "Master");

    elem = snd_mixer_find_selem(handle, s_elem);

    if (elem == NULL)
    {
        snd_mixer_selem_id_free(s_elem);
        snd_mixer_close(handle);

        exit(EXIT_FAILURE);
    }

    long int vol, max, min, percent;

    snd_mixer_handle_events(handle);
    snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
    snd_mixer_selem_get_playback_volume(elem, 0, &vol);

    percent = (vol * 100) / max;

    snd_mixer_selem_id_free(s_elem);
    snd_mixer_close(handle);

    return smprintf("\x05\uf028 %d",percent);
}
Esempio n. 13
0
static int open_mixer(PxDev *dev, int card, int playback)
{
   snd_mixer_elem_t *elem;
   char name[256];
   int err;
   int i;

   sprintf(name, "hw:%d", card);

   dev->card = card;
   dev->handle = NULL;

   do {
      err = snd_mixer_open(&dev->handle, 0);
      if (err < 0) {
         break;
      }

      err = snd_mixer_attach(dev->handle, name);
      if (err < 0) {
         break;
      }

      err = snd_mixer_selem_register(dev->handle, NULL, NULL);
      if (err < 0) {
         break;
      }

      err = snd_mixer_load(dev->handle);
      if (err < 0) {
         break;
      }

      for (elem = snd_mixer_first_elem(dev->handle);
           elem != NULL;
           elem = snd_mixer_elem_next(elem))
      {
         if (!playback) {
            if (!snd_mixer_selem_has_capture_volume(elem) &&
                !snd_mixer_selem_has_capture_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
         else {
            if (!snd_mixer_selem_has_playback_volume(elem) &&
                !snd_mixer_selem_has_playback_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
         dev->numselems++;
      }

      dev->selems = calloc(dev->numselems, sizeof(PxSelem));
      if (dev->selems == NULL) {
         break;
      }

      i = 0;
      for (elem = snd_mixer_first_elem(dev->handle);
           elem != NULL;
           elem = snd_mixer_elem_next(elem))
      {
         if (!playback) {
            if (!snd_mixer_selem_has_capture_volume(elem) &&
                !snd_mixer_selem_has_capture_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
         else {
            if (!snd_mixer_selem_has_playback_volume(elem) &&
                !snd_mixer_selem_has_playback_switch(elem) &&
                !snd_mixer_selem_has_common_volume(elem)) {
               continue;
            }
         }
               
         if (snd_mixer_selem_id_malloc(&dev->selems[i].sid) < 0) {
            break;
         }

         snd_mixer_selem_get_id(elem, dev->selems[i].sid);
         dev->selems[i].elem = elem;

         snprintf(name,
                  sizeof(name),
                  "%s:%d",
                  snd_mixer_selem_id_get_name(dev->selems[i].sid),
                  snd_mixer_selem_id_get_index(dev->selems[i].sid));

         dev->selems[i].name = strdup(name);
         if (!dev->selems[i].name) {
            break;
         }
         i++;
      }

      if (i == dev->numselems) {
         return TRUE;
      }

   } while (FALSE);

   if (dev->selems) {
      for (i = 0; i < dev->numselems; i++) {
         if (dev->selems[i].sid) {
            snd_mixer_selem_id_free(dev->selems[i].sid);
         }
         if (dev->selems[i].name) {
            free(dev->selems[i].name);
         }
      }
      free(dev->selems);
      dev->selems = NULL;
   }

   if (dev->handle) {
      snd_mixer_close(dev->handle);
      dev->handle = NULL;
   }

   return FALSE;
}
Esempio n. 14
0
/******************************************************************************
 *   setMixerVolume
 *****************************************************************************/
static Int setMixerVolume (Sound_Attrs *attrs)
{
    Int status;
    snd_mixer_t *rcMixer;
    snd_mixer_elem_t    *elem;
    snd_mixer_selem_id_t    *sid;

    snd_mixer_selem_id_malloc (&sid);

    /* Open the mixer device */
    status = snd_mixer_open (&rcMixer, 0);

    if ( status<0 ) {
        Dmai_err2 ("Failed to open mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }

    /* Attach mixer with sound card */
    status = snd_mixer_attach (rcMixer,AUDIO_MIXER);

    if (status <0) {
        Dmai_err2 ("Failed to attach mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }

    /* Register mixer with selected elements */
    status = snd_mixer_selem_register (rcMixer, NULL, NULL);

    if (status <0) {
        Dmai_err2 ("Failed to register mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }
    /* Load mixer */
    status = snd_mixer_load (rcMixer);

    if (status <0) {
        Dmai_err2 ("Failed to load mixer on %s (%s)\n",
                   AUDIO_MIXER, snd_strerror (status));
        return Dmai_EFAIL;
    }

    for (elem = snd_mixer_first_elem (rcMixer); elem; 
            elem=snd_mixer_elem_next(elem)) {

        snd_mixer_selem_get_id(elem,sid);
        if (!snd_mixer_selem_is_active(elem))
            continue;

        if (attrs->mode == Sound_Mode_OUTPUT || 
             attrs->mode == Sound_Mode_FULLDUPLEX) {
            if (snd_mixer_selem_has_playback_channel(elem, 
                 SND_MIXER_SCHN_FRONT_LEFT))
                snd_mixer_selem_set_playback_volume (elem, 
                SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain);
            if (snd_mixer_selem_has_playback_channel(elem, 
                          SND_MIXER_SCHN_FRONT_RIGHT))
                snd_mixer_selem_set_playback_volume (elem, 
                          SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain);
        }

        if (attrs->mode == Sound_Mode_INPUT || 
                    attrs->mode == Sound_Mode_FULLDUPLEX) {
            if (snd_mixer_selem_has_capture_channel(elem,
                    SND_MIXER_SCHN_FRONT_LEFT))
                snd_mixer_selem_set_capture_volume (elem, 
                           SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain);
            if (snd_mixer_selem_has_capture_channel(elem, 
                    SND_MIXER_SCHN_FRONT_RIGHT))
                snd_mixer_selem_set_capture_volume (elem, 
                           SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain);
        }
    }

    snd_mixer_selem_id_free (sid);
    snd_mixer_close (rcMixer);

    return Dmai_EOK;
}
Esempio n. 15
0
int main(void) {
    Display *xdisplay;
    XkbEvent xevent;
    int opcode, xkbEventBase, xkbErrorBase, major, minor;
    int currentLayout = 0;

    time_t timestamp;
    char datetime[DATETIME_BUFFER + 1];

    int status;
    snd_mixer_t *amixer;
    snd_mixer_elem_t *amixer_elem;
    snd_mixer_selem_id_t *amixer_selem;
    long int volume, volumeMin, volumeMax, volumePercent;

    struct udev *udev;
    struct udev_monitor *udev_monitor;
    struct udev_device *udev_device;
    int udev_fd;

    int ps_current = 0, ps_total = 0;

    openlog(NULL, LOG_CONS|LOG_PERROR|LOG_PID, LOG_DAEMON);

    if (!(xdisplay = XOpenDisplay(NULL))) {
        syslog(LOG_ERR, "Can't open display: %s!\n", strerror(errno));
        return EXIT_FAILURE;
    }

    if (!XkbQueryExtension(xdisplay, &opcode, &xkbEventBase, &xkbErrorBase, &major, &minor)) {
        syslog(LOG_ERR, "X doesn't support a compatible Xkb!\n");
        return EXIT_FAILURE;
    }

    if (!XkbSelectEvents(xdisplay, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask)) {
        syslog(LOG_ERR, "Could not set Xkb event mask!\n");
        return EXIT_FAILURE;
    }

    if ((status = snd_mixer_open(&amixer, 0)) < 0 || (status = snd_mixer_selem_register(amixer, NULL, NULL)) < 0 || (status = snd_mixer_attach(amixer, "default")) < 0) {
        syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status));
        return EXIT_FAILURE;
    }

    if ((status = snd_mixer_load(amixer)) || (status = snd_mixer_selem_id_malloc(&amixer_selem)) < 0) {
        syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status));
        return EXIT_FAILURE;
    }

    snd_mixer_selem_id_set_index(amixer_selem, 0);
    snd_mixer_selem_id_set_name(amixer_selem, "Master");

    amixer_elem = snd_mixer_find_selem(amixer, amixer_selem);
    snd_mixer_selem_get_playback_volume_range(amixer_elem, &volumeMin, &volumeMax);

    if (amixer_elem == NULL) {
        syslog(LOG_ERR, "Mixer simple element handle not found!\n");
        return EXIT_FAILURE;
    }

    udev = udev_new();
    if (udev == NULL) {
        syslog(LOG_ERR, "Can't create udev object!\n");
        return EXIT_FAILURE;
    }

    udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
    if (udev_monitor == NULL) {
        syslog(LOG_ERR, "Can't create udev monitor!\n");
        return EXIT_SUCCESS;
    }

    if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "power_supply", NULL) < 0) {
        syslog(LOG_ERR, "Could't watch power_supply events!\n");
        return EXIT_FAILURE;
    }

    if (udev_monitor_enable_receiving(udev_monitor) < 0) {
        syslog(LOG_ERR, "Could't bind udev monitor event!\n");
        return EXIT_FAILURE;
    }

    udev_fd = udev_monitor_get_fd(udev_monitor);

    while(1) {
        time(&timestamp);
        strftime(datetime, DATETIME_BUFFER, DATETIME_FORMAT, localtime(&timestamp));

        while(XPending(xdisplay)) {
            XNextEvent(xdisplay, &xevent.core);
            if (xevent.type == xkbEventBase && xevent.any.xkb_type == XkbStateNotify) {
                currentLayout = xevent.state.group;
            }
        }

        if ((status = snd_mixer_handle_events(amixer)) < 0) {
            syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status));
            return EXIT_FAILURE;
        }

        if ((status = snd_mixer_selem_get_playback_volume(amixer_elem, SND_MIXER_SCHN_MONO, &volume)) < 0) {
            syslog(LOG_ERR, "Alsa failed: %s!\n", snd_strerror(status));
            return EXIT_FAILURE;
        }
        volumePercent = (volume * 100) / volumeMax;

        fd_set fds;
        int ret;
        struct timeval tv = {.tv_sec = 0, .tv_usec = 0};

        FD_ZERO(&fds);
        FD_SET(udev_fd, &fds);
        ret = select(udev_fd + 1, &fds, NULL, NULL, &tv);

        if (ret > 0 && FD_ISSET(udev_fd, &fds)) {
            udev_device = udev_monitor_receive_device(udev_monitor);
            if (udev_device == NULL) {
                syslog(LOG_ERR, "Can't get udev device!\n");
                return EXIT_SUCCESS;
            }

            printf("Name: %s\n", udev_device_get_sysname(udev_device));
            printf("Node: %s\n", udev_device_get_devnode(udev_device));
            printf("Subsystem: %s\n", udev_device_get_subsystem(udev_device));
            printf("Devtype: %s\n", udev_device_get_devtype(udev_device));
            printf("Action: %s\n", udev_device_get_action(udev_device));

            /*ps_current = atoi(udev_device_get_property_value(udev_device, "POWER_SUPPLY_CHARGE_NOW"));*/
            /*ps_total = atoi(udev_device_get_property_value(udev_device, "POWER_SUPPLY_CHARGE_FULL"));*/
            printf("%s\n", udev_device_get_sysattr_value(udev_device, "energy_now"));
            printf("%s\n", udev_device_get_sysattr_value(udev_device, "energy_full"));
            udev_device_unref(udev_device);
        }


        printf("%s %s\t%s %li\t%s %i\t%s %s\n",
               GLYPH_KEYBOARD, layouts[currentLayout],
               GLYPH_VOLUME, volumePercent,
               GLYPH_BATTERY, ps_current,
               GLYPH_CLOCK, datetime
              );

        usleep(SLEEP_MSECONDS * 1000);
    }

    snd_mixer_selem_id_free(amixer_selem);
    snd_mixer_close(amixer);

    XCloseDisplay(xdisplay);
    closelog();

    return EXIT_SUCCESS;
}