266 lines
6.5 KiB
C
266 lines
6.5 KiB
C
|
/* csnlock v1.02
|
||
|
* Copyright (C) 2002 Simon Hunter (lists@sprig.dyn.dhs.org)
|
||
|
*
|
||
|
* cnslock is a dock application that displays the current state of the
|
||
|
* three lock keys (caps, num, and scroll)
|
||
|
*
|
||
|
* 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 receive a copy of the GNU General Public License along with
|
||
|
* this program; if you still want it, write to the Free Software Foundation, Inc.,
|
||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
*
|
||
|
* Hacked from various wm applets.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/* general includes */
|
||
|
#include <stdio.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <time.h>
|
||
|
#include <math.h>
|
||
|
#include <unistd.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <assert.h>
|
||
|
#define _GNU_SOURCE
|
||
|
#include <getopt.h>
|
||
|
#include <ctype.h>
|
||
|
|
||
|
/* gdk includes */
|
||
|
#include <gdk/gdk.h>
|
||
|
#include <gdk/gdkx.h>
|
||
|
|
||
|
/* x11 includes */
|
||
|
#include <X11/xpm.h>
|
||
|
#include <X11/Xlib.h>
|
||
|
#include <X11/extensions/shape.h>
|
||
|
|
||
|
/* header includes */
|
||
|
#include "include/defines.h"
|
||
|
#include "include/applet.h"
|
||
|
#include "include/cnslock.h"
|
||
|
#include "include/kleds.h"
|
||
|
|
||
|
/* graphic includes */
|
||
|
#include "graphics/none.h"
|
||
|
#include "graphics/caps.h"
|
||
|
#include "graphics/num.h"
|
||
|
#include "graphics/scroll.h"
|
||
|
#include "graphics/caps_num.h"
|
||
|
#include "graphics/caps_scroll.h"
|
||
|
#include "graphics/num_scroll.h"
|
||
|
#include "graphics/caps_num_scroll.h"
|
||
|
|
||
|
/* stuff */
|
||
|
void cnslock_update(void);
|
||
|
|
||
|
/* misc support functions */
|
||
|
void prepare_backbuffer(int solid);
|
||
|
void parse_options(int argc, char **argv);
|
||
|
void do_help(void);
|
||
|
void do_version(void);
|
||
|
void make_rgb_buffer256(unsigned char *target, unsigned char *source,int width, int height, int frames, char *cmap);
|
||
|
|
||
|
/* globals */
|
||
|
AppletData ad;
|
||
|
|
||
|
/* keeps track of mouse focus */
|
||
|
int proximity;
|
||
|
|
||
|
/* background style (n/a) */
|
||
|
int selected_background=1;
|
||
|
|
||
|
/* initial positional data (n/a) */
|
||
|
int posx=-1, posy=-1;
|
||
|
|
||
|
/* window manager style (0=wm, 1=other) */
|
||
|
int manager_style=0;
|
||
|
|
||
|
/* the main routine */
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
GdkEvent *event;
|
||
|
|
||
|
srand(time(NULL));
|
||
|
|
||
|
/* initialize GDK */
|
||
|
if (!gdk_init_check(&argc, &argv))
|
||
|
{
|
||
|
fprintf(stderr, "GDK init failed, bye bye. Check \"DISPLAY\" variable.\n");
|
||
|
exit(-1);
|
||
|
}
|
||
|
gdk_rgb_init();
|
||
|
|
||
|
/* parse command line options */
|
||
|
parse_options(argc, argv);
|
||
|
|
||
|
/* zero main data structure */
|
||
|
memset(&ad, 0, sizeof(ad));
|
||
|
|
||
|
/* intialise keyboard leds */
|
||
|
init_kleds();
|
||
|
|
||
|
/* create dockapp window. creates windows, allocates memory, etc */
|
||
|
make_new_cnslock_dockapp(manager_style);
|
||
|
|
||
|
/* draw initial background */
|
||
|
prepare_backbuffer(selected_background);
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
while(gdk_events_pending())
|
||
|
{
|
||
|
event = gdk_event_get();
|
||
|
if(event)
|
||
|
{
|
||
|
switch (event->type)
|
||
|
{
|
||
|
case GDK_DESTROY:
|
||
|
gdk_exit(0);
|
||
|
exit(0);
|
||
|
break;
|
||
|
case GDK_BUTTON_PRESS:
|
||
|
/* printf("button press\n"); */
|
||
|
break;
|
||
|
case GDK_ENTER_NOTIFY:
|
||
|
proximity = 1;
|
||
|
break;
|
||
|
case GDK_LEAVE_NOTIFY:
|
||
|
proximity = 0;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
usleep(20000);
|
||
|
cnslock_update();
|
||
|
|
||
|
/* actually draw the rgb buffer to screen */
|
||
|
|
||
|
if (manager_style==0)
|
||
|
gdk_draw_rgb_image(ad.iconwin, ad.gc, XMIN, YMIN, XMAX, YMAX, GDK_RGB_DITHER_NONE, ad.rgb, XMAX * 3);
|
||
|
else
|
||
|
gdk_draw_rgb_image(ad.win, ad.gc, XMIN, YMIN, XMAX, YMAX, GDK_RGB_DITHER_NONE, ad.rgb, XMAX * 3);
|
||
|
}
|
||
|
return 0;
|
||
|
} /* main */
|
||
|
|
||
|
/* update caps, num, scroll lock */
|
||
|
void cnslock_update(void)
|
||
|
{
|
||
|
int status;
|
||
|
|
||
|
memcpy(&ad.rgb, &ad.bgr, RGBSIZE);
|
||
|
|
||
|
status = check_kleds();
|
||
|
if ((status & 0) == 0)
|
||
|
make_rgb_buffer256(ad.rgb,none_data,none_width,none_height,1, *none_cmap);
|
||
|
if ((status & 1) == 1)
|
||
|
make_rgb_buffer256(ad.rgb,c_data,c_width,c_height,1, *c_cmap);
|
||
|
if ((status & 2) == 2)
|
||
|
make_rgb_buffer256(ad.rgb,n_data,n_width,n_height,1, *n_cmap);
|
||
|
if ((status & 3) == 3)
|
||
|
make_rgb_buffer256(ad.rgb,cn_data,cn_width,cn_height,1, *cn_cmap);
|
||
|
if ((status & 4) == 4)
|
||
|
make_rgb_buffer256(ad.rgb,s_data,s_width,s_height,1, *s_cmap);
|
||
|
if ((status & 5) == 5)
|
||
|
make_rgb_buffer256(ad.rgb,cs_data,cs_width,cs_height,1, *cs_cmap);
|
||
|
if ((status & 6) == 6)
|
||
|
make_rgb_buffer256(ad.rgb,ns_data,ns_width,ns_height,1, *ns_cmap);
|
||
|
if ((status & 7) == 7)
|
||
|
make_rgb_buffer256(ad.rgb,cns_data,cns_width,cns_height,1, *cns_cmap);
|
||
|
|
||
|
memcpy(&ad.bgr, &ad.rgb, RGBSIZE);
|
||
|
}
|
||
|
|
||
|
void prepare_backbuffer(int solid)
|
||
|
{
|
||
|
make_rgb_buffer256(ad.rgb,none_data,none_width,none_height,1, *none_cmap);
|
||
|
|
||
|
/* copy it to the "frequent use" buffer */
|
||
|
memcpy(&ad.bgr, &ad.rgb, RGBSIZE);
|
||
|
|
||
|
} /* prepare_backbuffer */
|
||
|
|
||
|
void make_rgb_buffer256(unsigned char *target, unsigned char *source, int width, int height, int frames, char *cmap)
|
||
|
{
|
||
|
int i, j = 0;
|
||
|
|
||
|
for (i = 0; i < (width * height * frames); i++)
|
||
|
{
|
||
|
target[j] = cmap[3*source[i]];
|
||
|
target[j+1] = cmap[3*source[i]+1];
|
||
|
target[j+2] = cmap[3*source[i]+2];
|
||
|
j += 3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void parse_options(int argc, char *argv[])
|
||
|
{
|
||
|
int c = 0;
|
||
|
|
||
|
struct option long_options[] = {
|
||
|
{"help", no_argument, NULL, 1},
|
||
|
{"h", no_argument, NULL, 1},
|
||
|
{"version", no_argument, NULL, 2},
|
||
|
{"v", no_argument, NULL, 2},
|
||
|
{"window", no_argument, NULL, 3},
|
||
|
{"w", no_argument, NULL, 3},
|
||
|
|
||
|
{0, 0, 0, 0}
|
||
|
};
|
||
|
|
||
|
while ((c = getopt_long_only(argc, argv, "", long_options, NULL)) != -1)
|
||
|
{
|
||
|
switch(c)
|
||
|
{
|
||
|
case 1:
|
||
|
do_help();
|
||
|
exit(0);
|
||
|
break;
|
||
|
case 2:
|
||
|
do_version();
|
||
|
exit(0);
|
||
|
break;
|
||
|
case 3:
|
||
|
manager_style = 1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void do_version(void)
|
||
|
{
|
||
|
printf("\ncnslock applet v%.2f\n\n", VERSION);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
-h,--help Display help
|
||
|
-v,--version Display version
|
||
|
-w,--window Alternative window system
|
||
|
*/
|
||
|
|
||
|
void do_help(void)
|
||
|
{
|
||
|
do_version();
|
||
|
printf("This is an applet that displays the various states of the CAPS, NUM and SCROLL LOCK keys.\n"
|
||
|
"\nUsage: cnslock [options]\n\n"
|
||
|
" -h\t--help\t\tShow this message and exit.\n"
|
||
|
" -v\t--version\tShow version and exit.\n"
|
||
|
" -w\t--window\tUse alternative windowing system.\n\n"
|
||
|
);
|
||
|
}
|
||
|
|