Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
yes, xmountains still works fine and creates nice graphics on my desktop.
however, i would like to change the default colors it uses.
there's no options for this in "man xmountains".
i managed to grab the source code.
it compiles nicely and quickly on my system.
i would like to change the source to use some custom colors (hardcoded or preferably from a file).
so i did a "grep -i color *" and it seems the relevant file is X_graphics.c.
i don't know where to go from there - it seems to be getting the colors from some default colormap. how can i change this?
here's the file in its entirety (but i'm not 100% sure it's the only relevant code for my desires):
Code:
#include <stdio.h>
#include <string.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<X11/Xatom.h>
# define VROOT /* always do this */
#ifdef VROOT
#include"vroot.h"
#endif
#include "paint.h"
char X_graphics_Id[]="$Id: X_graphics.c,v 1.26 2009/08/28 09:09:17 spb Exp $";
char *display=NULL; /* name of display to open, NULL for default */
char *geom=NULL; /* geometry of window, NULL for default */
Atom wm_protocols;
Atom wm_delete_window;
#ifndef FALSE
#define TRUE 1
#define FALSE 0
#endif
int quit_xmount=FALSE;
Display *dpy;
int screen;
unsigned int graph_width;
unsigned int graph_height;
Window parent, win, root;
int use_root=FALSE;
int do_clear=FALSE;
int pixmap_installed=FALSE;
int swosh=FALSE;
/* plot history */
int plot_x, plot_y1, plot_y2;
unsigned long plot_col;
int plot_saved=FALSE;
#include <X11/bitmaps/gray>
Pixmap stip;
unsigned int depth=0;
GC gc;
Pixmap pix;
Pixmap bg_pix;
Colormap map, defaultmap;
XColor *table=NULL;
void zap_events();
void finish_graphics();
Graph g={
1024,
768,
0,
0,
0.3,
1.0,
0.3,
0.6,
2.5,
4.0,
(40.0 * PI)/180.0,
0.0,
0.5,
0.0,
0.6,
DEF_COL,
60,
10,
2,
FALSE,
TRUE,
20,
0,
0
};
void finish_artist();
/*{{{void zap_events(int snooze)*/
void zap_events(snooze)
int snooze;
{
XEvent event;
XExposeEvent *expose = (XExposeEvent *)&event;
int exw, exh;
while( XPending(dpy) ){
XNextEvent(dpy, &event);
switch(event.type) {
case ClientMessage:
if (event.xclient.message_type == wm_protocols &&
event.xclient.data.l[0] == wm_delete_window) {
quit_xmount=TRUE;
}
break;
case ButtonPress:
break;
case ButtonRelease:
quit_xmount=TRUE;
break;
case Expose:
if( (expose->x < graph_width) && (expose->y < graph_height))
{
if( (expose->x + expose->width) > graph_width)
{
exw=graph_width - expose->x;
}else{
exw = expose->width;
}
if( (expose->y + expose->height) > graph_height)
{
exh=graph_height - expose->y;
}else{
exh = expose->height;
}
if(g.repeat < 0)
{
XCopyArea(dpy, pix, win, gc, expose->x - g.repeat, expose->y,
exw, exh,
expose->x,expose->y);
}
else
{
XCopyArea(dpy,pix,win,gc,expose->x,expose->y,
exw,exh,
expose->x,expose->y);
}
}
break;
default:
fprintf(stderr,"xmountains: unrecognized event %d\n",event.type);
/* XCloseDisplay(dpy);
* exit(1);
*/
break;
}
}
if( quit_xmount )
{
finish_graphics();
finish_artist();
exit(0);
}
}
/*}}}*/
/*{{{void finish_graphics()*/
void finish_graphics()
{
unsigned long attmask;
XSetWindowAttributes attributes;
int x,y;
unsigned int border;
int count;
XFreePixmap(dpy,pix);
XFreeGC(dpy,gc);
XFreePixmap(dpy,stip);
/* reset things if this was the root window. */
if( use_root )
{
if( pixmap_installed && do_clear )
{
/* restore default pixmap for the root window */
XSetWindowBackgroundPixmap(dpy,win,ParentRelative);
XClearWindow(dpy,win);
}else{
XGetGeometry(dpy,win,&root,&x,&y,&graph_width,&graph_height,&border,&depth);
XClearArea(dpy,win,0,0,graph_width,graph_height,FALSE);
}
if( map != defaultmap )
{
attmask = 0;
attmask |= CWColormap;
attributes.colormap = defaultmap;
XChangeWindowAttributes(dpy,win,attmask,&attributes);
}
}
if( map != defaultmap )
{
XFreeColormap(dpy, map );
}
if((count = XPending(dpy)))
{
fprintf(stderr,"WARNING: %d events still pending\n",count);
}
XCloseDisplay(dpy);
}
/*}}}*/
/*{{{void blank_region(lx,ly,ux,uy)*/
void blank_region(lx,ly,ux,uy)
int lx,ly,ux,uy;
{
if( depth < 4 )
{
/* use a textured gray sky on monochrome displays
* we may need this on any low-depth display
*/
XSetForeground(dpy,gc,WhitePixel(dpy,screen));
XSetFillStyle(dpy,gc,FillOpaqueStippled);
XFillRectangle(dpy,pix,gc,lx,ly,ux,uy);
XSetFillStyle(dpy,gc,FillSolid);
}else{
XSetForeground(dpy,gc,table[SKY].pixel);
XFillRectangle(dpy,pix,gc,lx,ly,ux,uy);
}
}
/*}}}*/
/*{{{void blank_col( pos )*/
void blank_col( pos )
int pos;
{
blank_region(pos,0,pos,graph_height);
}
/*}}}*/
/*{{{void init_graphics( ... )*/
void init_graphics( want_use_root, use_window, use_background, want_clear,gptr,red,green,blue )
int want_use_root; /* display on the root window */
Window use_window; /* display on external window */
int use_background; /* install the pixmap as the background-pixmap */
int want_clear;
Graph *gptr;
Gun *red;
Gun *green;
Gun *blue;
{
/*{{{defs*/
Visual *vis;
int x=0;
int y=0;
int gbits=0;
unsigned long attmask;
XSetWindowAttributes attributes;
char * winname="Xmountains";
XTextProperty textprop;
unsigned int border;
unsigned long gcvmask;
XGCValues gcv;
XWindowAttributes xgwa;
int i;
int newmap=FALSE;
/*}}}*/
if (use_window) use_root = 0;
do_clear = want_clear;
use_root = want_use_root;
pixmap_installed = use_background;
graph_width = gptr->graph_width;
graph_height = gptr->graph_height;
/*{{{open display*/
dpy = XOpenDisplay(display);
if( ! dpy )
{
fprintf(stderr,"failed to open display\n");
exit(1);
}
screen = DefaultScreen(dpy);
parent = (use_window ? use_window : RootWindow(dpy, screen));
/*}}}*/
/*{{{find appropriate vis*/
/* map=defaultmap=DefaultColormap(dpy,screen); */
XGetWindowAttributes (dpy, parent, &xgwa);
map=defaultmap=xgwa.colormap;
vis = DefaultVisual(dpy,screen);
depth = DefaultDepth(dpy,screen);
/*}}}*/
/*{{{set colormap*/
table = (XColor *)malloc(gptr->n_col * sizeof(XColor));
if( NULL == table )
{
fprintf(stderr,"malloc failed for colour table\n");
exit(1);
}
for(i = 0; i < gptr->n_col; i++)
{
table[i].red = red[i];
table[i].green = green[i];
table[i].blue = blue[i];
while( ! XAllocColor(dpy,map,table+i) )
{
if( newmap ){
fprintf(stderr,"failed to allocate colour %d\n",i);
XCloseDisplay(dpy);
exit(1);
}else{
map = XCopyColormapAndFree(dpy,map);
newmap=TRUE;
}
}
}
/*}}}*/
/*{{{create window*/
attmask = 0;
if( use_root || use_window )
{
win = (use_window ? use_window : parent);
if( ! use_background )
{
attmask |= CWEventMask;
attributes.event_mask = ExposureMask; /* catch expose events */
}
attmask |= CWColormap;
attributes.colormap = map;
XChangeWindowAttributes(dpy,win,attmask,&attributes);
}else{
if( geom )
{
gbits =XParseGeometry(geom,&x,&y,&graph_width,&graph_height);
if((gbits & XValue) && (gbits & XNegative))
{
x += DisplayWidth(dpy,screen) - graph_width;
}
if((gbits & YValue) && (gbits & YNegative))
{
y += DisplayHeight(dpy,screen) - graph_height;
}
}
attmask |= CWEventMask;
if( ! use_background )
{
attributes.event_mask = ButtonPressMask|ButtonReleaseMask|ExposureMask;
}else{
attributes.event_mask = ButtonPressMask|ButtonReleaseMask;
}
attmask |= CWBackPixel;
attributes.background_pixel = BlackPixel(dpy,screen);
attmask |= CWBackingStore;
attributes.backing_store = NotUseful;
attmask |= CWColormap;
attributes.colormap = map;
win = XCreateWindow(dpy,parent,x,y,graph_width,graph_height,0,
depth,InputOutput,vis,attmask,&attributes);
/* Setup for ICCCM delete window. */
wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", False);
wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
(void) XSetWMProtocols (dpy, win, &wm_delete_window, 1);
textprop.value = (unsigned char *) winname;
textprop.encoding = XA_STRING;
textprop.format = 8;
textprop.nitems = strlen(winname);
XSetWMName(dpy,win,&textprop);
}
/*}}}*/
/*{{{create pixmap*/
XGetGeometry(dpy,win,&root,&x,&y,&graph_width,&graph_height,&border,&depth);
stip = XCreateBitmapFromData(dpy,win,gray_bits,gray_width,gray_height);
gcvmask = 0;
gcvmask |= GCForeground;
gcv.foreground = WhitePixel(dpy,screen);
gcvmask |= GCBackground;
gcv.background = BlackPixel(dpy,screen);
gcvmask |= GCGraphicsExposures;
gcv.graphics_exposures = FALSE;
gcvmask |= GCStipple;
gcv.stipple = stip;
gcvmask |= GCFillStyle;
gcv.fill_style = FillSolid;
gcv.graphics_exposures = FALSE;
gc = XCreateGC(dpy,win,gcvmask,&gcv);
/* if we are going to install this as a root pixmap, throw away
* the old one FIRST. this reduces fragmentation
*/
if( use_background && (use_root || use_window))
{
XSetWindowBackgroundPixmap(dpy,win,None);
}
if( use_root )
{
/* in case of virtual window manager set to size of display */
/* This is bogus -- always obey the size of the window itself */
/* graph_width = DisplayWidth(dpy,screen); */
/* graph_height = DisplayHeight(dpy,screen); */
}
if(swosh)
{
if(gptr->repeat < 0)
{
gptr->pixmap_width = graph_width - gptr->repeat;
bg_pix = XCreatePixmap(dpy, win, graph_width, graph_height, depth);
}
else
{
if(gptr->repeat == 0)
{
gptr->repeat = graph_width;
}
gptr->pixmap_width = graph_width + gptr->repeat;
}
}
else
{
gptr->pixmap_width = graph_width;
}
pix = XCreatePixmap(dpy, win, gptr->pixmap_width, graph_height, depth);
/*}}}*/
blank_region(0, 0, gptr->pixmap_width, graph_height);
if( use_background )
{
XSetWindowBackgroundPixmap(dpy,win,pix);
}
if( ! use_root )
{
XMapWindow(dpy, win );
}
XClearWindow(dpy,win);
zap_events(0);
gptr->graph_width = graph_width;
gptr->graph_height = graph_height;
}
/*}}}*/
/*{{{void scroll_screen( int dist )*/
void scroll_screen( dist )
int dist;
{
int reverse=FALSE;
if( dist < 0 )
{
dist = -dist;
reverse=TRUE;
}
/* scroll the pixmap */
if( dist > g.pixmap_width )
{
dist = g.pixmap_width;
}
if( reverse )
{
/* copy the data */
XCopyArea(dpy, pix, pix, gc, 0, 0, g.pixmap_width - dist, graph_height, dist, 0);
/* blank new region */
blank_region(0,0,dist,graph_height);
}else{
/* copy the data */
XCopyArea(dpy, pix, pix, gc, dist, 0, g.pixmap_width - dist, graph_height, 0, 0);
/* blank new region */
blank_region(g.pixmap_width - dist, 0, dist, graph_height);
}
/* update the window to match */
if( pixmap_installed )
{
/* this line never seems to be needed on any system I know about
* but the manual says an X server
* may make a copy of a background pixmap
* so in principle we should re-install.
*/
XSetWindowBackgroundPixmap(dpy,win,None);
if(swosh && reverse)
{
XCopyArea(dpy, pix, bg_pix, gc, dist, 0, graph_width, graph_height, 0, 0);
XSetWindowBackgroundPixmap(dpy, win, bg_pix);
}
else
{
XSetWindowBackgroundPixmap(dpy,win,pix);
}
XClearWindow(dpy,win);
}else{
if(reverse)
{
XCopyArea(dpy, pix, win, gc, dist, 0, graph_width, graph_height, 0, 0);
}
else
{
XCopyArea(dpy, pix, win, gc, 0, 0, graph_width, graph_height, 0, 0);
}
}
}
/*}}}*/
/*{{{void plot_pixel( int x, int y, Gun value )*/
void plot_pixel( x, y, value )
int x;
int y;
Gun value;
{
int do_draw, draw_x, draw_y1, draw_y2;
unsigned long draw_colour;
/* if x is negative this means flush the stored request */
if(! plot_saved) /* no stored values */
{
plot_x = x;
plot_y1=plot_y2 = y;
plot_col=table[value].pixel;
do_draw=FALSE;
plot_saved = (x >=0);
}else{
if( x < 0 ) /* requesting a flush */
{
draw_x=plot_x;
draw_y1=plot_y1;
draw_y2=plot_y2;
draw_colour = plot_col;
plot_saved=FALSE;
do_draw=TRUE;
}else{ /* plot request with saved value */
if( (x==plot_x) && (plot_col == table[value].pixel)) /* add to line */
{
if(y<plot_y1) plot_y1=y;
if(y>plot_y2) plot_y2=y;
do_draw=FALSE;
}else{
draw_x=plot_x;
draw_y1=plot_y1;
draw_y2=plot_y2;
draw_colour=plot_col;
do_draw=TRUE;
plot_x=x;
plot_y1=plot_y2=y;
plot_col=table[value].pixel;
}
}
}
if( do_draw )
{
XSetForeground(dpy,gc,draw_colour);
if( draw_y1 == draw_y2 )
{
XDrawPoint(dpy,pix,gc,draw_x,draw_y1);
}else{
XDrawLine(dpy,pix,gc,draw_x,draw_y1,draw_x,draw_y2);
}
}
}
/*}}}*/
/*{{{void flush_region(int x, int y, int w, int h)*/
void flush_region( x, y, w, h)
int x;
int y;
int w;
int h;
{
/* flush outstanding plots */
plot_pixel(-1,0,0);
if(!swosh)
{
XCopyArea(dpy,pix,win,gc,x,y,w,h,x,y);
}
}
/*}}}*/
i don't code in C at all, and esp. the X libraries are a huge mistery to me (i did try once before).
or maybe i don't have to change the program at all, but X can provide a different default colormap???
thanks a lot!
i've been playing with this for a while now.
fortunately it compiles very quickly, so i can test the looks of different color combinations (monochrome example).
ultimately, i would like the program to read these options (the float values between 0 and 1, 24 of them altogether) from a file.
i guess option parsing happens in xmountains.c.
but i have no clue how i can make xmountains.c parse a file (i think 24 color values is a bit too much for the command line) or how i could pass the values on to artist.c.
i know my way around a shell script, but C is unknown to me.
would someone care to lend a hand?
edit:
hmmm, maybe option parsing is not necessary for that.
maybe "artist.c" itself could look for a file in an appropriate location and format, and if found, assign these values, and if not, use default values.
yes, i'm aware that i was basically asking for a handout there.
but hey, i got this!
i'm actually pretty effing proud with myself because it's the first time i succeeded doing some real coding in C, that actually results in a working program...
it uses libconfig to parse a config file.
the config file format is a little too complex for the task.
but really i'd like to ask if someone could have a look at the code changes and tell me if there's some crass mistakes in there.
i prepared a diff to the original xmountains.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.