Fun with C

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#31 Post by 01micko »

Almost :) ...Virtual only.

The problem is the logic. The clock draw needs it's own 'true' loop for some reason.. but of course that never ends so the next part of the program can't take place. So, I added the XPending() (EDIT: as you did but I shifted the paint() call to before the XPending())call to the true loop, reduced the sleep a bit and it works, but it tends to flicker a bit more. It's taking too long to draw. The clock face is quite complex, figuring out 56 different angles to draw at, plus font characters then the actual hand drawing operation. This (I think) can be sped up if I put the actual face on another surface, however, once the hands are drawn that surface needs to be refreshed. I'll think about that, (as I have done).

Code: Select all

while (1) { 
		paint(cs, width, height, style); 
		while (XPending (dpy)) { 
			XNextEvent(dpy, &e); 
			if (e.type == KeyPress) { 
				char buf[128] = {0}; 
				KeySym keysym; 
				XLookupString(&e.xkey, buf, sizeof(buf), &keysym, NULL); 
				if (keysym == XK_q) { 
				goto finish; 
				} 
			} else if (e.type == ButtonPress) { 
				XSetInputFocus (dpy, win, RevertToNone, CurrentTime); 
			} 
		}
		usleep(200000); /*reduced as Xpending() takes time */
	} 
finish: 
	cairo_surface_destroy(cs); 
	XCloseDisplay(dpy);  
As for the clock error for fatdog rox, maybe the desktop isn't the first child window? I guess I could test for that, one day :) .

I'll also look into XShapeCombineMask().

Image
Last edited by 01micko on Wed 30 Jul 2014, 02:07, edited 2 times in total.
Puppy Linux Blog - contact me for access

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#32 Post by technosaurus »

here is the beginning of object oriented C tutorial using structs and function pointers:

Code: Select all

#include <stdio.h>
/* this is an example how to use structs and function pointers for an imaginary camera API
each camera type can supply its own functions, properties etc... so we need a way to map the functions to our API
*/

/* we have to forward declare the struct due to circular reference */
struct camera_t;


/* functions operate on a single camera struct, modify it directly and return success/failure as int */
typedef int (*Fi)(camera_t *);

/* We'll use these to access functions, insert new ones before NUM_FUNCS */
enum{ NOOP, ZOOM_IN, ZOOM_OUT, ZOOM_STOP, INFRA_ON, INFRA_OFF, NUM_FUNCS};

typedef struct camera_t{
	unsigned properties;
	unsigned action;
	FILE *readbuf; /* using FILE* vs fd for portability ...win32 etc... */
	FILE *writebuf;
	Fi funcs[NUM_FUNCS]; /* note NUM_FUNCS as in previous enum */
}camera_t;

enum{
	zoomCapable = 1,
	zoomingIn = 2,
	zoomingOut = 4,
	infraredCapable = 8,
	infraredOn = 16,
	//.... =32, ...=64 etc...
};//flags to be set in properties

/* provide a noop action for first function and unsupported functions*/
int noop(camera_t cam){return 0;}
//these would be in the camera's header/object included as reference
int startZoomIn(camera_t *cam);//ZOOM_IN
int startZoomOut(camera_t *cam);//ZOOM_OUT
int stopZoom(camera_t *cam);//ZOOM_STOP
int infraOn(camera_t *cam);//INFRA_ON
int infraOff(camera_t *cam);//INFRA_OFF

/* using a macro to initialize a struct directly provides more compact code
   than initializing each member separately in a function and returning it.
*/
#define initCam(name, prop,action,rbuf,wbuf,zin,zout,zstop,ion,ioff) \
    camera_t name = {prop,action,rbuf,wbuf,{noop,zin,zout,zstop,ion,ioff}}

//assign camera's corresponding functions in same order as enum above 
initCam(mycam,zoomCapable|infraredCapable, 0, stdin, stdout, startZoomIn,
         startZoomOut,stopZoom,infraOn,infraOff);

//usage
mycam.funcs[INFRA_ON](&mycam);
/* notice the &, that is because the functions take a pointer to a camera_t struct;
the & give the address of mycam, which is the same as if we set up a pointer to it.
This allows all of our functions to operate on a single instance of camera_t without copying it into and out of functions.
This reduces code size and complexity, while allowing us to use an int return value to indicate error/success
*/

/* more complex usage */
int run(camera_t *cam){
  unsigned action = cam->action; //use a local copy so we can reset .action
  cam->action=0; //reset the action
/* note the  '->' and no '&' now vs. '.' with '&cam'; we are using a pointer to camera_t */
  if (action< NUM_FUNCS) return cam->funcs[action](cam);
  else return -1;
}
while(1){
  if (mycam.action && run(&mycam) == -1)
    printf("error"); /*could add: %d\n", errno); or similar here */
  sleep(1); /* only handle events once per second to reduce cpu usage*/
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#33 Post by jamesbond »

01micko wrote:but it tends to flicker a bit more.
Try this to reduce the flicker:

instead of

Code: Select all

cs = cairo_xlib_surface_create(dpy, win, 
				DefaultVisual(dpy, scr), width, height);
use

Code: Select all

	Pixmap pixmap = XCreatePixmap (dpy, win, width, height, mydepth);
	XFillRectangle (dpy, pixmap, DefaultGC(dpy, scr), 0,0, width, height);
	cs = cairo_xlib_surface_create(dpy, pixmap, 
				DefaultVisual(dpy, scr), width, height);
And after

Code: Select all

paint(cs, width, height, style);
you add

Code: Select all

XCopyArea (dpy, pixmap, win, DefaultGC (dpy, scr), 0,0, width, height, 0,0);
As a downside you'll get black corners around the the clock, but that's one more reason why you should learn XShapeCombineMask :)


EDIT: you can also do this in the "pure cairo" way by using a second cairo surface, like this:

Code: Select all

	cs = cairo_xlib_surface_create(dpy, win, 
				DefaultVisual(dpy, scr), width, height);
	cairo_surface_t *csbuf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);				
	cairo_t *cspaint = cairo_create (cs);
	cairo_set_source_surface (cspaint, csbuf, 0, 0);
and

Code: Select all

		paint(csbuf, width, height, style);
		cairo_paint (cspaint);
Of course, don't mix the Pixmap method and the pure cairo method - use either one :)
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]

mcewanw
Posts: 3169
Joined: Thu 16 Aug 2007, 10:48
Contact:

#34 Post by mcewanw »

darkcity wrote: For anyone wanting to learn this language I'd recommend it.
http://c.learncodethehardway.org/book/
hmmm... It's been about 6 years since I last programmed in C, but I thought I'd take a look at the recommended book as an alternative to my trusty old Kernighan and Dennis Ritchie (K&R) C book (which the author of the above book seems to somewhat despise...). All I can say is that this new book's teaching approach is to start reasonably slow and then, suddenly, jump in the deep end! I imagine 'some' newcomers to C will have a brain explosion (or implosion) when they are suddenly confronted with Ch17 and 18 (they probably won't find ch 15 or 16 particulary easy either, but the killer blow will be ch 17 I think!).

Unfortunately (as far as this recommended book is concerned), I love the K&R style of C programming (which is probably me showing my age), preferring pointer arithmetic to array indexing always, so some of the code style in the book is as painful to me as K&R style is to the author. I haven't read the whole thing yet, so can't comment on his claims that K&R includes a lot of bad code - I can say, however, that K&R includes lots of nice diagrams, which, as far as I'm concerned, nicely explain the subtle differences in how array indexing works compared to using pointers. Perhaps compilers have ironed out the differences nowadays, but still, I like a diagram or two in order to illustrate how C views memory. A picture is indeed worth a thousand words.

I'm not saying this is a bad book, however; for quick learners, who don't mind deep water, it may be very good, but for many newbies I think it could make them feel that C is impossibly hard to learn, which it isn't. Best for such learners, that they stick with the simpler basics first and then try to get their heads round pointers (which aren't so difficult actually, and little diagramatic pictures of 'what's pointing to what' really help), without jumping off the deep end until they are sure they are still afloat...

From memory, what I liked most about the K&R C book, is that it really reinforces how close to UNIX, C is, so after working through the book you really also begin to understand UNIX/Linux at a deeper system level, which leaves you understanding better the relationship between processes and their children and so on. The drawback of K&R may be that it is somewhat dry and technical in style - it hasn't been written to keep the reader amused... and it is now an ancient book of course.

William

EDIT: Actually, the example code in ch 18 is rather nice. The author is clearly very used to object oriented programming and likes C to be molded to mimic that. I like the way he uses compare_cb, via pointers to function to override the actual operation of the function, which is like a form of polymorphism (the actual function used changes depending on whether, sorted-order, reverse order, or strange-order, is passed to the test-sorting routine).
github mcewanw

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#35 Post by technosaurus »

mcewanw wrote:... preferring pointer arithmetic to array indexing always, so some of the code style in the book is as painful to me as K&R style is to the author ...what I liked most about the K&R C book, is that it really reinforces how close to UNIX, C is, so after working through the book you really also begin to understand UNIX/Linux at a deeper system level, which leaves you understanding better the relationship between processes and their children and so on. The drawback of K&R may be that it is somewhat dry and technical in style - it hasn't been written to keep the reader amused... and it is now an ancient book of course.

William

EDIT: Actually, the example code in ch 18 is rather nice. The author is clearly very used to object oriented programming and likes C to be molded to mimic that. I like the way he uses compare_cb, via pointers to function to override the actual operation of the function, which is like a form of polymorphism (the actual function used changes depending on whether, sorted-order, reverse order, or strange-order, is passed to the test-sorting routine).
K&R was written before many of the C standards were implemented, so it was common to use things like:

Code: Select all

void* (*f)()=dlsym(handle, "my_function");
which by C standards breaks about 10 different rules at once but reduces code complexity immensely because it can handle any number of arguments and any return type where the return size is <= the size of void* and get automatically casted. By the standard, one would have to do all kinds of ridiculousness to handle every combination _and_ create a mechanism to know which one to use (libffi does a lot of these or my K&R style example here)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#36 Post by 01micko »

pmck is vastly improved.
  • - more efficient, now the usleep is 950000
    - fixed background artefact issues
    - added antialiasing (YMMV - seems to depend on a lot of things, wm, video driver etc, but I do need to fix up the XRender part)
    - improved desktop detection
    - reduced flicker thanks to jamesbond's pure cairo method plus the efficiency
EDIT: more substantial improvements.
  • - learned that CAIRO_OPERATOR_OVER works well on the pixmap for shaping which vastly improves the rendering on screen
    - fixed a few small bugs
    - every math computation is related directly to the specified size now so that everything scales, including font and clock face markings.
It's pretty much finished now.

https://github.com/01micko/pmck
Last edited by 01micko on Thu 14 Aug 2014, 23:40, edited 1 time in total.
Puppy Linux Blog - contact me for access

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#37 Post by technosaurus »

@micko - do you think that with your new knowledge of xlib, you'd be able to figure out how to wedge in the ability to make jwm tray backgrounds transparent? The traybuttons already copy their colors from the tray, but to make a tray copy any colors from the root window, you have to change the whole opacity, so to be completely tranparent, the buttons would be invisible.

I think the area to start is in tray.c at:

Code: Select all

/** Draw the tray background on a drawable. */
void ClearTrayDrawable(const TrayComponentType *cp)
{
   const Drawable d = cp->pixmap != None ? cp->pixmap : cp->window;
   if(colors[COLOR_TRAY_BG1] == colors[COLOR_TRAY_BG2]) {
      JXSetForeground(display, rootGC, colors[COLOR_TRAY_BG1]);
      JXFillRectangle(display, d, rootGC, 0, 0, cp->width, cp->height);
   } else {
      DrawHorizontalGradient(d, rootGC, colors[COLOR_TRAY_BG1],
                             colors[COLOR_TRAY_BG2], 0, 0,
                             cp->width, cp->height);
   }
}
I think you should be able to check

Code: Select all

//pseudo code
#define COLOR_TRAY_BG_NONE some_value //probably in colors.h
if (colors[COLOR_TRAY_BG1] == COLOR_TRAY_BG_NONE)
   JXCopyArea( a, b, c, d, e, f, g, h, i, j ) //from root window
This has been nagging at me for a while, because that is the only thing stopping from having pseudo desktop icons. (just put a vertical tray at a fixed position with an icon button and a label button) ... discussed in this issue

Well that and tooltips on the tray but not in the menu where they would be useful for more detailed package descriptions. We've always had this amateurish halfway in-between mix of short,long and no descriptions in the menu.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#38 Post by 01micko »

technosaurus wrote:@micko - do you think that with your new knowledge of xlib, you'd be able to figure out how to wedge in the ability to make jwm tray backgrounds transparent?
My understanding of Shape is still in the development stage :) .

That said, I have just forked jwm and will take a look.
Puppy Linux Blog - contact me for access

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#39 Post by technosaurus »

01micko wrote:My understanding of Shape is still in the development stage :) .

That said, I have just forked jwm and will take a look.
Good to hear, I don't think shape will play into it, just {J}XCopyArea()

Here are some little C tricks: (*some of these require std=c99)

Code: Select all

/** If a function calls for a pointer to a struct, you can do this: */
	the_func(&(the_struct_t){.x=7,.a=1,.b=2});
	//Note: struct members can be assigned by name and out of order

/** You can avoid using malloc if the variable is not returned */
	void myfunc(size_t len){ char buf[len]; ... }

/** You can even use a variable length array in a struct */
	struct s { int x; int y; char data[]; };
	//Note: the variable length array must come at the end.

/** You can partially initialize arrays ... even out of order */
	struct{int x,y;}points[4] = {[1].y=10,[3].x=10,[2]={10,10}};
	//Note: all other values are initialized to 0. -> 10x10 box

/** You can use enums to represent numerical values in readable form */
	enum{ NOTHING, MAGIC_WORD, COLOR, ANIMAL, NUMBER_of_ENUMS};
	//Note: if you don't assign specific values, the last enum == count

/** You can use sorted structs to have a binary-searchable map */
	const struct {const char* s; int type;} map[] = {
		{"", NOTHING},
		{"abracadabra", MAGIC_WORD},
		{"blue",COLOR},
		{"cat", ANIMAL},
		{"zoom-wap",MAGIC_WORD}
	}

/** You can write a macro to give you array[] size (not (*) pointers) */
#define arr_sz(x) ((sizeof(x))/(sizeof(x[0])))

/** Binary search is simple, start in the middle and compare:
 *  If they are equal : return your match
 *  If your value is < current : reset your bottom to next index
 *  If your value is > current : reset your top to previous index
 *  Set index ~halfway bottom and top or (top-bottom)/2
 *  If bot > top, then its not found
 *
 * Here is an example using previous enum and map:
 */
int get_type(const char *s){
	int cmp,
		bot=0, //1st element in map[]
		top=arr_sz(map)-1, //last element in map[]
		i=top/2 //~halfway into map[]
	for (;bot<=top;){
		cmp=strcmp(s,map[i].s); //compare input *s to map.s
		if (! cmp) return map[i].type; //match found
		else if (cmp>0) bot=i+1; //set bottom to next string
		else top=i-1; //set top to previous string
		i=(bot+top)/2; //go ~halfway between bot and top
	}
	return NOTHING; //not in map
}

/** To "map" consecutive integers to strings is much simpler */
	const char *enum_strings[]={
		"",			 //NOTHING == 0
		"MAGIC_WORD", //MAGIC_WORD == 1
		"COLOR",		 //COLOR == 2
		"ANIMAL"		 //ANIMAL == 3
	};

/** Now the enum is the index so you can just do this: */
const char *get_enum_string(size_t i){
	return enum_strings[ ( i < NUMBER_of_ENUMS ) ? i : 0 ];
}

/** Function pointers can point to 99% of functions (so long as the
 *  return fits in a void*) if you use: */
	typedef void* (*func_t)();	//Note: this is not C standards,
								//but Posix recommends it for dlsym()
	enum{FOO,BAR,BAZ,EXIT};
	func_t f[4]={myfoo,mybar,mybaz,exit};
	!f[FOO](foo_a) && !f[BAR](bar_b,!0) && !f[BAZ](1,2,3,4) || f[EXIT](0);

/** You can use a union so multiple structs can use the same memory. */
	union{
		uint8_t data[4096]; //4096 is a common PAGESIZE
		struct{uint8_t pad[24];uint32_t magic}myfs;
		struct{uint8_t pad[2048];uint32_t magic}yourfs;
		struct{uint8_t pad[4000];uint32_t magic}anotherfs;
	}myunion;
	//here you can read in a page to myunion.data and access it directly
	//via myunion.myfs.magic or myunion.myfs.magic
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#40 Post by 01micko »

Ages ago, technosaurus wrote:
01micko wrote:My understanding of Shape is still in the development stage :) .

That said, I have just forked jwm and will take a look.
Good to hear, I don't think shape will play into it, just {J}XCopyArea()
Dunno. Haven't got that far into it.. but it is still on the 'to do'
technosaurus wrote:Here are some little C tricks: (*some of these require std=c99)

Code: Select all

...
Thanks. I'm 99% of the time using std=gnu99, which I suppose just adds the _GNU_SOURCE definition?

Anyway, I have been playing with bitmaps (.xbm) and 'coloring' in an attempt to create a light weight set of desktop icons. The code attached is very much a work in progress (as you will see :lol: ). However it was somewhat educational; and the icons do render and expose properly on a JWM desktop with <Backround="image" ... />

Would be nice if I could run this from 1 executable without too much bother. I suppose I could go the 'desktop' route and render each bitmap (pixmap) on a pseudo 'root' window.. dunno yet.

I also have a much, much prettier version using cairo for icons and pango to to get nice text which can convert (almost) any .desktop file (atm supports .svg, .png and .xpm .. and localisation.. at least with latin charsets). But it kind of is reinventing the wheel when ROX does that nicely enough anyway.
Attachments
bittop(2).png
on a real desktop in slacko64
(185.23 KiB) Downloaded 724 times
bittop-2.tar.gz
source, builds 4 execs for 4 icons placed on screen.. kill rox before using!
(4.12 KiB) Downloaded 193 times
bittop(1).png
tahrpup in VM
(31.91 KiB) Downloaded 695 times
Puppy Linux Blog - contact me for access

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#41 Post by 01micko »

And now for something different.. but more of the same (cairo) we have mkwallpaper

Code: Select all

/*
 * 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., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 * (c) Michael Amadio. Gold Coast QLD, Australia 01micko@gmail.com
 */
 
/** This program is designed to be used in Puppy Linux.
 * It is designed to be used in Woof-CE or in a running Puppy as root or
 * an ordinary user.
 */
 
#include <cairo-svg.h>
#include <pango/pangocairo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

#define _GNU_SOURCE
#define PROG "mkwallpaper"
#define THIS_VERSION "0.2"

char out_file[80]; 

void usage(){
	printf("%s-%s\n\n", PROG , THIS_VERSION);
	printf("\tGenerate SVG or PNG Puppy Linux wallpapers. SVG is default.\n\n");
	printf("Usage :\n");
	printf("\t%s [-l, -n, -f, -p, -s, -x, -y, -r, -w, -h]\n", PROG);
	printf("\t-n\t: image name\n");
	printf("\t-l\t: label for an image, up to 100 chars\n");
	printf("\t-f\t: a TTF font family\n");
	printf("\t-p\t: \"png\" or \"svg\" format\n");
	printf("\t-x\t: width of image in pixels\n");
	printf("\t-y\t: height of image in pixel\n");
	printf("\t-z\t: floating point RGB, quoted, "
					"space delimited values for colour (mandatory arg!)\n");
	printf("\t-w\t: \"woof\" FOR WOOF USE ONLY!!!\n");
	printf("\t-h\t: show this help and exit.\n");
	exit (EXIT_SUCCESS);
}

char *get_user_out_file(char *ww){
	char *my_home = getenv("HOME");
	if (strncmp(ww, "woof", 4) == 0) {
		strcpy(out_file, "usr/share/backgrounds"); /*woof only */
	} else if (strcmp(my_home, "/root") == 0) {
		strcpy(out_file, "/usr/share/backgrounds");
	} else {
		sprintf(out_file, "%s/%s", my_home, ".local/share/backgrounds");
	}
	mkdir(out_file, 0755);
	return out_file;
} 

void paint_img (char *label, 
				char *name, 
				char *font, 
				char *form,
				int wdth,
				int hght,
				char *fp_color,
				int f_size,
				char *woofy) {
	char destimg[120];
	
	int msg_len = strlen(label);
	if (msg_len > 20) {
		fprintf(stderr,"\"%s\" is too long!\n", label);
		exit (EXIT_FAILURE);
	}
	if (f_size == 20) f_size = hght / 10;
	
	if (!fp_color) exit (EXIT_FAILURE);
	
	float r, g , b;
	char red[6];
	char green[6];
	char blue[6];
	int len = strlen(fp_color);
	if (len > 31 ) {
		fprintf(stderr,"ERROR: colour argument too long\n");
		exit (EXIT_FAILURE);
	}
	int result = sscanf(fp_color, "%s %s %s", red, green, blue);
	if (result < 3) fprintf(stderr,"ERROR: less than 3 colour aguments!\n");	
	
	r = atof(red);
	g = atof(green);
	b = atof(blue);
	if ((r > 0.801) || (g > 0.801) || (b > 0.801)) {
		fprintf(stderr, "Color values are too high\n");
		exit (EXIT_FAILURE);
	}
	float r1, g1, b1, r2, g2, b2;
	r1 = r; g1 = g; b1 = b;
	r2 = r + 0.2;
	g2 = g + 0.2;
	b2 = b + 0.2;
	
	cairo_surface_t *cs;
	if (!form) strcpy(form, "svg");
	if (strcmp(form, "svg") == 0) {
		sprintf(destimg, "%s/%s.svg", get_user_out_file(woofy), name);
		cs = cairo_svg_surface_create(destimg, wdth, hght);
		
	} else {
		cs = cairo_image_surface_create 
							(CAIRO_FORMAT_ARGB32, wdth, hght);
		sprintf(destimg, "%s/%s.png", get_user_out_file(woofy), name);					
	}
	cairo_t *c;
	c = cairo_create(cs);
		
	cairo_rectangle(c, 0.0, 0.0, wdth, hght);
	cairo_pattern_t *linear = cairo_pattern_create_linear(0, 0, wdth, hght); 
	cairo_pattern_add_color_stop_rgb(linear, 0, r1, g1, b1); 
	cairo_pattern_add_color_stop_rgb(linear, 1, r2, g2, b2);
	cairo_set_source(c, linear);
	cairo_fill(c);
	
	PangoLayout *layout;
	PangoFontDescription *font_description;
	
	font_description = pango_font_description_new ();
	pango_font_description_set_family (font_description, font);
	pango_font_description_set_weight (font_description, PANGO_WEIGHT_BOLD);
	pango_font_description_set_style (font_description, PANGO_STYLE_OBLIQUE);
	pango_font_description_set_absolute_size (font_description, f_size * PANGO_SCALE);
	
	layout = pango_cairo_create_layout (c);
	pango_layout_set_font_description (layout, font_description);
	pango_layout_set_width (layout, wdth / 2 * PANGO_SCALE);
	pango_layout_set_wrap (layout, PANGO_WRAP_WORD);
	pango_layout_set_text (layout, label, -1);
	
	cairo_move_to(c, wdth / 2 , 4 * hght / 6);
	cairo_set_source_rgb(c, 0.1, 0.1, 0.1);
	pango_cairo_show_layout (c, layout);
	
	g_object_unref (layout);
	pango_font_description_free (font_description);
	if (strcmp(form, "png") == 0) {
		cairo_surface_write_to_png (cs, destimg);
	}
	cairo_surface_destroy(cs);	
	cairo_destroy(c);
	printf("image saved to %s\n", destimg);
}

int main(int argc, char **argv) {
	if (argc < 2) {
		usage();
		return 0;
	}
	if (strcmp(argv[1], "-h") == 0) {
		usage();
		return 0;
	}
	
	char *lvalue = "hello mksvg!"; /* the cli string that appears in image */
	char *nvalue = "foo"; /* image name */
	char *fvalue = "Sans"; /* font */
	char *pvalue = "svg";
	char *wvalue = "notwoof"; /* used for woof */
	char *zvalue = NULL; /* fp colour */
	int width = 200; int height = 60;
	int font_size = 20;
	int c;
	while ((c = getopt (argc, argv, "l:n:f:p:x:y:w:z:s::")) != -1) {
		switch (c)
		{
			case 'l':
				lvalue = optarg;
				break;
			case 'n':
				nvalue = optarg;
				break;
			case 'f':
				fvalue = optarg;
				break;
			case 'p':
				pvalue = optarg;
				break;
			case 'x':
				width = atoi(optarg);
				break;
			case 'y':
				height = atoi(optarg);
				break;
			case 'w':
				wvalue = optarg;
				break;
			case 'z':
				zvalue = optarg;
				break;
			case 's':
				font_size = atoi(optarg);
				break;
			default:
				usage();
		}
	}
	if (zvalue == NULL) {
		fprintf(stderr, "You must have 3 floating point value argument \"-z\"\n");
		usage();
		return 1;
	}
	paint_img(lvalue, nvalue, fvalue, pvalue,
						width, height, zvalue, font_size, wvalue);
	return 0;
}
..and a Makefile

Code: Select all

CC=gcc
#LIBDIR=/usr/lib64
LIBDIR=/usr/lib
CFLAGS=-Wall -pedantic -std=gnu99 -g -I/usr/include `pkg-config --libs --cflags pangocairo`
LDFLAGS=-Wall -g `pkg-config --libs pangocairo` -L$(LIBDIR)

all: mkwallpaper

mkwallpaper: mkwallpaper.o
	$(CC) -o $@ $^ $(LDFLAGS)

mkwallpaper.o: mkwallpaper.c
	$(CC) -o $@ $(CFLAGS) -c $^

clean:
	-rm -f *.o mkwallpaper
It's just a very simple program designed for lightweight SVG wallpapers to be produced while woofing up a new puppy. Everyone changes the wallpaper anyway!
Puppy Linux Blog - contact me for access

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

A replacement for the awful 'gtkdialog-splash'

#42 Post by 01micko »

Here is one for you all. It's not a drop in replacement for 'gtkdialog-splash' (that damned thing I started with quickpet in Lucid) but with a simple wrapper script it would/could/should be.

I'll attach the source (see EDIT below) and a screeny.

I call it gtksplash ... :lol:

It's written in C and mostly with glib (see the comments). IMHO, glib has certain short comings and some gdk/gtk stuff isn't very well documented.

Have fun!

EDIT: attachment removed .. see next page
Attachments
splash.png
scales icons nicely (this is a 150x150 image scaled to 32x32)
(15.89 KiB) Downloaded 302 times
Last edited by 01micko on Wed 25 Nov 2015, 07:00, edited 1 time in total.
Puppy Linux Blog - contact me for access

User avatar
L18L
Posts: 3479
Joined: Sat 19 Jun 2010, 18:56
Location: www.eussenheim.de/

Re: A replacement for the awful 'gtkdialog-splash'

#43 Post by L18L »

01micko wrote:Have fun!

Code: Select all

# ./gtksplash -s "Thank you" -i gtk-ok -c "#ffffcc" -f "Sans bold italic 48"
Attachments
gtksplash.png
(20.1 KiB) Downloaded 352 times

step
Posts: 1349
Joined: Fri 04 May 2012, 11:20

#44 Post by step »

Nice, thank you!
[url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Fatdog64-810[/url]|[url=http://goo.gl/hqZtiB]+Packages[/url]|[url=http://goo.gl/6dbEzT]Kodi[/url]|[url=http://goo.gl/JQC4Vz]gtkmenuplus[/url]

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#45 Post by 01micko »

@step, @L18L

Glad you like :)

L18L .. you have exposed a shortcoming. When using a large font the icon needs to be scaled larger with a short string. There are limitations with stock icons, but certainly not with svg.

The largest stock icon is the enum GTK_ICON_SIZE_DIALOG (6, which is 48x48). I could add to the test a simple reliance on font size.

What do you think? Own thread for this one?

Cheers
Puppy Linux Blog - contact me for access

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#46 Post by 01micko »

version 0.7

- added more sane ( maybe :roll: ) icon scaling
- function that detects font size and errors on stupid input
- hopefully more robust

Screeny says "Happy new year" in Chinese Traditional (maybe, confirmation needed).

Code: Select all

# ./gtksplash -t 50 -s"新年快樂
Attachments
splashes.png
(103.14 KiB) Downloaded 359 times
gtksplash-0.7.tar.bz2
(3.68 KiB) Downloaded 106 times
Puppy Linux Blog - contact me for access

User avatar
L18L
Posts: 3479
Joined: Sat 19 Jun 2010, 18:56
Location: www.eussenheim.de/

Re: A replacement for the awful 'gtkdialog-splash'

#47 Post by L18L »

01micko wrote:.. you have exposed a shortcoming.
That was not my intention.
But another shortcoming would be background colour (also transparent if possible).
01micko wrote:When using a large font the icon needs to be scaled larger with a short string. There are limitations with stock icons, but certainly not with svg.

The largest stock icon is the enum GTK_ICON_SIZE_DIALOG (6, which is 48x48). I could add to the test a simple reliance on font size.
... already done by you.
Thank you also for never forgetting other languages.
01micko wrote:What do you think? Own thread for this one?
Yes, own thread is useful I think.

User avatar
Geoffrey
Posts: 2355
Joined: Sun 30 May 2010, 08:42
Location: Queensland

#48 Post by Geoffrey »

Nice one Mick, skip taskbar?
[b]Carolina:[/b] [url=http://smokey01.com/carolina/pages/recent-repo.html]Recent Repository Additions[/url]
[img]https://dl.dropboxusercontent.com/s/ahfade8q4def1lq/signbot.gif[/img]

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#49 Post by 01micko »

Geoffrey wrote:Nice one Mick, skip taskbar?
Darn! I remembered that in an early dev version!

Here's a makeshift patch until I start a new thread

Code: Select all

diff -rupN gtksplash-0.7/gtksplash.c gtksplash-0.8/gtksplash.c
--- gtksplash-0.7/gtksplash.c	2015-11-25 12:51:31.185115091 +1000
+++ gtksplash-0.8/gtksplash.c	2015-11-25 20:49:51.236969669 +1000
@@ -14,7 +14,7 @@
 #include <limits.h>
 #include <signal.h>
 
-#define _VERSION "0.7"
+#define _VERSION "0.8"
 #define _PROGNAME "gtksplash" 
 
 /* declarations */
@@ -148,6 +148,7 @@ static void display_window(gchar *mystri
 		gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, padding);
 		gtk_widget_show(label);
 	}
+	gtk_window_set_skip_taskbar_hint(GTK_WINDOW(window), TRUE);
 	gtk_widget_show(window);
 }
 /* usage */
------------------------
L18L wrote:But another shortcoming would be background colour (also transparent if possible).
I wont say it's impossible, but it certainly is not easy. Are you thinking partial or full transparency? While not a priority I will consider.
L18L wrote:Yes, own thread is useful I think.
Me too. Will be soon.

Cheers!
Puppy Linux Blog - contact me for access

User avatar
L18L
Posts: 3479
Joined: Sat 19 Jun 2010, 18:56
Location: www.eussenheim.de/

gtksplash

#50 Post by L18L »

01micko wrote:
L18L wrote:But another shortcoming would be background colour (also transparent if possible).
I wont say it's impossible, but it certainly is not easy. Are you thinking partial or full transparency? While not a priority I will consider.
First idea is not always best idea.

gtksplash's job is to alert users.

"define also background when defining font color" is good practise.
So getting good contrast is possible.
But transparency is really bad as nobody can know the actual background,

Thus forget about transparency for gtksplash please.

Post Reply