104
static GdkPixbuf *_cairo_dock_get_pixbuf_from_pixmap (int XPixmapID, gboolean bAddAlpha) // cette fonction est inspiree par celle de libwnck.
117
cairo_surface_t *cairo_dock_create_surface_from_xpixmap (Pixmap Xid, cairo_t *pSourceContext, double fMaxScale, double *fWidth, double *fHeight)
106
Window root; // inutile.
107
int x, y; // inutile.
108
guint border_width; // inutile.
109
guint iWidth, iHeight, iDepth;
110
XGetGeometry (s_XDisplay,
111
XPixmapID, &root, &x, &y,
112
&iWidth, &iHeight, &border_width, &iDepth);
113
cd_message ("%s (%d) : %dx%dx%d pixels (%d;%d)\n", __func__, XPixmapID, iWidth, iHeight, iDepth, x, y);
115
//\__________________ On recupere le drawable associe.
116
GdkDrawable *pGdkDrawable = gdk_xid_table_lookup (XPixmapID);
118
g_object_ref (G_OBJECT (pGdkDrawable));
120
pGdkDrawable = gdk_pixmap_foreign_new (XPixmapID);
122
//\__________________ On recupere la colormap.
123
GdkColormap* pColormap = gdk_drawable_get_colormap (pGdkDrawable);
124
if (pColormap == NULL && gdk_drawable_get_depth (pGdkDrawable) > 1) // pour les bitmaps, on laisse la colormap a NULL, ils n'en ont pas besoin.
126
GdkScreen* pScreen = gdk_drawable_get_screen (GDK_DRAWABLE (pGdkDrawable));
127
pColormap = gdk_screen_get_system_colormap (pScreen); // au pire on a un colormap nul.
130
//\__________________ On recupere le buffer dans un GdkPixbuf.
131
GdkPixbuf *pIconPixbuf = gdk_pixbuf_get_from_drawable (NULL,
140
g_object_unref (G_OBJECT (pGdkDrawable));
141
g_return_val_if_fail (pIconPixbuf != NULL, NULL);
143
//\__________________ On lui ajoute un canal alpha si necessaire.
144
if (! gdk_pixbuf_get_has_alpha (pIconPixbuf) && bAddAlpha)
146
GdkPixbuf *tmp_pixbuf = gdk_pixbuf_add_alpha (pIconPixbuf, TRUE, 255, 255, 255);
147
g_object_unref (pIconPixbuf);
148
pIconPixbuf = tmp_pixbuf;
119
g_return_val_if_fail (cairo_status (pSourceContext) == CAIRO_STATUS_SUCCESS && Xid > 0, NULL);
120
GdkPixbuf *pPixbuf = cairo_dock_get_pixbuf_from_pixmap (Xid, TRUE);
123
cd_warning ("This pixmap is undefined. It can happen for exemple for a window that is in a minimized state when the dock is launching.");
126
g_print ("window pixmap : %dx%d\n", gdk_pixbuf_get_width (pPixbuf), gdk_pixbuf_get_height (pPixbuf));
127
cairo_surface_t *pSurface = cairo_dock_create_surface_from_pixbuf (pPixbuf,
130
g_tIconAuthorizedWidth[CAIRO_DOCK_APPLI],
131
g_tIconAuthorizedHeight[CAIRO_DOCK_APPLI],
136
g_object_unref (pPixbuf);
153
140
cairo_surface_t *cairo_dock_create_surface_from_xwindow (Window Xid, cairo_t *pSourceContext, double fMaxScale, double *fWidth, double *fHeight)
178
165
GdkPixbuf *pIconPixbuf = NULL;
179
166
if (pWMHints->flags & IconWindowHint)
181
cd_debug (" pas de _NET_WM_ICON, mais une fenetre");
182
168
Window XIconID = pWMHints->icon_window;
183
pIconPixbuf = _cairo_dock_get_pixbuf_from_pixmap (XIconID, TRUE); // pas teste.
169
cd_debug (" pas de _NET_WM_ICON, mais une fenetre (ID:%d)", XIconID);
170
Pixmap iPixmap = cairo_dock_get_window_background_pixmap (XIconID);
171
pIconPixbuf = cairo_dock_get_pixbuf_from_pixmap (iPixmap, TRUE); /// A valider ...
185
173
else if (pWMHints->flags & IconPixmapHint)
187
175
cd_debug (" pas de _NET_WM_ICON, mais un pixmap");
188
176
Pixmap XPixmapID = pWMHints->icon_pixmap;
189
pIconPixbuf = _cairo_dock_get_pixbuf_from_pixmap (XPixmapID, TRUE);
177
pIconPixbuf = cairo_dock_get_pixbuf_from_pixmap (XPixmapID, TRUE);
191
179
//\____________________ On lui applique le masque de transparence s'il existe.
192
180
if (pWMHints->flags & IconMaskHint)
194
182
Pixmap XPixmapMaskID = pWMHints->icon_mask;
195
GdkPixbuf *pMaskPixbuf = _cairo_dock_get_pixbuf_from_pixmap (XPixmapMaskID, FALSE);
183
GdkPixbuf *pMaskPixbuf = cairo_dock_get_pixbuf_from_pixmap (XPixmapMaskID, FALSE);
197
185
int iNbChannels = gdk_pixbuf_get_n_channels (pIconPixbuf);
198
186
int iRowstride = gdk_pixbuf_get_rowstride (pIconPixbuf);
250
239
g_free (icon->cParentDockName);
251
240
if (CAIRO_DOCK_IS_APPLI (icon) && g_bGroupAppliByClass && icon->cClass != NULL)
253
Icon *pSameClassIcon = cairo_dock_get_icon_with_class (pMainDock->icons, icon->cClass);
254
if (pSameClassIcon == NULL || pSameClassIcon == icon)
242
Icon *pSameClassIcon = cairo_dock_get_classmate (icon);
243
//if (pSameClassIcon != NULL)
244
// g_print ("class-mate : %s (%s)\n", pSameClassIcon->acName, pSameClassIcon->cParentDockName);
245
//pSameClassIcon = cairo_dock_get_icon_with_class (pMainDock->icons, icon->cClass);
246
if (pSameClassIcon == NULL/** || pSameClassIcon == icon || pSameClassIcon->cParentDockName == NULL*/) // aucun classmate => elle va dans le main dock.
256
248
cd_message (" classe %s encore vide", icon->cClass);
257
249
icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
250
CairoDock *pClassDock = cairo_dock_search_dock_from_name (icon->cClass);
251
if (pClassDock != NULL)
253
if (icon->pSubDock == NULL)
255
///icon->pSubDock = pClassDock;
256
///cd_warning ("on lie de force le sous-dock de la classe %s a l'icone %s", icon->cClass, icon->acName);
258
else if (pClassDock != icon->pSubDock)
259
cd_warning ("le sous-dock de la classe %s est orphelin (%s a deja un sous-dock) !", icon->cClass, icon->acName);
262
else // on la met dans le sous-dock de sa classe.
261
264
icon->cParentDockName = g_strdup (icon->cClass);
266
//\____________ On cree ce sous-dock si necessaire.
263
267
pParentDock = cairo_dock_search_dock_from_name (icon->cClass);
264
268
if (pParentDock == NULL) // alors il faut creer le sous-dock, et on decide de l'associer a pSameClassIcon.
266
270
cd_message (" creation du dock pour la classe %s", icon->cClass);
267
pParentDock = cairo_dock_create_subdock_for_class_appli (icon->cClass);
268
pSameClassIcon->pSubDock = pParentDock;
271
pParentDock = cairo_dock_create_subdock_for_class_appli (icon->cClass, pMainDock);
272
275
cd_message (" sous-dock de la classe %s existant", icon->cClass);
273
if (pSameClassIcon->pSubDock == NULL)
280
//\____________ On l'associe au classmate.
281
if (pSameClassIcon->pSubDock != NULL && pSameClassIcon->pSubDock != pParentDock)
283
cd_warning ("this appli (%s) already has a subdock, but it is not the class's subdock => we'll add its classmate in the main dock");
286
else if (pSameClassIcon->pSubDock == NULL)
274
287
pSameClassIcon->pSubDock = pParentDock;
291
if (CAIRO_DOCK_IS_LAUNCHER (pSameClassIcon) || CAIRO_DOCK_IS_APPLET (pSameClassIcon)) // c'est un inhibiteur; on place juste l'icone dans le sous-dock de sa classe.
293
if (pSameClassIcon->pSubDock != NULL && pSameClassIcon->pSubDock != pParentDock)
295
cd_warning ("icon %s alreay owns a subdock, it can't owns the class subdock '%s'", pSameClassIcon->acName, icon->cClass);
296
if (pParentDock->icons == NULL)
297
cairo_dock_destroy_dock (pParentDock, icon->cClass, NULL, NULL);
298
pParentDock = pMainDock;
299
icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
303
pSameClassIcon->pSubDock = pParentDock;
304
Icon *pInhibatedIcon = cairo_dock_get_icon_with_Xid (pSameClassIcon->Xid);
305
pSameClassIcon->Xid = 0;
306
if (pInhibatedIcon != NULL)
308
cairo_dock_insert_icon_in_dock (pInhibatedIcon, pParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, CAIRO_DOCK_APPLY_RATIO, FALSE);
312
else if (pParentDock->icons == NULL) // le sous-dock de cette classe est nouveau, on deplace le classmate dans le sous-dock, et on met un fake a sa place pour pointer dessus.
314
g_print ("nouveau sous-dock de la classe %s\n", pSameClassIcon->cClass);
315
Icon *pFakeClassIcon = g_new0 (Icon, 1);
316
pFakeClassIcon->acName = g_strdup (pSameClassIcon->cClass);
317
pFakeClassIcon->cClass = g_strdup (pSameClassIcon->cClass);
318
pFakeClassIcon->iType = pSameClassIcon->iType;
319
pFakeClassIcon->fOrder = pSameClassIcon->fOrder;
320
pFakeClassIcon->cParentDockName = g_strdup (pSameClassIcon->cParentDockName);
321
pFakeClassIcon->fWidth = pSameClassIcon->fWidth;
322
pFakeClassIcon->fHeight = pSameClassIcon->fHeight;
323
pFakeClassIcon->fXMax = pSameClassIcon->fXMax;
324
pFakeClassIcon->fXMin = pSameClassIcon->fXMin;
325
pFakeClassIcon->fXAtRest = pSameClassIcon->fXAtRest;
326
pFakeClassIcon->pSubDock = pParentDock; // grace a cela ce sera un lanceur.
328
CairoDock *pClassMateParentDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
329
pFakeClassIcon->Xid = pSameClassIcon->Xid;
330
cairo_dock_load_one_icon_from_scratch (pFakeClassIcon, CAIRO_CONTAINER (pClassMateParentDock)); // iBackingPixmap est nul donc on n'aura pas de miniature.
331
pFakeClassIcon->Xid = 0;
332
/// dessiner une embleme ?...
334
g_print ("on detache %s pour la passer dans le sous-dock de sa classe\n", pSameClassIcon->acName);
335
cairo_dock_detach_icon_from_dock (pSameClassIcon, pClassMateParentDock, FALSE);
336
g_free (pSameClassIcon->cParentDockName);
337
pSameClassIcon->cParentDockName = g_strdup (pSameClassIcon->cClass);
338
cairo_dock_insert_icon_in_dock (pSameClassIcon, pParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, CAIRO_DOCK_APPLY_RATIO, FALSE);
294
359
double fWidth, fHeight;
296
361
//\__________________ On regarde si on doit l'afficher ou la sauter.
297
gboolean bSkip = FALSE, bIsHidden = FALSE;
362
gboolean bSkip = FALSE, bIsHidden = FALSE, bIsFullScreen = FALSE, bIsMaximized = FALSE;
298
363
gulong *pXStateBuffer = NULL;
299
364
iBufferNbElements = 0;
300
365
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
301
366
if (iBufferNbElements > 0)
368
int i, iNbMaximizedDimensions = 0;
304
369
for (i = 0; i < iBufferNbElements && ! bSkip; i ++)
306
371
if (pXStateBuffer[i] == s_aNetWmSkipTaskbar)
308
373
else if (pXStateBuffer[i] == s_aNetWmHidden)
309
374
bIsHidden = TRUE;
375
else if (pXStateBuffer[i] == s_aNetWmMaximizedVert)
376
iNbMaximizedDimensions ++;
377
else if (pXStateBuffer[i] == s_aNetWmMaximizedHoriz)
378
iNbMaximizedDimensions ++;
379
else if (pXStateBuffer[i] == s_aNetWmFullScreen)
380
bIsFullScreen = TRUE;
310
381
//else if (pXStateBuffer[i] == s_aNetWmSkipPager) // contestable ...
384
bIsMaximized = (iNbMaximizedDimensions == 2);
313
385
//g_print (" -------- bSkip : %d\n", bSkip);
314
386
XFree (pXStateBuffer);
429
501
icon->fOrder = (pLastAppli != NULL ? pLastAppli->fOrder + 1 : 1);
430
502
icon->iType = CAIRO_DOCK_APPLI;
431
503
icon->bIsHidden = bIsHidden;
433
///cairo_dock_fill_one_icon_buffer (icon, pSourceContext, 1 + g_fAmplitude, pDock->bHorizontalDock, TRUE);
434
///cairo_dock_fill_one_text_buffer (icon, pSourceContext, g_iLabelSize, g_cLabelPolice, (g_bTextAlwaysHorizontal ? CAIRO_DOCK_HORIZONTAL : pDock->bHorizontalDock), pDock->bDirectionUp);
504
icon->bIsMaximized = bIsMaximized;
505
icon->bIsFullScreen = bIsFullScreen;
507
cairo_dock_get_window_geometry (Xid,
508
&icon->windowGeometry.x,
509
&icon->windowGeometry.y,
510
&icon->windowGeometry.width,
511
&icon->windowGeometry.height);
513
if (g_bShowThumbnail)
515
icon->iBackingPixmap = XCompositeNameWindowPixmap (s_XDisplay, Xid);
516
/*icon->iDamageHandle = XDamageCreate (s_XDisplay, Xid, XDamageReportNonEmpty); // XDamageReportRawRectangles
517
g_print ("backing pixmap : %d ; iDamageHandle : %d\n", icon->iBackingPixmap, icon->iDamageHandle);*/
435
521
cairo_dock_fill_icon_buffers_for_dock (icon, pSourceContext, pDock);
437
523
if (g_bUniquePid)
438
524
g_hash_table_insert (s_hAppliTable, pPidBuffer, icon);
439
525
cairo_dock_register_appli (icon);
440
526
XFree (pNameBuffer);
442
528
cairo_dock_set_window_mask (Xid, PropertyChangeMask | StructureNotifyMask);
543
gchar *cairo_dock_get_property_name_on_xwindow (Window Xid, Atom xPropertyAtom)
545
guchar *pNameBuffer = NULL;
546
Atom aReturnedType = 0;
547
int aReturnedFormat = 0;
548
unsigned long iLeftBytes, iBufferNbElements;
550
XGetWindowProperty (s_XDisplay, Xid, xPropertyAtom, 0, G_MAXULONG, False, s_aUtf8String, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
551
if (iBufferNbElements == 0)
553
XGetWindowProperty (s_XDisplay, Xid, xPropertyAtom, 0, G_MAXULONG, False, s_aString, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
555
g_print ("iBufferNbElements : %d\n", iBufferNbElements);
556
if (iBufferNbElements == 0)
558
g_print ("dommage !\n");
561
else return pNameBuffer;