Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfd16f9e22 | ||
|
|
b446ac99c9 | ||
|
|
8024e308d8 | ||
|
|
dd5586a76e | ||
|
|
20e755fbcb | ||
|
|
ccf3c7b169 | ||
|
|
4be89c3337 | ||
|
|
2220946a2f |
7
Makefile
7
Makefile
@@ -57,10 +57,15 @@ LDFLAGS += $(ASAN) -lpulse -lpulse-simple -pthread $(LDFLAGS_GLFW) -ldl -lm -lX1
|
||||
|
||||
PYTHON = python
|
||||
|
||||
GLAVA_VERSION = \"$(shell git describe --tags 2>/dev/null)\"
|
||||
ifeq ($(GLAVA_VERSION),\"\")
|
||||
GLAVA_VERSION = \"unknown\"
|
||||
endif
|
||||
|
||||
GLAD_INSTALL_DIR = glad
|
||||
GLAD_SRCFILE = ./glad/src/glad.c
|
||||
GLAD_ARGS = --generator=$(GLAD_GEN) --extensions=GL_EXT_framebuffer_multisample,GL_EXT_texture_filter_anisotropic
|
||||
CFLAGS_COMMON = -I glad/include
|
||||
CFLAGS_COMMON = -I glad/include -DGLAVA_VERSION="$(GLAVA_VERSION)"
|
||||
CFLAGS_USE = $(CFLAGS_COMMON) $(CFLAGS_GLX) $(CFLAGS_GLFW) $(CFLAGS_BUILD) $(CFLAGS_INSTALL) $(CFLAGS)
|
||||
|
||||
all: glava
|
||||
|
||||
@@ -51,10 +51,11 @@ GLava aims to be compatible with _most_ EWMH compliant window managers. Below is
|
||||
| WM | ! | Details
|
||||
| :---: | --- | --- |
|
||||
| Mutter (GNOME, Budgie) |  | `"native"` (default) opacity should be used
|
||||
| Openbox (LXDE or standalone) |  | [Some tweaks may be required](https://www.reddit.com/r/unixporn/comments/7vcgi4/oc_after_receiving_positive_feedback_here_i/dtrkvja/)
|
||||
| Openbox (LXDE or standalone) |  | No issues
|
||||
| Xfwm (XFCE) |  | Untested, but should work without issues
|
||||
| Fluxbox |  | Untested, but should work without issues
|
||||
| iceWM |  | No notable issues
|
||||
| IceWM |  | No issues
|
||||
| Bspwm |  | No issues
|
||||
| Herbstluftwm |  | `hc rule windowtype~'_NET_WM_WINDOW_TYPE_DESKTOP' manage=off` can be used to unmanage desktop windows
|
||||
| AwesomeWM |  | Can still be focused, may require other changes to config depending on layout
|
||||
| kwin (KDE) |  | [Issues with workspaces and stacking](https://github.com/wacossusca34/glava/issues/4), needs further testing
|
||||
@@ -62,8 +63,7 @@ GLava aims to be compatible with _most_ EWMH compliant window managers. Below is
|
||||
| EXWM |  | EXWM does not have a desktop, and forces window decorations
|
||||
| Unity |  | Needs testing
|
||||
| Enlightenment |  | Needs testing
|
||||
| Bspwm |  | Needs testing
|
||||
| xmonad |  | Needs testing
|
||||
| Xmonad |  | Needs testing
|
||||
| Any non EWMH-compliant WM |  | Window types and hints will not work if the window manager does not support the EWMH standards.
|
||||
|
||||
## Licensing
|
||||
|
||||
4
glava.c
4
glava.c
@@ -18,7 +18,6 @@
|
||||
#include "render.h"
|
||||
#include "xwin.h"
|
||||
|
||||
#define GLAVA_VERSION "1.4.1"
|
||||
#ifdef GLAD_DEBUG
|
||||
#define GLAVA_RELEASE_TYPE_PREFIX "debug, "
|
||||
#else
|
||||
@@ -272,7 +271,8 @@ int main(int argc, char** argv) {
|
||||
pthread_mutex_lock(&audio.mutex);
|
||||
modified = audio.modified;
|
||||
if (modified) {
|
||||
/* create our own copies of the audio buffers, so the streaming thread can continue to append to it */
|
||||
/* create our own copies of the audio buffers, so the streaming
|
||||
thread can continue to append to it */
|
||||
memcpy(lb, (void*) audio.audio_out_l, r->bufsize_request * sizeof(float));
|
||||
memcpy(rb, (void*) audio.audio_out_r, r->bufsize_request * sizeof(float));
|
||||
audio.modified = false; /* set this flag to false until the next time we read */
|
||||
|
||||
@@ -9,22 +9,22 @@
|
||||
|
||||
#include "fifo.h"
|
||||
|
||||
static pa_mainloop *m_pulseaudio_mainloop;
|
||||
static pa_mainloop* m_pulseaudio_mainloop;
|
||||
|
||||
static void cb(__attribute__((unused)) pa_context *pulseaudio_context,
|
||||
const pa_server_info *i,
|
||||
void *userdata) {
|
||||
static void cb(__attribute__((unused)) pa_context* pulseaudio_context,
|
||||
const pa_server_info* i,
|
||||
void* userdata) {
|
||||
|
||||
//getting default sink name
|
||||
struct audio_data *audio = (struct audio_data *)userdata;
|
||||
/* Obtain default sink name */
|
||||
struct audio_data* audio = (struct audio_data*) userdata;
|
||||
audio->source = malloc(sizeof(char) * 1024);
|
||||
|
||||
strcpy(audio->source,i->default_sink_name);
|
||||
|
||||
//appending .monitor suffix
|
||||
/* Append `.monitor` suffix */
|
||||
audio->source = strcat(audio->source, ".monitor");
|
||||
|
||||
//quiting mainloop
|
||||
/* Quiting mainloop */
|
||||
pa_context_disconnect(pulseaudio_context);
|
||||
pa_context_unref(pulseaudio_context);
|
||||
pa_mainloop_quit(m_pulseaudio_mainloop, 0);
|
||||
@@ -32,10 +32,9 @@ static void cb(__attribute__((unused)) pa_context *pulseaudio_context,
|
||||
}
|
||||
|
||||
|
||||
static void pulseaudio_context_state_callback(pa_context *pulseaudio_context,
|
||||
void *userdata) {
|
||||
static void pulseaudio_context_state_callback(pa_context* pulseaudio_context, void* userdata) {
|
||||
|
||||
// make sure loop is ready
|
||||
/* Ensure loop is ready */
|
||||
switch (pa_context_get_state(pulseaudio_context))
|
||||
{
|
||||
case PA_CONTEXT_UNCONNECTED:
|
||||
@@ -54,7 +53,6 @@ static void pulseaudio_context_state_callback(pa_context *pulseaudio_context,
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
// printf("PulseAudio context terminated!\n");
|
||||
pa_mainloop_quit(m_pulseaudio_mainloop, 0);
|
||||
break;
|
||||
}
|
||||
@@ -63,29 +61,29 @@ static void pulseaudio_context_state_callback(pa_context *pulseaudio_context,
|
||||
|
||||
void get_pulse_default_sink(struct audio_data* audio) {
|
||||
|
||||
pa_mainloop_api *mainloop_api;
|
||||
pa_context *pulseaudio_context;
|
||||
pa_mainloop_api* mainloop_api;
|
||||
pa_context* pulseaudio_context;
|
||||
int ret;
|
||||
|
||||
// Create a mainloop API and connection to the default server
|
||||
/* Create a mainloop API and connection to the default server */
|
||||
m_pulseaudio_mainloop = pa_mainloop_new();
|
||||
|
||||
mainloop_api = pa_mainloop_get_api(m_pulseaudio_mainloop);
|
||||
pulseaudio_context = pa_context_new(mainloop_api, "glava device list");
|
||||
|
||||
|
||||
// This function connects to the pulse server
|
||||
/* Connect to the PA server */
|
||||
pa_context_connect(pulseaudio_context, NULL, PA_CONTEXT_NOFLAGS,
|
||||
NULL);
|
||||
|
||||
// This function defines a callback so the server will tell us its state.
|
||||
/* Define a callback so the server will tell us its state */
|
||||
pa_context_set_state_callback(pulseaudio_context,
|
||||
pulseaudio_context_state_callback,
|
||||
(void*)audio);
|
||||
|
||||
// starting a mainloop to get default sink
|
||||
/* Start mainloop to get default sink */
|
||||
|
||||
// starting with one non blokng iteration in case pulseaudio is not able to run
|
||||
/* Start with one non blocking iteration in case pulseaudio is not able to run */
|
||||
if (!(ret = pa_mainloop_iterate(m_pulseaudio_mainloop, 0, &ret))){
|
||||
printf("Could not open pulseaudio mainloop to "
|
||||
"find default device name: %d\n"
|
||||
@@ -114,12 +112,11 @@ void get_pulse_default_sink(struct audio_data* audio) {
|
||||
#endif
|
||||
|
||||
void* input_pulse(void* data) {
|
||||
struct audio_data *audio = (struct audio_data *)data;
|
||||
struct audio_data* audio = (struct audio_data*) data;
|
||||
int i, n;
|
||||
size_t ssz = audio->sample_sz;
|
||||
float buf[ssz / 2];
|
||||
|
||||
/* The sample type to use */
|
||||
|
||||
const pa_sample_spec ss = {
|
||||
.format = FSAMPLE_FORMAT,
|
||||
.rate = audio->rate,
|
||||
@@ -129,10 +126,10 @@ void* input_pulse(void* data) {
|
||||
.maxlength = ssz * 2,
|
||||
.fragsize = ssz
|
||||
};
|
||||
|
||||
pa_simple *s = NULL;
|
||||
|
||||
pa_simple* s = NULL;
|
||||
int error;
|
||||
|
||||
|
||||
if (!(s = pa_simple_new(NULL, "glava", PA_STREAM_RECORD,
|
||||
audio->source, "audio for glava",
|
||||
&ss, NULL, &pb, &error))) {
|
||||
@@ -141,13 +138,13 @@ void* input_pulse(void* data) {
|
||||
audio->source, pa_strerror(error));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
n = 0;
|
||||
|
||||
|
||||
float* bl = (float*) audio->audio_out_l;
|
||||
float* br = (float*) audio->audio_out_r;
|
||||
size_t fsz = audio->audio_buf_sz;
|
||||
|
||||
|
||||
while (1) {
|
||||
|
||||
/* Record some data ... */
|
||||
@@ -163,17 +160,17 @@ void* input_pulse(void* data) {
|
||||
memmove(bl, &bl[ssz / 4], (fsz - (ssz / 4)) * sizeof(float));
|
||||
memmove(br, &br[ssz / 4], (fsz - (ssz / 4)) * sizeof(float));
|
||||
|
||||
// sorting out channelss
|
||||
/* sorting out channels */
|
||||
|
||||
for (n = 0, i = 0; i < ssz / 2; i += 2) {
|
||||
|
||||
// size_t idx = (i / 2) + (at * (BUFSIZE / 2));
|
||||
/* size_t idx = (i / 2) + (at * (BUFSIZE / 2)); */
|
||||
|
||||
int idx = (fsz - (ssz / 4)) + n;
|
||||
|
||||
if (audio->channels == 1) bl[idx] = (buf[i] + buf[i + 1]) / 2;
|
||||
|
||||
// stereo storing channels in buffer
|
||||
/* stereo storing channels in buffer */
|
||||
if (audio->channels == 2) {
|
||||
bl[idx] = buf[i];
|
||||
br[idx] = buf[i + 1];
|
||||
@@ -183,7 +180,7 @@ void* input_pulse(void* data) {
|
||||
audio->modified = true;
|
||||
|
||||
pthread_mutex_unlock(&audio->mutex);
|
||||
|
||||
|
||||
if (audio->terminate == 1) {
|
||||
pa_simple_free(s);
|
||||
break;
|
||||
|
||||
4
render.c
4
render.c
@@ -651,7 +651,7 @@ void transform_fft(struct gl_data* d, void** _, void* in) {
|
||||
}
|
||||
mmax=istep;
|
||||
}
|
||||
|
||||
|
||||
/* abs and log scale */
|
||||
for (n = 0; n < s->sz; ++n) {
|
||||
if (data[n] < 0.0F) data[n] = -data[n];
|
||||
@@ -736,7 +736,7 @@ struct renderer* rd_new(const char** paths, const char* entry,
|
||||
|
||||
#ifdef GLAVA_GLX
|
||||
DECL_WCB(wcb_glx);
|
||||
if (!forced && !getenv("WAYLAND_DISPLAY") && getenv("DISPLAY")) {
|
||||
if (!forced && getenv("DISPLAY")) {
|
||||
backend = "glx";
|
||||
}
|
||||
#endif
|
||||
|
||||
13
xwin.c
13
xwin.c
@@ -67,7 +67,7 @@ bool xwin_should_render(struct renderer* rd) {
|
||||
Atom actual_type;
|
||||
int actual_format, t;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char* data;
|
||||
unsigned char* data = NULL;
|
||||
|
||||
int handler(Display* d, XErrorEvent* e) { return 0; }
|
||||
|
||||
@@ -77,7 +77,7 @@ bool xwin_should_render(struct renderer* rd) {
|
||||
&actual_type, &actual_format, &nitems, &bytes_after, &data)) {
|
||||
goto close; /* if an error occurs here, the WM probably isn't EWMH compliant */
|
||||
}
|
||||
|
||||
|
||||
if (!nitems)
|
||||
goto close;
|
||||
|
||||
@@ -85,6 +85,11 @@ bool xwin_should_render(struct renderer* rd) {
|
||||
|
||||
prop = XInternAtom(d, "_NET_WM_STATE", true);
|
||||
|
||||
if (data) {
|
||||
XFree(data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
if (Success != XGetWindowProperty(d, active, prop, 0, LONG_MAX, false, AnyPropertyType,
|
||||
&actual_type, &actual_format, &nitems, &bytes_after, &data)) {
|
||||
goto close; /* some WMs are a little slow on creating _NET_WM_STATE, so errors may occur here */
|
||||
@@ -95,6 +100,8 @@ bool xwin_should_render(struct renderer* rd) {
|
||||
}
|
||||
}
|
||||
close:
|
||||
if (data)
|
||||
XFree(data);
|
||||
if (should_close)
|
||||
XCloseDisplay(d);
|
||||
return ret;
|
||||
@@ -114,7 +121,7 @@ static bool xwin_changeatom(struct gl_wcb* wcb, void* impl, const char* type,
|
||||
default: formatted[t] = c;
|
||||
}
|
||||
}
|
||||
bool ret = !strcmp(type, "DESKTOP");
|
||||
bool ret = !strcmp(formatted, "DESKTOP");
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), fmt, formatted);
|
||||
Atom desk = XInternAtom(d, buf, false);
|
||||
|
||||
Reference in New Issue
Block a user