absurd的专栏

欢迎大家加入Linux Mobile Research,本圈子主要致力于基于linux的嵌入式系统的学习和研究,包括内核、驱动、GUI、MMI、软件设计方法和软件优化等方面,欢迎大家加入,无论是高手还是新手,一起学习共同进步。

李先静ID:absurd
971273次访问,排名25好友130人,关注者135
Only those who attempt the absurd can achieve the impossible.
absurd的文章
原创 368 篇
翻译 1 篇
转载 55 篇
评论 1494 篇
李先静的公告
Broncho linux手机平台是构建在linux 2.6 之上,采用GTK+作为GUI的手机平台。欢迎大家到broncho.cn上交流,网站还在建设之中,近期我们会陆续把整理好的文档和代码更新到上去。
最近评论
shijie1983:雅虎管理咨询
网络营销
特价机票
杭州特价机票
杭州打折机票
杭州机票
杭州化妆培训
shijie1983:杭州特价机票
杭州打折机票
杭州机票
杭州化妆培训
unailbobo:谢谢
unailbobo:关于1,我查看源码没有看到gdk_events_init里有关于mainloop的任何代码???
文章分类
收藏
相册
1.个人相册
2.设计备忘录用图
3.设计本质论用图
4.scim架构用图
6.临时文件
7.其它文件
8.研究笔记用图
marvell-linux
1.友情链接
aimself@CSDN(RSS)
directfb中文网站(RSS)
Eric's Little Hut
eye_of_back的专栏(RSS)
Linux Mobile Research
Phoenix@上海(RSS)
segments的专栏(RSS)
study's Blog(RSS)
tracestudio
伐木丁丁鸟鸣嘤嘤(RSS)
会飞的鱼的专栏(RSS)
创系的技术博客
小四的BLOG(RSS)
小马哥的博客(RSS)
开源电信(RSS)
御风剑客
新奇的BLOG
易军军的网络家
李吉群的专栏(RSS)
2.亲情链接
凤凰的幸福蓄水池(RSS)
我的相册
3.软界高手
Donald E. Knuth (RSS)
孟岩(RSS)
透明(RSS)
4.LinuxMobile
celinuxforum(RSS)
GPE(RSS)
maemo.org(RSS)
opensource.motorola
palowireless
5.XWindow
Jserv's blog(RSS)
Keith Packard(RSS)
6.技术资源
7.开源项目
freedesktop(RSS)
GNU(RSS)
GTK+(RSS)
matchbox(RSS)
pxa27x-linux/
8.我的BLOG镜像
absurd@chinaunix
absurd@msn
My English BLOG(RSS)
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky

原创 GTK/DFB中的WaitCursor收藏

新一篇: GTK/DirectFB两个闪烁的问题 | 旧一篇: GTK+/DFB优化

GTK/DFB中的WaitCursor

转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>

虽然我们实现了单实例应用程序,即在应用程序第二次运行时自动激活第一个实例,并将参数传递给第一个运行实例。但如果在桌面连续点击应用程序的起动图标,会让应用程序起动过过程变得更慢,为了避免这种情况出现,有必要实现类似WaitCursor机制。GTK+-2.6/DFB中没有实现WaitCursor,新版本中好像也没有,只好自己动手了:

  • 在gdkwindow.h文件中增加两个函数:
gint          gdk_window_begin_wait_cursor(GdkWindow   *window);
gint          gdk_window_end_wait_cursor(GdkWindow   *window);
  • 在_GdkWindowObject结构中增加waitcursor的信息。
  struct
  {
    gint ref;
    gint elapsed;
    gint timeout_id;
  }wait_cursor;
  • 在gdkwindow-directfb.c中实现这两个函数,很简单,就是实现一个定时器,每隔一段时间更新一下Cursor。
gint gdk_window_begin_wait_cursor(GdkWindow   *window)
{
  GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
  g_return_val_if_fail(private != NULL, 0);

  private->wait_cursor.ref++;

  if(private->wait_cursor.ref == 1 && update_wait_cursor(window))
  {
    private->wait_cursor.elapsed = 0;
    private->wait_cursor.timeout_id = g_timeout_add(250, update_wait_cursor, window);
#ifndef LINUX_I386  
    gdk_directfb_display->layer->EnableCursor(gdk_directfb_display->layer, 1);
#endif
  }

  return private->wait_cursor.ref;
}

gint gdk_window_end_wait_cursor(GdkWindow   *window)
{
  GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
  if(private == NULL || private->wait_cursor.ref <=0)
  {
    return 0;
  }
  private->wait_cursor.ref--;
#ifndef LINUX_I386  
  gdk_directfb_display->layer->EnableCursor(gdk_directfb_display->layer, private->wait_cursor.ref != 0);
#endif

  return private->wait_cursor.ref;
}

static gboolean update_wait_cursor(gpointer user_data)
{
  GdkWindow   *window = user_data;
  GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
  g_return_val_if_fail(private != NULL, FALSE);

  int cursor_type = GDK_WAIT_BEGIN +
(private->wait_cursor.elapsed)%(GDK_WAIT_END - GDK_WAIT_BEGIN + 1);
  GdkCursor* cursor = gdk_cursor_new_for_display (gdk_display_get_default(),
cursor_type);
  gdk_window_set_cursor(window, cursor);
  gdk_cursor_unref(cursor);

  private->wait_cursor.elapsed++;
  if(private->wait_cursor.ref <= 0)
  {
    private->wait_cursor.elapsed = 0;
    private->wait_cursor.timeout_id = 0;
    gdk_window_set_cursor(window, NULL);
  }

  return private->wait_cursor.ref > 0;
}

在gdkcursor-directfb.c中加载Cursor图片,Cursor图片与主题关联:
static GdkCursor *
gdk_cursor_load_wait_cursor(GdkDisplay    *display,
                            GdkCursorType  cursor_type)
{
  GdkCursor* cursor = NULL;
  if(cursor_type >= GDK_WAIT_BEGIN && cursor_type <= GDK_WAIT_END)
  {
    int index = 0;
    GValue value = {0};
    char* theme = NULL;
    char filename[260] = {0};
    GObject* setting = g_object_get_data (G_OBJECT (gdk_screen_get_default()),
"gtk-settings");
    g_return_val_if_fail(setting != NULL, NULL);

    g_value_init(&value, G_TYPE_STRING);
    g_object_get_property (setting, "gtk-icon-theme-name", &value);
    theme = g_value_get_string(&value);
    index = cursor_type-GDK_WAIT_BEGIN + 1;
    snprintf(filename, sizeof(filename), WAITCURSOR, theme, index);
    if((cursor = gdk_cursor_new_from_name(display, filename)) == NULL)
    {
        snprintf(filename, sizeof(filename), WAITCURSOR, "hicolor", index);
        cursor = gdk_cursor_new_from_name(display, filename);
        g_debug("load %p %s", cursor, filename);
    }
    g_value_reset(&value);
  }

  return cursor;
}
  • 要注意的是gdk_cursor_new_from_pixbuf有点问题,pixbuf中的格式居然是GBRA而不是代码中要求的ARGB,要修改一下这个函数,否则无法实现透明效果。

  • 为了避免enable/disable时闪现一下传统的cursor,修改gdk_cursor_new_for_display,让alpha=0,让传统cursor全透明。
  • 出现WaitCursor时,丢弃按键和笔点事件,修改gdk_event_translate:
  if(private->wait_cursor.ref > 0)
  {
    switch (dfbevent->type)
    {
      case DWET_BUTTONDOWN:
      case DWET_BUTTONUP:
      case DWET_MOTION:
      case DWET_KEYDOWN:
      case DWET_KEYUP:
            return NULL;
      default:break;
    }
  }

在手机上和PC上有点不问,手机上平时不能显示cursor,而且waitcursor的位置要居中,所以还要修改DirectFB:

  • 在dfb_layer_context_create_window中禁止cursor,把以前的dfb_windowstack_cursor_enable(core, stack, true )改为dfb_windowstack_cursor_enable( core, stack, false )
  • 在wm_update_cursor里让位置居中:

#ifndef LINUX_I386
     if(context->stack->cursor.enabled && (flags & CCUF_POSITION))
     {
          stack->cursor.hot.x = stack->cursor.x - (context->width/2 -
stack->cursor.size.w);
          stack->cursor.hot.y = stack->cursor.y - (context->height/2 -
stack->cursor.size.h);
     }
#endif

测试了一下,基本功能正常。

~~end~~













发表于 @ 2008年07月18日 20:56:00|评论(loading...)|收藏

新一篇: GTK/DirectFB两个闪烁的问题 | 旧一篇: GTK+/DFB优化

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 李先静