LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This 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


Reply
  Search this Thread
Old 05-08-2016, 04:39 AM   #1
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
xmountains custom colors


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???

any help appreciated!
 
Old 05-08-2016, 10:44 AM   #2
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
Looks like the colors are defined in "artist.c":
Code:
  /* band base colours as RGB fractions */
  rb[0] = 0.450; rb[1] = 0.600; rb[2] = 1.000;
  gb[0] = 0.500; gb[1] = 0.600; gb[2] = 1.000;
  bb[0] = 0.333; bb[1] = 0.000; bb[2] = 1.000;

  /* {{{   black */
  red[BLACK]       = 0;
  green[BLACK]     = 0;
  blue[BLACK]      = 0;
  /* }}} */
  /* {{{   white */
  red[WHITE]       = COL_RANGE;
  green[WHITE]     = COL_RANGE;
  blue[WHITE]      = COL_RANGE;
  /* }}} */
  /* {{{   sky*/
  red[SKY]         = 0.404*COL_RANGE;
  green[SKY]       = 0.588*COL_RANGE;
  blue[SKY]        = COL_RANGE;
  /* }}} */
  /* {{{   sea (lit) */
  red[SEA_LIT]     = 0;
  green[SEA_LIT]   = 0.500*COL_RANGE;
  blue[SEA_LIT]    = 0.700*COL_RANGE;
  /* }}} */
  /* {{{   sea (unlit)*/
  red[SEA_UNLIT]   = 0;
  green[SEA_UNLIT] = ((g.ambient+(g.vfract/(1.0+g.vfract)))*0.500)*COL_RANGE;
  blue[SEA_UNLIT]  = ((g.ambient+(g.vfract/(1.0+g.vfract)))*0.700)*COL_RANGE;
  /* }}} */

For example if you want a red sky, make the following change:
Code:
  red[SKY]         = COL_RANGE;
  green[SKY]       = 0;
  blue[SKY]        = 0;
HTH
 
Old 05-09-2016, 12:32 AM   #3
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872

Original Poster
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
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.

Last edited by ondoho; 05-09-2016 at 12:37 AM.
 
Old 05-14-2016, 02:41 PM   #4
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872

Original Poster
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
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...


https://github.com/ohnonot/xmountaincolors

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.

and all other critique is also very welcome.
 
1 members found this post helpful.
Old 05-23-2016, 03:37 PM   #5
norobro
Member
 
Registered: Feb 2006
Distribution: Debian Sid
Posts: 792

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
Quote:
Originally Posted by ondoho View Post
i'm actually pretty effing proud with myself . . .
You should be. Nice work.
 
1 members found this post helpful.
Old 06-21-2018, 08:04 PM   #6
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872

Original Poster
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
I have moved all my repositories to https://framagit.org/ohnonot and https://notabug.org/ohnonot
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Vivacious Colors – Best Colors Icon Suite for Ubuntu/Mint LXer Syndicated Linux News 0 04-30-2016 01:21 AM
Custom Colors for CLI slack_ Linux - Software 4 02-26-2014 09:14 PM
LXer: Midnight Commander Custom Interface Colors LXer Syndicated Linux News 0 12-29-2013 10:03 PM
custom background and colors for rhgb steveheflin Linux - Kernel 2 06-11-2011 10:58 AM
Changing text colors in OpenOffice.org to custom html (hex) aldimeneira Linux - Software 0 08-24-2006 12:40 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 12:57 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration