注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

gmd20的个人空间

// 编程和生活

 
 
 

日志

 
 

Ubuntu Linux上面的提醒休息程序实现(锁屏,禁用键盘)  

2009-03-09 14:20:29|  分类: linux相关 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

GNOME窗体管理器下么的GTK+库实现了以下功能:
1。 锁屏,禁用鼠标键盘
   用GNOME库中的grab keyboard pointer 函数接口就可以了
2。通知区域图标(系统托盘)
用的libegg库,Gnome的一个子项目,去http://svn.gnome.org/viewvc/libegg/trunk/libegg/tray/
把eggtrayicon.c 和eggtrayicon.h 这两个文件下载回来加到项目中,像我这样用就行了。在网站上也可以看到他的使用例子。
像QQ 的Linux等程序都实现了这个功能的。这个库好像说是以后会整合到GTK+里面去的吧
3。GTK+中菜单的使用,复选菜单,图标菜单等
4。 gblade 库的使用
5。 GTK +中定时器的使用,更改背景颜色,字体颜色大小,全屏置顶窗口等
6。运行时获取程序的文件所在的目录的办法

===========================================================
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
* main.c
* Copyright (C) widebright 2009 <http://hi.baidu.com/widebright>
*
* main.c 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 3 of the License, or
* (at your option) any later version.
*
* main.c 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, see <http://www.gnu.org/licenses/>.
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <config.h>

#include <gtk/gtk.h>
#include <glade/glade.h>

#include "eggtrayicon.h"


static gint timer_min;
static gint timer_sec;

static int lock_seconds;
static int unlock_minutes;
static gboolean is_desktop_lock;


GtkLabel * label_message;
GtkLabel * label_time_left;
GtkWidget * window;
GtkMenu   * menu1;


gint every_minute_callback (gpointer data);
gint every_second_callback (gpointer data);
void lock_desktop(int lock_time);
void unlock_desktop();
GtkWidget* create_window (void);
char * get_exe_path();

/*
* Standard gettext macros.
*/
#ifdef ENABLE_NLS
# include <libintl.h>
# undef _
# define _(String) dgettext (PACKAGE, String)
# ifdef gettext_noop
#    define N_(String) gettext_noop (String)
# else
#    define N_(String) (String)
# endif
#else
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define N_(String) (String)
#endif



#include "callbacks.h"

/* For testing propose use the local (not installed) glade file */
/* #define GLADE_FILE PACKAGE_DATA_DIR"/relax_reminder/glade/relax_reminder.glade" */
#define GLADE_FILE "relax_reminder.glade"
   
GtkWidget*
create_window (void)
{
    GtkWidget *window;
    GladeXML *gxml;
    char *exe_path=get_exe_path();
    if (exe_path ==NULL)
    {
       perror("不能获取到程序的目录");
    }
   
    strcat (exe_path , "relax_reminder.glade");
    //gxml = glade_xml_new (GLADE_FILE, NULL, NULL);
    gxml = glade_xml_new (exe_path, NULL, NULL);
    free(exe_path);
   
    /* This is important */
    glade_xml_signal_autoconnect (gxml);
    window = glade_xml_get_widget (gxml, "window");
       
    //GdkColor window_bk={0,0,0,0};
    //GdkColor window_bk={0,55535,65535,55535};
    GdkColor window_bk={0, 26728,19275,13107};
   
    gtk_widget_modify_bg(window,
                        GTK_STATE_NORMAL //|GTK_STATE_ACTIVE|GTK_STATE_PRELIGHT|
                        //GTK_STATE_SELECTED|GTK_STATE_INSENSITIVE
                        ,&window_bk);           

    menu1 =(GtkMenu *) glade_xml_get_widget (gxml, "menu1");
       
    label_message =   ( GtkLabel *) glade_xml_get_widget (gxml, "label_message");
    label_time_left = ( GtkLabel *) glade_xml_get_widget (gxml, "label_time_left");

   
    PangoAttribute*   font =pango_attr_scale_new (2.5);
    //PangoAttribute*   bk_color =pango_attr_background_new (65535,65535,65535);
    PangoAttribute*   font_color =pango_attr_foreground_new (0,50000,0);
    PangoAttrList * attrs =pango_attr_list_new ();
    //pango_attr_list_insert (attrs, bk_color);
    pango_attr_list_insert (attrs, font_color);
    pango_attr_list_insert (attrs, font);

   
    gtk_label_set_attributes(label_message,attrs);
    gtk_label_set_attributes(label_time_left,attrs);
    pango_attr_list_unref (attrs);
   
   
    return window;
}
void lock_desktop(int lock_time)
{  
    is_desktop_lock=TRUE;
    lock_seconds = lock_time;
    g_source_remove(timer_min);
    timer_sec = g_timeout_add(1000,every_second_callback,NULL);
   
    gtk_widget_show (window);
    //窗体透明度
    gtk_window_set_opacity (GTK_WINDOW(window),0.5);
    //去掉标题栏
    //gtk_window_set_decorated (GTK_WINDOW(window),FALSE);
    //全屏窗口
    gtk_window_fullscreen(GTK_WINDOW(window));
    //置顶窗口
    gtk_window_set_keep_above(GTK_WINDOW(window),TRUE);
   
    //禁止其他程序获得键盘消息
    //gdk_keyboard_grab(window->window ,TRUE,GDK_CURRENT_TIME);其他程序也可以受到消息
    if(GDK_GRAB_SUCCESS !=gdk_keyboard_grab(window->window ,FALSE,GDK_CURRENT_TIME)) // 其他程序不能收到消息
    {
    sleep(1); //如果第一次请求不成功,等会在重试,
    if(GDK_GRAB_SUCCESS !=gdk_keyboard_grab(window->window ,FALSE,GDK_CURRENT_TIME)) // 其他程序不能收到消息
    {
        sleep(2);
        gdk_keyboard_grab(window->window ,FALSE,GDK_CURRENT_TIME);
    }
    }

}

void unlock_desktop()
{
    is_desktop_lock=FALSE;
    //释放键盘
    gdk_keyboard_ungrab(GDK_CURRENT_TIME);
       
    gtk_widget_hide (window);
    gtk_label_set_text(label_time_left,"");
    gtk_label_set_text(label_message,"widebright的休息提醒小程序");
   
    g_source_remove(timer_sec);
    timer_min = g_timeout_add(1000*60,every_minute_callback,NULL);
   

}

gint every_minute_callback (gpointer data)
{
    char messages[128];
   
    unlock_minutes ++;
    snprintf ( messages,128,"时间过去了%d分钟", unlock_minutes);
    gtk_label_set_text(label_time_left,messages);
    gtk_label_set_text(label_message,"widebright的休息提醒小程序");
   
    if (unlock_minutes % 60 ==0)
    {           
        unlock_minutes =0;
         lock_desktop(60 *10);
         gtk_label_set_text(label_message,"休息十分钟^_^");
    }
    else if (unlock_minutes % 15 ==0)
    {
         lock_desktop(60*2);
        gtk_label_set_text(label_message,"休息两分钟^_^");
    }
    return TRUE;
}

gint every_second_callback (gpointer data)
{
    char messages[128];
    snprintf ( messages,128,"还剩下 %d分%d秒",lock_seconds/60,lock_seconds%60);
    gtk_label_set_text(label_time_left,messages);   
   
    lock_seconds -- ;
    if (lock_seconds ==0)
    {
         unlock_desktop();
    }
       
    return TRUE;
}

static gboolean
tray_button_pressed (GtkWidget * widget, GdkEventButton * event,
                EggTrayIcon * tray_icon)
{
    g_return_val_if_fail (tray_icon, FALSE);
    g_return_val_if_fail ((event->type == GDK_BUTTON_PRESS), FALSE);

    switch (event->button)
    {
    case 1: //left button
        if (GTK_WIDGET_VISIBLE(window))
        {
           gtk_widget_hide (window);
        }
        else
        {
           gtk_window_unfullscreen(GTK_WINDOW(window));
           gtk_window_unmaximize(GTK_WINDOW(window));   
           gtk_window_deiconify (GTK_WINDOW(window));
           gtk_widget_show (window);
           gtk_window_resize(GTK_WINDOW(window),
                                           500,
                                           400);



           // gtk_widget_set_size_request ((GtkWidget *)window,
           //                                         500,
           //                                         400);
        }
        break;
    case 2:// middle button
        break;
    case 3: //right button
   
        gtk_menu_popup (menu1, NULL, NULL, NULL, NULL,
                event->button, event->time);
        break;
    default:

       /* Tell calling code that we have not handled this event; pass it on. */
       return FALSE;
    }
        /* Tell calling code that we have handled this event; the buck
         * stops here. */
    return TRUE;
}



void on_menuitem1_toggled (GtkCheckMenuItem * menuitem)
{
   
    if (gtk_check_menu_item_get_active (menuitem) )
    {
       //gtk_label_set_text(label_time_left,"选中");
       g_source_remove(timer_min);
              
    }
    else
    {
       //gtk_label_set_text(label_time_left,"没选中");
       timer_min = g_timeout_add(1000*60,every_minute_callback,NULL);
    }
           
}
void on_menuitem4_activate(GtkCheckMenuItem * menuitem)
{
    unlock_minutes = 0;
    gtk_label_set_text(label_time_left,"");
    gtk_label_set_text(label_message,"widebright的休息提醒小程序");
           
    //禁止其他程序获得键盘消息
    //gdk_keyboard_grab(window->window ,FALSE,GDK_CURRENT_TIME);
}
gboolean main_windows_on_delete (GtkWidget *widget)
{
     if (is_desktop_lock){
         return TRUE;
    }else{
         return gtk_widget_hide_on_delete (widget);
    }

}

//获取程序的文件所在的目录
char * get_exe_path()
{
char *path = malloc(256 * sizeof(char)) ;
if( readlink("/proc/self/exe",path, 256)< 0 )
{
    *path = '\0'; // free(path);
       return path ;
}
   
char *p = strrchr(path,'/');
*++p ='\0';
//printf("current   working   directory   :   %s\n",path);
return path;
}



int
main (int argc, char *argv[])
{
    EggTrayIcon *tray_icon; //通知区图标
    GtkWidget *image;
    GtkWidget *event_box;
    char *exe_path ;
   
#ifdef ENABLE_NLS
    bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
    textdomain (GETTEXT_PACKAGE);
#endif

   
    gtk_set_locale ();
    gtk_init (&argc, &argv);

    window = create_window ();
    gtk_window_set_title(GTK_WINDOW(window), "休息提醒小程序");
   
    gtk_widget_show (window);
    exe_path=get_exe_path();
    if (exe_path ==NULL)
    {
       perror("不能获取到程序的目录");
    }
    strcat (exe_path , "widebright.png");
    gtk_window_set_icon_from_file(GTK_WINDOW(window), exe_path,NULL);
    free(exe_path);
    //窗体透明度
    //gtk_window_set_opacity (GTK_WINDOW(window),0.5);
    //全屏窗口
    //gtk_window_fullscreen(GTK_WINDOW(window));
    //置顶窗口
    //gtk_window_set_keep_above(GTK_WINDOW(window),TRUE);
    //去掉标题栏
    //gtk_window_set_decorated (GTK_WINDOW(window),FALSE);

   
    tray_icon = egg_tray_icon_new ("widebright tray icon");
    event_box = gtk_event_box_new ();
   
    exe_path=get_exe_path();
    if (exe_path ==NULL)
    {
       perror("不能获取到程序的目录");
    }
    strcat (exe_path , "widebright.png");
    image = gtk_image_new_from_file(exe_path) ;
    free(exe_path);
   
    gtk_image_set_from_icon_set(GTK_IMAGE(image),
                                gtk_icon_set_new_from_pixbuf
                                    (gtk_image_get_pixbuf(GTK_IMAGE(image))),
                                GTK_ICON_SIZE_SMALL_TOOLBAR);
   

    gtk_container_add (GTK_CONTAINER (event_box), image);
    gtk_container_add (GTK_CONTAINER (tray_icon), event_box);
   
    g_signal_connect (G_OBJECT (event_box), "button-press-event",
            G_CALLBACK (tray_button_pressed), tray_icon);
   
    gtk_widget_set_tooltip_text (image, "widebright 的休息提醒程序");
   
    gtk_widget_show_all (GTK_WIDGET (tray_icon));
   
    is_desktop_lock =FALSE;
    lock_seconds = 0 ;
    unlock_minutes = 0;
    gtk_label_set_text(label_time_left,"");
    gtk_label_set_text(label_message,"widebright的休息提醒小程序");
    timer_min = g_timeout_add(1000*60,every_minute_callback,NULL);
   
    gtk_widget_hide (window);
       gtk_main ();
    return 0;
}
===========================程序界面的glade文件=================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface>
<widget id="window">
    <property name="visible">True</property>
    <property name="title" translatable="yes">window</property>
    <property name="window_position">GTK_WIN_POS_CENTER</property>
    <property name="default_width">500</property>
    <property name="default_height">400</property>
    <property name="opacity">0.48999999999999999</property>
    <signal name="delete_event" handler="main_windows_on_delete"/>
    <child>
      <widget id="vbox2">
        <property name="visible">True</property>
        <property name="homogeneous">True</property>
        <child>
          <widget id="alignment1">
            <property name="visible">True</property>
            <property name="yalign">1</property>
            <property name="xscale">0</property>
            <property name="yscale">0</property>
            <child>
              <widget id="label_message">
                <property name="visible">True</property>
                <property name="label" translatable="yes">休息十分钟^_^</property>
              </widget>
            </child>
          </widget>
        </child>
        <child>
          <widget id="alignment2">
            <property name="visible">True</property>
            <property name="yalign">0</property>
            <property name="xscale">0</property>
            <property name="yscale">0</property>
            <child>
              <widget id="label_time_left">
                <property name="visible">True</property>
                <property name="ypad">1</property>
                <property name="label" translatable="yes">时间还剩下</property>
              </widget>
            </child>
          </widget>
          <packing>
            <property name="position">1</property>
          </packing>
        </child>
      </widget>
    </child>
</widget>
<widget id="menu1">
    <property name="visible">True</property>
    <child>
      <widget id="menuitem4">
        <property name="visible">True</property>
        <property name="tooltip" translatable="yes">让定时器重新开始计时</property>
        <property name="label" translatable="yes">计时器清零</property>
        <property name="use_underline">True</property>
        <signal name="activate" handler="on_menuitem4_activate"/>
        <child internal-child="image">
          <widget id="menu-item-image1">
            <property name="visible">True</property>
            <property name="stock">gtk-refresh</property>
          </widget>
        </child>
      </widget>
    </child>
    <child>
      <widget id="menuitem1">
        <property name="visible">True</property>
        <property name="tooltip" translatable="yes">禁用锁屏功能</property>
        <property name="label" translatable="yes">暂时不要提醒我</property>
        <property name="use_underline">True</property>
        <signal name="toggled" handler="on_menuitem1_toggled"/>
      </widget>
    </child>
    <child>
      <widget id="menuitem2">
        <property name="visible">True</property>
      </widget>
    </child>
    <child>
      <widget id="menuitem3">
        <property name="visible">True</property>
        <property name="label" translatable="yes">退出</property>
        <property name="use_underline">True</property>
        <signal name="activate" handler="gtk_main_quit"/>
        <child internal-child="image">
          <widget id="menu-item-image2">
            <property name="stock">gtk-quit</property>
          </widget>
        </child>
      </widget>
    </child>
</widget>
</glade-interface>
==============================================

其他图标文件和makefile文件就不贴上来了,完整的程序可以联系我。
这个休息提醒程序还是蛮不错的,很适合我,呵呵。

最新代码已经传到这里了 https://code.google.com/p/relaxreminder/source/browse/
  评论这张
 
阅读(1693)| 评论(10)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017