I'm using the Allegro5 API to create my window and manage it. It allows me access to the XWindow which it creates with XCreateWindow
I have access to d->window but that's about it. From this, is there a way I could interact with the XEvents sent to this window? I want to implement clipboard functionality. I'm just not sure how I can deal with XSelection events.
You need to create the xevent loop, and to handle specific xevents. Here is a xlib hello world example, and that is how you can do it.
The example is copied from here :
#include<X11/Xlib.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
Display *dpy;
Window rootwin;
Window win;
Colormap cmap;
XEvent e;
int scr;
GC gc;
if(!(dpy=XOpenDisplay(NULL))) {
fprintf(stderr, "ERROR: could not open display\n");
exit(1);
}
scr = DefaultScreen(dpy);
rootwin = RootWindow(dpy, scr);
cmap = DefaultColormap(dpy, scr);
win=XCreateSimpleWindow(dpy, rootwin, 1, 1, 100, 50, 0,
BlackPixel(dpy, scr), BlackPixel(dpy, scr));
XStoreName(dpy, win, "hello");
gc=XCreateGC(dpy, win, 0, NULL);
XSetForeground(dpy, gc, WhitePixel(dpy, scr));
XSelectInput(dpy, win, ExposureMask|ButtonPressMask);
XMapWindow(dpy, win);
while(1) {
XNextEvent(dpy, &e);
if(e.type==Expose && e.xexpose.count<1)
XDrawString(dpy, win, gc, 10, 10, "Hello World!", 12);
else if(e.type==ButtonPress) break;
}
XCloseDisplay(dpy);
}
To build, create a Makefile :
all: hello
hello: hello.o
cc -o hello -Wall -L/usr/X11R6/lib -lX11 hello.o
hello.o: hello.c
cc -o hello.o -Wall -I/usr/X11R6/include -c hello.c
Related
I've been trying to set up a build environment for OpenGL using glfw3 and GLAD. I'm currently using WSL2 Ubuntu with an X Server for compilation and a makefile.
However, when I run my make I receive the following error:
src/glad.c:25:10: fatal error: glad/glad.h: No such file or directory
25 | #include <glad/glad.h>
This is odd to me because it seems that the makefile is able to compile the main.cpp file and create a main.o despite also including "glad/glad.h"
File structure:
-HelloTriangle
--include
---glad
----glad.h
---KHR
----khrplatform.h
--src
---glad.c
---main.cpp
--makefile
This is my make file:
BASE_OBJS = main.o glad.o
SRC_PATH = src
OBJS = $(addprefix $(SRC_PATH)/, $(BASE_OBJS))
CXX = g++
CXXFLAGS = -g -Iinclude
LDFLAGS =
LDLIBS = -lglfw -lGL -lX11 -lpthread -lXrandr -lXi -ldl
HelloTriangle: $(OBJS)
$(CXX) -o $# $(LDFLAGS) $^ $(LDLIBS)
clean:
rm $(OBJS)
This is my main.cpp:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
/*
Function to handle window resizing
*/
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
int main() {
/*
Initialize GLFW
Sets version to Core profile 3.3
*/
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
/*
Initialize a window context for OpenGL
Defines the windows width, height, and title
*/
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Hello Triangle", NULL, NULL);
if(window == NULL) {
std::cout << "Failed to create GLFW window" <<std::endl;
glfwTerminate();
return -1;
}
/*
Initialize GLAD
Handles OS-specific function pointers
*/
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
/*
Handle window resizing
*/
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
/*
Render loop
*/
while(!glfwWindowShouldClose(window)) {
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); }
You seem to set the CXXFLAGS (for the C++ compiler), but your glad.c is compiled with the C-compiler (which checks CFLAGS)
Is there a GTK3 function that detects if a window has focus? I am currently using the following code:
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
GtkWidget *LinuxWindow;
static void buttonMessage(GtkWidget *widget, gpointer data)
{
g_print("Yay, you clicked me!\n");
}
int main() {
GtkWidget *Box, *Button;
int argC = 0;
char **argV;
// Setup the window and fixed grid
gtk_init(&argC, &argV);
LinuxWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
Box = gtk_fixed_new();
// Set the title
gtk_window_set_title(GTK_WINDOW(LinuxWindow), "Title");
// Setup the window events
gtk_widget_show_all(LinuxWindow);
g_signal_connect(G_OBJECT(LinuxWindow), "destroy", G_CALLBACK(gtk_main_quit),
NULL);
// Add controls
Button = gtk_button_new_with_label("Click Me!");
g_signal_connect(Button, "clicked", G_CALLBACK(buttonMessage), NULL);
gtk_fixed_put(GTK_FIXED(Box), Button, 20, 20);
gtk_fixed_move(GTK_FIXED(Box), Button, 20, 20);
gtk_widget_set_size_request(Button, 30, 100);
gtk_container_add(GTK_CONTAINER(LinuxWindow), Box);
gtk_widget_show_all(LinuxWindow);
// Create a dialog
GtkWidget *dialog;
dialog = gtk_message_dialog_new(
GTK_WINDOW(LinuxWindow), GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Hello and welcome to my GTK GUI...", NULL);
gint ret = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(GTK_WIDGET(dialog));
printf("%i", ret);
// Add the fixed grid and go the to the main window loop
gtk_main();
return 0;
}
I am compiling it using
g++ -std=c++17 -m64 -o gtkTest myGtkApp.cpp -lX11 `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`
I want to detect if the window is focused and print it to the console.
There is a function: gtk_widget_is_focus ().
You need to assure parents have the "has-focus" property set.
Doc. excerpt:
gtk_widget_is_focus (GtkWidget *widget);
Determines if the widget is the focus widget within its toplevel. (This does not mean that the “has-focus” property is necessarily set; “has-focus” will only be set if the toplevel widget additionally has the global input focus.)
If you want to receive an event when the window is focused then register a callback for the enter-notify-event (signal)
In the linked doc. there is a section just three points after enter-notify-event that is what you want:
The “focus” signal
Sorry, I should have to mention this event the first time.
I've been struggling with getting SDL and SDL_ttf to work together. My minimal reproducible case (down below) works in VC++ but for the life of me I can't get it to work in a MinGW environment.
SDL version: 2.0.10 (latest at moment of writing)
SDL_ttf version: 2.0.15 (latest at moment of writing)
My set up looks like this:
Copied SDL and SDL_ttf lib and include folders to my project root.
Set up my link and include in my Makefile like so:
SRC_DIR=./app/src
INC_DIR=./app/inc
OBJ_DIR=./.obj
BUILD_DIR=./build
NAME=$(BUILD_DIR)/out
all: $(NAME)
CC=gcc
CXX=g++
CXXFLAGS=-Wall -Wextra -pedantic --std=c++17 -g
# Objects to build
STNAMES=\
main \
OBJECTS=$(patsubst %,$(OBJ_DIR)/%.o, $(STNAMES))
# Windows specific settings
ifeq ($(OS), Windows_NT)
LINK=\
-L./SDL2/lib \
-L./SDL2_ttf/lib \
-lmingw32 \
-lSDL2main \
-lSDL2 \
-lSDL2_ttf \
-lstdc++ \
INCLUDE=\
-I$(INC_DIR) \
-I./SDL2/include \
-I./SDL2_ttf/include \
define mkdir =
if not exist "$(1)" mkdir "$(1)"
endef
define rmdir =
if exist "$(1)" del /S/Q "$(1)"
endef
EXECUTABLE=$(NAME).exe
# macOS specific settings
# UNTESTED, assumes dependencies are installed with brew
else
LINK=$(shell sdl2-config --libs) -lc++
INCLUDE=\
-I$(shell brew --prefix)/include/SDL2 \
define mkdir
mkdir -p $(1)
endef
define rmdir =
rm -rf $(1)
endef
EXECUTABLE=$(NAME)
endif
$(NAME): $(OBJECTS)
#$(call mkdir,$(BUILD_DIR))
$(CC) -o $# $(OBJECTS) $(LINK)
#$(EXECUTABLE)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
#$(call mkdir,$(OBJ_DIR))
#$(CXX) -o $# -c $< $(CXXFLAGS) $(INCLUDE)
re:
#$(call rmdir,$(OBJ_DIR))
make
Added the dlls to MinGW's bin folder.
Here's a minimal reproducible test case which works for me on Visual Studio, but not on MinGW:
#include <iostream>
#include <SDL.h>
#include <SDL_ttf.h>
void drawText(SDL_Renderer* renderer, TTF_Font* font, int x, int y, const char* text) {
auto surface = TTF_RenderText_Solid(font, text, SDL_Color{ 255, 255, 255, 255 });
auto texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect dstRect = { x, y, surface->w, surface->h };
SDL_RenderCopy(renderer, texture, NULL, &dstRect);
SDL_DestroyTexture(texture);
SDL_FreeSurface(surface);
}
int main(int argc, char* argv[]) {
(void)argc;
(void)argv;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("some title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1920, 1080, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
TTF_Init();
bool running = true;
SDL_Event event;
auto font = TTF_OpenFont("assets/courier_prime.ttf", 36);
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
running = false;
}
SDL_SetRenderDrawColor(renderer, 25, 25, 25, 255);
SDL_RenderClear(renderer);
drawText(renderer, font, 10, 10, "Test string");
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255 );
auto rect = SDL_Rect{10, 100, 110, 200};
SDL_RenderFillRect(renderer, &rect);
SDL_RenderPresent(renderer);
}
TTF_CloseFont(font);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
return 0;
}
Regardless of where I place that SDL_RenderFillRect (before or after the drawText), the only thing I see is the text. The Rectangle is no longer visible.
I'm currently dealing with a mixed OS dev environment (mac and windows), hence why I'd like it to build on both using make.
Seems like it was an issue with SDL_RENDERER_ACCELERATED and openGL not being linked. Linking openGL did not fix the issue, however, swapping to the software renderer (SDL_RENDERER_SOFTWARE) did fix the rendering bug. Very strange that it does work on VS though. I guess that'll remain a mystery...
I am working on an GLFW desktop application that uses openGL ES 2.0 instead of the normal openGL!
The code that i wrote compiles great but when i run the application i hear some weird sound coming from my laptop and after a few seconds the window of the application goes unresponsive when i close the window the sound stops!
Is it a hardware/software problem or i did something wrong?
this my main.cpp:
#ifndef GLFW_INCLUDE_ES2
#define GLFW_INCLUDE_ES2
#endif
#include "game.h"
#include <GLFW/glfw3.h>
int init_gl();
void shutdown_gl();
void set_main_loop();
GLFWwindow* window;
int main()
{
if (init_gl() == GL_TRUE) {
on_surface_created();
on_surface_changed();
set_main_loop();
}
shutdown_gl();
return 0;
}
void shutdown_gl()
{
glfwDestroyWindow(window);
glfwTerminate();
}
int init_gl()
{
const int width = 480,
height = 800;
if (glfwInit() != GL_TRUE) {
return GL_FALSE;
}
window = glfwCreateWindow(width, height, "Simple example", NULL, NULL);
if (!window) {
return GL_FALSE;
}
glfwMakeContextCurrent(window);
return GL_TRUE;
}
void set_main_loop()
{
while (!glfwWindowShouldClose(window))
{
on_draw_frame();
glfwSwapBuffers(window);
}
}
tell me if u need the code from game.cpp!
The code is compiled on Ubuntu 14.04 using g++ with the commands:
g++ -I. -I../common -c main.cpp ../common/game.cpp
g++ main.o game.o -o main.exec -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread
You need to call glfwPollEvents() in your loop, however I'm not 100% sure as the sound could be caused by the application not being vsync-d.
Reference:
http://www.glfw.org/docs/latest/quick.html
I really need help on getting a simple GTK program in c++ running using MinGW. Here's my program:
# Makefile for Hello World Program (lab0).
all: lab0
lab0: lab0.o
g++ -Wall lab0.o -o lab0 -L C:/Users/Vic/Desktop/MinGW/lib -lgtk
lab0.o: lab0.c
g++ -Wall -I C:/Users/Vic/Desktop/MinGW/include/gtk-2.0/gtk -c lab0.c -o lab0.o
Program:
#include <gtk/gtk.h>
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *label;
gtk_init (&argc, &argv);
/* create the main, top level, window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* give it the title */
gtk_window_set_title (GTK_WINDOW (window), "Hello World");
/* Connect the destroy signal of the window to gtk_main_quit
* When the window is about to be destroyed we get a notification and
* stop the main GTK+ loop
*/
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
/* Create the "Hello, World" label */
label = gtk_label_new ("Hello, World");
/* and insert it into the main window */
gtk_container_add (GTK_CONTAINER (window), label);
/* make sure that everything, window and label, are visible */
gtk_widget_show_all (window);
/* start the main loop, and let it rest there until the application is closed */
gtk_main ();
return 0;
}
when i compile this using minGW i get this error:
g++ -Wall lab0.o -o lab0 -LC:/users/vic/desktop/mingw/lib -lgtk
/bin/Id: cannot find -lgtk
collect2: Id returned 1 exit status
make: *** [lab0] Error 1
I need to fix this problem and I need to figure out how to run gtk from my makefile.
Ideally, you would use pkg-config to help you find the header and library paths:
g++ -Wall lab0.o -o lab0 `pkg-config --cflags --libs gtk+-win32-2.0`
Or just the library path:
g++ -Wall lab0.o -o lab0 -LC:/users/vic/desktop/mingw/lib -lgtk `pkg-config --libs gtk+-win32-2.0`