439 lines
12 KiB
C
439 lines
12 KiB
C
|
|
/*
|
|
* wmtunlo
|
|
*
|
|
* Copyright (C) 2001 pasp
|
|
*
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <X11/X.h>
|
|
#include <X11/xpm.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <math.h>
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/xpm.h>
|
|
#include <X11/extensions/shape.h>
|
|
|
|
#include "master.h"
|
|
#include "mask.h"
|
|
|
|
#include "docklib.h"
|
|
|
|
void wmtunlo_read_prefs(void);
|
|
void wmtunlo_write_prefs(void);
|
|
|
|
void ButtonPressEvent(XButtonEvent *);
|
|
int GotFirstClick1, GotDoubleClick1;
|
|
int GotFirstClick2, GotDoubleClick2;
|
|
int GotFirstClick3, GotDoubleClick3;
|
|
int DblClkDelay;
|
|
int HasExecute;
|
|
char ClickCommand1[MAX_PATH];
|
|
char ClickCommand2[MAX_PATH];
|
|
char ClickCommand3[MAX_PATH];
|
|
|
|
int tex_block_w, tex_block_h, shade_switch, persp_switch;
|
|
int t_color_1, t_color_2;
|
|
float t_persp, t_shade_level;
|
|
float t_mov_counter, t_rot_counter;
|
|
float t_mov_step, t_rot_step;
|
|
float t_col_add_R, t_col_add_G, t_col_add_B;
|
|
float t_col_mul_R, t_col_mul_G, t_col_mul_B;
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
|
|
typedef struct {
|
|
Display *display;
|
|
int screen;
|
|
Visual *visual;
|
|
int depth;
|
|
Colormap cmap;
|
|
int format;
|
|
int bitmap_pad;
|
|
int Color[256];
|
|
unsigned char R[256];
|
|
unsigned char G[256];
|
|
unsigned char B[256];
|
|
} DisplayInfo;
|
|
|
|
XImage *xim;
|
|
XEvent event;
|
|
XColor xColor, xColors[256];
|
|
DisplayInfo Info;
|
|
int i, j, shade, k, l, p, q, result, col;
|
|
float xz, yz, px, py;
|
|
unsigned char *Image, *Texture, *Tunnel_map;
|
|
|
|
|
|
/* Read preferences */
|
|
wmtunlo_read_prefs();
|
|
|
|
/* Open window */
|
|
openXwindow(argc, argv, dock_master, dock_mask_bits, dock_mask_width, dock_mask_height);
|
|
|
|
/* Get Display parameters */
|
|
Info.display = display;
|
|
Info.screen = DefaultScreen(display);
|
|
Info.visual = DefaultVisual(display, Info.screen);
|
|
Info.depth = DefaultDepth(display, Info.screen);
|
|
Info.cmap = DefaultColormap(display, 0);
|
|
|
|
/* Initialize Color Table */
|
|
|
|
for (i=0; i<256; ++i) {
|
|
col = t_col_mul_R * (float)i + t_col_add_R;
|
|
if(col<0) col = 0;
|
|
if(col>255) col = 255;
|
|
Info.R[i] = col;
|
|
|
|
col = t_col_mul_G * (float)i + t_col_add_G;
|
|
if(col<0) col = 0;
|
|
if(col>255) col = 255;
|
|
Info.G[i] = col;
|
|
|
|
col = t_col_mul_B * (float)i + t_col_add_B;
|
|
if(col<0) col = 0;
|
|
if(col>255) col = 255;
|
|
Info.B[i] = col;
|
|
}
|
|
|
|
/* Create an XImage with null data. Then allocate space for data. */
|
|
Info.format = ZPixmap;
|
|
if (Info.depth == 8){
|
|
|
|
Info.bitmap_pad = 8;
|
|
|
|
/* Set a private colormap */
|
|
Info.cmap = XCreateColormap(Info.display, RootWindow(Info.display, Info.screen), Info.visual, AllocAll);
|
|
for (i=0; i<256; ++i){
|
|
Info.Color[i] = i;
|
|
xColors[i].pixel = i;
|
|
xColors[i].red = (unsigned short)Info.R[i] << 8;
|
|
xColors[i].green = (unsigned short)Info.G[i] << 8;
|
|
xColors[i].blue = (unsigned short)Info.B[i] << 8;
|
|
xColors[i].flags = DoRed | DoGreen | DoBlue;
|
|
}
|
|
XStoreColors(Info.display, Info.cmap, xColors, 256);
|
|
XSetWindowColormap(Info.display, win, Info.cmap);
|
|
|
|
} else if (Info.depth > 8) {
|
|
|
|
/* Allocate Colors */
|
|
for (i=0; i<256; ++i){
|
|
xColor.red = (unsigned short)Info.R[i] << 8;
|
|
xColor.green = (unsigned short)Info.G[i] << 8;
|
|
xColor.blue = (unsigned short)Info.B[i] << 8;
|
|
xColor.flags = DoRed | DoGreen | DoBlue;
|
|
XAllocColor(Info.display, Info.cmap, &xColor);
|
|
Info.Color[i] = xColor.pixel;
|
|
}
|
|
Info.bitmap_pad = 32;
|
|
|
|
} else {
|
|
fprintf(stderr, "Need at least 8-bit display!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
xim = XCreateImage(Info.display, Info.visual, Info.depth, Info.format, 0, (char *)0, 54, 54, Info.bitmap_pad, 0);
|
|
xim->data = (char *)malloc(xim->bytes_per_line * 54 );
|
|
|
|
/* Allocate memory for image data */
|
|
Image = (unsigned char *)malloc(sizeof(unsigned char)*54*54);
|
|
|
|
/* Generate tunnel map */
|
|
Tunnel_map = (unsigned char *)malloc(sizeof(unsigned char)*54*54*4);
|
|
|
|
for (k=0, yz=-54/2; yz<54/2; yz++)
|
|
for (xz=-54/2; xz<54/2; xz++) {
|
|
|
|
py = sqrt(xz*xz + yz*yz);
|
|
shade= py * t_shade_level;
|
|
if(shade>255) shade=255;
|
|
if(persp_switch) py = t_persp/py;
|
|
px = atan2(yz,xz) * 128.0 / M_PI;
|
|
result = (int)py * 256 + (int)px;
|
|
|
|
Tunnel_map[k++]= result&0xff;
|
|
Tunnel_map[k++]= result>>8;
|
|
Tunnel_map[k++]= shade&0xff;
|
|
}
|
|
|
|
/* Generate texture */
|
|
Texture = (unsigned char *)malloc(sizeof(unsigned char)*256*256);
|
|
|
|
for(i=0,q=1;i<256;i+=tex_block_h, q*=-1)
|
|
for(j=0,p=q;j<256;j+=tex_block_w, p*=-1)
|
|
for(l=0;l<tex_block_h;l++)
|
|
for(k=0;k<tex_block_w;k++)
|
|
if((j+k < 256) && (i+l < 256)) {
|
|
if(p>0)
|
|
Texture[(i+l)*256+j+k] = t_color_1;
|
|
else
|
|
Texture[(i+l)*256+j+k] = t_color_2;
|
|
}
|
|
|
|
/* Animation. */
|
|
|
|
t_mov_counter = 0.0;
|
|
t_rot_counter = 0.0;
|
|
|
|
while(1) {
|
|
|
|
/* Process any pending X events. */
|
|
|
|
while(XPending(display)){
|
|
XNextEvent(display, &event);
|
|
switch(event.type){
|
|
case Expose:
|
|
RedrawWindow();
|
|
break;
|
|
case EnterNotify:
|
|
XSetInputFocus(display, iconwin, RevertToNone, CurrentTime);
|
|
if (Info.depth == 8) XInstallColormap(display, Info.cmap);
|
|
break;
|
|
case LeaveNotify:
|
|
XSetInputFocus(display, None, RevertToNone, CurrentTime);
|
|
if (Info.depth == 8) XUninstallColormap(display, Info.cmap);
|
|
break;
|
|
case ButtonPress:
|
|
ButtonPressEvent(&event.xbutton);
|
|
break;
|
|
case ButtonRelease:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Draw tunnel. */
|
|
|
|
for(i=0;i<54;i++)
|
|
for(j=0;j<54;j++) {
|
|
|
|
if(shade_switch)
|
|
*(Image + 54*i + j) = (Tunnel_map[(54*i+j)*3 + 2] * Texture[ \
|
|
((Tunnel_map[(54*i+j)*3 + 1] + (int)t_mov_counter) & 0xff)*256 + \
|
|
Tunnel_map[(54*i+j)*3 + 0] - (int)t_rot_counter]) >> 8;
|
|
else
|
|
*(Image + 54*i + j) = Texture[ \
|
|
((Tunnel_map[(54*i+j)*3 + 1] + (int)t_mov_counter) & 0xff)*256 + \
|
|
Tunnel_map[(54*i+j)*3 + 0] - (int)t_rot_counter];
|
|
}
|
|
|
|
/* Move tunnel. */
|
|
|
|
t_mov_counter += t_mov_step;
|
|
if(t_mov_counter > 256.0) t_mov_counter = 0.0;
|
|
if(t_mov_counter < 0.0) t_mov_counter = 256.0;
|
|
t_rot_counter += t_rot_step;
|
|
if(t_rot_counter > 256.0) t_rot_counter = 0.0;
|
|
if(t_rot_counter < 0.0) t_rot_counter = 256.0;
|
|
|
|
/* Paste up image. */
|
|
for ( i=0; i<54; ++i )
|
|
for ( j=0; j<54; ++j ) {
|
|
XPutPixel(xim, i, j, Info.Color[*(Image + j*54 + i)]);
|
|
XFlush(display);
|
|
}
|
|
|
|
XPutImage(display, wmgen.pixmap, NormalGC, xim, 0, 0, 5, 5, 54, 54);
|
|
|
|
/* Make changes visible */
|
|
RedrawWindow();
|
|
|
|
/* Wait for next update */
|
|
usleep(10000L);
|
|
}
|
|
|
|
free(xim->data);
|
|
XDestroyImage(xim);
|
|
|
|
free(Image);
|
|
free(Tunnel_map);
|
|
free(Texture);
|
|
}
|
|
|
|
/*
|
|
* This routine handles button presses.
|
|
*
|
|
* Double click on
|
|
* Mouse Button 1: Execute the command defined in the -e command-line option.
|
|
* Mouse Button 2: No action assigned.
|
|
* Mouse Button 3: No action assigned.
|
|
*
|
|
*
|
|
*/
|
|
void ButtonPressEvent(XButtonEvent *xev){
|
|
|
|
DblClkDelay = 0;
|
|
if ((xev->button == Button1) && (xev->type == ButtonPress)){
|
|
if (GotFirstClick1) GotDoubleClick1 = 1;
|
|
else GotFirstClick1 = 1;
|
|
} else if ((xev->button == Button2) && (xev->type == ButtonPress)){
|
|
if (GotFirstClick2) GotDoubleClick2 = 1;
|
|
else GotFirstClick2 = 1;
|
|
} else if ((xev->button == Button3) && (xev->type == ButtonPress)){
|
|
if (GotFirstClick3) GotDoubleClick3 = 1;
|
|
else GotFirstClick3 = 1;
|
|
}
|
|
|
|
/*
|
|
* We got a double click on Mouse Button1 (i.e. the left one)
|
|
*/
|
|
if (GotDoubleClick1) {
|
|
GotFirstClick1 = 0;
|
|
GotDoubleClick1 = 0;
|
|
system(ClickCommand1);
|
|
}
|
|
|
|
/*
|
|
* We got a double click on Mouse Button2 (i.e. the left one)
|
|
*/
|
|
if (GotDoubleClick2) {
|
|
GotFirstClick2 = 0;
|
|
GotDoubleClick2 = 0;
|
|
system(ClickCommand2);
|
|
}
|
|
|
|
/*
|
|
* We got a double click on Mouse Button3 (i.e. the left one)
|
|
*/
|
|
if (GotDoubleClick3) {
|
|
GotFirstClick3 = 0;
|
|
GotDoubleClick3 = 0;
|
|
system(ClickCommand3);
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* Write preferences */
|
|
|
|
void wmtunlo_write_prefs(void)
|
|
{
|
|
if (p_prefs_openfile (p_getfilename_config (".clay", "wmtunlorc"), P_WRITE)) {
|
|
|
|
p_prefs_put_int("shade_switch", shade_switch);
|
|
p_prefs_put_int("persp_switch", persp_switch);
|
|
p_prefs_put_lf ();
|
|
p_prefs_put_float("t_shade_level", t_shade_level);
|
|
p_prefs_put_float("t_persp", t_persp);
|
|
p_prefs_put_float("t_mov_step", t_mov_step);
|
|
p_prefs_put_float("t_rot_step", t_rot_step);
|
|
p_prefs_put_lf ();
|
|
p_prefs_put_int("tex_block_w", tex_block_w);
|
|
p_prefs_put_int("tex_block_h", tex_block_h);
|
|
p_prefs_put_lf ();
|
|
p_prefs_put_float("t_col_add_R", t_col_add_R);
|
|
p_prefs_put_float("t_col_add_G", t_col_add_G);
|
|
p_prefs_put_float("t_col_add_B", t_col_add_B);
|
|
p_prefs_put_lf ();
|
|
p_prefs_put_float("t_col_mul_R", t_col_mul_R);
|
|
p_prefs_put_float("t_col_mul_G", t_col_mul_G);
|
|
p_prefs_put_float("t_col_mul_B", t_col_mul_B);
|
|
p_prefs_put_lf ();
|
|
p_prefs_put_int("t_color_1", t_color_1);
|
|
p_prefs_put_int("t_color_2", t_color_2);
|
|
p_prefs_put_lf ();
|
|
p_prefs_put_string("command1", ClickCommand1);
|
|
p_prefs_put_string("command2", ClickCommand2);
|
|
p_prefs_put_string("command3", ClickCommand3);
|
|
|
|
}
|
|
|
|
p_prefs_closefile ();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* Read preferences */
|
|
|
|
void wmtunlo_read_prefs(void)
|
|
{
|
|
if (p_prefs_openfile (p_getfilename_config(".clay", "wmtunlorc"), P_READ)) {
|
|
|
|
shade_switch = p_prefs_get_int("shade_switch");
|
|
persp_switch = p_prefs_get_int("persp_switch");
|
|
|
|
t_shade_level = p_prefs_get_float("t_shade_level");
|
|
t_persp = p_prefs_get_float("t_persp");
|
|
t_mov_step = p_prefs_get_float("t_mov_step");
|
|
t_rot_step = p_prefs_get_float("t_rot_step");
|
|
|
|
tex_block_w = p_prefs_get_int("tex_block_w");
|
|
tex_block_h = p_prefs_get_int("tex_block_h");
|
|
|
|
t_col_add_R = p_prefs_get_float("t_col_add_R");
|
|
t_col_add_G = p_prefs_get_float("t_col_add_G");
|
|
t_col_add_B = p_prefs_get_float("t_col_add_B");
|
|
|
|
t_col_mul_R = p_prefs_get_float("t_col_mul_R");
|
|
t_col_mul_G = p_prefs_get_float("t_col_mul_G");
|
|
t_col_mul_B = p_prefs_get_float("t_col_mul_B");
|
|
|
|
t_color_1 = p_prefs_get_int("t_color_1") % 255;
|
|
t_color_2 = p_prefs_get_int("t_color_2") % 255;
|
|
|
|
strcpy(ClickCommand1, p_prefs_get_string ("command1"));
|
|
strcpy(ClickCommand2, p_prefs_get_string ("command2"));
|
|
strcpy(ClickCommand3, p_prefs_get_string ("command3"));
|
|
|
|
p_prefs_closefile ();
|
|
|
|
} else {
|
|
|
|
shade_switch = 1;
|
|
persp_switch = 1;
|
|
|
|
t_shade_level = 5.2;
|
|
t_persp = 1000.0;
|
|
t_mov_step = 0.6;
|
|
t_rot_step = 0.3;
|
|
|
|
tex_block_w = 32;
|
|
tex_block_h = 32;
|
|
|
|
t_col_add_R = 24.0;
|
|
t_col_add_G = -12.0;
|
|
t_col_add_B = 55.0;
|
|
|
|
t_col_mul_R = 1.0;
|
|
t_col_mul_G = 1.0;
|
|
t_col_mul_B = 0.0;
|
|
|
|
t_color_1 = 20;
|
|
t_color_2 = 128;
|
|
|
|
strcpy(ClickCommand1, "xlock");
|
|
strcpy(ClickCommand2, "xlock -mode thornbird");
|
|
strcpy(ClickCommand3, "xlock -mode blank");
|
|
|
|
wmtunlo_write_prefs ();
|
|
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
|