aboutsummaryrefslogtreecommitdiff
path: root/gtk.c (follow)
Commit message (Collapse)AuthorAge
* gtk: Fix a missing "const" qualifier when building with GTK 2Ben Harris2022-11-22
|
* Add a way for midend_process_key() to report whether it handled a keypressBen Harris2022-11-08
| | | | | | | | This adds a new bool * argument, which can be NULL if front ends don't care whether the keypress was handled. Currently they all do that. Currently, "undo" and "redo" keys are treated as not handled if there's no move to undo or redo. This may be a little too strict.
* Teach the mid-end about device pixel ratiosBen Harris2022-11-08
| | | | | | | | | | | | | | The device pixel ratio indicates how many physical pixels there are in the platonic ideal of a pixel, at least approximately. In Web browsers, the device pixel ratio is used to represent "retina" displays with particularly high pixel densities, and also to reflect user-driven zooming of the page to different text sizes. The mid-end uses the device pixel ratio to adjust the tile size at startup, and can also respond to changes in device pixel ratio by adjusting the time size later. This is accomplished through a new argument to midend_size() which can simply be passed as 1.0 in any front end that doesn't care about this.
* unix, gtk: Install and use HTML helpBen Hutchings2022-08-01
| | | | | | - Generate HTML pages from the manual, and install them - Add "Contents" and "Help on <name>" menu items that will open the appropriate page in a web browser
* Re-fix the GTK dark theme check.Simon Tatham2022-08-01
| | | | | | | Ben Hutchings points out that when I 'harmlessly' changed 'dark_theme' from a gboolean to a bool, it wasn't harmless, because its address is passed to g_object_get, which expects a pointer to gboolean. (And of course it's a variadic function, so it can't type-check that.)
* Style cleanups from the previous fixes.Simon Tatham2022-07-31
| | | | | | | | | | | | | | Reordered the statements in the fixed Unruly blank_state so that there doesn't need to be a double if statement (and I think it's more sensible in any case to put each memset of a freshly allocated array immediately after the alloc). In GTK set_window_background, the nest of #ifdefs is now complicated enough to deserve a few comments on the #else and #endif lines. And while I was there I switched the gboolean to a bool, on my general principle that platform-specific boolean types are only worth using when you're passing them to a platform API function (and perhaps not even then, if it's not passed by reference).
* gtk: Adjust to reordering of XPM iconsBen Hutchings2022-07-31
| | | | | | | | | | | | | | Commit cc7f550 "Migrate to a CMake-based build system." reversed the order of xpm_icons, so the largest icon (96x96) is now first and the smallest (16x16) is now last. The About dialog now shows the smallest icon, and the window icon is now the largest icon. Change the array indexing so that the same size icons are used as before. Fixes: cc7f5503dc8f ("Migrate to a CMake-based build system.")
* gtk: Do not override window background colour when using a dark themeBen Hutchings2022-07-31
| | | | | | | | | | When the user chooses a global dark theme, the window background will be dark and the default text colour light. Overriding the window background to be light grey can make the menu and status bars unreadable. In case a dark theme is used, only set the background colour for the content area. References: https://bugs.debian.org/944237
* gtk.c: squelch uninitialised-variable warning.Simon Tatham2021-12-11
| | | | | | | | | | | | | Apparently some compilers can't work out that new_window() will always write to its error-message parameter if it returns failure, so they complain at the call site that 'error' might be used uninitialised. Fix by explicitly initialising it. (To NULL, which really _shouldn't_ stop the compiler from warning, because surely that's just as bad if it reaches the following printf!) Also, while I'm at it, move it into the block where it's used, so it doesn't look as if it might pervade the whole of main().
* Add 'const' to the draw_polygon coords array parameter.Simon Tatham2021-09-13
| | | | Thanks to Mouse for spotting that it was missing.
* GTK3: fix window redraw after copying to clipboard.Simon Tatham2021-05-25
| | | | | | | | | | | | | | | | | | | I just found out, in GTK3 under X11, that if you use the 'Copy' menu item to copy a text representation of the game to the clipboard, afterwards the puzzle window is no longer redrawn. That was pretty mysterious, and I still don't _fully_ understand it. But I think the main point is that when you set the GtkDrawingArea to be the owner of an X11 selection, that requires it to have an X11 window of its own, where previously it was managing fine as a logical subrectangle of its containing GtkWindow. And apparently switching strategies half way through the run is confusing to GTK, and causes redraws to silently stop working. The easy workaround is to make fe->window rather than fe->area the thing that owns GTK selections and receives the followup events. That must already have an X window, so nothing has to be changed when we make it a selection owner half way through the run.
* GTK 3: handle nontrivial window scale factors.Simon Tatham2020-04-07
| | | | | | | | | | | | | | | A user pointed out that if you run a GTK 3 puzzles with "GDK_SCALE=2" in the environment, the main game drawing area is blurred. That's because we're choosing the size of our backing Cairo surface based on the number of _logical_ pixels in the window size, not taking into account the fact that the non-unit scale factor means the number of physical pixels is larger. Everything 'works' in the basis - Cairo happily expands the smaller backing surface into the larger window - but resolution is lost in the process. Now we detect the window's scale factor, construct the backing surface appropriately, and compensate for that scaling when drawing to the surface and when blitting the surface to the window.
* Add printing support for GTK.Asher Gordon2019-12-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Printing is only available in GTK versions >= 2.10. We can only embed the page setup dialog on GTK >= 2.18, so on a GTK version less than that, we must use a separate page setup dialog. In GTK, printing is usually done one page at a time, so also modify printing.c to allow printing of a single page at a time. Create a separate drawing API for drawing to the screen and for printing. Create a vtable for functions which need to be different depending on whether they were called from the printing or drawing API. When a function is called from the printing API, it is passed a separate instance of the frontend than if it were called from the drawing API. In that instance of the frontend, an appropriate vtable is available depending on whether it was called from the printing or drawing API. The low-level functions used for printing are enabled even if printing is not enabled. This is in case we ever need to use them for something other than printing with GTK. For example, using Cairo as a printing backend when printing from the command line. Enabling the low-level functions even when GTK printing is not available also allows them to be compiled under as many build settings as possible, and thus lowers the chance of undetected breakage. Move the definition of ROOT2 from ps.c to puzzles.h so other files can use it (gtk.c needs it for hatching). Also add myself to the copyright list. [Committer's note: by 'printing', this log message refers to the GTK GUI printing system, which handles selecting a printer, printing to a file, previewing and so on. The existing facility to generate printable puzzles in Postscript form by running the GTK binaries in command-line mode with the --print option is unaffected. -SGT]
* Don't segfault when no icons are available.Asher Gordon2019-12-25
| | | | | | | | | | When no icons are available, n_xpm_icons will be 0, and menu_about_event() will try to access xpm_icons[n_xpm_icons-1]. Since n_xpm_icons is 0, this becomes xpm_icons[-1] which is an invalid value, causing a segfault. Instead, check if n_xpm_icons is 0, and if so, don't pass any icon to gtk_show_about_dialog().
* Make --screenshot work even in (Cairo) GTK2 builds.Simon Tatham2019-11-13
| | | | | | | | | | | | I had occasion recently to want to take a puzzle screenshot on a machine that didn't have the GTK3 libraries installed, but is advanced enough to build the GTK2+Cairo version of the puzzles. That _ought_ to be good enough to take screenshots using bare Cairo without GTK; I think the only reason why I didn't bother to support it before is because on GTK2, frontend_default_colours() queries the widget style to choose a shade of grey. But we have a fixed fallback shade of grey to use on GTK3, so it's easy to just use that same fallback in headless GTK2.
* Fix GTK 2 crash introduced by previous commit.Simon Tatham2018-11-25
| | | | | | | | | Moving the snaffle_colours() call earlier is fine in GTK 3, where the potential call to frontend_default_colour doesn't depend on the window already having been created. But it falls over in GTK 2 where it does. Moved the non-headless-mode version of that call back to where it was before the --screenshot change.
* Don't initialise GTK in --screenshot mode.Simon Tatham2018-11-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | I had this idea today and immediately wondered why I'd never had it before! To generate the puzzle screenshots used on the website and as program icons, we run the GTK front end with the --screenshot option, which sets up GTK, insists on connecting to an X server (or other display), draws the state of a puzzle on a Cairo surface, writes that surface out to a .png file, and exits. But there's no reason we actually need the GTK setup during that process, especially because the surface we do the drawing on is our _own_ surface, not even one provided to us by GTK. We could just set up a Cairo surface by itself, draw on it, and save it to a file. Calling gtk_init is not only pointless, but actively inconvenient, because it means the build script depends on having an X server available for the sole purpose of making gtk_init not complain. So now I've simplified things, by adding a 'headless' flag in new_window and the frontend structure, which suppresses all uses of actual GTK, leaving only the Cairo surface setup and enough supporting stuff (like colours) to generate the puzzle image. One awkward build dependency removed. This means that --screenshot no longer works in GTK 2, which I don't care about, because it only needs to run on _one_ platform.
* Use C99 bool within source modules.Simon Tatham2018-11-13
| | | | | | | | | | This is the main bulk of this boolification work, but although it's making the largest actual change, it should also be the least disruptive to anyone interacting with this code base downstream of me, because it doesn't modify any interface between modules: all the inter-module APIs were updated one by one in the previous commits. This just cleans up the code within each individual source file to use bool in place of int where I think that makes things clearer.
* Replace TRUE/FALSE with C99 true/false throughout.Simon Tatham2018-11-13
| | | | | | This commit removes the old #defines of TRUE and FALSE from puzzles.h, and does a mechanical search-and-replace throughout the code to replace them with the C99 standard lowercase spellings.
* Adopt C99 bool in the midend API.Simon Tatham2018-11-13
| | | | | | | | | | | | | This changes parameters of midend_size and midend_print_puzzle, the return types of midend_process_key, midend_wants_statusbar, midend_can_format_as_text_now and midend_can_{undo,redo}, the 'bval' field in struct config_item, and finally the return type of the function pointer passed to midend_deserialise and identify_game. The last of those changes requires a corresponding fix in clients of midend_deserialise and identify_game, so in this commit I've also updated all the in-tree front ends to match. I expect downstream front ends will need to do the same when they merge this change.
* Fix a misuse of errno.Simon Tatham2018-11-06
| | | | | | | | | | In menu_save_event, we checked ctx.error to see if an errno value had been left in it by the savefile_write callback, but if so, then we were passing the _current_ value of errno to strerror() in place of the saved value in ctx.error. This may well have been benign, but I spotted it in an eyeball review just now and thought I'd better fix it before it bit anyone.
* Stop using deprecated gdk_beep().Simon Tatham2018-05-09
| | | | | Switched over to gdk_display_beep(), which should work in any GTK2 or GTK3 environment. (This code base doesn't care about GTK1 any more.)
* Move fgetline out into misc.c.Simon Tatham2018-04-22
| | | | I'm about to want to use it outside the GTK front end.
* Build fixes for GTK2.Simon Tatham2017-10-24
| | | | | | | | I had left one mention of the new GTK3-only variable 'awaiting_resize_ack' unprotected by #ifdefs. Also, the GTK2 version of message_box() was missing some consts in its prototype, presumably because when I had that #ifdeffed out the compiler didn't warn me about those ones.
* Make the code base clean under -Wwrite-strings.Simon Tatham2017-10-01
| | | | | I've also added that warning option and -Werror to the build script, so that I'll find out if I break this property in future.
* Assorted char * -> const char * API changes.Simon Tatham2017-10-01
| | | | | | I went through all the char * parameters and return values I could see in puzzles.h by eye and spotted ones that surely ought to have been const all along.
* Return error messages as 'const char *', not 'char *'.Simon Tatham2017-10-01
| | | | | They're never dynamically allocated, and are almost always string literals, so const is more appropriate.
* Use a proper union in struct config_item.Simon Tatham2017-10-01
| | | | | | This allows me to use different types for the mutable, dynamically allocated string value in a C_STRING control and the fixed constant list of option names in a C_CHOICES.
* Fix changing puzzle size in a maximised GTK3 window.Simon Tatham2017-09-30
| | | | | | | | | | | | | | | | | | | | | | While working on the Net scalability today I noticed that changing preset from (say) 13x11 to 5x5 in GTK3 Net while the window is maximised does not have the desired effect (that being that, since the maximised window does not change size, the new puzzle size is instead scaled to fit neatly in the existing window). A git bisect suggests that this was a side effect of commit 8dfe5cec3; it looks as if there was a useful side effect of setting fe->area as the 'geometry widget' for fe->window, namely, that any attempt to resize the window thereafter (even if it had no effect on the window size) would trigger a configure event on the geometry widget, so we'd get a notification of our new size even if it was the same as our old size. But that 'geometry widget' feature is deprecated, so I have to work around it another way. Fortunately, I've found a fallback event that still does occur, namely "size_allocate" on fe->window. So I'm trapping that as well and using it as an indication that a configure event won't be forthcoming.
* Fix auto-selection of presets in GTK.Simon Tatham2017-09-30
| | | | | | | | | | | | | | In commit a7dc17c42 I apparently introduced two bugs in changed_preset(). Firstly, the Custom menu option was being written into the 'found' variable in nearly all cases, because it has a NULL user-data pointer which caused it to take the wrong branch of an if statement due to an erroneous complex condition. Secondly, having written _something_ into 'found', I had set it to inactive rather than active due to forgetting to change a FALSE into a TRUE. Now when I start up Net with my usual nonstandard default parameters (I like the 13x11 wrapping, so I set NET_DEFAULT=13x11w in my environment), the right menu entry comes up ticked.
* Map Ctrl-Shift-Z to Redo.Simon Tatham2017-09-20
| | | | | | This is in addition to the existing keystrokes r, ^R and ^Y. I've become used to Ctrl-Shift-Z in other GUI games, and my fingers keep getting confused when my own puzzles don't handle it the same way.
* Generate special fake keypresses from menu options.Simon Tatham2017-09-20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes an amusing UI bug that I think can currently only come up in the unpublished puzzle 'Group', but there's no reason why other puzzles _couldn't_ do the thing that triggers the bug, if they wanted to. Group has unusual keyboard handling, in that sometimes (when a cell is selected for input and the key in question is valid for the current puzzle size) the game's interpret_move function will eat keystrokes like 'n' and 'u' that would otherwise trigger special UI events like New Game or Undo. The bug is that fake keypress events generated from the GUI menus looked enough like those keystrokes that interpret_move would eat those too. So if you start, say, a 16x16 Group puzzle, select an empty cell, and then choose 'new game' from the menu, Group will enter 'n' into the cell instead of starting a new game! I've fixed this by inventing a new set of special keystroke values called things like UI_NEWGAME and UI_UNDO, and having the GUI menus in all my front ends generate those in place of 'n' and 'u'. So now the midend can tell the difference between 'n' on the keyboard and New Game from the menu, and so Group can treat them differently too. In fact, out of sheer overcaution, midend.c will spot keystrokes in this range and not even _pass_ them to the game back end, so Group shouldn't be able to override these special events even by mistake. One fiddly consequence is that in gtk.c I've had to rethink the menu accelerator system. I was adding visible menu accelerators to a few menu items, so that (for example) 'U' and 'R' showed up to the right of Undo and Redo in the menu. Of course this had the side effect of making them real functioning accelerators from GTK's point of view, which activate the menu item in the same way as usual, causing it to send whatever keystroke the menu item generates. In other words, whenever I entered 'n' into a cell in a large Group game, this was the route followed by even a normal 'n' originated from a real keystroke - it activated the New Game menu item by mistake, which would then send 'n' by mistake instead of starting a new game! Those mistakes cancelled each other out, but now I've fixed the latter, I've had to fix the former too or else the GTK front end would now undo all of this good work, by _always_ translating 'n' on the keyboard to UI_NEWGAME, even if the puzzle would have wanted to treat a real press of 'n' differently. So I've fixed _that_ in turn by putting those menu accelerators in a GtkAccelGroup that is never actually enabled on the main window, so the accelerator keys will be displayed in the menu but not processed by GTK's keyboard handling. (Also, while I was redoing this code, I've removed the logic in add_menu_item_with_key that reverse-engineered an ASCII value into Control and Shift modifiers plus a base key, because the only arguments to that function were fixed at compile time anyway so it's easier to just write the results of that conversion directly into the call sites; and I've added the GTK_ACCEL_LOCKED flag, in recognition of the fact that _because_ these accelerators are processed by a weird mechanism, they cannot be dynamically reconfigured by users and actually work afterwards.)
* Rework the preset menu system to permit submenus.Simon Tatham2017-04-26
| | | | | | | | | | | | | | | | | | | | To do this, I've completely replaced the API between mid-end and front end, so any downstream front end maintainers will have to do some rewriting of their own (sorry). I've done the necessary work in all five of the front ends I keep in-tree here - Windows, GTK, OS X, Javascript/Emscripten, and Java/NestedVM - and I've done it in various different styles (as each front end found most convenient), so that should provide a variety of sample code to show downstreams how, if they should need it. I've left in the old puzzle back-end API function to return a flat list of presets, so for the moment, all the puzzle backends are unchanged apart from an extra null pointer appearing in their top-level game structure. In a future commit I'll actually use the new feature in a puzzle; perhaps in the further future it might make sense to migrate all the puzzles to the new API and stop providing back ends with two alternative ways of doing things, but this seemed like enough upheaval for one day.
* GTK API deprecation: in GTK 3.22, stop using gdk_cairo_create.Simon Tatham2017-02-27
| | | | | This is another annoyingly removed function, replaced by a tower of about four assorted objects you have to create in succession.
* GTK API deprecation: use GtkCssProvider for window background.Simon Tatham2017-02-27
| | | | | | | | | | | | | | gdk_window_set_background_rgba is deprecated as of GTK 3.22, because apparently you can't just _say_ any more 'here is what I want my window's background colour to be in places where a widget isn't'. Instead you have to provide a GtkStyleProvider which can be slotted into a wobbly tower of other providers with associated priorities, so that the user can override your choices if they really want to. And the easiest way to constructc a GtkStyleProvider in turn is to write *actual CSS* and get GTK to parse it, so I end up converting my nice numeric RGB values into a complicated text format for another part of _the same process_ to parse back into numbers. Sigh.
* Add some missing calls to midend_redraw().Simon Tatham2016-12-27
| | | | | | | | | | | | | | | | | I've just noticed that the GTK game window was not being redrawn when changing between puzzle modes that don't involve a window resize - by selecting a preset from the Type menu (e.g. changing between different 12x12 settings in Flood) or via the Custom menu. It looks as if the bug was introduced in commit 8dfe5cec3, which suggests that it was a side effect of the switch from gtk_window_resize_to_geometry to plain gtk_window_resize. My guess is that the implementation of the former function inside GTK might have happened to trigger an unconditional window resize, while the latter took the shortcut of doing nothing if the window was already the right size; hence, resize_fe() would have been reliably generating a redraw event without me having to ask for one, but now it doesn't, so I have to trigger one myself any time I've just called resize_fe.
* Stop using deprecated GTK 3 geometry-based functions.Simon Tatham2016-12-03
| | | | | | Now we work out for ourselves how the drawing-area size relates to the overall window size, by adding on the height of fe->menubar and/or fe->statusbar.
* Implement align_label for GTK 3.[14,16).Simon Tatham2015-12-06
| | | | | | | | | | gtk_misc_set_alignment was deprecated in GTK 3.14. But my replacement code using gtk_label_set_{x,y}align doesn't work there, because that function wasn't introduced until GTK 3.16, so there are two minor versions in the middle where a third strategy is needed. (That middle strategy doesn't permit arbitrary float alignments, but that's OK, bceause we only actually use multiples of 0.5.)
* Fix GTK puzzle resizing, *again*.Simon Tatham2015-10-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Jonas Kölker points out that commit a800ff16b (which fixed a bug in the previous attempt) left in another bug: if the puzzle size was changed while the window was maximised, the system would fail to recompute the tile size and would redraw completely wrongly. So it's not optional after all to run midend_size(), even if the drawing area size hasn't changed. I've reverted that code to be unconditional, and now only the refresh of the Cairo-side backing store system is conditionalised - and that's conditionalised on changes to either the size of the actual window _or_ the size of the contained pixmap. (The latter should defend against redraw failure in the case where the puzzle aspect ratio changes, so that neither the window size nor the tile size changes but a recentre is still needed.) I _think_ this now fixes all the cases of resizing: this time I've tested making an unmaximised puzzle window bigger or smaller, and within a maximised window, forcing the puzzle to scale up, scale down, or change its aspect ratio without changing its tile size. All work, on GTK2 and GTK3, and yet we still don't get the visible flicker on status line updates that was the reason I started fiddling with this code in the first place. (We _do_ still call configure_area on every update of the status line, at least under GTK3; that's going to cause a forced full redraw on every timer tick in Mines, which is wasteful of CPU, so it would still be nice to find a better way of identifying the cases in which no resizing at all was necessary and we could avoid renewing the game drawstate. But the current code at least doesn't have any display _errors_ that I know of, which is an improvement on its previous state.)
* Fix two memory leaks in GTK frontend.Jonas Kölker2015-10-18
| | | | | | | | - The file selector for loading and saving gets a g_free(). - The handling of saving (menu_save_event) gets an sfree(). - It's also slightly restructured to prevent future errors. - menu_load_event was already structured to prevent this error. - The OLD_FILESEL code seems to not need a g_free().
* In GTK frontend, bind mouse8/mouse9 to undo/redo.Jonas Kölker2015-10-14
| | | | | | These button codes are generated by the back/forward button pair on the sides of some mice, and web browsers treat these as the back and forward actions in the page history.
* GTK 3 cleanup: stop using GtkDialog for config boxes.Simon Tatham2015-10-04
| | | | | | | | | | | It's becoming annoying to keep working within the increasing restrictions on GtkDialog, in particular the fact that not only do we have to let it have complete control of the button area, but also it's not clear whether we can intercept a press of the 'OK' button and display an error message rather than ending the dialog. So, as I did in PuTTY, I'm resorting to using an ordinary GtkWindow with controls I laid out myself.
* GTK 3 cleanup: use GtkAboutDialog for the About box.Simon Tatham2015-10-04
| | | | | | This is again easier than faffing about doing it manually, and as an added bonus, we get to put the largest of our icons in the box as a logo :-)
* GTK 3 cleanup: use GtkMessageDialog for message_box().Simon Tatham2015-10-04
| | | | | | This is a lot easier than faffing about setting up a dialog box ourself, and also avoids direct access to GtkDialog's action area (deprecated in GTK 3.16).
* GTK 3.16 deprecation: stop using gtk_misc_set_alignment.Simon Tatham2015-10-04
| | | | | The new equivalent is gtk_label_set_{x,y}align. But we can't use that in all GTK 3 builds, because it's very new.
* Fix switching to a larger puzzle size under GTK 2.Simon Tatham2015-10-03
| | | | | | | | | | | | | Commit 8b491946e had a bug: configure_area stopped doing most of its work if the new size already matched fe->w and fe->h, but in fact the GTK2 resize_fe() _already_ set up fe->w and fe->h for the new size. I managed not to notice, because I checked it all worked on GTK 3 but only tested resizing to a _smaller_ puzzle on GTK 2. Ahem. Now we don't change fe->w and fe->h at all until configure_area is called. Also, we initialise them to dummy values at setup time, so that configure_area won't compare the new size with uninitialised data.
* Insert a manual reference in the default status bar text.Jonas Kölker2015-10-03
| | | | | | To guide developers to the resources they need. [actual wording tweaked by SGT]
* GTK 3 port: don't turn off drawing area double buffering.Simon Tatham2015-10-03
| | | | | | | | | | | | I think I did this in GTK2 on the basis that our server-side cache pixmap was double-buffering enough for us - any puzzle which erased a big area with a background rectangle and then redrew over the top of it would do so only on the off-screen pixmap, and the updates would only be copied to the visible window after it was all done. In GTK3, I don't think there's any need - this is all the usual way things are done anyway, as far as I can see. So I've turned this call back off, at least until I hear of a reason why I need it again.
* GTK 3 port: change API functions for widget sizing.Simon Tatham2015-10-03
| | | | | set_usize is deprecated, and get_preferred_size is the GTK 3 thing we should use in place of size_request.
* GTK 3 port: use GtkBox directly, not GtkHBox and GtkVBox.Simon Tatham2015-10-03
| | | | | I've done this by #defining the old names in terms of the new ones, because the old ones are still more concise!