2015年8月3日 星期一

VM 中使用智慧卡讀卡機

在 VMware 的 VM 中,可以用分享的方式使用智慧卡讀卡機 (smart card reader)。

在 Linux host 中,安裝 pcsc-lite 及 ccid driver。再啟動 pcscd 的 daemon。
Vmare 的 config 中,要加上 usb.ccid.useSharedMode = "TRUE" 的設定

參考
https://pubs.vmware.com/workstation-9/index.jsp?topic=%2Fcom.vmware.ws.using.doc%2FGUID-8AA77FED-BE63-45CB-8FB6-6D7C4A35F76B.html

假如不要使用分享的方式使用智慧卡讀卡機
則修改 VM 的設定檔,例如 Win_XP.vmx ,加入
usb.generic.allowCCID = "TRUE"
usb.ccid.disable = "TRUE"



VMware Workstation Pro 16.0

參考 Disable Smart Card Sharing

修改 /etc/vmware/config,加上
usb.ccid.useSharedMode = "FALSE"

不過還是看不到,就算把 "Show all USB input devices" 打勾也是看不到。











2015年8月1日 星期六

在 Linux 版的 Sublime Text 3 中,使用 gcin 輸入中文

 今天試用了 Sublime Text 3, 要支援中文輸入,得用 fcitx 輸入法,但是實在不習慣它的拆字界面,還是覺得使用 gcin 比較順手。但知道憑一己之力,不知那時才有成功的可能。很幸運的是,爬文幾個小時候,發現在網友的互相討論之下,已有了解決方式。
參考連結如下。

http://www.sublimetext.com/forum/viewtopic.php?f=3&t=7006&start=10#p41343
http://www.sublimetext.com/forum/viewtopic.php?f=3&t=7006&start=20#p61143
(以上為 Sublime Text forum)
http://whitequark.org/blog/2014/04/14/xcompose-support-in-sublime-text/

PS: 我使用的是 Gentoo Linux

原始碼
    /*
    sublime-imfix.c
    Use LD_PRELOAD to interpose some function to fix sublime input method support for linux.
    By Cjacker Huang <jianzhong.huang at i-soft.com.cn>
    By whitequark@whitequark.org

    How to compile:
    gcc -shared -o libsublime-imfix.so sublime_imfix.c  `pkg-config --libs --cflags gtk+-2.0` -fPIC
    How to use:
    LD_PRELOAD=./libsublime-imfix.so sublime_text

    Changes:
    2014 06-09
    1, Fix cursor position update for sublime text 3.
    2, Combine the codes from whitequark(fix for xim immodule) and add cursor update support for XIM immodule.
    */

    /*for RTLD_NEXT*/
    #define _GNU_SOURCE

    #include <gtk/gtk.h>
    #include <gdk/gdkx.h>
    #include <assert.h>
    #include <dlfcn.h>
    #include <stdio.h>
    #include <string.h>
    #include <gtk/gtk.h>
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>

    #ifdef VERBOSE
    #define DEBUG(fmt, ...) do { \
        FILE* err = fopen("/tmp/libsublime-immethod-fix.log", "a"); \
        if (err) { \
          fprintf(err, fmt, __VA_ARGS__); \
          fclose(err); \
        } \
      } while(0)
    #else
    #define DEBUG(fmt, ...)
    #endif

    typedef GdkSegment GdkRegionBox;

    struct _GdkRegion
    {
      long size;
      long numRects;
      GdkRegionBox *rects;
      GdkRegionBox extents;
    };

    GtkIMContext *local_context;

    //this func is interposed to support cursor position update.
    void gdk_region_get_clipbox (const GdkRegion *region,
                GdkRectangle    *rectangle)
    {
      g_return_if_fail (region != NULL);
      g_return_if_fail (rectangle != NULL);

      rectangle->x = region->extents.x1;
      rectangle->y = region->extents.y1;
      rectangle->width = region->extents.x2 - region->extents.x1;
      rectangle->height = region->extents.y2 - region->extents.y1;
      GdkRectangle rect;
      rect.x = rectangle->x;
      rect.y = rectangle->y;
      rect.width = 0;
      rect.height = rectangle->height;
      //The caret width is 2 in sublime text 2
      //And is 1 in sublime text 3.
      //Maybe sometimes we will make a mistake, but for most of the time, it should be the caret.
      if((rectangle->width == 2 || rectangle->width == 1)  && GTK_IS_IM_CONTEXT(local_context)) {
            gtk_im_context_set_cursor_location(local_context, rectangle);
      }
    }

    //this is needed, for example, if you input something in file dialog and return back the edit area
    //context will lost, so here we set it again.
    static GdkFilterReturn event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer im_context)
    {
        XEvent *xev = (XEvent *)xevent;
        if(xev->type == KeyRelease && GTK_IS_IM_CONTEXT(im_context)) {
           GdkWindow * win = g_object_get_data(G_OBJECT(im_context),"window");
           if(GDK_IS_WINDOW(win))
             gtk_im_context_set_client_window(im_context, win);
        }
        return GDK_FILTER_CONTINUE;
    }

    void gtk_im_context_set_client_window (GtkIMContext *context,
              GdkWindow    *window)
    {
        GtkIMContextClass *klass;
        g_return_if_fail (GTK_IS_IM_CONTEXT (context));
        klass = GTK_IM_CONTEXT_GET_CLASS (context);
        if (klass->set_client_window)
            klass->set_client_window (context, window);

        //below is our interposed codes to save the context to local_context.
        if(!GDK_IS_WINDOW (window))
            return;
        g_object_set_data(G_OBJECT(context),"window",window);
        int width = gdk_window_get_width(window);
        int height = gdk_window_get_height(window);
        if(width != 0 && height !=0) {
            gtk_im_context_focus_in(context);
            local_context = context;
        }
        //only add this event_filter when using 'fcitx' immodule.
        //for xim immodule, this function is as same as original from gtk2.
        const gchar * immodule = g_getenv("GTK_IM_MODULE");
        if(immodule && !strcmp(immodule, "fcitx")) {
            gdk_window_add_filter (window, event_filter, context);
        }
    }

    /*below codes is from whitequark, fix for xim immodule */

    /* See gtkimcontextxim.c */
    GType gtk_type_im_context_xim = 0;

    #define GTK_TYPE_IM_CONTEXT_XIM            (gtk_type_im_context_xim)
    #define GTK_IM_CONTEXT_XIM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIM))
    #define GTK_IM_CONTEXT_XIM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
    #define GTK_IS_IM_CONTEXT_XIM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_IM_CONTEXT_XIM))
    #define GTK_IS_IM_CONTEXT_XIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_XIM))
    #define GTK_IM_CONTEXT_XIM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))

    typedef struct _GtkIMContextXIM       GtkIMContextXIM;
    typedef struct _GtkIMContextXIMClass  GtkIMContextXIMClass;

    struct _GtkIMContextXIMClass
    {
      GtkIMContextClass parent_class;
    };

    typedef struct _StatusWindow StatusWindow;
    typedef struct _GtkXIMInfo GtkXIMInfo;

    struct _GtkIMContextXIM
    {
      GtkIMContext object;

      GtkXIMInfo *im_info;

      gchar *locale;
      gchar *mb_charset;

      GdkWindow *client_window;
      GtkWidget *client_widget;

   /* The status window for this input context; we claim the
    * status window when we are focused and have created an XIC
    */
      StatusWindow *status_window;

      gint preedit_size;
      gint preedit_length;
      gunichar *preedit_chars;
      XIMFeedback *feedbacks;

      gint preedit_cursor;

      XIMCallback preedit_start_callback;
      XIMCallback preedit_done_callback;
      XIMCallback preedit_draw_callback;
      XIMCallback preedit_caret_callback;

      XIMCallback status_start_callback;
      XIMCallback status_done_callback;
      XIMCallback status_draw_callback;

      XIMCallback string_conversion_callback;

      XIC ic;

      guint filter_key_release : 1;
      guint use_preedit : 1;
      guint finalizing : 1;
      guint in_toplevel : 1;
      guint has_focus : 1;
    };

    static GClassInitFunc orig_gtk_im_context_xim_class_init;
    static GType (*orig_g_type_module_register_type)(
            GTypeModule *, GType, const gchar *, const GTypeInfo *,
            GTypeFlags);
    static gboolean (*orig_gtk_im_context_xim_filter_keypress)(
            GtkIMContext *context, GdkEventKey *event);

    static gboolean
    hook_gtk_im_context_xim_filter_keypress(GtkIMContext *context, GdkEventKey *event)
    {
      GtkIMContextXIM *im_context_xim = GTK_IM_CONTEXT_XIM(context);
      if (!im_context_xim->client_window) {
        DEBUG("im_context_xim == %p\n", im_context_xim);
        DEBUG("event->window == %p\n", event->window);

        gtk_im_context_set_client_window(context, event->window);
      }

      return orig_gtk_im_context_xim_filter_keypress(context, event);
    }

    static void hook_gtk_im_context_xim_class_init (
            GtkIMContextXIMClass *class)
    {
      orig_gtk_im_context_xim_class_init(class, NULL); /* wat? */

      GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);

      assert(!orig_gtk_im_context_xim_filter_keypress);
      orig_gtk_im_context_xim_filter_keypress = im_context_class->filter_keypress;
      im_context_class->filter_keypress = hook_gtk_im_context_xim_filter_keypress;
      DEBUG("orig_gtk_im_context_xim_filter_keypress: %p\n",
            orig_gtk_im_context_xim_filter_keypress);
    }

    GType
    g_type_module_register_type (GTypeModule *module,
                                 GType parent_type,
                                 const gchar *type_name,
                                 const GTypeInfo *type_info,
                                 GTypeFlags flags)
    {
      if (!orig_g_type_module_register_type) {
        orig_g_type_module_register_type = dlsym(RTLD_NEXT, "g_type_module_register_type");
        assert(orig_g_type_module_register_type);
      }

      if (type_name && !strcmp(type_name, "GtkIMContextXIM")) {
        assert(!orig_gtk_im_context_xim_class_init);
        orig_gtk_im_context_xim_class_init = type_info->class_init;

        assert(sizeof(GtkIMContextXIM) == type_info->instance_size);

        const GTypeInfo hook_im_context_xim_info =
        {
          type_info->class_size,
          type_info->base_init,
          type_info->base_finalize,
          (GClassInitFunc) hook_gtk_im_context_xim_class_init,
          type_info->class_finalize,
          type_info->class_data,
          type_info->instance_size,
          type_info->n_preallocs,
          type_info->instance_init,
        };

        DEBUG("orig_gtk_im_context_xim_class_init: %p\n", orig_gtk_im_context_xim_class_init);

        gtk_type_im_context_xim =
          orig_g_type_module_register_type(module, parent_type,
              type_name, &hook_im_context_xim_info, flags);

        return gtk_type_im_context_xim;
      }

      return orig_g_type_module_register_type(module, parent_type, type_name, type_info, flags);
    }



編譯:
$ gcc -shared -o libsublime-imfix.so sublime-imfix.c  `pkg-config --libs --cflags gtk+-2.0` -fPIC

設定環境變數:
$ export GTK_IM_MODULE=xim

執行:
$ LD_PRELOAD=./libsublime-imfix.so subl3

如上,Sublime Text 3 中文切換,必需將 GTK_IM_MODULE 設成 xim
但是會讓所有的程式,gcin 的輸入視窗都黏在視窗左上角,不會跟著程式的游標 。
只好要用 Sublime Text 時,才設成 xim。終究能夠直接輸入中文,比起以往必需用 copy and paste 來輸入中文,要好得多了。

另外,有下面一些小小的不便。
  • 在輸入中文時,若想用 Backspace 來修正時,無法刪除輸入的字根,反而會刪除編輯的內容。必須按 Escape 鍵,取消所有的輸入,重新輸一次。
  • 無法用 ctrl+, 或 ctrl+. 來輸入中文的豆號和句號。
修改 sublime-text-3.desktop 中的執行指令
Exec=bash -c 'GTK_IM_MODULE=xim LD_PRELOAD=/usr/local/lib/libsublime-imfix.so subl3' %F



關於中文輸入法的環境變數的設定,可以參考
http://moto.debian.tw/viewtopic.php?t=9525

如果是 GTK(gnome) 的程式,可能你沒有設定 GTK_IM_MODULE=gcin, QT 的程式必須在在 qtconfig 設定 XIM over-the-spot。如果你的 QT 支援 QT_IM_MODULE,只要設定 QT_IM_MODULE=gcin就可以了。

2015年7月26日 星期日

Laravel, 自動載入自訂 Namespace

在 Laravel 5.0 中,若是在預設的 app 目錄下,建立自訂 Namespace 或檔案,將會自動載入。
但若是自訂的 Namespace 或是檔案,是在與 app 同一層的目錄下,則必須自行設定,才會自動載入。

修改 composer.json 檔案,在 "autoload" 的下面,加上自訂的項目。下面的範例中,新增了要自動載入的項目 "myFunction.php""Nspace" 的 namespace。

"autoload": {
        "classmap": [
            "database"
        ],
        "files": [
            "myfolder/myFunction.php"
        ],

        "psr-4": {
            "App\\": "app/",
            "Nspace\\": "Nspace/"
        }
    },


然後,執行 composer dump-autoload,其將在 vendor/composer 的目錄下,產生對應的 autoload 的檔案,例如 autoload_psr4.phpautoload_files.php 等。

其於 autoload_psr4.php 中,新增一行
  'Nspace\\' => array($baseDir . '/Nspace'),

瞭解後,亦可自行手動加入吧。

後記 (2016-10-28)

雖然,經測試後,這樣做可以自動載入自訂的 Namespace,不過,我後來都偷懶,直接放在 APP的目錄下,比較省事。

2015年6月20日 星期六

多讀書,持續成長

想要持續成長,要多讀書。

生活在都巿中的人,包括我身邊的同事,吃一餐飯,花個 3,5 百元,覺得是合理的。但是,一整年,可能不曾買過一本書。5百元的書,一般會認為太貴了。可是,看看歐美的書籍的訂價,折算成台幣,都超過千元。當然,中國的書,卻比台灣便宜許多。

那一本書的價值,到底多少,才會覺得划算呢?

從交易的角度來看,我認為能讓自己在交易過程中,賺回買那一本書的錢,在價值上,就已超過它的價格。所以,有時候買學習交易或投資的書,只是覺得其中某一段講得有道理。

我在剛開始學習交易 (或投資) 時,幾乎可以找到的書都看,一心想參透其中的奧秘。其中,有些東西,在當時,並不能體會,甚至覺得他言過其實。但在跌跌撞撞下,經過 7,8 年,有時在挫折或困境中,突然想起以前念過的某句話,或某種說法,才會明白,原來是在說這個。

大部分人都會有個疑問,那些書會說出真正有用的東西嗎? 我想或許可以自己問自己,我自己吃飯的本事,會完全告訴別人嗎? 噢,當然不會。

既然沒有人會把真正的秘訣寫出來,那為何要讀書呢? 我個人的看法是,就像瞎子摸象一般,多讀書,再加上練習,慢慢的能摸索出一條路來。

反過來說,常常我們在當下一心追尋的東西,並非真的是重要的,反而人家說出來真正有道理的東西,我們會覺得那太過平凡,甚至是笑話。就像,某本書上,作者提到曾問某人,交易最重要的是什麼,對方答 "成本",可是,大部分人並不同意。我自己在練習幾年後,發現每天不論賺賠,只有券商是穩定有收入的,自己簡直就是幫券商在打工。



2015年6月18日 星期四

獲利之道 -- 等待好機會,再大力出擊

獲利之道 -- 等待好機會,再大力出擊

前輩的經驗,獲利,不在勝率多少,而在獲利的多少。做對一次,可以彌補 3 次的失敗。

要確定,等待什麼樣的機會 -- 這必需多看歷史線圖,然後,天天練習,訓練感覺。

無法等待,是因為 -- 怕錯失機會,怕機會一去不回頭。
要克服此因素,只能採用試單的方式。

等待反轉再出手,相對上比較安全。

要從 pattern 上,才能判斷是要反轉或延續。

不管做對或做錯,出場都是很艱難的一部分。不論如何,假若進場後,並未如預期的發展,應該減少部位,減輕心理壓力,並且減少停損的損失。


2015年6月11日 星期四

我是天才

常常,小有一些成就時,心裡就不禁得意的想,「我是天才」。
這是一個要開始賠錢的徵兆,而且會連續賠錢,直到承認自己一無是處為止。
學習交易的過程,就在自認是天才與笨蛋之間擺盪,直到認清自己為止。

我們天天都在走路,沒有人會認為走個 2,3百公尺,有什麼了不起,也不會覺得爬一層樓,會覺得很厲害。
可是,對一個剛學走路的小孩,這卻很不容易,值得高興一番。

交易,到最後,就是一種工作罷了,和在巿場賣炸雞排,沒什麼兩樣,只是比較不容而已。
到最後,輸贏只是工作的一部分。每天,照著策略,等待機會,嘗試,放棄;或嘗試,追擊,出場。

同時,也知道自己,隨著價格上上下下,心也上下不已,在貪婪與恐懼之間擺盪。

2015年6月10日 星期三

部位大小,取決於風險承受度

交易部位的大小,取決於自己的風險承受度,並非資金的多少。
所持有的部位,在確定進場理由消失,或確認反轉前,振盪必須在能夠忍受的範圍內。
換句話說,就是停損出場,所賠旳錢,不會讓自己心疼。

只有這樣,才能等待趨勢的發展,而不會因為虧損超出自己所能忍受,而將部位提早平掉。

網誌存檔