dockapps/wmfemon/wmfemon.c
2012-02-12 22:50:31 +00:00

323 lines
10 KiB
C

//WindowMaker DVB frontend monitor dock applet version 1. MaxCompress
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>
#include <unistd.h>
#include <time.h>
#include <stdint.h>
#include <unistd.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
#include <X11/xpm.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/dvb/frontend.h>
#define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d"
static Atom delete_win;
Font f1,f2;
Window W1,Wicon,W2;
Window W2=0;
Display *XD;
GC xgc;
unsigned int d[7][4]={{22, 2,19,9},{2, 2,19,9},{2,12,19,9},
{2,22,19,9},{22,12,19,9},{2,32,19,9},{32,32,42,9}};
// #define DEBUG
unsigned long getcolor(char *color_name)
{
/* getcolor("darkblue") veya getcolor("rgb:52/55/52") olabilir. */
XColor color;
if (!XParseColor(XD, DefaultColormap(XD, DefaultScreen(XD)), color_name, &color))
fprintf(stderr, "can't parse color %s\n", color_name), exit(1);
if (!XAllocColor(XD, DefaultColormap(XD, DefaultScreen(XD)), &color)) {
fprintf(stderr, "can't allocate color %s. Using black\n", color_name);
return BlackPixel(XD, DefaultScreen(XD)); }
return color.pixel;
}
void xmon(int fefd)
{
fe_status_t status;
uint16_t snr, signal, level;
//uint32_t ber, uncorrected_blocks;
struct dvb_frontend_parameters dfp;
XWindowAttributes xwattr;
char a[250];
XTextItem xti;
int freq;
ioctl(fefd, FE_READ_STATUS, &status);
ioctl(fefd, FE_READ_SIGNAL_STRENGTH, &signal);
ioctl(fefd, FE_READ_SNR, &snr);
//ioctl(fefd, FE_READ_BER, &ber);
//ioctl(fefd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
ioctl(fefd, FE_GET_FRONTEND, &dfp);
if (dfp.frequency+10600000 >= 11700000) freq=dfp.frequency+10600000;
else freq=dfp.frequency+ 9750000;
XGetWindowAttributes(XD,Wicon,&xwattr);
level=(signal)*(xwattr.width-1)/(0xffff);
XSetForeground(XD,xgc,getcolor("gray70"));
XFillRectangle(XD,Wicon,xgc,0,0,xwattr.width,xwattr.height);
if (status & FE_HAS_LOCK) XSetForeground(XD,xgc,getcolor("rgb:ff/00/00"));
else XSetForeground(XD,xgc,getcolor("wheat4"));
XFillRectangle(XD,Wicon,xgc,0,15,level,20);
level=(snr)*(xwattr.width-1)/(0xffff);
XFillRectangle(XD,Wicon,xgc,0,38,level,20);
XSetForeground(XD,xgc,getcolor("white"));
XDrawRectangle(XD,Wicon,xgc,0,14,59,21);
XDrawRectangle(XD,Wicon,xgc,0,37,59,21);
XSetForeground(XD,xgc,getcolor("black"));
XDrawLine(XD,Wicon,xgc,0,14,59,14); XDrawLine(XD,Wicon,xgc,0,14,0,35);
XDrawLine(XD,Wicon,xgc,0,37,59,37); XDrawLine(XD,Wicon,xgc,0,37,0,58);
level=(signal)*100/(0xffff);
sprintf(a,"sig %%%d",level);
XSetForeground(XD,xgc,getcolor("black"));
/* ascent font un dikey uzunlugu imis. */
xti.chars=a;
xti.nchars=strlen(a);
xti.delta=0;
xti.font=f2;
XDrawText(XD,Wicon,xgc,2,29,&xti,1);
level=(snr)*100/(0xffff);
sprintf(a,"snr %%%d",level);
xti.chars=a;
xti.nchars=strlen(a);
xti.delta=0;
xti.font=f2;
XDrawText(XD,Wicon,xgc,2,52,&xti,1);
//sprintf(a,"stat %02x|sig %04x|snr %04x|ber %08x|unc %08x|if %08d|sym %d|f %d", status, signal, snr, ber, uncorrected_blocks, dfp.frequency,dfp.u.qpsk.symbol_rate,freq);
sprintf(a,"f %d", freq);
xti.chars=a;
xti.nchars=strlen(a);
xti.delta=0;
xti.font=f1;
XDrawText(XD,Wicon,xgc,1,11,&xti,1);
XFlush(XD); /*Flush etmeden ekrana bok gibi yaziyor.*/
}
void xmon_W2(int fefd)
{
fe_status_t status;
uint16_t snr, signal, level;
uint32_t ber, uncorrected_blocks;
struct dvb_frontend_parameters dfp;
XWindowAttributes xwattr;
char a[250];
XTextItem xti;
int freq;
ioctl(fefd, FE_READ_STATUS, &status);
ioctl(fefd, FE_READ_SIGNAL_STRENGTH, &signal);
ioctl(fefd, FE_READ_SNR, &snr);
ioctl(fefd, FE_READ_BER, &ber);
ioctl(fefd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);
ioctl(fefd, FE_GET_FRONTEND, &dfp);
if (dfp.frequency+10600000 >= 11700000) freq=dfp.frequency+10600000;
else freq=dfp.frequency+ 9750000;
XGetWindowAttributes(XD,W2,&xwattr);
level=(signal)*(xwattr.width-1)/(0xffff);
XSetForeground(XD,xgc,getcolor("gray70"));
XFillRectangle(XD,W2,xgc,0,0,xwattr.width,xwattr.height);
if (status & FE_HAS_LOCK) XSetForeground(XD,xgc,getcolor("rgb:ff/00/00"));
else XSetForeground(XD,xgc,getcolor("wheat4"));
XFillRectangle(XD,W2,xgc,0,15,level,20);
level=(snr)*(xwattr.width-1)/(0xffff);
XFillRectangle(XD,W2,xgc,0,38,level,20);
XSetForeground(XD,xgc,getcolor("white"));
XDrawRectangle(XD,W2,xgc,0,14,xwattr.width-1,21);
XDrawRectangle(XD,W2,xgc,0,37,xwattr.width-1,21);
XSetForeground(XD,xgc,getcolor("black"));
XDrawLine(XD,W2,xgc,0,14,xwattr.width-1,14); XDrawLine(XD,Wicon,xgc,0,14,0,35);
XDrawLine(XD,W2,xgc,0,37,xwattr.width-1,37); XDrawLine(XD,Wicon,xgc,0,37,0,58);
level=(signal)*100/(0xffff);
sprintf(a,"sig %%%d",level);
XSetForeground(XD,xgc,getcolor("black"));
/* ascent font un dikey uzunlugu imis. */
xti.chars=a;
xti.nchars=strlen(a);
xti.delta=0;
xti.font=f2;
XDrawText(XD,W2,xgc,2,29,&xti,1);
level=(snr)*100/(0xffff);
sprintf(a,"snr %%%d",level);
xti.chars=a;
xti.nchars=strlen(a);
xti.delta=0;
xti.font=f2;
XDrawText(XD,W2,xgc,2,52,&xti,1);
sprintf(a,"stat %02x|sig %04x|snr %04x|ber %08x|unc %08x|if %08d|sym %d|f %d", status, signal, snr, ber, uncorrected_blocks, dfp.frequency,dfp.u.qpsk.symbol_rate,freq);
//sprintf(a,"f %d", freq);
xti.chars=a;
xti.nchars=strlen(a);
xti.delta=0;
xti.font=f1;
XDrawText(XD,W2,xgc,1,11,&xti,1);
XFlush(XD); /*Flush etmeden ekrana bok gibi yaziyor.*/
}
int main(int argc, char **argv)
{
XClassHint classhint;
XWMHints wmhints;
XGCValues gcval;
unsigned int adapter = 0, frontend = 0;
char fedev[128];
int fefd;
int z;
struct dvb_frontend_info fe_info;
int bekle=0, bekle2=0;
/* Komut satiri */
/*
fprintf(stderr,"Option Sayisi=%d\n",argc);
for (sayac2=2;sayac2<=argc;sayac2++)
{
fprintf(stderr,"Option %d=%s\n",sayac2,argv[sayac2-1]);
}
*/
/*
while ((opt=getopt(argc, argv, "h:d:"))!=-1) {
switch (opt) {
case 'h':
fprintf(stderr, "Help: [-h] [-d device] [-t aralik]\n");
break;
case 'd':
dev=strdup(optarg);
break;
default:
fprintf(stderr, "\nUsage: %s %s", argv[0], USAGE);
exit(1);
} }
*/
XD = XOpenDisplay("");
if (!XD) { fprintf(stderr, "Default Display acilamadi.\n"); return 1; }
W1 = XCreateSimpleWindow(XD, DefaultRootWindow(XD),0, 0, 64, 64, 1, 50, getcolor("yellow"));
Wicon = XCreateSimpleWindow(XD, W1, 0, 0, 60, 60, 1, 50, getcolor("darkgreen"));
wmhints.initial_state = WithdrawnState;
wmhints.icon_window = Wicon;
wmhints.icon_x = 64;
wmhints.icon_y = 64;
wmhints.window_group = W1;
wmhints.flags = StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
XSetWMHints(XD, W1, &wmhints);
XMapWindow(XD, W1);
classhint.res_name = "wmfemon";
classhint.res_class = "wmfemon";
XSetClassHint(XD, W1, &classhint);
XSelectInput(XD, W1, ExposureMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask);
XSelectInput(XD, Wicon, ExposureMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask);
XStoreName(XD, W1, "wmfemon");
XSetIconName(XD, W1, "wmfemon");
gcval.foreground = 50;
gcval.background = 150;
gcval.graphics_exposures = False;
gcval.font = XLoadFont(XD,"-*-fixed-medium-r-normal-*-10-*-*-*-*-*-*-1");
xgc = XCreateGC(XD, W1, GCForeground | GCBackground | GCGraphicsExposures | GCFont, &gcval);
//f1=XLoadFont(XD,"-*-fixed-medium-r-normal-*-10-*-*-*-*-*-*-1");
f1=XLoadFont(XD,"-*-clean-medium-r-*-*-12-*-*-*-*-*-*-*");
f2=XLoadFont(XD,"-*-helvetica-*-r-*-*-12-*-*-*-*-*-*-*");
snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend);
printf("Device: '%s'\n", fedev);
if ((fefd = open(fedev, O_RDONLY | O_NONBLOCK)) < 0) { perror("opening frontend failed"); return 0;}
z = ioctl(fefd, FE_GET_INFO, &fe_info);
if (z < 0) { perror("ERR ioctl FE_GET_INFO:"); close(fefd); return 0;}
/* main loop */
while (1)
{
XEvent event;
while (XPending(XD))
{
XNextEvent(XD, &event);
switch (event.type)
{
case Expose:
/* update */
fprintf(stderr,"Expose (Update) event geldi.\n");
fprintf(stderr,"xexpose.window=%ld\n",event.xexpose.window);
xmon(fefd);
break;
case MotionNotify:
#ifdef DEBUG
fprintf(stderr,"xmotion x=%d,y=%d\n",event.xmotion.x,event.xmotion.y);
fprintf(stderr,"xmotion window=%ld\n",event.xmotion.window);
fprintf(stderr,"W1 window=%ld\n",W1);
fprintf(stderr,"Wicon window=%ld\n",Wicon);
fprintf(stderr,"-----------------------\n");
#endif
break;
case UnmapNotify:
fprintf(stderr,"UnmapNotify geldi.\n");
break;
case DestroyNotify:
fprintf(stderr,"DestroyNotify geldi.\n");
XCloseDisplay(XD);
exit(0);
break;
case ClientMessage:
//Kapat tusu icin amma yarak isler lazim ulan. wmclockmon dockapp.c'den alinti.
//printf("ClientMessage\n");fflush(stdout);
if (event.xclient.data.l[0] == delete_win) {
if (event.xclient.window==W2)
{ XDestroyWindow(XD,W2); W2=0;
}
}
break;
case ButtonPress:
//fprintf(stderr,"x=%d,y=%d\n",event.xbutton.x,event.xbutton.y);
break;
case ButtonRelease:
fprintf(stderr,"x=%d,y=%d\n",event.xbutton.x,event.xbutton.y);
if (W2==0)
{ W2 = XCreateSimpleWindow(XD, DefaultRootWindow(XD),100,100,600,60,1,50,getcolor("blue"));
if (!W2) { perror("Error: W2"); }
delete_win = XInternAtom(XD, "WM_DELETE_WINDOW", False); //DIKKAT: Kapatma tusunun cikmasi icin bu yarak gerekiyor.
XSetWMProtocols (XD, W2, &delete_win, 1);
XStoreName(XD, W2, "DVB Frontend Monitor for WindowMaker");
XSetIconName(XD, W2, "DVB Signal");
XMapWindow(XD, W2);
} else
{ XDestroyWindow(XD,W2); W2=0;
}
break;
}
}
if (bekle == 0) xmon(fefd);
bekle++;
bekle %= 10; // 10 modulu. W1 1000 ms.
if (W2)
{ if (bekle2 == 0) xmon_W2(fefd);
bekle2++;
bekle2 %= 3; // 3 modulu. W2 biraz daha hizli gostersin. 300 ms.
}
usleep(100000L);
} //while
return 0;
}