#define __cdecl typedef unsigned long HWND; #include "../mumble_plugin.h" #include #include #include #include #include #include #include #include #include #include #include static wchar_t wcPluginName[256]; static char memname[256]; struct LinkedMem { uint32_t uiVersion; uint32_t ui32count; float fPosition[3]; float fFront[3]; float fTop[3]; wchar_t name[256]; }; static int32_t GetTickCount() { struct timeval tv; gettimeofday(&tv,NULL); return tv.tv_usec / 1000 + tv.tv_sec * 1000; } static struct LinkedMem * const lm_invalid = reinterpret_cast(-1); static struct LinkedMem *lm = lm_invalid; static int shmfd = -1; static uint32_t last_tick = 0; static uint32_t last_count = 0; static void unlock() { lm->ui32count = last_count = 0; lm->uiVersion = 0; wcsncpy(wcPluginName, L"Link", 256); } static int trylock() { if (lm == lm_invalid) return false; if (lm->uiVersion == 1) { if (lm->ui32count != last_count) { last_tick = GetTickCount(); last_count = lm->ui32count; if (lm->name[0]) { wcsncpy(wcPluginName, lm->name, 256); } return true; } } return false; } static int fetch(float *pos, float *front, float *top) { if (lm->ui32count != last_count) { last_tick = GetTickCount(); last_count = lm->ui32count; } else if ((GetTickCount() - last_tick) > 5000) return false; for (int i=0;i<3;i++) pos[i]=lm->fPosition[i]; for (int i=0;i<3;i++) front[i]=lm->fFront[i]; for (int i=0;i<3;i++) top[i]=lm->fTop[i]; return true; } __attribute__((constructor)) static void load_plugin() { bool bCreated = false; snprintf(memname, 256, "/MumbleLink.%d", getuid()); shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR); if (shmfd < 0) { bCreated = true; shmfd = shm_open(memname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); } if (shmfd < 0) { fprintf(stderr,"Mumble Link plugin: error creating shared memory\n"); return; } if (bCreated) ftruncate(shmfd, sizeof(struct LinkedMem)); lm = static_cast( mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0)); if ((lm != lm_invalid) && bCreated) memset(lm, 0, sizeof(struct LinkedMem)); } __attribute__((destructor)) static void unload_plugin() { if (lm != lm_invalid) munmap(lm, sizeof(struct LinkedMem)); if (shmfd > -1) close(shmfd); shm_unlink(memname); } static MumblePlugin linkplug = { MUMBLE_PLUGIN_MAGIC, L"Link v1.0.1", wcPluginName, NULL, NULL, trylock, unlock, fetch }; extern "C" __attribute__((visibility("default"))) MumblePlugin *getMumblePlugin() { return &linkplug; }