Mercurial > pidgin
view plugins/win32/transparency/win2ktrans.c @ 5366:23898d72679c
[gaim-migrate @ 5742]
control-a is already used.
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Wed, 14 May 2003 01:15:58 +0000 |
parents | d635e8fe2fba |
children | 6d6ae91c5de7 |
line wrap: on
line source
/* * win2ktrans * * copyright (c) 1998-2002, rob flynn <rob@marko.net> * * Contributions by Herman Bloggs <hermanator12002@yahoo.com> * * 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., 59 temple place, suite 330, boston, ma 02111-1307 usa * */ #include <gdk/gdkwin32.h> #include <gmodule.h> #include "gaim.h" #include "gtkplugin.h" #include "gtkblist.h" #include "win32dep.h" /* * MACROS & DEFINES */ #define WINTRANS_PLUGIN_ID "win-gaim-trans" #define WINTRANS_VERSION 1 /* These defines aren't found in mingw's winuser.h */ #ifndef LWA_ALPHA #define LWA_ALPHA 0x00000002 #endif #ifndef WS_EX_LAYERED #define WS_EX_LAYERED 0x00080000 #endif /* Transparency plugin configuration */ #define OPT_WGAIM_IMTRANS 0x00000001 #define OPT_WGAIM_SHOW_IMTRANS 0x00000002 #define OPT_WGAIM_BLTRANS 0x00000004 #define OPT_WGAIM_BUDDYWIN_ONTOP 0x00000008 #define blist (gaim_get_blist()?(GAIM_GTK_BLIST(gaim_get_blist())?((GAIM_GTK_BLIST(gaim_get_blist()))->window):NULL):NULL) /* * DATA STRUCTS */ typedef struct { GtkWidget *win; GtkWidget *slider; } slider_win; /* * GLOBALS */ /* * LOCALS */ static int imalpha = 255; static int blalpha = 255; guint trans_options = 0; GList *window_list = NULL; /* * PROTOS */ BOOL (*MySetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)=NULL; extern GtkWidget *gaim_button(const char*, guint*, int, GtkWidget*); static void save_trans_prefs(); /* * CODE */ /* Set window transparency level */ void set_wintrans(GtkWidget *window, int trans) { if(MySetLayeredWindowAttributes) { HWND hWnd = GDK_WINDOW_HWND(window->window); SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE) | WS_EX_LAYERED); MySetLayeredWindowAttributes(hWnd,0,trans,LWA_ALPHA); } } void set_wintrans_off(GtkWidget *window) { if(MySetLayeredWindowAttributes) { HWND hWnd = GDK_WINDOW_HWND(window->window); SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); /* Ask the window and its children to repaint */ RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } } static void change_alpha(GtkWidget *w, gpointer data) { set_wintrans(GTK_WIDGET(data), gtk_range_get_value(GTK_RANGE(w))); } int has_transparency() { return MySetLayeredWindowAttributes ? TRUE : FALSE; } GtkWidget *wintrans_slider(GtkWidget *win) { GtkWidget *hbox; GtkWidget *label, *slider; GtkWidget *frame; frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT); gtk_widget_show(frame); hbox = gtk_hbox_new(FALSE, 5); gtk_container_add(GTK_CONTAINER(frame), hbox); label = gtk_label_new(_("Opacity:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); gtk_widget_show(hbox); slider = gtk_hscale_new_with_range(50,255,1); gtk_range_set_value(GTK_RANGE(slider), imalpha); gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1); /* On slider val change, update window's transparency level */ gtk_signal_connect(GTK_OBJECT(slider), "value-changed", GTK_SIGNAL_FUNC(change_alpha), win); gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5); /* Set the initial transparency level */ set_wintrans(win, imalpha); gtk_widget_show_all(hbox); return frame; } static slider_win* find_slidwin( GtkWidget *win ) { GList *tmp = window_list; while(tmp) { if( ((slider_win*)(tmp->data))->win == win) return (slider_win*)tmp->data; tmp = tmp->next; } return NULL; } gboolean win_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) { slider_win *slidwin=NULL; /* Remove window from the window list */ debug_printf("win2ktrans.dll: Conv window destoyed.. removing from list\n"); if((slidwin=find_slidwin(widget))) { window_list = g_list_remove(window_list, (gpointer)slidwin); g_free(slidwin); } return FALSE; } static void gaim_new_conversation(char *who) { GList *wl, *wl1; GtkWidget *vbox=NULL; GtkWidget *win=NULL; struct gaim_gtk_window *gaimwin; struct gaim_conversation *c; c = gaim_find_conversation(who); gaimwin = GAIM_GTK_WINDOW(c->window); win = gaimwin->window; /* check prefs to see if we want trans */ if ((trans_options & OPT_WGAIM_IMTRANS) && (trans_options & OPT_WGAIM_SHOW_IMTRANS)) { /* Look up this window to see if it already has a scroller */ if(!find_slidwin(win)) { GtkWidget *slider_box=NULL; slider_win *slidwin=NULL; /* Get top vbox */ for ( wl1 = wl = gtk_container_get_children(GTK_CONTAINER(win)); wl != NULL; wl = wl->next ) { if ( GTK_IS_VBOX(GTK_OBJECT(wl->data)) ) vbox = GTK_WIDGET(wl->data); else { debug_printf("no vbox found\n"); return; } } g_list_free(wl1); slider_box = wintrans_slider(win); gtk_box_pack_start(GTK_BOX(vbox), slider_box, FALSE, FALSE, 0); /* Add window to list, to track that it has a slider */ slidwin = g_new0( slider_win, 1 ); slidwin->win = win; slidwin->slider = slider_box; window_list = g_list_append(window_list, (gpointer)slidwin); /* Set callback to remove window from the list, if the window is destroyed */ g_signal_connect(GTK_OBJECT(win), "destroy_event", G_CALLBACK(win_destroy_cb), NULL); } else return; } if((trans_options & OPT_WGAIM_IMTRANS) && !(trans_options & OPT_WGAIM_SHOW_IMTRANS)) { set_wintrans(win, imalpha); } } static void blist_created() { if(blist) { if(trans_options & OPT_WGAIM_BUDDYWIN_ONTOP) SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); else SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); if(trans_options & OPT_WGAIM_BLTRANS) set_wintrans(blist, blalpha); else set_wintrans_off(blist); } } static void alpha_change(GtkWidget *w, gpointer data) { int *alpha = (int*)data; *alpha = gtk_range_get_value(GTK_RANGE(w)); } static void bl_alpha_change(GtkWidget *w, gpointer data) { alpha_change(w, data); if(blist) change_alpha(w, blist); } /* Load options */ static void load_trans_prefs() { FILE *f; char buf[1024]; int ver=0; char tag[256]; if (gaim_home_dir()) g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S ".gaim" G_DIR_SEPARATOR_S "wintransrc", gaim_home_dir()); else return; if ((f = fopen(buf, "r"))) { fgets(buf, sizeof(buf), f); sscanf(buf, "# wintransrc v%d", &ver); if ((ver > 1) || (buf[0] != '#')) return; while (!feof(f)) { fgets(buf, sizeof(buf), f); sscanf(buf, "%s {", tag); if (strcmp(tag, "options")==0) { fgets(buf, sizeof(buf), f); sscanf(buf, "\ttrans_options { %d", &trans_options); continue; } else if (strcmp(tag, "trans")==0) { int num; for(fgets(buf, sizeof(buf), f);buf[0] != '}' && !feof(f);fgets(buf, sizeof(buf), f)) { sscanf(buf, "\t%s { %d", tag, &num); if(strcmp(tag, "imalpha")==0) { imalpha = num; } else if(strcmp(tag, "blalpha")==0) { blalpha = num; } } } } } else save_trans_prefs(); blist_created(); } /* Save options */ static void write_options(FILE *f) { fprintf(f, "options {\n"); fprintf(f, "\ttrans_options { %u }\n", trans_options); fprintf(f, "}\n"); } static void write_trans(FILE *f) { fprintf(f, "trans {\n"); fprintf(f, "\timalpha { %d }\n", imalpha); fprintf(f, "\tblalpha { %d }\n", blalpha); fprintf(f, "}\n"); } static void save_trans_prefs() { FILE *f; char buf[1024]; if (gaim_home_dir()) { g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S ".gaim" G_DIR_SEPARATOR_S "wintransrc", gaim_home_dir()); } else return; if ((f = fopen(buf, "w"))) { fprintf(f, "# wintransrc v%d\n", WINTRANS_VERSION); write_trans(f); write_options(f); fclose(f); } else debug_printf("Error opening wintransrc\n"); } static void set_trans_option(GtkWidget *w, int option) { trans_options ^= option; save_trans_prefs(); if(option == OPT_WGAIM_BUDDYWIN_ONTOP) { if(blist) { if(trans_options & OPT_WGAIM_BUDDYWIN_ONTOP) SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); else SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } } else if(option == OPT_WGAIM_BLTRANS) { if(blist) { if(trans_options & OPT_WGAIM_BLTRANS) set_wintrans(blist, blalpha); else set_wintrans_off(blist); } } } /* * EXPORTED FUNCTIONS */ G_MODULE_EXPORT gboolean plugin_load(GaimPlugin *plugin) { gaim_signal_connect(plugin, event_new_conversation, gaim_new_conversation, NULL); gaim_signal_connect(plugin, event_signon, blist_created, NULL); MySetLayeredWindowAttributes = (void*)wgaim_find_and_loadproc("user32.dll", "SetLayeredWindowAttributes" ); load_trans_prefs(); return TRUE; } G_MODULE_EXPORT gboolean plugin_unload(GaimPlugin *plugin) { debug_printf("Removing win2ktrans.dll plugin\n"); /* Remove slider bars */ if(window_list) { GList *tmp=window_list; while(tmp) { slider_win *slidwin = (slider_win*)tmp->data; gtk_widget_destroy(slidwin->slider); set_wintrans_off(slidwin->win); g_free(slidwin); tmp=tmp->next; } g_list_free(window_list); window_list = NULL; } if(blist) { SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); set_wintrans_off(blist); } return TRUE; } G_MODULE_EXPORT GtkWidget *get_config_frame(GaimPlugin *plugin) { GtkWidget *ret; GtkWidget *imtransbox, *bltransbox; GtkWidget *hbox; GtkWidget *label, *slider; GtkWidget *button; GtkWidget *trans_box; ret = gtk_vbox_new(FALSE, 18); gtk_container_set_border_width (GTK_CONTAINER (ret), 12); /* IM Convo trans options */ imtransbox = make_frame (ret, _("IM Conversation Windows")); button = gaim_button(_("_IM window transparency"), &trans_options, OPT_WGAIM_IMTRANS, imtransbox); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(set_trans_option), (int *)OPT_WGAIM_IMTRANS); trans_box = gtk_vbox_new(FALSE, 18); if (!(trans_options & OPT_WGAIM_IMTRANS)) gtk_widget_set_sensitive(GTK_WIDGET(trans_box), FALSE); gtk_widget_show(trans_box); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gaim_gtk_toggle_sensitive), trans_box); button = gaim_button(_("_Show slider bar in IM window"), &trans_options, OPT_WGAIM_SHOW_IMTRANS, trans_box); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(set_trans_option), (int *)OPT_WGAIM_SHOW_IMTRANS); gtk_box_pack_start(GTK_BOX(imtransbox), trans_box, FALSE, FALSE, 5); /* IM transparency slider */ hbox = gtk_hbox_new(FALSE, 5); label = gtk_label_new(_("Opacity:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); slider = gtk_hscale_new_with_range(50,255,1); gtk_range_set_value(GTK_RANGE(slider), imalpha); gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1); gtk_signal_connect(GTK_OBJECT(slider), "value-changed", GTK_SIGNAL_FUNC(alpha_change), (void*)&imalpha); gtk_signal_connect(GTK_OBJECT(slider), "focus-out-event", GTK_SIGNAL_FUNC(save_trans_prefs), NULL); gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5); gtk_widget_show_all(hbox); gtk_box_pack_start(GTK_BOX(trans_box), hbox, FALSE, FALSE, 5); /* Buddy List trans options */ bltransbox = make_frame (ret, _("Buddy List Window")); button = gaim_button(_("_Keep Buddy List window on top"), &trans_options, OPT_WGAIM_BUDDYWIN_ONTOP, bltransbox); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(set_trans_option), (int *)OPT_WGAIM_BUDDYWIN_ONTOP); button = gaim_button(_("_Buddy List window transparency"), &trans_options, OPT_WGAIM_BLTRANS, bltransbox); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(set_trans_option), (int *)OPT_WGAIM_BLTRANS); trans_box = gtk_vbox_new(FALSE, 18); if (!(trans_options & OPT_WGAIM_BLTRANS)) gtk_widget_set_sensitive(GTK_WIDGET(trans_box), FALSE); gtk_widget_show(trans_box); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gaim_gtk_toggle_sensitive), trans_box); gtk_box_pack_start(GTK_BOX(bltransbox), trans_box, FALSE, FALSE, 5); /* IM transparency slider */ hbox = gtk_hbox_new(FALSE, 5); label = gtk_label_new(_("Opacity:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); slider = gtk_hscale_new_with_range(50,255,1); gtk_range_set_value(GTK_RANGE(slider), blalpha); gtk_widget_set_usize(GTK_WIDGET(slider), 200, -1); gtk_signal_connect(GTK_OBJECT(slider), "value-changed", GTK_SIGNAL_FUNC(bl_alpha_change), (void*)&blalpha); gtk_signal_connect(GTK_OBJECT(slider), "focus-out-event", GTK_SIGNAL_FUNC(save_trans_prefs), NULL); gtk_box_pack_start(GTK_BOX(hbox), slider, FALSE, TRUE, 5); gtk_widget_show_all(hbox); gtk_box_pack_start(GTK_BOX(trans_box), hbox, FALSE, FALSE, 5); /* If this version of Windows dosn't support Transparency, grey out options */ if(!has_transparency()) { debug_printf("This version of windows dosn't support transparency\n"); gtk_widget_set_sensitive(GTK_WIDGET(imtransbox), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(trans_box), FALSE); } gtk_widget_show_all(ret); return ret; } static GaimGtkPluginUiInfo ui_info = { get_config_frame }; static GaimPluginInfo info = { 2, /**< api_version */ GAIM_PLUGIN_STANDARD, /**< type */ GAIM_GTK_PLUGIN_TYPE, /**< ui_requirement */ 0, /**< flags */ NULL, /**< dependencies */ GAIM_PRIORITY_DEFAULT, /**< priority */ WINTRANS_PLUGIN_ID, /**< id */ N_("Transparency"), /**< name */ VERSION, /**< version */ /** summary */ N_("This plugin enables variable alpha transparency on conversation windows.\n\n* Note: This plugin requires Win2000 or WinXP."), /** description */ N_("This plugin enables variable alpha transparency on conversation windows.\n\n* Note: This plugin requires Win2000 or WinXP."), "Herman Bloggs <hermanator12002@yahoo.com>", /**< author */ WEBSITE, /**< homepage */ plugin_load, /**< load */ plugin_unload, /**< unload */ NULL, /**< destroy */ &ui_info, /**< ui_info */ NULL /**< extra_info */ }; static void __init_plugin(GaimPlugin *plugin) { } GAIM_INIT_PLUGIN(wintrans, __init_plugin, info);