【发布时间】:2020-01-03 01:35:24
【问题描述】:
我是 Linux 上的 c 编程新手。我的目标是创建一个高效的程序来监控已安装分区 (parm1) 上的可用空间,并在托盘中放置一个图标来表示它,显示我的名字 (parm2) 和可用空间百分比(计算 parm3 的脚本),每 xxx 秒运行一次该脚本 (parm4) 并在值更改时刷新图标 (图标文件名 parm5)。
对于初学者,我刚刚从这里复制了一个示例 c 程序,我只是想让它按原样编译和运行,以便在托盘中嵌入一个带有图标的程序。
freedesktop XEmbed systray client code in C, Xlib
我对其进行了调整以合并建议的更改并删除错误,它编译干净,但似乎需要添加库才能创建可执行文件。
我如何找出需要哪些库,以及它们的放置顺序?
/* from: https://stackoverflow.com/questions/45392284/freedesktop-xembed-systray-client-code-in-c-xlib */
#include <X11/Xutil.h>
#include <string.h>
#include <unistd.h>
#define MIN(A, B) ((A) < (B) ? (A) : (B))
/* --------- XEMBED and systray stuff */
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
int usleep(useconds_t useconds); //pass in microseconds
static int trapped_error_code = 0;
static int (*old_error_handler) (Display *, XErrorEvent *);
static int
error_handler(Display *display, XErrorEvent *error) {
trapped_error_code = error->error_code;
return 0;
}
void
trap_errors(void) {
trapped_error_code = 0;
old_error_handler = XSetErrorHandler(error_handler);
}
int
untrap_errors(void) {
XSetErrorHandler(old_error_handler);
return trapped_error_code;
}
void
send_systray_message(Display* dpy, long message, long data1, long data2, long data3) {
XEvent ev;
Atom selection_atom = XInternAtom (dpy,"_NET_SYSTEM_TRAY_S0",False);
Window tray = XGetSelectionOwner (dpy,selection_atom);
if ( tray != None)
XSelectInput (dpy,tray,StructureNotifyMask);
memset(&ev, 0, sizeof(ev));
ev.xclient.type = ClientMessage;
ev.xclient.window = tray;
ev.xclient.message_type = XInternAtom (dpy, "_NET_SYSTEM_TRAY_OPCODE", False );
ev.xclient.format = 32;
ev.xclient.data.l[0] = CurrentTime;
ev.xclient.data.l[1] = message;
ev.xclient.data.l[2] = data1; // <--- your window is only here
ev.xclient.data.l[3] = data2;
ev.xclient.data.l[4] = data3;
trap_errors();
XSendEvent(dpy, tray, False, NoEventMask, &ev);
XSync(dpy, False);
usleep(10000);
if (untrap_errors()) {
/* Handle errors */
}
}
/* ------------ Regular X stuff */
int
main(int argc, char **argv) {
int width, height;
XWindowAttributes wa;
XEvent ev;
Display *dpy;
int screen;
Window root, win;
/* init */
if (!(dpy=XOpenDisplay(NULL)))
return 1;
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if(!XGetWindowAttributes(dpy, root, &wa))
return 1;
width = height = MIN(wa.width, wa.height);
/* create window */
win = XCreateSimpleWindow(dpy, root, 0, 0, width, height, 0, 0, 0xFFFF9900);
/* call send_systray_messsage */
send_systray_message(dpy, SYSTEM_TRAY_REQUEST_DOCK, win, 0, 0); // pass win only once
XMapWindow(dpy, win);
XSync(dpy, False);
/* run */
while(1) {
while(XPending(dpy)) {
XNextEvent(dpy, &ev); /* just waiting until we error because window closed */
}
}
}
$ gcc xmbed_system_tray.c -o xmbed_system_tray
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `trap_errors':
xmbed_system_tray.c:(.text+0x3a): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `untrap_errors':
xmbed_system_tray.c:(.text+0x57): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `send_systray_message':
xmbed_system_tray.c:(.text+0xa8): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xc2): undefined reference to `XGetSelectionOwner'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xe8): undefined reference to `XSelectInput'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x131): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1ab): undefined reference to `XSendEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1bf): undefined reference to `XSync'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `main':
xmbed_system_tray.c:(.text+0x1f3): undefined reference to `XOpenDisplay'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x24f): undefined reference to `XGetWindowAttributes'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2b2): undefined reference to `XCreateSimpleWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2ed): undefined reference to `XMapWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2fe): undefined reference to `XSync'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x316): undefined reference to `XNextEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x322): undefined reference to `XPending'
collect2: error: ld returned 1 exit status
【问题讨论】: