dockapps/wmtunlo/wmtunlo.c
2017-02-21 11:15:02 +00:00

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 ();
}
}
/*----------------------------------------------------------------------*/