PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : XShape Extension und Xft



Trillian
25-08-2003, 19:52
Hi,
ich versuche z.Z. mittels der XShape Extension und Xft einen String in ein Fenster zu malen. Dabei soll das Fenster transparent wirken, ich will nur den String sehen.

Ich weiß von libxosd, aber das Ding ist hoffnungslos verbuggt und ich habe Mühe, daraus die für mich relevanten Code-Zeilen rauszufiltern.

Kennt jemand eine gute Referenz der XShape Extension? Mit Google habe ich nichts finden können und die man page ist ein schlechter Witz :/

Danke schonmal

pik7
25-08-2003, 21:36
hallo,



und die man page ist ein schlechter Witz :/


wohl wahr!

aber man kann imlib2 verwenden wenn du
nur den Strings sehen willst.
Funktioniert prima mit ttf Fonts.
Und man kann sich die pixmaps rendern lassen die man für den
shape kram braucht und mit ein bisschen rumgefummel
bekommt man das auch hin.
Dann kann man auch z.b Zeichen png's auf den Schirm bringen.

wenn's das ist was du brauchst

gruß

Trillian
26-08-2003, 17:31
Ah, ich wusste garnicht, dass es da was in Imlib2 gibt.
Danke für den Tip, ich werd mir die Doku dazu mal angucken.

Sodele, habe folgendes hinbekommen:

* Ich benutze XCreateWindow() (bzw. ecore_x_window_create) mit dem "Override" Flag
* Ich kopiere einen Bereich des Root-Window in ein Imlib_Image
* In das Image rendere ich meinen Text
* Ich rendere das Image in mein Fenster

Das sieht gut aus, solange man nicht das unter dem Fenster liegende Programm/Fenster aktiviert/fokussiert - dann merkt man natürlich, dass da drüber ein Fenster liegt.

Ich will nun mit der XShape Extension ein Fenster erstellen, dass die Form des gerenderten Textes hat, so dass ich quasi "echte" Transparenz habe. Geht das überhaupt?

Muss ich dazu imlib_create_scaled_image_from_drawable() einsetzen? Eine andere Funktion, die was mit Shapes zu tun hat, gibts wohl nicht :D

Aus der Beschreibung zu der Funktion:

If (parameter) get_mask_from_shape and the current drawable is a window its shape is used for determining the alpha channel.

Das verstehe ich nicht... Wie setze ich diese Funktion ein? Um XShapeCombineFoo() zu benutzen, benötige ich doch ein Fenster, oder?

Bin etwas verwirrt :)

pik7
26-08-2003, 21:03
hallo,



* Ich kopiere einen Bereich des Root-Window in ein Imlib_Image
* In das Image rendere ich meinen Text
* Ich rendere das Image in mein Fenster

Das sieht gut aus, solange man nicht das unter dem Fenster liegende Programm/Fenster aktiviert/fokussiert - dann merkt man natürlich, dass da drüber ein Fenster liegt.


Und wenn du den ganzen Bereich des Root-Window in ein
Image renderst und dann deinen text reinmachst
und dann das Image als neuen WindowBackground setzt?



Das verstehe ich nicht... Wie setze ich diese Funktion ein? Um XShapeCombineFoo() zu benutzen, benötige ich doch ein Fenster, oder?


Shape Extensions machen "non-rectangular" Windows,
also windows die nicht vier ecken haben:)

Ist schon ein parr Monde her wo ich da ma was mit gemacht habe
deshalb bin ich da nicht mehr so auf der höhe.
mit
void imlib_render_pixmaps_for_whole_image(Pixmap *pixmap_return, Pixmap *mask_return);

kannst du dir die masken rendern lassen die du für die Shapes brauchst.
Kannst ja mal dein code zeigen dann kann ich mir da eine bessere Vorstellung von machen.
Vielleicht fällt mir ja dann noch was ein dazu.
(aber heute nicht mehr)

gruß

Trillian
28-08-2003, 17:57
Das RootWindow möchte ich eigentlich nicht benutzen... das wäre mir zu unsauber :)
Die grundsätzliche Funktionalität von XShape war mir auch klar, nur /weiß ich noch nicht, wie genau das ganze ist.

imlib_render_pixmaps_for_whole_image() scheint jedenfalls ganz gut zu sein, werde ich gleich ausprobieren.

pik7
28-08-2003, 20:19
hallo



Das RootWindow möchte ich eigentlich nicht benutzen... das wäre mir zu unsauber


War vieleicht etwas blöd von mir geschrieben.
Was ich eigentlich meinte:

Du kopierst einen Bereich des RootWindow
in ein Image.
In das Image renderst du deinen Text..
Dann machst du dir ein Window ohne Borders(oder mit nach belieben)
mit der größe des Images und setzt das Image
besser gesagt die Pixmap mit
XSetWindowBackgroundPixmap(disp,win,map);
als WindowBackground.
Hat den Vorteil das du dann keine Expose Events
zu beachten brauchst ,der XServer kümmert sich um
die WindowBackgrounds.
Wenn du dann noch das Window sozusagen "festkleben" willst
auf dem RootWindow kannst du noch den stack_mode ändern:

XWindowChanges changes:
changes.stack_mode=Below;
XConfigureWindow(disp,win,CWStackMode,&changes);

dann kommt das Window nicht mehr hoch wenn du es anklickst.
Veieicht kannste ja das gebrauchen.

Hoffe konnte mich verständlich ausdrücken

gruß

Trillian
28-08-2003, 20:37
Original geschrieben von pik7
Du kopierst einen Bereich des RootWindow
in ein Image.
In das Image renderst du deinen Text..
Dann machst du dir ein Window ohne Borders(oder mit nach belieben)
mit der größe des Images und setzt das Image
besser gesagt die Pixmap mit
XSetWindowBackgroundPixmap(disp,win,map);
als WindowBackground.

Ich bin nicht ganz sicher, ob ich das richtig verstanden habe :o

1.) Image vom Rootwindow kopieren
2.) In das Image den Text rendern
3.) Neues Window erstellen
3.) Das Image in ein Pixmap umwandeln und als Hintergrund des neu erstellten Fensters setzen

Richtig?

Das geht doch einfacher:

1.) Image vom RootWindow kopieren
2.) In das Image den Text rendern

Oder bekomme ich dann Probleme mit den Expose-Events? Scheinbar nicht, denn das funktioniert hier schon.

pik7
28-08-2003, 20:56
hallo,



Richtig?

Richtig



1.) Image vom RootWindow kopieren
2.) In das Image den Text rendern

und weiter?



Oder bekomme ich dann Probleme mit den Expose-Events? Scheinbar nicht, denn das funktioniert hier schon.

Was funktioniert?

Ist eigentlich kein Poblem aber wenn man
void imlib_render_image_on_drawable(int x, int y);
zum rendern ins Window benutzt muss man die Expose Events
beachten.

Trillian
28-08-2003, 21:09
Ich erstelle ein neues Fenster, das den Inhalt der dahinter liegenden Fenster erbt:

ecore_x_window_override_new();

(Entspricht:
XSetWindowAttributes attr.override_redirect = True;
und "CWOverrideRedirect" bei den Flags fürs neue Window)

Und dann benutze ich dieses Fenster als drawable und rendere mit
imlib_render_image_on_drawable() :)

Das Expose-Event behandele ich nicht.

pik7
28-08-2003, 21:16
hallo,

Hab ich jetzt mal ausprobiert mit
imlib_render_image_on_drawable();
Bei mir muß ich die Expose Events beachten
sonst gibts Müll wenn ich mit einem anderen Window
über das Window mit dem Image rüberziehe.

aber wenns bei dir funktioniert

gruß

Trillian
29-08-2003, 14:03
Probiers mal mit dem Override Flag. Sag bescheid, wenn du die genauen Parameter brauchst.

Trillian
29-08-2003, 16:35
Funzt! :)



static int on_window_expose (void *udata, int type, void *event)
{
Ecore_X_Event_Window_Damage *e = event;
Ecore_X_Pixmap pmap, mask;
Imlib_Font font;
Imlib_Image im;

if (!(im = imlib_create_image(200, 100))) {
printf("can't get image\n");
return 0;
}

imlib_context_set_image (im);
imlib_image_clear ();
imlib_context_set_anti_alias (TRUE);
imlib_image_set_has_alpha (TRUE);
imlib_context_set_blend (TRUE);

/* setup font */
if (!(font = imlib_load_font("orbit/30"))) {
printf("can't get font\n");
return 0;
}

imlib_context_set_font(font);
imlib_context_set_color (45, 196, 45, 255);
imlib_text_draw(10, 10, "Foobar");
imlib_free_font();

imlib_context_set_drawable (e->win);
imlib_render_pixmaps_for_whole_image ((Pixmap*) &pmap, (Pixmap*) &mask);
ecore_x_window_shape_mask_set (e->win, mask);

imlib_render_image_on_drawable (0, 0);

imlib_free_image ();
imlib_free_pixmap_and_mask (pmap);

return 0;
}



Das ist ein Expose-Event Handler a la Ecore. Das ganze funzt mit einem ganz normalen Fenster ;)

Hoffentlich hilft das irgendwem :D

Edit: Code aktualisiert, überflüssige Aufrufe entfernt.

pik7
29-08-2003, 17:01
hallo,



Hoffentlich hilft das irgendwem :D


natürlich:D

Du benutzt Ecore, die lib die man für
E17 braucht.
Wollte ich mir schon seit ein parr Wochen mal installieren
aber wegen Zeitmangels nicht zu gekommen.
Werde ich mir aber diese Wochenende mal zu Gemüte führen.
Scheint eine gute Sache zu sein.

gruß

Trillian
29-08-2003, 17:36
Dann solltest du drauf achten, dass du es aus dem "SPLIT" Branch auscheckst. Die Version im Main Branch ist veraltet.