II. Làm việc với của sổ X Windows
1. Thay đổi tiêu đề cửa sổ
Code:
XStoreName(display, win, “ OPENGL in Linux ”);
+ Hàm này giống SetWindowText cửa WINAPI.
2. Hiển thị cửa sổ.
Code:
XMapWindow(display, win);
+ Hàm này giống ShowWindow
+ Còn muốn ShowWindow(hWnd, SW_HIDE); thì XUnmapWindow (...)
4. Sửa đổi cửa sổ
Bao gồm các hàm:
+ XConfigureWindow (Thay đổi vị trí, kích thước, chiều cao, rộng)
+ XMoveWindow (Di chuyển cửa sổ)
+ XResizeWindow
+ XSetWindowBorderWidth
... Và nhiều nữa mình sẽ share link tài liệu ở cuối bài viết...
4. Nhận sự kiện
Code:
XSelectInput(display, win, ExposureMask | KeyPressMask | StructureNotifyMask);
EventMask ở đây chỉ báo trước cho X System biết chương trình sẽ nhận những sự kiện nào gồm.
Code:
NoEventMask No events
KeyPressMask Keyboard down events
KeyReleaseMask Keyboard up events
ButtonPressMask Pointer button down events
ButtonReleaseMask Pointer button up events
EnterWindowMask Pointer window entry events
LeaveWindowMask Pointer window leave events
PointerMotionMask All pointer motion events
PointerMotionHintMask Fewer pointer motion events
Button1MotionMask Pointer motion while button 1 down
Button2MotionMask Pointer motion while button 2 down
Button3MotionMask Pointer motion while button 3 down
Button4MotionMask Pointer motion while button 4 down
Button5MotionMask Pointer motion while button 5 down
ButtonMotionMask Pointer motion while any button down
KeymapStateMask Any keyboard state change on
EnterNotify ,
LeaveNotify ,
FocusIn
or FocusOut
ExposureMask Any exposure (except GraphicsExpose and NoExpose )
VisibilityChangeMask Any change in visibility
StructureNotifyMask Any change in window configuration.
ResizeRedirectMask Redirect resize of this window
SubstructureNotifyMask Notify about reconfiguration of children
SubstructureRedirectMask Redirect reconfiguration of children
FocusChangeMask Any change in keyboard focus
PropertyChangeMask Any change in property
ColormapChangeMask Any change in colormap
OwnerGrabButtonMask Modifies handling of pointer events
Tuy nhiên nếu bạn không nhớ mấy cái vớ vẫn này thì cứ "thà giết nhàm còn hơn bỏ sót"
Code:
const int event_mask = ExposureMask |
ButtonPressMask |
ButtonReleaseMask |
EnterWindowMask |
LeaveWindowMask |
PointerMotionMask |
FocusChangeMask |
KeyPressMask |
KeyReleaseMask |
SubstructureNotifyMask |
StructureNotifyMask |
SubstructureRedirectMask;
là gần như đầy đủ các sự kiện thường dùng về phím, chuột . Rồi sau này chúng ta sẽ switch sau.
5. Phân tích sự kiện
Cũng là 1 vòng lặp while () giống Win32. Người ta vẫn gọi nó là Event Loop
Code:
bool done = false;
XEvent event;
while (!done) {
XNextEvent(display, &event);
switch (event.type) {
case Expose:
cout << “Expose event received” << endl;
break;
case ConfigureNotify:
cout << “ConfigureNotify event received” << endl;
break;
case KeyPress:
cout << “Keypress detected” << endl;
done = true; // Exit on any keypress
break;
}
}
Ở đây chúng ta quan tâm tới XEvent và Event Type.
XEvent giống như là MSG cửa Windows. Nó chứa handle cửa sổ và xác định loại message tương ứng, và các tham số đi kem tương ứng như chuột thì x,y. Key thì là UCHAR....
Một đoạn code mình copy tổng quá hơn về phân tích event
Code:
bool handle_event ( XEvent& report, window_base* p )
{
switch ( report.type )
{
case Expose: // Giống On_Paint
{
p->on_expose();
break;
}
case ButtonPress:
{
if ( report.xbutton.button & Button2 )
{
p->on_right_button_down ( report.xbutton.x,
report.xbutton.y );
}
else if ( report.xbutton.button & Button1 )
{
p->on_left_button_down ( report.xbutton.x,
report.xbutton.y );
}
break;
}
case ButtonRelease:
{
if ( report.xbutton.button & Button2 )
{
p->on_right_button_up ( report.xbutton.x,
report.xbutton.y );
}
else if ( report.xbutton.button & Button1 )
{
p->on_left_button_up ( report.xbutton.x,
report.xbutton.y );
}
break;
}
case EnterNotify:
{
p->on_mouse_enter ( report.xcrossing.x,
report.xcrossing.y );
break;
}
case LeaveNotify:
{
p->on_mouse_exit ( report.xcrossing.x,
report.xcrossing.y );
break;
}
case MotionNotify:
{
p->on_mouse_move ( report.xmotion.x,
report.xmotion.y );
break;
}
case FocusIn:
{
p->on_got_focus();
break;
}
case FocusOut:
{
p->on_lost_focus();
break;
}
case KeyPress:
case KeyRelease:
{
char buf[11];
KeySym keysym;
XComposeStatus status;
int count = XLookupString ( &report.xkey,
buf,
10,
&keysym,
&status );
buf[count] = 0;
if ( report.type == KeyPress )
{
p->on_key_press ( character(keysym,
buf,
report.xkey.state) );
}
else
{
p->on_key_release ( character(keysym,
buf,
report.xkey.state) );
}
break;
}
case DestroyNotify:
{
p->on_destroy();
break;
}
case MapNotify:
{
p->on_show();
break;
}
case UnmapNotify:
{
p->on_hide();
break;
}
case ClientMessage:
{
break;
}
}
}
Còn đây là một chương trình tương đối đầy đủ:
Code:
Listing 26.3 xwelcome.cpp
--------------------------------------------------------------------------------
#include <iostream.h>
#include <stdlib.h> // Need exit()
#include <X11/Xlib.h> // Most X programs need these headers
#include <X11/Xutil.h>
#include <X11/Xos.h>
Display *display; // X server display structure
int main()
{
// Attempt to establish communications with the X Server
//
display = XOpenDisplay(NULL);
if (display == NULL) {
cerr << “Failure connecting to X Server”
exit(1);
}
// Calculate window’s dimensions and position
//
int intScreenNum = DefaultScreen(display);
int intDisplayWidth = DisplayWidth(display, intScreenNum);
int intDisplayHeight = DisplayHeight(display, intScreenNum);
int intWidth = intDisplayWidth / 3;
int intHeight = intDisplayHeight / 8;
int intXPos = 0;
int intYPos = 0;
// Get the most basic of colors (black and white)
//
int intBlackColor, intWhiteColor;
intBlackColor = BlackPixel(display, intScreenNum);
intWhiteColor = WhitePixel(display, intScreenNum);
// Create window (this does not make it visible)
Window win =
XCreateSimpleWindow(
display, // X server display struct
DefaultRootWindow(display), // Parent window
intXPos, intYPos, // Position
intWidth, intHeight, // Window width & height
0, // Border width (default)
intBlackColor, intWhiteColor); // Background, foreground
// Assign a name for the window title bar (probably)
//
XStoreName(display, win, “Welcome to X Programming”);
// Map the window to the display
// Window is visible when first Expose event is received
//
XMapWindow(display, win);
// Specify the types of events we want to receive
//
XSelectInput(display, win,
ExposureMask | KeyPressMask | StructureNotifyMask);
// The infamous event loop
//
bool done = false;
XEvent event;
while (!done) {
XNextEvent(display, &event);
switch (event.type) {
case Expose:
cout << “Expose event received” << endl;
break;
case ConfigureNotify:
cout << “ConfigureNotify event received” << endl;
break;
case KeyPress:
cout << “Keypress detected” << endl;
done = true; // Exit on any keypress
break;
}
}
// Disconnect X server connection and exit.
// (Program may never get to here)
//
XCloseDisplay(display);
return 0;
}
Đó chỉ là 1% kiến thức thiết yếu về X Programing in Linux
Các bạn có thể tham khảo như MSDN for XLIB ở đây
Init OPENGL mình xin hẹn lần sau... cón tiếp...