⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xdisplay.c

📁 多种LINUX系统下程序
💻 C
字号:
/* *      xdisplay.c -- actually displaying things * *      Copyright (C) 1996   *          Thomas Sailer (sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu) * *      This program is free software; you can redistribute it and/or modify *      it under the terms of the GNU General Public License as published by *      the Free Software Foundation; either version 2 of the License, or *      (at your option) any later version. * *      This program is distributed in the hope that it will be useful, *      but WITHOUT ANY WARRANTY; without even the implied warranty of *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *      GNU General Public License for more details. * *      You should have received a copy of the GNU General Public License *      along with this program; if not, write to the Free Software *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* ---------------------------------------------------------------------- */#include "multimon.h"#include <sys/types.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include <signal.h>#include <math.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <X11/X.h>#include <X11/Xlib.h>#include <X11/Xutil.h>/* ---------------------------------------------------------------------- */#define WIDTH 512#define HEIGHT 256union comdata {	short s[WIDTH];	unsigned char b[0];};#define SAMPLING_RATE 22050/* ---------------------------------------------------------------------- *//* * child data structures */static Display *display = NULL;static Window window;static GC gc;static Pixmap pixmap;static unsigned long col_zeroline;static unsigned long col_background;static unsigned long col_trace;static int cmdpipe[2];static int datapipe[2];/* * parent data */struct xdisp {	int used;	pid_t pid;	int cmdfd;	int datafd;};#define NUMCLI 16static struct xdisp cli[NUMCLI] = { { 0, }, };/* ---------------------------------------------------------------------- */static int x_error_handler(Display *disp, XErrorEvent *evt){    char err_buf[256], mesg[256], number[256];    char *mtype = "XlibMessage";    XGetErrorText(disp, evt->error_code, err_buf, sizeof(err_buf));    (void)fprintf(stderr, "X Error: %s\n", err_buf);    XGetErrorDatabaseText(disp, mtype, "MajorCode",                          "Request Major code %d", mesg, sizeof(mesg));    (void)fprintf(stderr, mesg, evt->request_code);    (void)sprintf(number, "%d", evt->request_code);    XGetErrorDatabaseText(disp, "XRequest", number, "", err_buf,                          sizeof(err_buf));    (void)fprintf(stderr, " (%s)\n", err_buf);    abort();}/* ---------------------------------------------------------------------- */static Bool predicate(Display *display, XEvent *event, char *arg){	return True;}/* ---------------------------------------------------------------------- */static char *x_getkey(void){	XWindowAttributes winattrs;	XEvent evt;	static char kbuf[32];	int i;	if (!display)		return NULL;	while (XCheckIfEvent(display, &evt, predicate, NULL)) { 		switch (evt.type) {		case KeyPress:			i = XLookupString((XKeyEvent *)&evt, kbuf, 					  sizeof(kbuf)-1, NULL, NULL);			if (i) {				kbuf[i] = 0;				return kbuf;			}			continue;		case DestroyNotify:			XCloseDisplay(display);			exit(0);		case Expose:			XGetWindowAttributes(display, window, &winattrs);			XCopyArea(display, window, pixmap, gc, 0, 0, 				  winattrs.width, winattrs.height, 0, 0);			continue;		default:			continue;		}	}	return NULL;}/* ---------------------------------------------------------------------- */static void process_keystrokes(void){	char *cp;	while ((cp = x_getkey())) {		printf("X: Keys pressed: %s\n", cp);	}}/* ---------------------------------------------------------------------- */static int do_x_select(int fd, int wr){	int *xconn, xconnnum;	int max = fd, i;	fd_set rmask, wmask;		if (!XInternalConnectionNumbers(display, &xconn, &xconnnum)) {		perror("XInternalConnectionNumbers");		exit(1);	}	FD_ZERO(&rmask);	FD_ZERO(&wmask);	if (wr)		FD_SET(fd, &wmask);	else		FD_SET(fd, &rmask);	for (i = 0; i < xconnnum; i++) {		FD_SET(xconn[i], &rmask);		if (xconn[i] > max)			max = xconn[i];	}	i = select(max+1, &rmask, &wmask, NULL, NULL);	if (i < 0) {		perror("select");		exit(1);	}	for (i = 0; i < xconnnum; i++) 		if (FD_ISSET(xconn[i], &rmask))			XProcessInternalConnection(display, xconn[i]);	XFree(xconn);	process_keystrokes();	if (wr)		return FD_ISSET(fd, &wmask);	else		return FD_ISSET(fd, &rmask);}/* ---------------------------------------------------------------------- */static void child_win_init(void){	XSetWindowAttributes attr;	XGCValues gcv;	XColor color, dummy;	XSizeHints sizehints;		/*	 * start graphical output	 */	if (!(display = XOpenDisplay(NULL))) {		fprintf(stderr, "X: Unable to open X display\n");		exit(1);	}	XSetErrorHandler(x_error_handler);        XAllocNamedColor(display, DefaultColormap(display, 0), "red",                         &color, &dummy);        col_zeroline = color.pixel;        col_background = WhitePixel(display, 0);        col_trace = BlackPixel(display, 0);        attr.background_pixel = col_background;	window = XCreateWindow(display, XRootWindow(display, 0),			       200, 200, WIDTH, HEIGHT, 5, 			       DefaultDepth(display, 0),			       InputOutput, DefaultVisual(display, 0),			       CWBackPixel, &attr);        if (!(pixmap = XCreatePixmap(display, window, WIDTH, HEIGHT,                                     DefaultDepth(display, 0)))) {                fprintf(stderr, "X: unable to open offscreen pixmap\n");                exit(1);        }        XSelectInput(display, window, KeyPressMask | StructureNotifyMask                     | ExposureMask) ;	gcv.line_width = 1;	gcv.line_style = LineSolid;	gc = XCreateGC(display, pixmap, GCForeground | GCLineWidth, &gcv);	/*	 * Do not allow the window to be resized	 */	memset(&sizehints, 0, sizeof(sizehints));	sizehints.min_width = sizehints.max_width = WIDTH;	sizehints.min_height = sizehints.max_height = HEIGHT;	sizehints.flags = PMinSize | PMaxSize;	XSetWMNormalHints(display, window, &sizehints);	XMapWindow(display, window);	XSynchronize(display, 1);}	/* ---------------------------------------------------------------------- */#define YCOORD(x) (((x)>>8)+(HEIGHT/2))static void child_process(void){	union comdata d;	unsigned char *bp;	int i, j;	/*	 * main loop	 */	for (;;) {		/*		 * send synchronisation mark		 */		while (!do_x_select(cmdpipe[1], 1));		i = write(cmdpipe[1], "r", 1);		if (i < 1) {			perror("write");			exit(1);		}		/*		 * read data		 */		for (j = sizeof(d), bp = d.b; j > 0; ) {			while (!do_x_select(datapipe[0], 0));			i = read(datapipe[0], bp, j);			if (i < 1) {				perror("read");				exit(1);			}			j -= i;			bp += i;		}		/*		 * clear pixmap		 */		XSetState(display, gc, col_background, col_background,			  GXcopy, AllPlanes);                XFillRectangle(display, pixmap, gc, 0, 0,                                WIDTH, HEIGHT);		/*		 * draw zero line		 */		XSetForeground(display, gc, col_zeroline);		XDrawLine(display, pixmap, gc, 0, YCOORD(0), WIDTH,			  YCOORD(0));		/*		 * draw input		 */		XSetForeground(display, gc, col_trace);		for (i = 1; i < WIDTH; i++)                XDrawLine(display, pixmap, gc, i-1, YCOORD(d.s[i-1]),                          i, YCOORD(d.s[i]));		XCopyArea(display, pixmap, window, gc, 0, 0, 			  WIDTH, HEIGHT, 0, 0);		/* XSync(display, 0); */	}        XDestroyWindow(display, window);        XCloseDisplay(display);}/* ---------------------------------------------------------------------- */static void sigchld_handler(int sig){	pid_t pid;	int st;	unsigned int cnum;	while ((pid = wait4(0, &st, WNOHANG, NULL)) != (pid_t)-1) {		for (cnum = 0; cnum < NUMCLI; cnum++)			if (cli[cnum].used && cli[cnum].pid == pid) {				cli[cnum].used = 0;				close(cli[cnum].cmdfd);				close(cli[cnum].datafd);				cli[cnum].pid = (pid_t)-1;				fprintf(stderr, "child process %i died, "					"status %i\n", (int)pid, st);			}	}}/* ---------------------------------------------------------------------- */void xdisp_terminate(int cnum){	if (cnum  < 0 || cnum >= NUMCLI)		return;	kill(cli[cnum].pid, SIGTERM);}/* ---------------------------------------------------------------------- */int xdisp_start(void){	unsigned int cnum;	/*	 * find free client struct	 */	for (cnum = 0; (cnum < NUMCLI) && cli[cnum].used; cnum++);	if (cnum >= NUMCLI)		return -1;	signal(SIGCHLD, sigchld_handler);	/*	 * start "IPC" mechanism (using the pipes)	 */	if (pipe(cmdpipe))		return -1;	if (pipe(datapipe)) {		close(cmdpipe[0]);		close(cmdpipe[1]);	}	if ((cli[cnum].pid = fork())) {		if (cli[cnum].pid == (pid_t)-1) {			/* error */			close(cmdpipe[0]);			close(cmdpipe[1]);			close(datapipe[0]);			close(datapipe[1]);			return -1;		}		/* parent */		cli[cnum].cmdfd = cmdpipe[0];		close(cmdpipe[1]);		close(datapipe[0]);		cli[cnum].datafd = datapipe[1];		cli[cnum].used = 1;		fcntl(cmdpipe[0], F_SETFL, 		      (fcntl(cmdpipe[0], F_GETFL, 0) | O_NDELAY));		return cnum;	}	/*	 * child; the X process	 */	close(cmdpipe[0]);	close(datapipe[1]);	close(0);  /* close stdin */	child_win_init();	child_process();	exit(0);}/* ---------------------------------------------------------------------- */int xdisp_update(int cnum, float *f){	unsigned char *bp;	short *sp;	int i, j;	char c;	union comdata d;	if (cnum < 0 || cnum >= NUMCLI)		return 0;	i = read(cli[cnum].cmdfd, &c, 1);	if (i < 0 && errno != EAGAIN) {		perror("read");		xdisp_terminate(cnum);		return 0;	}	if (i < 1)		return 0;	if (c != 'r')		return 0;	for (sp = d.s, i = 0; i < WIDTH; i++, sp++, f++) {		if (*f >= 1)			*sp = 32767;		else if (*f <= -1)			*sp = -32767;		else 			*sp = 32767.0 * (*f);	}	bp = d.b;	j = sizeof(d);	while (j > 0) {		i = write(cli[cnum].datafd, bp, j);		if (i < 0 && errno != EAGAIN) {			perror("write");			xdisp_terminate(cnum);			return 0;		}		if (i > 0) {			bp += i;			j -= i;		}	}	return 1;}/* ---------------------------------------------------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -