Fun with C

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#21 Post by jamesbond »

My entry: Xannotate, a desktop annotation tool.

EDIT: add screenshot.

EDIT: Version 2014-07-27 now supports three pens, eraser, and support for alpha transparency (faster!) if you run a compositing manager (xcompmgr, compton, or kwin). Still works even if you don't have them.

Draw with left-button, erase with right-button. Shift-left-click changes pens. 'Pause' to enter/leave drawing mode, Shift-Pause to show/hide drawing, Ctrl-Pause to clear drawing and start over, Alt-Shift-Pause to capture a screenshot (in PNG format, with or without your drawing in it). Ctrl-Shift-Pause to exit.

And you can change "Pause" to something else.

Depends only on Xlib (libX11, libXext, libXrender) and pnglite which is included.
Attachments
xannotate00000.png
The annotation was done directly on screen, not in mtpaint
(43.07 KiB) Downloaded 689 times
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]

User avatar
Ted Dog
Posts: 3965
Joined: Wed 14 Sep 2005, 02:35
Location: Heart of Texas

#22 Post by Ted Dog »

JB how are you capturing keypresses would same be used for onscreen keyboard under fatdog64 and ARM? :D
I keep bringing this up because it has halted the project at a year now. I am having the yearly visit with the Dr. next week. She moved on and had most of our ideas done in window tablets since then. I posted a link to the news story ( That should have been a show with Fatdog !!) :wink:

User avatar
8-bit
Posts: 3406
Joined: Wed 04 Apr 2007, 03:37
Location: Oregon

#23 Post by 8-bit »

In writing something in C, sometimes one gets carried away in writing the code and fails to add sufficient comment sections to the code to explain what a section of the code is supposed to do.
And later, without comments in the code, one may go back to code he/she has written and be at a loss as to trying to make sense of it.
So with any C code, I recommend heavy commenting.
It only increases the source code file size and and does not increase the size of the compiled result.
Also, it helps others in understanding what the code does.

And keep in mind that C programmers may not have the level of experience you have. So cryptic comments will not help.

amigo
Posts: 2629
Joined: Mon 02 Apr 2007, 06:52

#24 Post by amigo »

I think programmers should spend their first five years only learning to write good comments... LOL

User avatar
Ted Dog
Posts: 3965
Joined: Wed 14 Sep 2005, 02:35
Location: Heart of Texas

#25 Post by Ted Dog »

8-bit wrote:In writing something in C, sometimes one gets carried away in writing the code and fails to add sufficient comment sections to the code to explain what a section of the code is supposed to do.
And later, without comments in the code, one may go back to code he/she has written and be at a loss as to trying to make sense of it.
So with any C code, I recommend heavy commenting.
It only increases the source code file size and and does not increase the size of the compiled result.
Also, it helps others in understanding what the code does.

And keep in mind that C programmers may not have the level of experience you have. So cryptic comments will not help.
I disagree. heavily commented code should be avoided to much cludder. Take a look at BKs scripts. Impossible to follow due to curtains of comments. On the other hand look and Kirks and JBs just enough at the key points of flow to speed understanding.
I followed a winner of the C http://www0.us.ioccc.org/
http://blog.aerojockey.com/post/iocccsim

in a job and ahhhhhh the horror. I took a c test that used the winners of that contest to get a job. I SO RAILED AGAINST that as a testing criteria I even correctly pointed out Carl had gave the interview the idea to use this as a C skill test, AND I WOULD NEVER SUBJECT ANYONE TO SUCH A NIGHTMARE, I do not justify my job security to code obfuscation. Got the job offer but refused ( second time working after Carl I learned my lession )

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

#26 Post by jamesbond »

Ted Dog wrote:JB how are you capturing keypresses would same be used for onscreen keyboard under fatdog64 and ARM? :D
I keep bringing this up because it has halted the project at a year now. I am having the yearly visit with the Dr. next week. She moved on and had most of our ideas done in window tablets since then. I posted a link to the news story ( That should have been a show with Fatdog !!) :wink:
xvkbd should have worked. I remember I tested it and it did. I'm not too confident of matchbox_keyboard. Anyway, the way I capture the keyboard is XGrabKey - every X-based "hotkey" manager would do it that way, nothing special.

I have another entry for this: Xscreenshot, a simple program to take screenshot of selected area of the desktop. Its specialty: you can use it to quickly take successive screenshots. Especially useful when taking screenshot for documentation. Saves to PNG file. Depends only on Xlib.

xannotate is 22K, xscreenshot is 17K. This is on x86_64; I'm sure it is smaller on x86.

Enjoy.

From the readme:
README wrote:xscreenshot is a simple program to take screenshot of your desktop.

You can run it to take a single screenshot, or run it in multiple-shots mode.

The single-shot mode is meant to be used with other hotkey programs
(such as xbindkeys). In this mode, once you have taken your screenshot
it will exit. This is the default mode.

In multiple-shots mode, xscreenshot will run until you tell it to exit.
You can toggle between normal mode, or screenshot taking mode.
In normal mode, the mouse can be used as normal (hence the name).
In screenshot mode, you can take multiple screenshots, one after another.

The screenshot is saved as PNG file.

Mouse buttons
-------------
Left-click: press to start selection, move to choose, release to take a shot.
Right-click:
- if pressed during active selection (that is, when left-button is pressed too):
cancel selection, and you can start over.
- if pressed when there is no active selection:
- in single-shot mode, xscreenshot will exit
- in multiple-shot mode: no effect

Keys usage
----------
Hotkey - toggle screenshot/normal mode
Ctrl-Shift-hotkey - terminate xscreenshot
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]

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

#27 Post by 01micko »

More xlib/cairo fun ... I really should learn xcb next as xlib can suck :o

pmck

Compiled on 64 it's 20k stripped. Slightly less on x86.
readme wrote:pmck
====

a poor man's clock

This is a simple analog clock based on xlib and cairo.

This is not meant for production systems as it has bugs and was written just as
a proof of concept.

Build
-----
Just run 'make' and install the pmck the binary in your path. Optionally,
install the pmckrc file to $HOME/.config/ and edit to your preferences.

Usage
-----
Just run 'pmck' from the command line, it needs no options. It will read an rc file
in $HOME/.config/pmckrc to set different features. There is an example rc file
provided. This should be self explanatory. You can set the size, background
and foreground colours and the style, 2 to choose from. You can autostart it if
you wish. See your distro's documentation for this feature.

On some window managers the root window is not the desktop window. In the case
of ROX-Filer pinboard this is easily overcome by finding the child window which
is "ROX-Pinboard", which in most cases is the very first child. However, in the
case of XFCE I had trouble coding the correct window so added 1 single option to the
command line; the desktop window ID which can be found by running "xwininfo" and
clicking on a blank part of the desktop. The string will be a hex value something
like "0xae44010". Just type (or script) "pmck $hex_value_here". This should work
with any other WM/DE also as it overrides the internal algorithm.

Bugs
----
- must quit with CTRL-C or kill, there is code block supposed to quit with 'q'.. :(
- redraws forever, so may use too much CPU and eventually memory
- may run 1 or 2 seconds behind system time.
- need a click on desktop to display (rox bug - FIXED)
- some window managers may need the the window on top for the clock to display
- can flicker at times of heavy load or on slow machines
- a compositor such as xcompmgr is needed so artefacts do not display under clockface
- at larger sizes the second hand may flicker or disappear
Free virtual beer/coffee/other beverage for the one who solves the quit bug!
Puppy Linux Blog - contact me for access

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

#28 Post by technosaurus »

maybe try

Code: Select all

	while (1) {
		XNextEvent(dpy, &e);
		if(e.type == Expose && e.xexpose.count < 1) {
			//while (1) {
				paint(cs, width, height, style);
			//	usleep(500000);
			//}

		} 
		else if (e.type == KeyPress) {
			char buf[128] = {0};
			KeySym keysym;
			XLookupString(&e.xkey, buf, sizeof buf, &keysym, NULL);
			if (keysym == XK_q) {
				break;
			}
		}
		usleep(500000); //moved here for 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].

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

#29 Post by 01micko »

Nope. Clock doesn't redraw and it doesn't quit. Sorry, no chocolates.
Puppy Linux Blog - contact me for access

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

#30 Post by jamesbond »

Make sure you prepare plenty of beers and chocolates :lol: Better make it real not virtual :lol: :lol:

change

Code: Select all

XSelectInput(dpy, win, ExposureMask|KeyPressMask);
to

Code: Select all

XSelectInput(dpy, win, ExposureMask|KeyPressMask|ButtonPressMask);
then change your loop to this one.

Code: Select all

	while (1) {
		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);
			}
		}
		paint(cs, width, height, style);
		usleep(500000);
	}
finish:
	cairo_surface_destroy(cs);
	XCloseDisplay(dpy);
To quit, click the clock, then press q.
On some window managers the root window is not the desktop window. In the case
of ROX-Filer pinboard this is easily overcome by finding the child window which
is "ROX-Pinboard", which in most cases is the very first child.
Doesn't work for me. I only run openbox + rox; and I have to resort to using xwininfo trick.
- a compositor such as xcompmgr is needed so artefacts do not display under clockface
Not enough. Do this: run pmck; cover it with something, show it again (and see the garbage), *then* run xcompmgr. xcompmgr will not remove that garbage (in fact it will keep it). Learn to use XShapeCombineMask instead, and you will not depend on xcompmgr at all.
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]

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

Post Reply