/** * @author Edouard DUPIN * * @copyright 2011, Edouard DUPIN, all right reserved * * @license BSD v3 (see license file) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__TARGET_OS__Linux) #include #elif defined(__TARGET_OS__MacOs) #include #endif #include #include /* #define GUI_LOCK() XLockDisplay(m_display) #define GUI_UNLOCK() XUnlockDisplay(m_display) */ bool hasDisplay = false; //#define DEBUG_X11_EVENT #ifdef DEBUG_X11_EVENT #define X11_DEBUG EWOL_DEBUG #define X11_VERBOSE EWOL_VERBOSE #define X11_INFO EWOL_INFO #define X11_CRITICAL EWOL_CRITICAL #else #define X11_DEBUG EWOL_VERBOSE #define X11_VERBOSE EWOL_VERBOSE #define X11_INFO EWOL_VERBOSE #define X11_CRITICAL EWOL_VERBOSE #endif int64_t ewol::getTime(void) { struct timespec now; int ret = clock_gettime(CLOCK_REALTIME, &now); if (ret != 0) { // Error to get the time ... now.tv_sec = time(NULL); now.tv_nsec = 0; } //EWOL_VERBOSE("current time : " << now.tv_sec << "s " << now.tv_usec << "us"); return (int64_t)((int64_t)now.tv_sec*(int64_t)1000000 + (int64_t)now.tv_nsec/(int64_t)1000); } // attributes for a single buffered visual in RGBA format with at least 4 bits per color and a 16 bit depth buffer static int attrListSgl[] = { GLX_RGBA, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None }; // attributes for a double buffered visual in RGBA format with at least 4 bits per color and a 16 bit depth buffer static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 4, GLX_GREEN_SIZE, 4, GLX_BLUE_SIZE, 4, GLX_DEPTH_SIZE, 16, None }; extern "C" { typedef struct Hints { unsigned long flags; unsigned long functions; unsigned long decorations; long inputMode; unsigned long status; } Hints; } #include #include #undef __class__ #define __class__ "x11Interface" class X11Interface : public ewol::eContext { private: ewol::SpecialKey m_guiKeyBoardMode; // for double and triple click selection, we need to save the previous click up and down position , and the previous time ... Atom m_delAtom; Display* m_display; Window m_WindowHandle; XIM m_xim; XIC m_xic; int32_t m_originX; int32_t m_originY; int32_t m_cursorEventX; int32_t m_cursorEventY; int32_t m_currentHeight; int32_t m_currentWidth; XVisualInfo* m_visual; bool m_doubleBuffered; bool m_run; //forcing the position bool m_grabAllEvent; //!< grab mode enable... vec2 m_forcePos; //!< position to reset the cursor bool m_positionChangeRequested; //!< the position modifiquation has been requested vec2 m_curentGrabDelta; //!< the position in X11 will arrive by pool bool m_inputIsPressed[MAX_MANAGE_INPUT]; // internal copy of the clipBoard ... bool m_clipBoardRequestPrimary; //!< if false : request the copy/past buffer, if true : request current selection bool m_clipBoardOwnerPrimary; //!< we are the owner of the current selection bool m_clipBoardOwnerStd; //!< we are the owner of the current copy buffer // Atom access... Atom XAtomeSelection; Atom XAtomeClipBoard; Atom XAtomeTargetString; Atom XAtomeTargetStringUTF8; Atom XAtomeTargetTarget; Atom XAtomeEWOL; Atom XAtomeDeleteWindows; enum ewol::cursorDisplay m_currentCursor; //!< select the current cursor to display : char32_t m_lastKeyPressed; //!< The last element key presed... public: X11Interface(int32_t _argc, const char* _argv[]) : ewol::eContext(_argc, _argv), m_display(NULL), m_originX(0), m_originY(0), m_cursorEventX(0), m_cursorEventY(0), m_currentHeight(0), m_currentWidth(0), m_visual(NULL), m_doubleBuffered(0), m_run(false), m_grabAllEvent(false), m_forcePos(0,0), m_positionChangeRequested(false), m_curentGrabDelta(0,0), m_clipBoardRequestPrimary(false), m_clipBoardOwnerPrimary(false), m_clipBoardOwnerStd(false), XAtomeSelection(0), XAtomeClipBoard(0), XAtomeTargetString(0), XAtomeTargetStringUTF8(0), XAtomeTargetTarget(0), XAtomeEWOL(0), XAtomeDeleteWindows(0), m_currentCursor(ewol::cursorArrow), m_lastKeyPressed(0) { X11_INFO("X11:INIT"); for (int32_t iii=0; iii Kill Requested ..."); OS_Stop(); m_run = false; } break; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Selection AREA // /////////////////////////////////////////////////////////////////////////////////////////////////////////////// case SelectionClear: { // Selection has been done on an other program == > clear ours ... X11_INFO("X11 event SelectionClear"); #ifdef DEBUG_X11_EVENT { XSelectionRequestEvent *req=&(event.xselectionrequest); char * atomNameProperty = XGetAtomName(m_display, req->property); char * atomNameTarget = XGetAtomName(m_display, req->target); EWOL_INFO("X11 property: \"" << atomNameProperty << "\""); EWOL_INFO("X11 target: \"" << atomNameTarget << "\""); if (NULL != atomNameProperty) { XFree(atomNameProperty); } if (NULL != atomNameTarget) { XFree(atomNameTarget); } } #endif if (true == m_clipBoardOwnerPrimary) { m_clipBoardOwnerPrimary = false; } else if (true == m_clipBoardOwnerStd) { m_clipBoardOwnerStd = false; } else { EWOL_ERROR("X11 event SelectionClear == > but no selection requested anymore ..."); } break; } case SelectionNotify: X11_INFO("X11 event SelectionNotify"); if (event.xselection.property == None) { EWOL_VERBOSE(" == > no data ..."); } else { unsigned char *buf = 0; Atom type; int format; unsigned long nitems, bytes; XGetWindowProperty(m_display, m_WindowHandle, event.xselection.property, 0, // offset (~0L), // length False, // delete AnyPropertyType, // reg_type &type,// *actual_type_return, &format,// *actual_format_return &nitems,// *nitems_return &bytes, // *bytes_after_return &buf// **prop_return); ); if (true == m_clipBoardRequestPrimary) { std::string tmpppp((char*)buf); ewol::clipBoard::setSystem(ewol::clipBoard::clipboardSelection, tmpppp); // just transmit an event , we have the data in the system OS_ClipBoardArrive(ewol::clipBoard::clipboardSelection); } else { std::string tmpppp((char*)buf); ewol::clipBoard::setSystem(ewol::clipBoard::clipboardStd, tmpppp); // just transmit an event , we have the data in the system OS_ClipBoardArrive(ewol::clipBoard::clipboardStd); } } break; case SelectionRequest: { X11_INFO("X11 event SelectionRequest"); XSelectionRequestEvent *req=&(event.xselectionrequest); #ifdef DEBUG_X11_EVENT { char * atomNameProperty = XGetAtomName(m_display, req->property); char * atomNameSelection = XGetAtomName(m_display, req->selection); char * atomNameTarget = XGetAtomName(m_display, req->target); EWOL_INFO(" from: " << atomNameProperty << " request=" << atomNameSelection << " in " << atomNameTarget); if (NULL != atomNameProperty) { XFree(atomNameProperty); } if (NULL != atomNameSelection) { XFree(atomNameSelection); } if (NULL != atomNameTarget) { XFree(atomNameTarget); } } #endif std::string tmpData = ""; if (req->selection == XAtomeSelection) { tmpData = ewol::clipBoard::get(ewol::clipBoard::clipboardSelection); } else if (req->selection == XAtomeClipBoard) { tmpData = ewol::clipBoard::get(ewol::clipBoard::clipboardStd); } const char * magatTextToSend = tmpData.c_str(); Atom listOfAtom[4]; if(strlen(magatTextToSend) == 0 ) { respond.xselection.property= None; } else if(XAtomeTargetTarget == req->target) { // We need to generate the list of the possibles target element of atom int32_t nbAtomSupported = 0; listOfAtom[nbAtomSupported++] = XAtomeTargetTarget; listOfAtom[nbAtomSupported++] = XAtomeTargetString; listOfAtom[nbAtomSupported++] = XAtomeTargetStringUTF8; listOfAtom[nbAtomSupported++] = None; XChangeProperty( m_display, req->requestor, req->property, XA_ATOM, 32, PropModeReplace, (unsigned char*)listOfAtom, nbAtomSupported ); respond.xselection.property=req->property; EWOL_INFO(" == > Respond ... (test)"); } else if(XAtomeTargetString == req->target) { XChangeProperty( m_display, req->requestor, req->property, req->target, 8, PropModeReplace, (unsigned char*)magatTextToSend, strlen(magatTextToSend)); respond.xselection.property=req->property; EWOL_INFO(" == > Respond ..."); } else if (XAtomeTargetStringUTF8 == req->target) { XChangeProperty( m_display, req->requestor, req->property, req->target, 8, PropModeReplace, (unsigned char*)magatTextToSend, strlen(magatTextToSend)); respond.xselection.property=req->property; EWOL_INFO(" == > Respond ..."); } else { respond.xselection.property= None; } respond.xselection.type= SelectionNotify; respond.xselection.display= req->display; respond.xselection.requestor= req->requestor; respond.xselection.selection=req->selection; respond.xselection.target= req->target; respond.xselection.time = req->time; XSendEvent (m_display, req->requestor,0,0,&respond); // flush the message on the pipe ... XFlush (m_display); break; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// case Expose: X11_INFO("X11 event Expose"); specialEventThatNeedARedraw=true; break; case GraphicsExpose: X11_INFO("X11 event GraphicsExpose"); specialEventThatNeedARedraw=true; break; case NoExpose: X11_INFO("X11 event NoExpose"); break; case CreateNotify: X11_INFO("X11 event CreateNotify"); break; case DestroyNotify: X11_INFO("X11 event DestroyNotify"); break; case GravityNotify: X11_INFO("X11 event GravityNotify"); break; case VisibilityNotify: X11_INFO("X11 event VisibilityNotify"); break; case CirculateNotify: X11_INFO("X11 event CirculateNotify"); break; case ReparentNotify: X11_INFO("X11 event ReparentNotify"); break; case PropertyNotify: specialEventThatNeedARedraw=true; X11_INFO("X11 event PropertyNotify"); break; case ConfigureNotify: specialEventThatNeedARedraw=true; X11_INFO("X11 event ConfigureNotify"); if (m_display == event.xconfigure.display) { //EWOL_INFO("X11 event ConfigureNotify event=" << (int32_t)event.xconfigure.event << " Window=" << (int32_t)event.xconfigure.window << " above=" << (int32_t)event.xconfigure.above << " border_width=" << (int32_t)event.xconfigure.border_width ); m_originX = event.xconfigure.x; m_originY = event.xconfigure.y; X11_INFO("X11 configure windows position : (" << m_originX << "," << m_originY << ")"); m_currentHeight = event.xconfigure.height; m_currentWidth = event.xconfigure.width; X11_INFO("X11 configure windows size : (" << m_currentHeight << "," << m_currentWidth << ")"); OS_Resize(vec2(event.xconfigure.width, event.xconfigure.height)); } break; case ButtonPress: X11_INFO("X11 event ButtonPress"); m_cursorEventX = event.xbutton.x; m_cursorEventY = (m_currentHeight-event.xbutton.y); if (event.xbutton.button < MAX_MANAGE_INPUT) { m_inputIsPressed[event.xbutton.button] = true; } OS_SetMouseState(event.xbutton.button, true, vec2(event.xbutton.x, m_cursorEventY)); break; case ButtonRelease: X11_INFO("X11 event ButtonRelease"); m_cursorEventX = event.xbutton.x; m_cursorEventY = (m_currentHeight-event.xbutton.y); if (event.xbutton.button < MAX_MANAGE_INPUT) { m_inputIsPressed[event.xbutton.button] = false; } OS_SetMouseState(event.xbutton.button, false, vec2(event.xbutton.x, m_cursorEventY)); break; case EnterNotify: X11_INFO("X11 event EnterNotify"); m_cursorEventX = event.xcrossing.x; m_cursorEventY = (m_currentHeight-event.xcrossing.y); //EWOL_DEBUG("X11 event : " << event.type << " = \"EnterNotify\" (" << (float)event.xcrossing.x << "," << (float)event.xcrossing.y << ")"); //gui_uniqueWindows->GenEventInput(0, ewol::EVENT_INPUT_TYPE_ENTER, (float)event.xcrossing.x, (float)event.xcrossing.y); m_curentGrabDelta -= vec2(m_originX, -m_originY); EWOL_DEBUG("change grab delta of : " << vec2(m_originX, m_originY) ); break; case LeaveNotify: X11_INFO("X11 event LeaveNotify"); m_cursorEventX = event.xcrossing.x; m_cursorEventY = (m_currentHeight-event.xcrossing.y); //EWOL_DEBUG("X11 event : " << event.type << " = \"LeaveNotify\" (" << (float)event.xcrossing.x << "," << (float)event.xcrossing.y << ")"); m_curentGrabDelta += vec2(m_originX, -m_originY); EWOL_DEBUG("change grab delta of : " << vec2(m_originX, m_originY) ); break; case MotionNotify: X11_INFO("X11 event MotionNotify"); if( true == m_grabAllEvent && event.xmotion.x == (int32_t)m_forcePos.x() && event.xmotion.y == (int32_t)m_forcePos.y()) { X11_VERBOSE("X11 reject mouse move (grab mode)"); // we get our requested position... m_positionChangeRequested = false; m_curentGrabDelta = vec2(0,0); } else { m_cursorEventX = event.xmotion.x; m_cursorEventY = (m_currentHeight-event.xmotion.y); if(true == m_grabAllEvent) { m_cursorEventX -= m_forcePos.x(); m_cursorEventY -= (m_currentHeight-m_forcePos.y()); } vec2 newDelta = vec2(m_cursorEventX, m_cursorEventY); if(true == m_grabAllEvent) { m_cursorEventX -= m_curentGrabDelta.x(); m_cursorEventY -= m_curentGrabDelta.y(); } m_curentGrabDelta = newDelta; // For compatibility of the Android system : bool findOne = false; for (int32_t iii=0; iii= 0) { // repeated kay from previous element : if (count>0) { // transform it in unicode m_lastKeyPressed = etk::setUtf8(buf); } //EWOL_INFO("event Key : " << event.xkey.keycode << " char=\"" << buf << "\"'len=" << strlen(buf) << " unicode=" << unicodeValue); OS_SetKeyboard(m_guiKeyBoardMode, m_lastKeyPressed, (event.type == KeyPress), thisIsAReapeateKey); if (true == thisIsAReapeateKey) { OS_SetKeyboard(m_guiKeyBoardMode, m_lastKeyPressed, !(event.type == KeyPress), thisIsAReapeateKey); } } else { EWOL_WARNING("Unknow event Key : " << event.xkey.keycode << " res='" << buf << "' repeate=" << thisIsAReapeateKey); } } break; } if (true == find) { //EWOL_DEBUG("eventKey Move type : " << getCharTypeMoveEvent(keyInput) ); OS_SetKeyboardMove(m_guiKeyBoardMode, keyInput, (event.type == KeyPress), thisIsAReapeateKey); if (true == thisIsAReapeateKey) { OS_SetKeyboardMove(m_guiKeyBoardMode, keyInput, !(event.type == KeyPress), thisIsAReapeateKey); } } } break; } //case DestroyNotify: // break; case MapNotify: X11_INFO("X11 event : MapNotify"); specialEventThatNeedARedraw=true; OS_Show(); break; case UnmapNotify: X11_INFO("X11 event : UnmapNotify"); specialEventThatNeedARedraw=true; OS_Hide(); break; default: X11_INFO("X11 event : " << event.type << " = \"???\""); break; } } if(true == m_run) { if (m_doubleBuffered && hasDisplay) { glXSwapBuffers(m_display, m_WindowHandle); XSync(m_display,0); } // draw after switch the previous windows ... //EWOL_DEBUG("specialEventThatNeedARedraw"<visual, AllocNone); attr.border_pixel = 0; attr.event_mask = StructureNotifyMask | SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | FocusChangeMask | SubstructureRedirectMask; // set no background at the gui attr.background_pixmap = None; // select internal attribute attr_mask = CWBackPixmap | CWColormap | CWBorderPixel | CWEventMask; // Create the window int32_t tmp_width = 640;//DisplayWidth(m_display, DefaultScreen(m_display))/2; int32_t tmp_height = 480;//DisplayHeight(m_display, DefaultScreen(m_display))/2; OS_Resize(vec2(tmp_width, tmp_height)); x=20; y=20; m_originX = x; m_originY = y; EWOL_INFO("X11 request creating windows at pos=(" << m_originX << "," << m_originY << ") size=(" << tmp_width << "," << tmp_height << ")" ); // Real create of the window m_WindowHandle = XCreateWindow(m_display, Xroot, x, y, tmp_width, tmp_height, 1, m_visual->depth, InputOutput, m_visual->visual, attr_mask, &attr); if( !m_WindowHandle ) { EWOL_CRITICAL("Couldn't create the window"); exit(-1); } /* Configure it... (ok, ok, this next bit isn't "minimal") */ textprop.value = (unsigned char*)title; textprop.encoding = XA_STRING; textprop.format = 8; textprop.nitems = strlen(title); hints.x = x; hints.y = y; hints.width = tmp_width; hints.height = tmp_height; hints.flags = USPosition|USSize; StartupState = XAllocWMHints(); StartupState->initial_state = NormalState; StartupState->flags = StateHint; XSetWMProperties(m_display, m_WindowHandle,&textprop, &textprop,/* Window title/icon title*/ NULL, 0,/* Argv[], argc for program*/ &hints, /* Start position/size*/ StartupState,/* Iconised/not flag */ NULL); XFree(StartupState); /* open it, wait for it to appear */ XMapWindow(m_display, m_WindowHandle); //XIfEvent(m_display, &event, WaitForMapNotify, (char*)&m_WindowHandle); m_xim = XOpenIM(m_display, NULL, NULL, NULL); if (m_xim == NULL) { EWOL_ERROR("Could not open input method"); return false; } /* XIMStyles *styles=NULL; char* failed_arg = XGetIMValues(m_xim, XNQueryInputStyle, &styles, NULL); if (failed_arg != NULL) { EWOL_ERROR("XIM Can't get styles"); return false; } for (int32_t iii=0; iiicount_styles; ++iii) { EWOL_INFO("style " << styles->supported_styles[iii]); } */ m_xic = XCreateIC(m_xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, m_WindowHandle, NULL); if (m_xic == NULL) { EWOL_ERROR("Could not open IC"); return false; } XSetICFocus(m_xic); // set the kill atom so we get a message when the user tries to close the window if ((m_delAtom = XInternAtom(m_display, "WM_DELETE_WINDOW", 0)) != None) { XSetWMProtocols(m_display, m_WindowHandle, &m_delAtom, 1); } vec2 tmpSize(400, 300); OS_Resize(tmpSize); return true; } /****************************************************************************************/ void setIcon(const std::string& _inputFile) { egami::Image dataImage; // load data if (false == egami::load(dataImage, _inputFile)) { EWOL_ERROR("Error when loading Icon"); return; } int32_t depth = DefaultDepth(m_display, DefaultScreen(m_display) ); EWOL_DEBUG("X11 Create icon size=(" << dataImage.getWidth() << "," << dataImage.getHeight() << ") depth=" << depth); switch(depth) { case 8: EWOL_CRITICAL("Not manage pixmap in 8 bit... == > no icon ..."); return; case 16: break; case 24: break; case 32: break; default: EWOL_CRITICAL("Unknow thys type of bitDepth : " << depth); return; } char* tmpVal = new char[4*dataImage.getWidth()*dataImage.getHeight()]; if (NULL == tmpVal) { EWOL_CRITICAL("Allocation error ..."); return; } char* tmpPointer = tmpVal; switch(depth) { case 16: for(ivec2 pos(0,0); pos.y() tmpColor = dataImage.get(pos); int16_t tmpVal = (((uint16_t)((uint16_t)tmpColor.r()>>3))<<11) + (((uint16_t)((uint16_t)tmpColor.g()>>2))<<5) + ((uint16_t)((uint16_t)tmpColor.b()>>3)); *tmpPointer++ = (uint8_t)(tmpVal>>8); *tmpPointer++ = (uint8_t)(tmpVal&0x00FF); } } break; case 24: for(ivec2 pos(0,0); pos.y() tmpColor = dataImage.get(pos); *tmpPointer++ = tmpColor.b(); *tmpPointer++ = tmpColor.g(); *tmpPointer++ = tmpColor.r(); tmpPointer++; } } break; case 32: for(ivec2 pos(0,0); pos.y() tmpColor = dataImage.get(pos); *tmpPointer++ = tmpColor.a(); *tmpPointer++ = tmpColor.b(); *tmpPointer++ = tmpColor.g(); *tmpPointer++ = tmpColor.r(); } } break; default: return; } XImage* myImage = XCreateImage(m_display, m_visual->visual, depth, ZPixmap, 0, (char*)tmpVal, dataImage.getWidth(), dataImage.getHeight(), 32, 0); Pixmap tmpPixmap = XCreatePixmap(m_display, m_WindowHandle, dataImage.getWidth(), dataImage.getHeight(), depth); switch(tmpPixmap) { case BadAlloc: EWOL_ERROR("X11: BadAlloc"); break; case BadDrawable: EWOL_ERROR("X11: BadDrawable"); break; case BadValue: EWOL_ERROR("X11: BadValue"); break; default: EWOL_DEBUG("Create Pixmap OK"); break; } GC tmpGC = DefaultGC(m_display, DefaultScreen(m_display) ); int error = XPutImage(m_display, tmpPixmap, tmpGC, myImage, 0, 0, 0, 0, dataImage.getWidth(), dataImage.getHeight()); switch(error) { case BadDrawable: EWOL_ERROR("X11: BadDrawable"); break; case BadGC: EWOL_ERROR("X11: BadGC"); break; case BadMatch: EWOL_ERROR("X11: BadMatch"); break; case BadValue: EWOL_ERROR("X11: BadValue"); break; default: EWOL_DEBUG("insert image OK"); break; } // allocate a WM hints structure. XWMHints* win_hints = XAllocWMHints(); if (!win_hints) { EWOL_ERROR("XAllocWMHints - out of memory"); return; } // initialize the structure appropriately. first, specify which size hints we want to fill in. in our case - setting the icon's pixmap. win_hints->flags = IconPixmapHint; // next, specify the desired hints data. in our case - supply the icon's desired pixmap. win_hints->icon_pixmap = tmpPixmap; // pass the hints to the window manager. XSetWMHints(m_display, m_WindowHandle, win_hints); EWOL_INFO(" == > might be done "); // finally, we can free the WM hints structure. XFree(win_hints); // Note when we free the pixmap ... the icon is removed ... == > this is a real memory leek ... //XFreePixmap(m_display, tmpPixmap); myImage->data = NULL; XDestroyImage(myImage); delete[] tmpVal; } /****************************************************************************************/ static void setVSync(bool _sync) { // Function pointer for the wgl extention function we need to enable/disable typedef int32_t (APIENTRY *PFNWGLSWAPINTERVALPROC)( int ); PFNWGLSWAPINTERVALPROC wglSwapIntervalEXT = 0; const char *extensions = (char*)glGetString( GL_EXTENSIONS ); if( strstr( extensions, "WGL_EXT_swap_control" ) == 0 ) { EWOL_ERROR("Can not set the vertical synchronisation status" << _sync << " (1)"); return; } else { wglSwapIntervalEXT = (PFNWGLSWAPINTERVALPROC)glXGetProcAddress( (const GLubyte *)"wglSwapIntervalEXT" ); if(wglSwapIntervalEXT) { wglSwapIntervalEXT(_sync); } else { EWOL_ERROR("Can not set the vertical synchronisation status" << _sync << " (2)"); } } } /****************************************************************************************/ bool createOGlContext(void) { X11_INFO("X11:CreateOGlContext"); /* create a GLX context */ GLXContext RenderContext = glXCreateContext(m_display, m_visual, 0, GL_TRUE); /* connect the glx-context to the window */ glXMakeCurrent(m_display, m_WindowHandle, RenderContext); if (glXIsDirect(m_display, RenderContext)) { EWOL_INFO("XF86 DRI enabled\n"); } else { EWOL_INFO("XF86 DRI NOT available\n"); } // enable vertical synchronisation : (some computer has synchronisation disable) setVSync(true); return true; } /****************************************************************************************/ void setTitle(const std::string& _title) { X11_INFO("X11: set Title (START)"); XTextProperty tp; tp.value = (unsigned char *)_title.c_str(); tp.encoding = XA_WM_NAME; tp.format = 8; tp.nitems = strlen((const char*)tp.value); XSetWMName(m_display, m_WindowHandle, &tp); XStoreName(m_display, m_WindowHandle, (const char*)tp.value); XSetIconName(m_display, m_WindowHandle, (const char*)tp.value); XSetWMIconName(m_display, m_WindowHandle, &tp); X11_INFO("X11: set Title (END)"); } /****************************************************************************************/ void clipBoardGet(enum ewol::clipBoard::clipboardListe _clipboardID) { switch (_clipboardID) { case ewol::clipBoard::clipboardSelection: if (false == m_clipBoardOwnerPrimary) { m_clipBoardRequestPrimary = true; // generate a request on X11 XConvertSelection(m_display, XAtomeSelection, XAtomeTargetStringUTF8, XAtomeEWOL, m_WindowHandle, CurrentTime); } else { // just transmit an event , we have the data in the system OS_ClipBoardArrive(_clipboardID); } break; case ewol::clipBoard::clipboardStd: if (false == m_clipBoardOwnerStd) { m_clipBoardRequestPrimary = false; // generate a request on X11 XConvertSelection(m_display, XAtomeClipBoard, XAtomeTargetStringUTF8, XAtomeEWOL, m_WindowHandle, CurrentTime); } else { // just transmit an event , we have the data in the system OS_ClipBoardArrive(_clipboardID); } break; default: EWOL_ERROR("Request an unknow ClipBoard ..."); break; } } /****************************************************************************************/ void clipBoardSet(enum ewol::clipBoard::clipboardListe _clipboardID) { switch (_clipboardID) { case ewol::clipBoard::clipboardSelection: // Request the selection : if (false == m_clipBoardOwnerPrimary) { XSetSelectionOwner(m_display, XAtomeSelection, m_WindowHandle, CurrentTime); m_clipBoardOwnerPrimary = true; } break; case ewol::clipBoard::clipboardStd: // Request the clipBoard : if (false == m_clipBoardOwnerStd) { XSetSelectionOwner(m_display, XAtomeClipBoard, m_WindowHandle, CurrentTime); m_clipBoardOwnerStd = true; } break; default: EWOL_ERROR("Request an unknow ClipBoard ..."); break; } } }; /** * @brief Main of the program * @param std IO * @return std IO */ int ewol::run(int _argc, const char *_argv[]) { etk::setArgZero(_argv[0]); X11Interface* interface = new X11Interface(_argc, _argv); if (NULL == interface) { EWOL_CRITICAL("Can not create the X11 interface ... MEMORY allocation error"); return -2; } int32_t retValue = interface->run(); delete(interface); interface = NULL; return retValue; }