Changeset View
Changeset View
Standalone View
Standalone View
intern/ghost/intern/GHOST_SystemX11.cpp
| Show First 20 Lines • Show All 375 Lines • ▼ Show 20 Lines | GHOST_IWindow *GHOST_SystemX11::createWindow(const STR_String &title, | ||||
| return window; | return window; | ||||
| } | } | ||||
| /** | /** | ||||
| * Create a new offscreen context. | * Create a new offscreen context. | ||||
| * Never explicitly delete the context, use disposeContext() instead. | * Never explicitly delete the context, use disposeContext() instead. | ||||
| * \return The new context (or 0 if creation failed). | * \return The new context (or 0 if creation failed). | ||||
| */ | */ | ||||
| GHOST_IContext *GHOST_SystemX11::createOffscreenContext() | GHOST_IContext *GHOST_SystemX11::createOffscreenContext( | ||||
| GHOST_PlatformSupportCallbackPtr platform_support_callback) | |||||
| { | { | ||||
| // During development: | // During development: | ||||
| // try 4.x compatibility profile | // try 4.x compatibility profile | ||||
| // try 3.3 compatibility profile | // try 3.3 compatibility profile | ||||
| // fall back to 3.0 if needed | // fall back to 3.0 if needed | ||||
| // | // | ||||
| // Final Blender 2.8: | // Final Blender 2.8: | ||||
| // try 4.x core profile | // try 4.x core profile | ||||
| Show All 14 Lines | |||||
| #if defined(WITH_GL_PROFILE_CORE) | #if defined(WITH_GL_PROFILE_CORE) | ||||
| GLX_CONTEXT_CORE_PROFILE_BIT_ARB; | GLX_CONTEXT_CORE_PROFILE_BIT_ARB; | ||||
| #elif defined(WITH_GL_PROFILE_COMPAT) | #elif defined(WITH_GL_PROFILE_COMPAT) | ||||
| GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; | GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; | ||||
| #else | #else | ||||
| # error // must specify either core or compat at build time | # error // must specify either core or compat at build time | ||||
| #endif | #endif | ||||
| if (platform_support_callback) { | |||||
| char title[1024]; | |||||
| char message[1024]; | |||||
| char link[1024]; | |||||
| GHOST_DialogOptions dialog_options = platform_support_callback(title, message, link); | |||||
| if (dialog_options & GHOST_DialogShow) { | |||||
| showMessageBox(title, message, link, dialog_options); | |||||
| } | |||||
| if (dialog_options & GHOST_DialogExit) { | |||||
| /* TODO: Find a better way to exit. | |||||
| * It currently crashes as timer events cannot be processed. */ | |||||
| exit(); | |||||
| } | |||||
| } | |||||
| GHOST_Context *context; | GHOST_Context *context; | ||||
| for (int minor = 5; minor >= 0; --minor) { | for (int minor = 5; minor >= 0; --minor) { | ||||
| context = new GHOST_ContextGLX(false, | context = new GHOST_ContextGLX(false, | ||||
| (Window)NULL, | (Window)NULL, | ||||
| m_display, | m_display, | ||||
| (GLXFBConfig)NULL, | (GLXFBConfig)NULL, | ||||
| profile_mask, | profile_mask, | ||||
| ▲ Show 20 Lines • Show All 1,715 Lines • ▼ Show 20 Lines | else { | ||||
| strcpy(txt_select_buffer, buffer); | strcpy(txt_select_buffer, buffer); | ||||
| } | } | ||||
| if (owner != m_window) | if (owner != m_window) | ||||
| fprintf(stderr, "failed to own primary\n"); | fprintf(stderr, "failed to own primary\n"); | ||||
| } | } | ||||
| } | } | ||||
| class DialogData { | |||||
| public: | |||||
| /* Width of the dialog */ | |||||
| uint width; | |||||
| /* Heigth of the dialog */ | |||||
| uint height; | |||||
| /* Default padding (x direction) between controls and edge of dialog */ | |||||
| uint padding_x; | |||||
| /* Default padding (y direction) between controls and edge of dialog */ | |||||
| uint padding_y; | |||||
| /* Width of a single button */ | |||||
| uint button_width; | |||||
| /* Height of a single button */ | |||||
| uint button_height; | |||||
| /* Inset of a button to its text */ | |||||
| uint button_inset_x; | |||||
| /* Size of the border of the button */ | |||||
| uint button_border_size; | |||||
| /* Height of a line of text */ | |||||
| uint line_height; | |||||
| /* offset of the text inside the button */ | |||||
| uint button_text_offset_y; | |||||
| /* Construct a new DialogData with the default settings */ | |||||
| DialogData() | |||||
| : width(512), | |||||
| height(100), | |||||
| line_height(16), | |||||
| padding_x(10), | |||||
| padding_y(5), | |||||
| button_width(50), | |||||
| button_height(24), | |||||
| button_inset_x(10), | |||||
| button_border_size(1) | |||||
| { | |||||
| button_text_offset_y = button_height - line_height; | |||||
| } | |||||
| void drawButton(Display *display, | |||||
| Window &window, | |||||
| GC &borderGC, | |||||
| GC &buttonGC, | |||||
| uint button_num, | |||||
| const char *label) | |||||
| { | |||||
| XFillRectangle(display, | |||||
| window, | |||||
| borderGC, | |||||
| width - (padding_x + button_width) * button_num, | |||||
| height - padding_y - button_height, | |||||
| button_width, | |||||
| button_height); | |||||
| XFillRectangle(display, | |||||
| window, | |||||
| buttonGC, | |||||
| width - (padding_x + button_width) * button_num + button_border_size, | |||||
| height - padding_y - button_height + button_border_size, | |||||
| button_width - button_border_size * 2, | |||||
| button_height - button_border_size * 2); | |||||
| XDrawString(display, | |||||
| window, | |||||
| borderGC, | |||||
| width - (padding_x + button_width) * button_num + button_inset_x, | |||||
| height - padding_y - button_text_offset_y, | |||||
| label, | |||||
| strlen(label)); | |||||
| } | |||||
| /* Is the mouse inside the given button */ | |||||
| bool isInsideButton(XEvent &e, uint button_num) | |||||
| { | |||||
| return ((e.xmotion.y > height - padding_y - button_height) && | |||||
| (e.xmotion.y < height - padding_y) && | |||||
| (e.xmotion.x > width - (padding_x + button_width) * button_num) && | |||||
| (e.xmotion.x < width - padding_x - (padding_x + button_width) * (button_num - 1))); | |||||
| } | |||||
| }; | |||||
| static void split(const char *text, const char *seps, char ***str, int *count) | |||||
| { | |||||
| char *tok, *data; | |||||
| int i; | |||||
| *count = 0; | |||||
| data = strdup(text); | |||||
| for (tok = strtok(data, seps); tok != NULL; tok = strtok(NULL, seps)) | |||||
| (*count)++; | |||||
| free(data); | |||||
| data = strdup(text); | |||||
| *str = (char **)malloc((size_t)(*count) * sizeof(char *)); | |||||
| for (i = 0, tok = strtok(data, seps); tok != NULL; tok = strtok(NULL, seps), i++) | |||||
| (*str)[i] = strdup(tok); | |||||
| free(data); | |||||
| } | |||||
| static void computeTextSize(XFontSet *fs, | |||||
| wchar_t **texts, | |||||
| int size, | |||||
| unsigned int spaceBetweenLines, | |||||
| unsigned int *w, | |||||
| unsigned int *h) | |||||
| { | |||||
| int i; | |||||
| XRectangle rect = {0, 0, 0, 0}; | |||||
| *h = 0; | |||||
| *w = 0; | |||||
| for (i = 0; i < size; i++) { | |||||
| XwcTextExtents(*fs, texts[i], (int)wcslen(texts[i]), &rect, NULL); | |||||
| *w = (rect.width > *w) ? (rect.width) : *w; | |||||
| *h += rect.height + spaceBetweenLines; | |||||
| fflush(stdin); | |||||
| } | |||||
| } | |||||
| GHOST_TSuccess GHOST_SystemX11::showMessageBox(const char *title, | |||||
| const char *message, | |||||
| const char *link, | |||||
| GHOST_DialogOptions dialog_options) const | |||||
| { | |||||
| char **text_splitted = NULL; | |||||
| int textLines = 0; | |||||
| split(message, "\n", &text_splitted, &textLines); | |||||
| DialogData dialog_data; | |||||
| Window window; | |||||
| XEvent e; | |||||
| int screen = DefaultScreen(m_display); | |||||
| window = XCreateSimpleWindow(m_display, | |||||
| RootWindow(m_display, screen), | |||||
| 0, | |||||
| 0, | |||||
| dialog_data.width, | |||||
| dialog_data.height, | |||||
| 1, | |||||
| BlackPixel(m_display, screen), | |||||
| WhitePixel(m_display, screen)); | |||||
| /* Set title */ | |||||
| { | |||||
| Atom wm_Name = XInternAtom(m_display, "_NET_WM_NAME", False); | |||||
| Atom utf8Str = XInternAtom(m_display, "UTF8_STRING", False); | |||||
| Atom winType = XInternAtom(m_display, "_NET_WM_WINDOW_TYPE", False); | |||||
| Atom typeDialog = XInternAtom(m_display, "_NET_WM_WINDOW_TYPE_DIALOG", False); | |||||
| XChangeProperty(m_display, | |||||
| window, | |||||
| wm_Name, | |||||
| utf8Str, | |||||
| 8, | |||||
| PropModeReplace, | |||||
| (const unsigned char *)title, | |||||
| (int)strlen(title)); | |||||
| XChangeProperty( | |||||
| m_display, window, winType, XA_ATOM, 32, PropModeReplace, (unsigned char *)&typeDialog, 1); | |||||
| } | |||||
| /* Create buttons GC */ | |||||
| XGCValues buttonBorderGCValues; | |||||
| buttonBorderGCValues.foreground = BlackPixel(m_display, screen); | |||||
| buttonBorderGCValues.background = WhitePixel(m_display, screen); | |||||
| XGCValues buttonGCValues; | |||||
| buttonGCValues.foreground = WhitePixel(m_display, screen); | |||||
| buttonGCValues.background = BlackPixel(m_display, screen); | |||||
| GC buttonBorderGC = XCreateGC(m_display, window, GCForeground, &buttonBorderGCValues); | |||||
| GC buttonGC = XCreateGC(m_display, window, GCForeground, &buttonGCValues); | |||||
| XSelectInput(m_display, window, ExposureMask | ButtonPressMask | ButtonReleaseMask); | |||||
| XMapWindow(m_display, window); | |||||
| while (1) { | |||||
| XNextEvent(m_display, &e); | |||||
| if (e.type == Expose) { | |||||
| for (int i = 0; i < textLines; i++) { | |||||
| XDrawString(m_display, | |||||
| window, | |||||
| DefaultGC(m_display, screen), | |||||
brecht: Warning to be silenced:
```
intern/ghost/intern/GHOST_SystemX11.cpp:2330:15: warning: ignoring… | |||||
| dialog_data.padding_x, | |||||
| dialog_data.padding_x + (i + 1) * dialog_data.line_height, | |||||
| text_splitted[i], | |||||
| (int)strlen(text_splitted[i])); | |||||
| } | |||||
| dialog_data.drawButton(m_display, window, buttonBorderGC, buttonGC, 1, "Ok"); | |||||
| if (strlen(link)) { | |||||
| dialog_data.drawButton(m_display, window, buttonBorderGC, buttonGC, 2, "Help"); | |||||
| } | |||||
| } | |||||
| else if (e.type == ButtonRelease) { | |||||
| if (dialog_data.isInsideButton(e, 1)) { | |||||
| break; | |||||
| } | |||||
| else if (strlen(link) && dialog_data.isInsideButton(e, 2)) { | |||||
| string cmd = "xdg-open \"" + string(link) + "\""; | |||||
| system(cmd.c_str()); | |||||
| } | |||||
| } | |||||
| } | |||||
| for (int i = 0; i < textLines; i++) { | |||||
| free(text_splitted[i]); | |||||
| } | |||||
| free(text_splitted); | |||||
| XFreeGC(m_display, buttonBorderGC); | |||||
| XFreeGC(m_display, buttonGC); | |||||
| return GHOST_kSuccess; | |||||
| } | |||||
| #ifdef WITH_XDND | #ifdef WITH_XDND | ||||
| GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType, | GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType, | ||||
| GHOST_TDragnDropTypes draggedObjectType, | GHOST_TDragnDropTypes draggedObjectType, | ||||
| GHOST_IWindow *window, | GHOST_IWindow *window, | ||||
| int mouseX, | int mouseX, | ||||
| int mouseY, | int mouseY, | ||||
| void *data) | void *data) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 196 Lines • Show Last 20 Lines | |||||
Warning to be silenced:
intern/ghost/intern/GHOST_SystemX11.cpp:2330:15: warning: ignoring return value of ‘int system(const char*)’, declared with attribute warn_unused_result [-Wunused-result] system(cmd.c_str()); ~~~~~~^~~~~~~~~~~~~