• 让基于DirectFB的GTK+ 支持全局剪切板


    让基于DirectFBGTK+ 支持全局剪切板

     

    转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd

    作者联系方式:李先静 <xianjimli at hotmail dot com>

    更新时间:2007-7-17

     

    最近发现基于DirectFBGTK+不支持全局剪切板,在一个进程中放到剪切板中的内容,在当前进程内粘贴没有问题,但在另外一个进程中就不行了。GTK+的剪切板虽然功能强大,但使用稍嫌麻烦,一些概念也不太直观,里面的实现就更复杂了,今天花了几个小时才看明白。这里记点笔记:

     

    记得DirectFB提供了SetClipBoardDataGetClipBoardData两个函数,也确认过它是把剪切的数据放在共享内存中的,为什么不支持全局剪切板呢?我浏览了一下gdk-directfb中的代码,发现它没有实现剪切板功能。下载最新的GDK,里面也没有实现剪切板,只好自己动手修改了。

     

    于是在gdkselection-directfb.c中加了两个函数:

    gboolean gdk_set_clipboard_data(const char *mime_type, const void *data, unsigned int size)
    {
       struct timeval timestamp = {0};
     
       return DirectFB->SetClipboardData(DirectFB, mime_type, data, size, &timestamp) == DFB_OK;
    }
     
    gboolean gdk_get_clipboard_data(char **mime_type, void **data, unsigned int* size)
    {
       struct timeval timestamp = {0};

       return DirectFB->GetClipboardData(DirectFB, mime_type, data, size) == DFB_OK;
    }

     

    gtkclipboard.c:gtk_clipboard_set_text向剪切板里存放文本数据,我把原来的gtk_clipboard_set_text改名为gtk_clipboard_set_text_local,因为它只能在当前进程内使用。把gtk_clipboard_set_text的实现做了修改,让它同时把数据放到全局剪切板中,其实现如下:

    void      
    gtk_clipboard_set_text (GtkClipboard *clipboard,
                const gchar  *text,
                gint          len)
    {
      g_return_if_fail (clipboard != NULL);
      g_return_if_fail (text != NULL);

      gdk_set_clipboard_data("text/plain", text, strlen(text) + 1);
      
      gtk_clipboard_set_text_local(clipboard, text, len);
    }

     

    gtkclipboard.ctext_get_func是获取数据时一个回调函数,该函数把数据设置到selection_data对象中。对该函数也做了修改,让它从全局剪切板中取数据,其实现如下:

    static void 
    text_get_func (GtkClipboard     *clipboard,
               GtkSelectionData *selection_data,
               guint             info,
               gpointer          data)
    {                  
      unsigned int size = 0;
      const char* text  = NULL;
      const char* mime_type = NULL;

      gdk_get_clipboard_data(&mime_type, &text, &size);
      
      if(mime_type != NULL && strcmp(mime_type, "text/plain") == 0)
      {
        gtk_selection_data_set_text (selection_data, text, -1);
      }
      else 
      {
        gtk_selection_data_set_text (selection_data, "", -1);
      }
    }

     

    gtk_selection_data_targets_include_text函数用于来获知剪切板中是否有文本内容可供粘贴,通常用该函数来决定粘贴菜单是否灰显。将其修改为如下:

    gtk_selection_data_targets_include_text (GtkSelectionData *selection_data)
    {
      GdkAtom *targets;
      gint n_targets;
      gint i;
      gboolean result = FALSE;
      const char* mime_type = NULL;
      const char* text = NULL;
      unsigned int size = 0;

    GtkClipboard* clipboard = NULL;


      init_atoms ();

      clipboard = gtk_clipboard_get_for_display(selection_data->display,
            GDK_SELECTION_CLIPBOARD);

     if(gdk_get_clipboard_data(&mime_type, &text, &size)
            && mime_type != NULL && strcmp(mime_type, "text/plain") == 0)
          {
              gtk_clipboard_set_text_local(clipboard, text, size);

              result = TRUE;
        }


      return result;
    }  

     

    大致测试了一下,基本上可用,还有几个问题有待解决:

    1.       代码需要优化,避免重复调用gtk_clipboard_set_text_local

    2.       目前只支持文本,其它格式需要做类似的修改。

    3.       修改了GTK的代码,这本来是平台相关的,应该隔离到GDK里面。明天再看看有没有更好的办法。

     

    ~~end~~

  • 相关阅读:
    深入浅出HTTP协议
    HTTP协议 URL
    HTTP Request
    HTTP 响应
    浅谈OpenStack架构
    Google云平台技术架构
    接口文档神器之apidoc
    .haccess 配置生效
    php namespace与use
    mysql 带条件的sum/count 使用技巧
  • 原文地址:https://www.cnblogs.com/zhangyunlin/p/6167704.html
Copyright © 2020-2023  润新知