¿©±â¼ ¿ì¸®´Â °£´ÜÇÑ ±×¸®±â ÇÁ·Î±×·¥À» ¸¸µé °ÍÀÌ´Ù. ±× °úÁ¤¿¡¼ ¿ì¸®´Â ¸¶¿ì½º À̺¥Æ®¸¦ ¾î¶»°Ô ´Ù·ç´ÂÁö ¾Ë¾Æº¼ °ÍÀÌ°í, À©µµ ¾È¿¡ ¾î¶»°Ô ±×¸²À» ±×¸®´ÂÁö, ±×¸®°í ÇȽº¸ÊÀ» ¹è°æÀ¸·Î Çؼ ´õ ³ªÀº ±×¸²À» ±×¸®´Â ¹æ¹ýµµ ¹è¿ï °ÍÀÌ´Ù. °£´ÜÇÑ ±×¸®±â ÇÁ·Î±×·¥À» ¸¸µç ÈÄ¿¡, ¿ì¸®´Â ±×°Í¿¡ drawing tablet °°Àº XInput device¸¦ Áö¿øÇÏ´Â µîÀÇ È®ÀåÀ» ½ÃµµÇÒ °ÍÀÌ´Ù. GTK´Â ±×·± device µé·ÎºÎÅÍ pressure¿Í tilt°°Àº, È®ÀåµÈ Á¤º¸¸¦ ¾ò¾î³¾ ¼ö ÀÖ°Ô ÇÏ´Â support routineÀ» Á¦°øÇÑ´Ù.
¿ì¸®°¡ ÀÌ¹Ì »ìÆ캻 GTKÀÇ ½Ã±×³ÎÀº ¸Þ´º ¾ÆÀÌÅÛ ¼±ÅÃó·³ °í¼öÁØÀÇ µ¿ÀÛÀ» À§ÇÑ °ÍµéÀÌ´Ù. ÇÏÁö¸¸, ¸¶¿ì½ºÀÇ ¿òÁ÷ÀÓÀ̶óµçÁö Å°º¸µåÀÇ ´·¯Áü°°Àº, Àú¼öÁØÀÇ Á¦¾î¸¦ °øºÎÇÏ´Â °Íµµ ¶§¶§·Î À¯¿ëÇÒ °ÍÀÌ´Ù. GTK ½Ã±×³Î Áß¿¡´Â ÀÌ·± Àú¼öÁØÀÇ À̺¥Æ®¸¦ À§ÇÑ °Íµéµµ ÀÖ´Ù. ÀÌ·± À̺¥Æ®¸¦ À§ÇÑ Çڵ鷯´Â ±×·± À̺¥Æ®¿¡ ´ëÇÑ Á¤º¸¸¦ °¡Áö°í ÀÖ´Â ±¸Á¶Ã¼¸¦ °¡¸®Å°°í ÀÖ´Â ¶Ç´Ù¸¥ ÀÎÀÚµéÀ» °¡Áö°Ô µÈ´Ù. ¿¹¸¦µé¾î, motion event Çڵ鷯´Â ¾Æ·¡¿Í °°Àº GdkEventMotion ±¸Á¶Ã¼¸¦ ÇâÇÑ Æ÷ÀÎÅ͸¦ ÀÎÀÚ·Î °¡Áö°í ÀÖ´Ù.
struct _GdkEventMotion
{
GdkEventType type;
GdkWindow *window;
guint32 time;
gdouble x;
gdouble y;
...
guint state;
...
};
ÀÎÀÚ type
Àº À̺¥Æ®ÀÇ Å¸ÀÔÀÌ µÇ°í, ÀÌ °æ¿ì¿¡´Â GDK_MOTION_NOTIFY
ÀÌ´Ù.
ÀÎÀÚ window
´Â ±× À̺¥Æ®°¡ ¹ß»ýÇÑ À©µµ°¡ µÉ °ÍÀÌ´Ù.
ÀÎÀÚ x
¿Í y
´Â ±× À̺¥Æ®ÀÇ
ÁÂÇ¥À̸ç, state´Â À̺¥Æ®°¡ ¹ß»ýÇßÀ» ¶§ÀÇ modifier state
¸¦ ¼³Á¤ÇÑ´Ù(Áï, ¾î¶²
modifier key¿Í modifier buttonÀÌ ´·¯Á³´ÂÁö ¼³Á¤). ÀÌ°ÍÀº ¾Æ·¡ º¸ÀÌ´Â
»ó¼ö°ªµéÀ» ºñÆ® OR½ÃŲ °ÍÀÌ´Ù.
GDK_SHIFT_MASK
GDK_LOCK_MASK
GDK_CONTROL_MASK
GDK_MOD1_MASK
GDK_MOD2_MASK
GDK_MOD3_MASK
GDK_MOD4_MASK
GDK_MOD5_MASK
GDK_BUTTON1_MASK
GDK_BUTTON2_MASK
GDK_BUTTON3_MASK
GDK_BUTTON4_MASK
GDK_BUTTON5_MASK
´Ù¸¥ ½Ã±×³Îµé¿¡ ´ëÇؼó·³, À̺¥Æ®°¡ ¹ß»ýÇßÀ» ¶§ ±×°ÍÀÌ ¾î¶² °ÇÁö °áÁ¤
Çϱâ À§ÇØ ¿ì¸®´Â gtk_signal_connect()
¸¦ ÀÌ¿ëÇÑ´Ù. ±×·¯³ª ¶ÇÇÑ ¿ì¸®°¡ ¾î¶²
À̺¥Æ®°¡ ŽÁöµÇ¾îÁö±æ ¿øÇÏ´ÂÁö GTK°¡ ¾Ë ¼ö ÀÖµµ·Ï ÇؾßÇÑ´Ù. À̸¦ À§Çؼ´Â
ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ´Ù.
void gtk_widget_set_events (GtkWidget *widget,
gint events);
µÎ ¹ø° ÀÎÀÚ´Â ¿ì¸®°¡ °ü½ÉÀ» °¡Áø À̺¥Æ®¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ°ÍÀº ¿©·¯ °¡ÁöÀÇ À̺¥Æ®¸¦ À§Çؼ ¸î°¡Áö »ó¼ö¸¦ ºñÆ® OR½ÃŲ °ÍÀÌ´Ù. ¾ÕÀ¸·ÎÀÇ ÂüÁ¶¸¦ À§Çؼ ÀÌ »ó¼öµé¸¦ ¼Ò°³ÇÑ´Ù.
GDK_EXPOSURE_MASK
GDK_POINTER_MOTION_MASK
GDK_POINTER_MOTION_HINT_MASK
GDK_BUTTON_MOTION_MASK
GDK_BUTTON1_MOTION_MASK
GDK_BUTTON2_MOTION_MASK
GDK_BUTTON3_MOTION_MASK
GDK_BUTTON_PRESS_MASK
GDK_BUTTON_RELEASE_MASK
GDK_KEY_PRESS_MASK
GDK_KEY_RELEASE_MASK
GDK_ENTER_NOTIFY_MASK
GDK_LEAVE_NOTIFY_MASK
GDK_FOCUS_CHANGE_MASK
GDK_STRUCTURE_MASK
GDK_PROPERTY_CHANGE_MASK
GDK_PROXIMITY_IN_MASK
GDK_PROXIMITY_OUT_MASK
gtk_widget_set_events()
¸¦ È£ÃâÇÒ ¶§ °üÂûµÇ¾î¾ß ÇÒ ¸î °³ÀÇ ¹Ì¹¦ÇÑ »çÇ×ÀÌ
ÀÖ´Ù. ¸ÕÀú, ±×°ÍÀº GTK widgetÀ» À§ÇÑ XÀ©µµ°¡ ¸¸µé¾îÁö±â ÀÌÀü¿¡ È£ÃâµÇ¾î¾ß
ÇÑ´Ù. Áï, ÀÌ°ÍÀº widgetÀ» »õ·Î ¸¸µç Á÷ÈÄ¿¡ È£ÃâµÇ¾î¾ß ÇÑ´Ù´Â ¸»ÀÌ´Ù. µÑ°
·Î, ±× widgetÀº °ü·ÃµÈ XÀ©µµ¸¦ ²À °¡Á®¾ß ÇÑ´Ù. È¿À²À» À§Çؼ ¸¹Àº widget
typeµéÀº ±×µé¸¸ÀÇ À©µµ¸¦ °¡ÁöÁö ¾Ê°í ±×µéÀÇ parent À©µµ ¾È¿¡ ±×·Á³Ö´Â´Ù.
ÀÌ·± widgetÀº ´ÙÀ½°ú °°Àº °ÍµéÀÌ´Ù.
GtkAlignment
GtkArrow
GtkBin
GtkBox
GtkImage
GtkItem
GtkLabel
GtkPaned
GtkPixmap
GtkScrolledWindow
GtkSeparator
GtkTable
GtkViewport
GtkAspectFrame
GtkFrame
GtkVPaned
GtkHPaned
GtkVBox
GtkHBox
GtkVSeparator
GtkHSeparator
ÀÌ·± À̺¥Æ®µéÀ» ŽÁöÇϱâ À§ÇØ ¿ì¸®´Â EventBox widgetÀ» ÇÊ¿ä·Î ÇÑ´Ù. ÀÚ¼¼ ÇÑ °ÍÀº The EventBox WidgetÀ» ÂüÁ¶Ç϶ó.
¿ì¸®ÀÇ ±×¸®±â ÇÁ·Î±×·¥¿¡¼´Â
¸¶¿ì½º ¹öÆ°ÀÌ ´·¯Áö´Â °Í°ú ¿òÁ÷ÀÌ´Â °ÍÀ» ŽÁöÇÏ°í ½Í¾îÇϹǷÎ,
GDK_POINTER_MOTION_MASK
¿Í GDK_BUTTON_PRESS_MASK
¸¦ ¼³Á¤ÇÑ´Ù.
¿ì¸®´Â ¶ÇÇÑ À©µµ°¡
´Ù½Ã ±×·ÁÁ®¾ß ÇÒ ¶§¸¦ ¾Ë¾Æ¾ß ÇϹǷΠGDK_EXPOSURE_MASK
µµ ¼³Á¤ÇÑ´Ù. ºñ·Ï
¿ì¸®´Â À©µµÀÇ Å©±â°¡ º¯ÇßÀ» ¶§¸¦ Configure event·Î½á ŽÁöÇØ¾ß ÇÏÁö¸¸, ¿ì¸®´Â
À̸¦ À§ÇØ GDK_STRUCTURE_MASK
flag¸¦ ¼³Á¤ÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ÀÌ°ÍÀº ¸ðµç À©µµ¿¡
´ëÇØ ÀÚµ¿ÀûÀ¸·Î ¼³Á¤µÇ±â ¶§¹®ÀÌ´Ù.
±×·±µ¥ GDK_POINTER_MOTION_MASK
¸¦ ¼³Á¤
ÇÏ´Â µ¥ ÀÖ¾î ¹®Á¦Á¡ÀÌ ÀÖ´Ù´Â °ÍÀÌ ¹àÇôÁú °ÍÀÌ´Ù. ÀÌ°ÍÀº »ç¿ëÀÚ°¡ ¸¶¿ì½º¸¦
¿òÁ÷ÀÏ ¶§¸¶´Ù ¼¹ö°¡ event queue¿¡ motion event¸¦ °è¼Ó ´õÇÒ °ÍÀÌ´Ù. ¾î¶²
motion event¸¦ ´Ù·ç±â À§ÇØ 0.1ÃÊ°¡ °É¸°´Ù°í »ý°¢ÇØ º¸ÀÚ. ±×·¯³ª X ¼¹ö´Â
¸Å 0.05Ãʸ¶´Ù »õ·Î¿î motionÀ» queue¿¡ ÀúÀåÇÑ´Ù. ¿ì¸®´Â °ð »ç¿ëÀÚ°¡ ±×¸®´Â
µ¥ ´ëÇÑ ¹æ¹ýÀ» °¡Áö°Ô µÉ °ÍÀÌ´Ù. ¸¸¾à »ç¿ëÀÚ°¡ 5Ãʵ¿¾È ±×¸²À» ±×¸®¸é,
±×µéÀÌ ¸¶¿ì½º ¹öÆ°À» ³õ°í ³ ÈÄ ¶Ç´Ù¸¥ 5ÃÊ°¡, ±×°ÍÀ» Àâ¾Æ³»±â À§ÇØ ÇÊ¿äÇÏ°Ô
µÉ °ÍÀÌ´Ù. ¿ì¸®°¡ ¿øÇÏ´Â °ÍÀº ÁøÇàµÇ´Â °¢°¢ÀÇ À̺¥Æ®¿¡ ´ëÇØ ´Ü ÇϳªÀÇ motion
event¸¦ ŽÁöÇÏ´Â °ÍÀÌ´Ù. ÀÌ·¸°Ô Çϱâ À§Çؼ ¿ì¸®´Â
GDK_POINTER_MOTION_HINT_MASK
¸¦ ¼³Á¤ÇÑ´Ù.
¿ì¸®°¡ GDK_POINTER_MOTION_HINT_MASK
¸¦ ¼³Á¤Çϸé, ¼¹ö´Â
¸¶¿ì½º Æ÷ÀÎÅÍ°¡ ¿ì¸®ÀÇ À©µµ¿¡ µé¾î¿À°í ³ª¼ ¶Ç´Â ¹öÆ°ÀÇ press³ª release
À̺¥Æ®°¡ ¹ß»ýÇÏ°í ³ª¼ óÀ½À¸·Î ¿òÁ÷ÀÏ ¶§ motion event¸¦ º¸³»ÁØ´Ù. µÚµû¸£´Â
motion event´Â ¿ì¸®°¡ ¾Æ·¡ÀÇ ÇÔ¼ö·Î½á ºÐ¸íÇÏ°Ô ¸¶¿ì½º Æ÷ÀÎÅÍÀÇ À§Ä¡¸¦ ¹°¾îº¼
¶§±îÁö ¾ïÁ¦µÉ °ÍÀÌ´Ù.
GdkWindow* gdk_window_get_pointer (GdkWindow *window,
gint *x,
gint *y,
GdkModifierType *mask);
(´õ °£´ÜÇÑ ¾²ÀÓ»õ¸¦ °¡Áø gtk_widget_get_pointer()
¶ó´Â ÇÔ¼öµµ ÀÖÁö¸¸, ±×´ÙÁö
À¯¿ëÇÏÁö´Â ¾ÊÀ½ÀÌ µå·¯³¯ °ÍÀÌ´Ù. ¿Ö³ÄÇÏ¸é ±×°ÍÀº ¸¶¿ì½º ¹öÆ°ÀÇ »óÅ¿¡ °ü°è
¾øÀÌ Æ÷ÀÎÅÍÀÇ À§Ä¡¸¸À» ¸»ÇØÁֱ⠶§¹®ÀÌ´Ù.)
¿ì¸®ÀÇ À©µµ¿¡ À̺¥Æ®¸¦ ¼¼ÆÃÇÏ´Â ÄÚµå´Â ±×·¯¹Ç·Î ÀÌ·± ½ÄÀ¸·Î µÉ °ÍÀÌ´Ù.
gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
(GtkSignalFunc) expose_event, NULL);
gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
(GtkSignalFunc) configure_event, NULL);
gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
(GtkSignalFunc) motion_notify_event, NULL);
gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
(GtkSignalFunc) button_press_event, NULL);
gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK);
"expose_event"¿Í "configure_event"´Â ´ÙÀ½À» À§Çؼ ³²°ÜµÐ´Ù. "motion_ notify_event"¿Í "button_press_event"ÀÇ Çڵ鷯´Â ²Ï °£´ÜÇÏ´Ù.
static gint
button_press_event (GtkWidget *widget, GdkEventButton *event)
{
if (event->button == 1 && pixmap != NULL)
draw_brush (widget, event->x, event->y);
return TRUE;
}
static gint
motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
{
int x, y;
GdkModifierType state;
if (event->is_hint)
gdk_window_get_pointer (event->window, &x, &y, &state);
else
{
x = event->x;
y = event->y;
state = event->state;
}
if (state & GDK_BUTTON1_MASK && pixmap != NULL)
draw_brush (widget, x, y);
return TRUE;
}
ÀÌÁ¦ ½ºÅ©¸°¿¡ ±×¸²À» ±×¸®´Â °úÁ¤¿¡ ´ëÇØ ¾Ë¾Æº¸ÀÚ. À̶§ ÇÊ¿äÇÑ °ÍÀº DrawingArea widgetÀÌ´Ù. ±×¸²À» ±×¸®´Â ¿µ¿ªÀÇ widgetÀ̶õ º»ÁúÀûÀ¸·Î ´Ù¸§ ¾Æ´Ñ XÀ©µµ´Ù. ÀÌ°ÍÀº ¿ì¸®°¡ ¿øÇÏ´Â °ÍÀ» ¹«¾ùÀÌµç ±×·Á³ÖÀ» ¼ö ÀÖ´Â ºó ĵ¹ö½º´Ù. Drawing area´Â ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ ¸¸µé¾îÁø´Ù.
GtkWidget* gtk_drawing_area_new (void);
ÀÌ widgetÀÇ µðÆúÆ® Å©±â´Â ÀÌ ÇÔ¼ö·Î½á ¼³Á¤ÇÑ´Ù.
void gtk_drawing_area_size (GtkDrawingArea *darea,
gint width,
gint height);
¸ðµç widget¿¡ ´ëÇØ ¿øÇÑ´Ù¸é ÀÌ µðÆúÆ® Å©±â´Â gtk_widget_set_usize()
·Î½á
¿À¹ö·ÎµåµÉ ¼ö ÀÖ´Ù. ±×¸®°í »ç¿ëÀÚ°¡ Á÷Á¢ ±× drawing area¸¦ Æ÷ÇÔÇÑ À©µµÀÇ
Å©±â¸¦ º¯°æÇÏ¸é ¿ª½Ã ¿À¹ö·ÎµåµÈ´Ù.
¿ì¸®°¡ DrawingArea widgetÀ» ¸¸µé ¶§, ±×¸± ´ë»óÀÌ ¹«¾ùÀΰ¡¿¡ ÀüÀûÀ¸·Î ÁÖÀǸ¦ ±â¿ï¿©¾ß ÇÑ´Ù. ¸¸¾à ¿ì¸®ÀÇ À©µµ°¡ °¨Ãß¾îÁ³´Ù°¡ ´Ù½Ã µå·¯³µ´Ù¸é, ¿ì¸®´Â exposure ¸¶½ºÅ©¸¦ ¼³Á¤ÇÏ°í ±×¸®°í ¿ø·¡ °¨Ãß¾îÁ³¾ú´ø ³»¿ëÀÌ ¹«¾ùÀ̾ú´ÂÁö ²À ´Ù½Ã ±×·ÁÁà¾ß ÇÑ´Ù. µ¡ºÙ¿©¼, À©µµÀÇ ÀϺκÐÀÌ Áö¿öÁ³´Ù°¡ ´Ü°èÀûÀ¸·Î ´Ù½Ã ±×·ÁÁö´Â °ÍÀº ½Ã°¢ÀûÀ¸·Î »ê¸¸ÇØÁú ¼ö ÀÖ´Ù. ÀÌ·± ¹®Á¦¿¡ ´ëÇÑ ÇعýÀº offscreen backing pixmapÀ» ÀÌ¿ëÇÏ´Â °ÍÀÌ´Ù. ½ºÅ©¸° À§·Î ¹Ù·Î ±×¸®´Â ´ë½Å, º¸ÀÌÁö ¾Ê´Â ¼¹ö ¸Þ¸ð¸®¿¡ ÀúÀåµÈ ¾î¶² À̹ÌÁö À§¿¡ ±×·Á³õ°í, À̹ÌÁö°¡ º¯Ç߰ųª ¶Ç´Â À̹ÌÁöÀÇ »õ·Î¿î ¿µ¿ªÀÌ º¸¿©Áö°Ô µÇ¸é ÇØ´çÇÏ´Â ¿µ¿ªÀ» ½ºÅ©¸°¿¡ º¹»çÇØ ÁÖ´Â °ÍÀÌ´Ù.
¾î¶² offscreen pixmapÀ» ¸¸µé±â À§ÇØ, ¿ì¸®´Â ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ´Ù.
GdkPixmap* gdk_pixmap_new (GdkWindow *window,
gint width,
gint height,
gint depth);
ÀÎÀÚ window
´Â ÀÌ ÇȽº¸ÊÀÌ Æ¯¼ºÀ» À̾î¹ÞÀ» GDK À©µµ¸¦ ¼³Á¤ÇÑ´Ù.
width
¿Í
height
´Â ÇȽº¸ÊÀÇ Å©±â¸¦ Á¤ÇÑ´Ù. depth
´Â color depth·Î¼,
ÀÌ »õ·Î¿î À©µµ¿¡¼ÀÇ ÇÑ Çȼ¿´ç ºñÆ®ÀÇ ¼ö´Ù.
¸¸¾à depth
°¡ -1
·Î ¼³Á¤µÇ¸é, ±×°ÍÀº À©µµÀÇ depth¿Í ¶È°°¾ÆÁø´Ù.
¿ì¸®´Â ÇȽº¸ÊÀ» "configure_event" handler ¾È¿¡ ¸¸µç´Ù. ÀÌ À̺¥Æ®´Â À©µµ°¡ óÀ½ »ý¼ºµÉ ¶§¸¦ Æ÷ÇÔÇؼ, À©µµÀÇ Å©±â°¡ º¯ÇÒ ¶§¸¶´Ù ¹ß»ýÇÑ´Ù.
/* ±×¸± ¿µ¿ª¿¡ ´ëÇÑ backing pixmap */
static GdkPixmap *pixmap = NULL;
/* Àû´çÇÑ Å©±âÀÇ backing pixmapÀ» Çϳª ¸¸µç´Ù. */
static gint
configure_event (GtkWidget *widget, GdkEventConfigure *event)
{
if (pixmap)
{
gdk_pixmap_destroy(pixmap);
}
pixmap = gdk_pixmap_new(widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
gdk_draw_rectangle (pixmap,
widget->style->white_gc,
TRUE,
0, 0,
widget->allocation.width,
widget->allocation.height);
return TRUE;
}
gdk_draw_rectangle()
À» ºÎ¸£¸ç ÇȽº¸ÊÀ» white·Î ÃʱâÈÇÑ´Ù. ¿©±â¿¡ ´ëÇØ
Àá±ñ ´õ ¾ê±âÇÒ °ÍÀÌ´Ù. ±×·¯¸é ¿ì¸®ÀÇ exposure event handler´Â ´Ü¼øÈ÷ ±×
ÇȽº¸ÊÀÇ °ü°èµÈ portionÀ» ½ºÅ©¸° À§·Î º¹»çÇÑ´Ù(¿ì¸®´Â exposure eventÀÇ
event->area Çʵå·Î½á redrawÇÒ ¿µ¿ªÀ» °áÁ¤ÇÑ´Ù).
/* Backing pixmapÀ¸·ÎºÎÅÍ ½ºÅ©¸°À» º¹±¸ÇÑ´Ù. */
static gint
expose_event (GtkWidget *widget, GdkEventExpose *event)
{
gdk_draw_pixmap(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
¿ì¸®´Â ÀÌÁ¦ ÇȽº¸Ê¿¡ ´ëÇØ ¾î¶»°Ô ½ºÅ©¸°À» º¸Á¸ÇÏ´ÂÁö º¸¾Ò´Ù. ±×·±µ¥
¿ì¸®ÀÇ ÇȽº¸Ê¿¡ ½ÇÁ¦·Î Àç¹ÌÀÖ´Â °ÍµéÀ» ¾î¶»°Ô ±×·Á³ÖÀ»±î? GTKÀÇ GDK
¶óÀ̺귯¸®¿¡´Â drawablesµéÀ» ±×¸®´Â µ¥ ÇÊ¿äÇÑ ¸¹Àº ¼öÀÇ ÇÔ¼öµéÀÌ ÀÖ´Ù.
DrawableÀ̶õ °£´ÜÈ÷ ¾îµò°¡¿¡ ±×·ÁÁú ¼ö ÀÖ´Â ±× ¹«¾ùÀÌ´Ù. ¿©±â¼ ¾îµð¶õ
ÇϳªÀÇ window, pixmap, ¶Ç´Â bitmap(Èæ¹éÀÇ À̹ÌÁö)ÀÌ µÉ ¼ö ÀÖ´Ù. ¿ì¸®´Â
ÀÌ¹Ì ÀÌ·± ÇÔ¼ö µÎ°¡Áö¸¦ º¸¾Ò´Ù. gdk_draw_rectangle()
°ú
gdk_draw_pixmap()
ÀÌ ±×°ÍÀÌ´Ù. ÀÌ ÇÔ¼öµéÀÇ ¿ÏÀüÇÑ ¸®½ºÆ®´Â ÀÌ·¸´Ù.
gdk_draw_line ()
gdk_draw_rectangle ()
gdk_draw_arc ()
gdk_draw_polygon ()
gdk_draw_string ()
gdk_draw_text ()
gdk_draw_pixmap ()
gdk_draw_bitmap ()
gdk_draw_image ()
gdk_draw_points ()
gdk_draw_segments ()
ÀÌ ÇÔ¼öµé¿¡ ´ëÇØ ´õ ÀÚ¼¼È÷ ¾Ë·Á¸é Âü°í ¹®¼¸¦ º¸°Å³ª
<gdk/gdk.h>
ÆÄÀÏÀ»
º¸¶ó. ÀÌ ÇÔ¼öµéÀº óÀ½ µÎ °³ÀÇ ÀÎÀÚ¸¦ °øÅëÀûÀ¸·Î °¡Áø´Ù. ù ¹ø°´Â ±×·Á
³ÖÀ» drawable, ±×¸®°í µÎ¹ø°´Â graphics context(GC)ÀÌ´Ù.
C´Â foreground/background color³ª line width°°Àº, ±×·ÁÁú °Í¿¡ ´ëÇÑ Á¤º¸µéÀ» ĸ½¶ÈÇÑ °ÍÀÌ´Ù. GDK´Â GC¸¦ »õ·Î ¸¸µé°í º¯ÇüÇϴµ¥ ÇÊ¿äÇÑ ¸ðµç ÇÔ¼öµéÀ» °¡Áö°í ÀÖÁö¸¸, ¹¹µçÁö °£´ÜÈ÷ À¯ÁöÇϱâ À§Çؼ(Keep things simple) ¿ì¸®´Â ÀÌ¹Ì Á¤ÀǵǾî ÀÖ´Â GC¸¸À» ¾µ °ÍÀÌ´Ù. °¢ widgetÀº ¿¬°üµÈ ½ºÅ¸ÀÏÀÌ ÀÖ´Ù(À̵éÀº rc ÆÄÀÏÀ» ÆíÁýÇÔÀ¸·Î½á º¯Çü°¡´ÉÇÏ´Ù. GTKÀÇ rc ÆÄÀÏ¿¡ ´ëÇÑ ºÎºÐÀ» ÂüÁ¶). ÀÌ°ÍÀº ´Ù¸¥ °Íµé »çÀÌ¿¡¼ GCÀÇ °³¼ö¸¦ ÀúÀåÇÑ´Ù. ÀÌ·± GC¿¡ Á¢±ÙÇÏ´Â ¸î°¡Áö ¿¹¸¦ º¸ÀÌ°Ú´Ù.
widget->style->white_gc
widget->style->black_gc
widget->style->fg_gc[GTK_STATE_NORMAL]
widget->style->bg_gc[GTK_WIDGET_STATE(widget)]
Çʵå fg_gc
, bg_gc
, dark_gc
, light_gc
µîÀº ¾Æ·¡ °ªµéÀ»
°¡Áú ¼ö ÀÖ´Â GtkStateType
À̶ó´Â ÀÎÀÚ·Î ³ªÅ¸³»¾îÁø´Ù.
GTK_STATE_NORMAL,
GTK_STATE_ACTIVE,
GTK_STATE_PRELIGHT,
GTK_STATE_SELECTED,
GTK_STATE_INSENSITIVE
¿¹¸¦µé¾î, GTK_STATE_SELECTED
¿¡ ´ëÇØ µðÆúÆ® foreground »ö±òÀº whiteÀÌ°í
background »ö±òÀº dark blueÀÌ´Ù. ½ÇÁ¦·Î ½ºÅ©¸° À§·Î ±×¸®´Â ÇÔ¼öÀÎ
draw_brush()
´Â ±×·¯¹Ç·Î ÀÌ·¸°Ô µÈ´Ù.
/* ½ºÅ©¸°¿¡ »ç°¢ÇüÀ» Çϳª ±×¸°´Ù. */
static void
draw_brush (GtkWidget *widget, gdouble x, gdouble y)
{
GdkRectangle update_rect;
update_rect.x = x - 5;
update_rect.y = y - 5;
update_rect.width = 10;
update_rect.height = 10;
gdk_draw_rectangle (pixmap,
widget->style->black_gc,
TRUE,
update_rect.x, update_rect.y,
update_rect.width, update_rect.height);
gtk_widget_draw (widget, &update_rect);
}
¿ì¸®°¡ ÇȽº¸Ê À§·Î ºê·¯½¬¸¦ Ç¥½ÃÇÏ´Â »ç°¢ÇüÀ» ±×¸®°í ³ª¼, ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
void gtk_widget_draw (GtkWidget *widget,
GdkRectangle *area);
ÀÌ°ÍÀº area¶ó´Â ÀÎÀÚ·Î ÁÖ¾îÁø ¿µ¿ªÀÌ ¾÷µ¥ÀÌÆ®µÇ¾î¾ß ÇÔÀ» X¿¡°Ô ¾Ë·ÁÁØ´Ù. °á±¹ X´Â expose À̺¥Æ®¸¦ ¹ß»ýÇÏ°í, ÀÌ°ÍÀº ¿ì¸®ÀÇ expose À̺¥Æ® Çڵ鷯°¡ °ü°èµÈ ¿µ¿ªÀ» ½ºÅ©¸° À§·Î º¹»çÇÏ°Ô²û ÇÒ °ÍÀÌ´Ù.
ÀÌÁ¦ ¿ì¸®´Â main À©µµ¸¦ ¸¸µå´Â °Í °°ÀÌ ÀϺΠÈçÇÑ Ç׸ñµéÀ» Á¦¿ÜÇÏ°í ÀÌ ±×¸®±â ÇÁ·Î±×·¥À» ¸ðµÎ »ìÆ캸¾Ò´Ù. ¿ÏÀüÇÑ ¼Ò½ºÄÚµå´Â ÀÌ ¹®¼¸¦ ±¸ÇÑ °÷À̳ª ´ÙÀ½ À§Ä¡¿¡¼ ±¸ÇÒ ¼ö ÀÖ´Ù.
http://www.msc.cornell.edu/~otaylor/gtk-gimp/tutorial
ÀÌÁ¦ drawing tablet °°ÀÌ, ±×´ÙÁö ºñ½ÎÁö ¾ÊÀ¸¸é¼ ¸¶¿ì½ºº¸´Ù ÈξÀ ¿¹¼úÀûÀΠǥÇöÀ» ÆíÇÏ°Ô ±×¸± ¼ö ÀÖ°Ô ÇØÁÖ´Â ÀÔ·ÂÀåÄ¡(input device)¸¦ ±¸ÀÔÇÏ´Â °ÍÀÌ °¡´ÉÇÑ ½Ã´ë´Ù. ÀÌ·± ÀåÄ¡¸¦ ÀÌ¿ëÇÏ´Â °¡Àå °£´ÜÇÑ ¹æ¹ýÀÌ¾ß °£´ÜÈ÷ ¸¶¿ì½º¸¦ ´ëÄ¡ÇØ ¹ö¸®´Â °ÍÀÌ°ÚÁö¸¸, ÀÌ·² °æ¿ì ±×·± ÀÔ·ÂÀåÄ¡ÀÇ ´ÙÀ½°ú °°Àº ¸¹Àº ÀåÁ¡À» ÀÒ°Ô µÉ ¼öµµ ÀÖ´Ù.
XInput extension¿¡ ´ëÇÑ Á¤º¸¸¦ ¾òÀ¸·Á¸é XInput-HOWTO ¸¦ º¸¶ó. ¿¹¸¦µé¾î GdkEventMotion ±¸Á¶Ã¼ÀÇ Àüü Á¤ÀÇ°°Àº °É ºÁµµ, extended device¸¦ Áö¿øÇϱâ À§ÇÑ Çʵ带 °¡Áö°í ÀÖÀ½À» ¾Ë °ÍÀÌ´Ù.
struct _GdkEventMotion
{
GdkEventType type;
GdkWindow *window;
guint32 time;
gdouble x;
gdouble y;
gdouble pressure;
gdouble xtilt;
gdouble ytilt;
guint state;
gint16 is_hint;
GdkInputSource source;
guint32 deviceid;
};
pressure
ÀÎÀÚ´Â 0°ú 1 »çÀÌÀÇ ºÎµ¿¼Ò¼öÁ¡¼ö·Î µÈ pressure¸¦ ÁØ´Ù.
xtilt
¿Í ytile
´Â °¢ ¹æÇâÀ¸·ÎÀÇ tilt °¢µµ¿¡ ÇØ´çÇÏ´Â -1ºÎÅÍ 1 »çÀÌÀÇ
°ªÀ» °¡Áú ¼ö ÀÖ´Ù. source
¿Í deviceid
ÀÎÀÚ´Â µÎ°¡Áö ´Ù¸¥ ¹æ½ÄÀ¸·Î
¹ß»ýÇÑ À̺¥Æ®¿¡ ´ëÇØ
ÀåÄ¡(device)¸¦ ¼³Á¤ÇÑ´Ù. source
´Â ÀåÄ¡ÀÇ Å¸ÀÔ¿¡ ´ëÇÑ °£´ÜÇÑ Á¤º¸¸¦ ÁØ´Ù.
ÀÌ°ÍÀº ´ÙÀ½ÀÇ enumeration °ªµéÀ» °¡Áú ¼ö ÀÖ´Ù.
GDK_SOURCE_MOUSE
GDK_SOURCE_PEN
GDK_SOURCE_ERASER
GDK_SOURCE_CURSOR
deviceid
´Â °¢ ÀåÄ¡¿¡ ´ëÇØ °íÀ¯ÀÇ ¼ýÀÚ ID¸¦ ¼³Á¤ÇÑ´Ù. ÀÌ°ÍÀº
gdk_input_list_devices()
ÇÔ¼ö·Î(µÚ¿¡ ³ª¿È) ±× ÀåÄ¡¿¡ ´ëÇÑ ´õ ¸¹Àº
Á¤º¸¸¦ Á¶»çÇÏ°íÀÚ ÇÒ
¶§ ¾²ÀÏ ¼ö ÀÖ´Ù. Core pointer device(º¸Åë ¸¶¿ì½º)¿¡ ´ëÇØ Æ¯º°È÷
GDK_CORE_POINTER
¶ó´Â »ó¼ö°ªÀÌ ¾²ÀδÙ.
GTK¿¡°Ô ¿ì¸®°¡ °ü½ÉÀ» °¡Áø extended deviceÀÇ Á¤º¸°¡ ¹«¾ùÀÎÁö ¾Ë·Á ÁÖ·Á¸é, ¿ì¸® ÇÁ·Î±×·¥¿¡ ´Ü ÇÑ ÁÙ¸¸ ´õÇØÁÖ¸é µÈ´Ù.
gtk_widget_set_extension_events (drawing_area, GDK_EXTENSION_EVENTS_CURSOR);
GDK_EXTENSION_EVENTS_CURSOR
¶ó´Â °ªÀ» ÁÜÀ¸·Î½á ¿ì¸®´Â È®ÀåµÈ À̺¥Æ®µé¿¡
°ü½ÉÀÌ ÀÖÀ½À» ¾Ë¸°´Ù. ´Ü, À̶§ ¿ì¸®´Â »õ·Î Ä¿¼¸¦ ±×·Á¼´Â ¾ÈµÈ´Ù. Ä¿¼¸¦
±×¸®´Â ¹®Á¦¿¡ ´ëÇؼ´Â µÚ¿¡ ³ª¿Ã
º¹ÀâÇÑ ÀÌ¿ë ºÎºÐÀ» ÂüÁ¶Ç϶ó. ¿ì¸®°¡
¿ì¸®¸¸ÀÇ Ä¿¼¸¦ ±×¸®·Á ÇÑ´Ù¸é GDK_EXTENSION_EVENTS_ALL
À» ¾²¸é µÇ°í, µðÆúÆ®
·Î µ¹¾Æ°¡·Á¸é GDK_EXTENSION_EVENTS_NONE
À» ¾´´Ù.
À̾߱â´Â ÀÌ°ÍÀ¸·Î ³¡³ªÁö ¾Ê´Â´Ù. µðÆúÆ®·Î, extension device´Â disable µÇ¾î ÀÖ´Ù. ¿ì¸®´Â »ç¿ëÀÚ·Î ÇÏ¿©±Ý ±×µéÀÇ extension deviceµéÀ» enable½ÃÅ°°í ¼³Á¤ÇÒ ¼ö ÀÖ°Ô ÇØÁÖ´Â ¸ÅÄ¿´ÏÁòÀÌ ÇÊ¿äÇÏ´Ù. GTK´Â ÀÌ °úÁ¤À» ÀÚµ¿ÀûÀ¸·Î ÇØ ÁÖ´Â InputDialog widgetÀ» Á¦°øÇÑ´Ù. ´ÙÀ½°ú °°Àº °úÁ¤´ë·Î InputDialog widgetÀ» °ü¸®ÇÑ´Ù. ÀÌ°ÍÀº device°¡ Á¸ÀçÇÏÁö ¾ÊÀ¸¸é dialog·Î ¾Ë·ÁÁÖ°í, ³ª¸ÓÁö °æ¿ì¿£ topÀ¸·Î ¿Ã·Áº¸³½´Ù.
void
input_dialog_destroy (GtkWidget *w, gpointer data)
{
*((GtkWidget **)data) = NULL;
}
void
create_input_dialog ()
{
static GtkWidget *inputd = NULL;
if (!inputd)
{
inputd = gtk_input_dialog_new();
gtk_signal_connect (GTK_OBJECT(inputd), "destroy",
(GtkSignalFunc)input_dialog_destroy, &inputd);
gtk_signal_connect_object
(GTK_OBJECT(GTK_INPUT_DIALOG(inputd)->close_button),
"clicked",
(GtkSignalFunc)gtk_widget_hide,
GTK_OBJECT(inputd));
gtk_widget_hide ( GTK_INPUT_DIALOG(inputd)->save_button);
gtk_widget_show (inputd);
}
else
{
if (!GTK_WIDGET_MAPPED(inputd))
gtk_widget_show(inputd);
else
gdk_window_raise(inputd->window);
}
}
(¿ì¸®°¡ ÀÌ dialog¸¦ ´Ù·ç´Â ¹æ¹ý¿¡ ÁÖÀǸ¦ ±â¿ï¿©¾ß ÇÒ °ÍÀÌ´Ù. "destroy"
½Ã±×³Î¿¡ ¿¬°á½ÃÄÑ µÎ´Â °ÍÀ¸·Î, ¿ì¸®´Â dialog°¡ Æı«µÈ ÀÌÈÄ Æ÷ÀÎÅ͸¦ dialog
¿¡ ³²°ÜµÎ´Â ½Ç¼ö - ÀÌ°ÍÀº Segfault(!)¸¦ ºÎ¸¥´Ù - ¸¦ ÇÇÇÒ ¼ö ÀÖ´Ù.)
InputDialog´Â "Close" ±×¸®°í "Save"¶ó´Â µÎ ¹öÆ°À» °¡Áö°í ÀÖÀ¸¸ç, µðÆúÆ® ·Î´Â ¾Æ¹«·± µ¿ÀÛÀÌ ¿¬°áµÇ¾î ÀÖÁö ¾Ê´Ù. À§¿¡¼´Â "Close" ¹öÆ°À» dialog¸¦ °¨Ãߴµ¥ ½è°í, "Save" ¹öÆ°Àº °¨Ãß¾î ¹ö·È´Ù. ÀÌ ÇÁ·Î±×·¥¿¡¼ XInputÀ» ÀúÀå ÇÏ´Â ¿É¼ÇÀ» °®ÃßÁö ¾Ê¾Ò±â ¶§¹®ÀÌ´Ù.
ÀÏ´Ü ÀåÄ¡(device)¸¦ enable½ÃÄ×À¸¸é, ¿ì¸®´Â À̺¥Æ® ±¸Á¶Ã¼ÀÇ ³ª¸ÓÁö Çʵ忡 ÀÖ´Â extended deviceÀÇ Á¤º¸¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. »ç½Ç, ÀÌ Á¤º¸¸¦ ÀÌ¿ëÇÏ´Â °Ç ¾ðÁ¦³ª ¾ÈÀüÇÏ´Ù. Extended event°¡ disableµÇ¾î ÀÖ´õ¶óµµ À̵éÀº ÀûÀýÇÑ µðÆúÆ®°ªÀ» °¡Áö°í Àֱ⠶§¹®ÀÌ´Ù.
ÇÑ °¡Áö ÁÖÀÇÇÒ °ÍÀº gdk_window_get_pointer()
´ë½Å¿¡
gdk_input_window_get_pointer()
¸¦ È£ÃâÇÑ´Ù´Â °ÍÀÌ´Ù.
ÀÌ°ÍÀº gdk_window_get_pointer
°¡ extended device Á¤º¸¸¦ ¸®ÅÏÇÏÁö ¸øÇϱâ
¶§¹®ÀÌ´Ù.
void gdk_input_window_get_pointer (GdkWindow *window,
guint32 deviceid,
gdouble *x,
gdouble *y,
gdouble *pressure,
gdouble *xtilt,
gdouble *ytilt,
GdkModifierType *mask);
ÀÌ ÇÔ¼ö¸¦ ºÎ¸¦ ¶§, À©µµÀÇ °æ¿ì¿Í ¸¶Âù°¡Áö·Î deviceÀÇ ID¸¦ ¸í½ÃÇØ Áà¾ß
ÇÑ´Ù. º¸Åë, ¿ì¸®´Â device ID¸¦ event ±¸Á¶Ã¼ÀÇ deviceid
Çʵå·ÎºÎÅÍ ÃëÇÒ
°ÍÀÌ´Ù. ´Ù½Ã Çѹø, ÀÌ ÇÔ¼ö´Â extension event°¡ disableµÈ »óÅ¿¡¼µµ ÇÕ´çÇÑ
°ªÀ» ¸®ÅÏÇÔÀ» ±â¾ïÇÏÀÚ. (ÀÌ °æ¿ì¿£, event->deviceid
´Â
GDK_CORE_POINTER
¶ó´Â
°ªÀ» °¡Áú °ÍÀÌ´Ù.)
±×·¡¼ ¿ì¸®ÀÇ button-press ¿Í motion À̺¥Æ® Çڵ鷯ÀÇ ±âº»ÀûÀÎ ±¸Á¶´Â ±×¸® º¯ÇÏÁö ¾Ê´Â´Ù - ¿ì¸° ´ÜÁö extended¿¡ ÇØ´çÇÏ´Â Á¤º¸¸¦ ´Ù·ê Äڵ带 Ãß°¡Çϱ⸸ ÇÏ¸é µÈ´Ù.
static gint
button_press_event (GtkWidget *widget, GdkEventButton *event)
{
print_button_press (event->deviceid);
if (event->button == 1 && pixmap != NULL)
draw_brush (widget, event->source, event->x, event->y, event->pressure);
return TRUE;
}
static gint
motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
{
gdouble x, y;
gdouble pressure;
GdkModifierType state;
if (event->is_hint)
gdk_input_window_get_pointer (event->window, event->deviceid,
&x, &y, &pressure, NULL, NULL, &state);
else
{
x = event->x;
y = event->y;
pressure = event->pressure;
state = event->state;
}
if (state & GDK_BUTTON1_MASK && pixmap != NULL)
draw_brush (widget, event->source, x, y, pressure);
return TRUE;
}
¿ì¸° ¶ÇÇÑ »õ·Î¿î Á¤º¸¸¦ ÀÌ¿ëÇÏ´Â ÀÏÀ» ¹º°¡ ÇØ¾ß ÇÑ´Ù. ¿ì¸®ÀÇ
draw_brush()
ÇÔ¼ö´Â °¢ event->source
¸¶´Ù ´Ù¸¥ »ö±ò·Î ±×¸± ¼ö ÀÖ°Ô ÇÏ°í,
±×¸®°í pressure¿¡ µû¶ó brushÀÇ Å©±â¸¦ º¯ÇÏ°Ô ÇÑ´Ù.
/* ½ºÅ©¸°¿¡ »ç°¢ÇüÀ» ±×¸°´Ù. Å©±â´Â pressure¿¡ ÀÇÁ¸ÇÏ°í,
* ±×¸®°í »ö±òÀº deviceÀÇ Å¸ÀÔ¿¡ ÀÇÁ¸ÇÑ´Ù. */
static void
draw_brush (GtkWidget *widget, GdkInputSource source,
gdouble x, gdouble y, gdouble pressure)
{
GdkGC *gc;
GdkRectangle update_rect;
switch (source)
{
case GDK_SOURCE_MOUSE:
gc = widget->style->dark_gc[GTK_WIDGET_STATE (widget)];
break;
case GDK_SOURCE_PEN:
gc = widget->style->black_gc;
break;
case GDK_SOURCE_ERASER:
gc = widget->style->white_gc;
break;
default:
gc = widget->style->light_gc[GTK_WIDGET_STATE (widget)];
}
update_rect.x = x - 10 * pressure;
update_rect.y = y - 10 * pressure;
update_rect.width = 20 * pressure;
update_rect.height = 20 * pressure;
gdk_draw_rectangle (pixmap, gc, TRUE,
update_rect.x, update_rect.y,
update_rect.width, update_rect.height);
gtk_widget_draw (widget, &update_rect);
}
Device¿¡ ´ëÇÑ Á¤º¸¸¦ ¾î¶»°Ô ´õ ¾Ë¾Æ³»´ÂÁö º¸¿©ÁÖ´Â ¿¹Á¦·Î¼, ¿ì¸® ÇÁ·Î ±×·¥Àº °¢ ¹öÆ°À» ´©¸£¸é deviceÀÇ À̸§À» ÇÁ¸°Æ®ÇÒ °ÍÀÌ´Ù. DeviceÀÇ À̸§À» ¾Ë¾Æ³»±â À§ÇÏ¿© ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ´Ù.
GList *gdk_input_list_devices (void);
ÀÌ°ÍÀº GdkDeviceInfo ±¸Á¶Ã¼ÀÇ GList(glib ¶óÀ̺귯¸®¿¡¼ ¿Â ¿¬°á¸®½ºÆ® ŸÀÔ)¸¦ ¸®ÅÏÇÑ´Ù. GdkDeviceInfo ±¸Á¶Ã¼´Â ÀÌ·¸°Ô Á¤ÀǵǾî ÀÖ´Ù.
struct _GdkDeviceInfo
{
guint32 deviceid;
gchar *name;
GdkInputSource source;
GdkInputMode mode;
gint has_cursor;
gint num_axes;
GdkAxisUse *axes;
gint num_keys;
GdkDeviceKey *keys;
};
¿©±âÀÖ´Â ´ëºÎºÐÀÇ Çʵå´Â ¿©·¯ºÐÀÌ XInput ¼³Á¤À» ÀúÀåÇÏ´Â ±â´ÉÀ» Ãß°¡ÇÏÁö
¾Ê¾Ò´Ù¸é ¹«½ÃÇصµ ±¦ÂúÀº ¼³Á¤ Á¤º¸µéÀÌ´Ù. Áö±Ý ¿ì¸®°¡ °ü½ÉÀ» °¡Áø °ÍÀº
´Ü¼øÈ÷ X°¡ device¿¡ ºÎ¿©ÇÑ À̸§(name
)ÀÌ´Ù. ¼³Á¤(configuration)Çʵ忡
ÇØ´çÇÏÁö ¾Ê´Â °ÍÀº has_cursor
ÀÌ´Ù. ±×·±µ¥ ¿ì¸®´Â
GDK_EXTENSION_EVENTS_CURSOR
¸¦ ¼³Á¤ÇßÀ¸¹Ç·Î, ÀÌ Çʵ忡 ´ëÇؼ´Â
°ÆÁ¤ÇÏÁö ¸»ÀÚ.
print_button_press()
ÇÔ¼ö´Â ¸ÅÄ¡µÇ´Â ¸®½ºÆ®¸¦ ¸®ÅÏÇÒ ¶§±îÁö ´Ü¼øÈ÷ ¹Ýº¹µÉ
°ÍÀ̸ç, deviceÀÇ À̸§À» ÇÁ¸°Æ®ÇØ ÁÙ °ÍÀÌ´Ù.
static void
print_button_press (guint32 deviceid)
{
GList *tmp_list;
/* gdk_input_list_devices´Â ³»ºÎÀûÀÎ ¸®½ºÆ®¸¦ ¸®ÅÏÇϸç,
* µû¶ó¼ ¿ì¸®´Â ÈÄ¿¡ ÀÌ°ÍÀ» ÇØÁ¦ÇØ ÁÖÁö ¾ÊÀ» °ÍÀÌ´Ù. */
tmp_list = gdk_input_list_devices();
while (tmp_list)
{
GdkDeviceInfo *info = (GdkDeviceInfo *)tmp_list->data;
if (info->deviceid == deviceid)
{
printf("Button press on device '%s'\n", info->name);
return;
}
tmp_list = tmp_list->next;
}
}
ÀÌ°ÍÀ¸·Î ¿ì¸®ÀÇ ``XInputize'' ÇÁ·Î±×·¥À» ¿ÏÀüÈ÷ º¯°æÇß´Ù. ù ¹öÁ¯°ú ¸¶Âù°¡Áö·Î ÀÌ°ÍÀÇ ¿ÏÀüÇÑ ¼Ò½º ÄÚµå´Â ÀÌ ¹®¼¸¦ ±¸ÇÑ °÷À̳ª ´ÙÀ½ À§Ä¡¿¡¼ ±¸ÇÒ ¼ö ÀÖ´Ù.
http://www.msc.cornell.edu/~otaylor/gtk-gimp/tutorial
ºñ·Ï ¿ì¸® ÇÁ·Î±×·¥ÀÌ ÀÌÁ¦ XInputÀ» ²Ï Àß Áö¿øÇÔ¿¡µµ ºÒ±¸ÇÏ°í, ¾îÇà ÀüüÀû
À¸·Î ºÁ¼ ¹º°¡ ºÎÁ·ÇØ º¸ÀÌ´Â ¸éµµ ÀÖ´Ù. ¸ÕÀú, »ç¿ëÀÚ´Â ÇÁ·Î±×·¥À» ½ÇÇàÇÒ
¶§¸¶´Ù ±×µéÀÇ ÀåÄ¡µéÀ» ¼³Á¤ÇÏ·Á°í ÇÏÁø ¾ÊÀ» °ÍÀ̹ǷÎ, ¿ì¸®´Â ±× ÀåÄ¡µéÀÇ
¼³Á¤À» ÀúÀåÇÒ ¼ö ÀÖµµ·Ï ÇØÁà¾ß ÇÑ´Ù. ÀÌ°ÍÀº gdk_input_list_devices()
ÀÇ
¸®ÅÏÀ» µÇÇ®ÀÌÇÏ°í, ¼³Á¤À» ÆÄÀÏ¿¡ ±â·Ï(write)ÇÏ´Â °ÍÀ¸·Î ÀÌ·ç¾îÁø´Ù.
ÇÁ·Î±×·¥ÀÌ ´ÙÀ½ ¹ø ½ÇÇàµÉ ¶§ ÇöÀçÀÇ state¸¦ º¹±¸ÇØ ÁÖ±â À§Çؼ, GDK´Â device ¼³Á¤¿¡ ´ëÇÑ ´ÙÀ½ ÇÔ¼öµéÀ» Á¦°øÇÑ´Ù.
gdk_input_set_extension_events()
gdk_input_set_source()
gdk_input_set_mode()
gdk_input_set_axes()
gdk_input_set_key()
(gdk_input_list_devices()
°¡ ¸®ÅÏÇÑ ¸®½ºÆ®´Â Á¤È®È÷ º¯°æµÇÁö ¾ÊÀ» ¼ö ÀÖ´Ù.)
ÀÌ°Í¿¡ ´ëÇÑ ¿¹Á¦´Â ±×¸®±â ÇÁ·Î±×·¥ÀÎ Gsumi(
http://www.msc.cornell.edu/~otaylor/gsumi/¿¡ ÀÖ´Ù.)°¡ µÉ °ÍÀÌ´Ù.
°á±¹, ¸ðµç ¾îÇõ鿡 ´ëÇØ ÀÌ ¸ñÀûÀ¸·Î
Ç¥ÁØÀûÀÎ ¹æ½ÄÀ» °¡Áú ¼ö ÀÖ´Ù¸é ¸ÚÁø ÀÏÀÌ µÉ °ÍÀÌ´Ù. ÀÌ°ÍÀº ¾Æ¸¶ GNOME
¶óÀ̺귯¸®°¡ GTKº¸´Ù ¾à°£ ³ôÀº ·¹º§¿¡ ¼ÓÇÒ °ÍÀÌ´Ù.
¿ì¸®°¡ ¾Õ¿¡¼ ´Ù·é °Í¿¡¼ ºüÁø ¶ÇÇϳª Áß¿äÇÑ °ÍÀº cursor¿¡ ´ëÇÑ °ÍÀÌ´Ù. XFree86°ú ´Ù¸¥ Ç÷§ÆûµéÀº ÇöÀç·Î¼´Â µ¿½Ã¿¡ µÑÀ» - Core pointer, ±×¸®°í ¾îÇÿ¡ ÀÇÇÑ Á÷Á¢ÀûÀÎ Á¶ÀÛ - »ç¿ëÇÏ¿© ÀåÄ¡¸¦ ´Ù·ê ¼ö ¾ø´Ù. ÀÌ°Í¿¡ ´ëÇØ ´õ ÀÚ¼¼ÇÑ Á¤º¸´Â XInput-HOWTO¸¦ º¸¶ó. ÀÌ°ÍÀº ÃÖ´ëÇÑÀÇ ÀÌ¿ëÀÚ¸¦ È®º¸ÇÏ·Á´Â ¾îÇÃÀ̶ó¸é ÀڽŸ¸ÀÇ Ä¿¼¸¦ ±×·ÁÁÖ´Â °Ô ÇÊ¿äÇÔÀ» ÀǹÌÇÑ´Ù.
ÀڽŸ¸ÀÇ Ä¿¼¸¦ ±×¸®´Â ¾îÇÃÀº ´ÙÀ½ÀÇ µÎ ÀÏÀ» ÇØ¾ß ÇÑ´Ù. ù°·Î ÇöÀçÀÇ ÀåÄ¡°¡ ±×·ÁÁø Ä¿¼¸¦ ÇÊ¿ä·Î ÇÏ´ÂÁöÀÇ ¿©ºÎ¸¦ °áÁ¤ÇÏ°í, µÑ°·Î ÇöÀçÀÇ ÀåÄ¡°¡ Á¢±Ù(proximity)µÇ¾î ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ °áÁ¤ÇÑ´Ù. (ÇöÀçÀÇ ÀåÄ¡°¡ drawing tabletÀÏ °æ¿ì, stylus°¡ tablet¿¡¼ ¶³¾îÁ³À» ¶§ Ä¿¼°¡ º¸ÀÌÁö ¾Ê°Ô ÇÏ´Â °ÍÀÌ ÁÁÀ» °ÍÀÌ´Ù. ÀåÄ¡°¡ stylus¿Í ºÙ¾î ÀÖÀ» ¶§, À̸¦ Á¢±ÙµÇ¾ú´Ù(in proximity)°í Ç¥ÇöÇÑ´Ù.) ù¹ø° ÀÛ¾÷Àº ¿ì¸®°¡ deviceÀÇ À̸§À» ¾Ë¾Æ³»±â À§ÇØ ÇßµíÀÌ, deviceÀÇ ¸®½ºÆ®¸¦ Á¶»ç ÇÔÀ¸·Î½á ÇØ°áµÈ´Ù. µÎ¹ø° ÀÛ¾÷Àº "proximity_out" À̺¥Æ®¸¦ ¼³Á¤ÇÔÀ¸·Î½á ÇØ°áÇÑ´Ù. °¢ÀÚÀÇ Ä¿¼¸¦ ±×¸®´Â ¿¹Á¦´Â GTK ¹èÆ÷ÆÇ¿¡ ÀÖ´Â 'testinput' ÇÁ·Î ±×·¥¿¡¼ ãÀ» ¼ö ÀÖÀ» °ÍÀÌ´Ù.