Simple Clock

interpretive language scripts


Moderator: Forum moderators

User avatar
mikewalsh
Moderator
Posts: 5674
Joined: Tue Dec 03, 2019 1:40 pm
Location: King's Lynn, UK
Has thanked: 611 times
Been thanked: 1747 times

Re: Simple Clock

Post by mikewalsh »

@rockedge :-

Erik, where exactly did you build this thing? I've been trying in a few Puppies, with zero results; Puppies don't seem to include most of the necessary ".h" files, even as a virgin ISO. The actual libs exist, but no (header?) files are to be found anywhere. Even DevX and kernel sources loaded together don't help!

I assume either KLV or one of the Dogs? I'm guessing, from the look of things, that this has been written to expect a standard Debian structure, hence why I'm thinking one of Fred's DebianDogs.....

I would like it in the Puppies! (And not necessarily a requirement for the very newest, either.....)

Compiling is NOT my strong point......although I can build IF I know what I'm supposed to be doing.

Mike. ;)

Puppy "stuff" ~ MORE Puppy "stuff" ~ ....and MORE! :D
_______________________________________________________

Image

ozsouth
Posts: 1400
Joined: Sun Jul 12, 2020 2:38 am
Location: S.E. Australia
Has thanked: 213 times
Been thanked: 617 times

Re: Simple Clock

Post by ozsouth »

@mikewalsh - I'm sure you need to also install the headers package (for your kernel) to compile this.

User avatar
mikewalsh
Moderator
Posts: 5674
Joined: Tue Dec 03, 2019 1:40 pm
Location: King's Lynn, UK
Has thanked: 611 times
Been thanked: 1747 times

Re: Simple Clock

Post by mikewalsh »

@ozsouth :-

ozsouth wrote: Fri Jun 24, 2022 1:10 am

@mikewalsh - I'm sure you need to install the headers package (for your kernel) to compile this.

Well, Puppies don't have a "headers package".....do they? Or is this what the kernel sources SFS does? (I don't think that's its purpose, but I'm willing to be proved wrong. Nah, can't be; this is to do with installed packages, nowt to do wi' t'kernel).

Leastways, I've never actually seen a Puppy "header" package, let alone installed one. Most of the time, all I ever use is the DevX itself....

Eee, I hate showing my ignorance.....but I'm more than willing to accept advice! :D

(*shrug*)

(Looking through the kernel sources SFS, everything in there is a ".c" package or file. This is wanting ".h" and ".pc" packages/files. I also noticed that in many cases, where there's a ".pc" package for GTK 3.0, Puppy calls it

Code: Select all

gtk+-x11-3.0.pc

.....as opposed to the

Code: Select all

gtk+-3.0.pc

.....in misko's code.)

I'm getting rapidly lost with all this stuff..... :roll:

Mike. ;)

Puppy "stuff" ~ MORE Puppy "stuff" ~ ....and MORE! :D
_______________________________________________________

Image

ozsouth
Posts: 1400
Joined: Sun Jul 12, 2020 2:38 am
Location: S.E. Australia
Has thanked: 213 times
Been thanked: 617 times

Re: Simple Clock

Post by ozsouth »

@mikewalsh - usually when I made a kernel, I made both sources & headers packages. devx in very old puppies had headers inside as kernel-changing wasn't done. Not the case these days. Compiling drivers doesn't need headers. Compiling other software generally does.

User avatar
rockedge
Site Admin
Posts: 5856
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2102 times
Been thanked: 2194 times
Contact:

Re: Simple Clock

Post by rockedge »

@mikewalsh,
I made a PET package and called it sClock. Compiled in Bionic64-8, with devx loaded. No headers no kernel source needed.
Important: libgtk-3-dev_3.22.30 needs to be installed to compile against!
compile command I used:

Code: Select all

gcc sclock.c -o sclock $(pkg-config --cflags --libs gtk+-3.0)

A couple of adjustments to the .desktop file in the PET package need to be made to provide a proper icon.

UPDATE: Fixed and updated, download from here -> viewtopic.php?p=60475#p60475

User avatar
rockedge
Site Admin
Posts: 5856
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2102 times
Been thanked: 2194 times
Contact:

Re: Simple Clock

Post by rockedge »

Would be really cool to add a modification so it will remain on all of the virtual desktops. Right now I just start 4 instances on for each workspace. A single "exit" kills all instances together.

But one instance like the background or auto start 4 instances or how ever many virtual desktops/workspaces exist.

In KLV it runs transparently and so far on Bionic64-8 it is not transparent.

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: Simple Clock

Post by misko_2083 »

rockedge wrote: Thu Jun 23, 2022 7:21 pm

can I include sclock in KLV's? Include it as feature.

Yes you can. It's GPL 3.0.

rockedge wrote: Fri Jun 24, 2022 3:06 am

Would be really cool to add a modification so it will remain on all of the virtual desktops. Right now I just start 4 instances on for each workspace. A single "exit" kills all instances together.

But one instance like the background or auto start 4 instances or how ever many virtual desktops/workspaces exist.

In KLV it runs transparently and so far on Bionic64-8 it is not transparent.

Added --stck to show on all desktops.

Code: Select all

#include <time.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib.h>
#include <pango/pango.h>
#include <cairo/cairo.h>

GdkRGBA color_bg;
GdkRGBA color_border;
static gchar *bgcolor = NULL;
static gchar *border_color = NULL;
static gchar *color = NULL;
static gchar *date = NULL;
static gchar *font = NULL;
static gboolean above = FALSE;
static gint border;
static gboolean center = FALSE;
static gboolean lock = FALSE;
static gboolean stick = FALSE;
static gint opacity;
static gint  posx = 0;
static gint  posy = 0;

static gboolean
on_timeout (gpointer user_data)
{
  GtkLabel *label = GTK_LABEL (user_data);
  GError *error = NULL;
  char *out = NULL;

  time_t timer;
  char buff[64];
  struct tm* tm_info;

  time (&timer);
  tm_info = localtime (&timer);
  strftime (buff, 64, date, tm_info);

  gchar *markup = g_strdup_printf ("<b><span font='%s' foreground='%s'>%s</span></b>",
                                   font, color, buff);
  if (pango_parse_markup (markup,
                         -1,
                          0,
                          NULL,
                          &out,
                          NULL,
                          &error) == FALSE)
  {
    g_printerr ("%s\nSwitching to default values\n", error->message);
    color = "red";
    date = "%r";
    font = "Sans Bold 20";

    gchar *markup = g_strdup_printf ("<span font='%s' foreground='%s'>%s</span>",
                                     font, color, buff);

    if (out)
       free (out);
    g_error_free (error);
  }
  
  gtk_label_set_markup (GTK_LABEL (label), markup);

  g_free (markup);

  return G_SOURCE_CONTINUE;
}

void destroy_handler (GtkApplication* app, gpointer data)
{
  g_application_quit(G_APPLICATION (data));
}

static void
toggle_lock_position (GtkWidget *menu_item, gpointer user_data)
{
  if (lock == TRUE)
      lock = FALSE;
  else
      lock = TRUE;
}

static gboolean
key_handler (GtkWidget *w, GdkEventKey *ev, gpointer data)
{
  GtkApplication *app = GTK_APPLICATION (data);
  switch (ev->keyval)
    {
    case GDK_KEY_Escape:
        destroy_handler(NULL, app);
        return TRUE;
    }
  return FALSE;
}

static gboolean
button_handler (GtkWidget *window, GdkEventButton *ev, gpointer data)
{
  if ((ev->button == 1) && (lock == FALSE))
    {
      gtk_window_begin_move_drag (GTK_WINDOW(window),
          ev->button,
          ev->x_root,
          ev->y_root,
          ev->time);
      return TRUE;
    }
  if (ev->button == 3)
    {
      GtkApplication *app = GTK_APPLICATION (data);
      GtkWidget *toggle_lock, *exit, *popup_menu;

      popup_menu = gtk_menu_new ();
      gtk_menu_set_reserve_toggle_size (GTK_MENU (popup_menu), FALSE);
      if (lock == TRUE)
          toggle_lock = gtk_menu_item_new_with_label ("Unlock");
      else
          toggle_lock = gtk_menu_item_new_with_label ("Lock");
      gtk_widget_show (toggle_lock);
      exit = gtk_menu_item_new_with_label ("Exit");
      gtk_widget_show (exit);
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), toggle_lock);
      gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), exit);
      g_signal_connect (G_OBJECT (toggle_lock), "activate", G_CALLBACK (toggle_lock_position), NULL);
      g_signal_connect (G_OBJECT (exit), "activate", G_CALLBACK (destroy_handler), app);
      gtk_menu_popup_at_pointer (GTK_MENU (popup_menu), NULL);
      return TRUE;
    }
  return FALSE;
}

static void
geometry_hints (GtkWidget *widget,
                    gpointer data)
{
  GdkGeometry         hints;

  hints.min_width = 0;
  hints.max_width = gtk_widget_get_allocated_width (widget);
  hints.min_height = 0;
  hints.max_height = gtk_widget_get_allocated_height (widget);

  gtk_window_set_geometry_hints(
        GTK_WINDOW (widget),
        widget,
        &hints,
        (GdkWindowHints)(GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE));
}

static void
draw_handler (GtkWidget *widget,
              cairo_t *cr,
              gpointer user_data)
{
  float alpha;
  float alpha_border;
  if (opacity) {
      alpha = alpha_border = (float) opacity / 100;
  }
  else {
      alpha = color_bg.alpha;
      alpha_border = color_border.alpha;
  }
  
  cairo_set_source_rgba (cr, color_bg.red, color_bg.green, color_bg.blue,  alpha);
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); 
  cairo_paint(cr);

  if (border) {
     if (border_color == NULL) {
         cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.7);
     }
     else {
         cairo_set_source_rgba (cr, color_border.red, color_border.green, color_border.blue,  alpha_border);
      }
      cairo_rectangle(cr, border / 2, border / 2, gtk_widget_get_allocated_width (widget) - border,
                                                gtk_widget_get_allocated_height (widget) - border);
      cairo_set_line_width(cr, border);
      cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); 
      cairo_stroke(cr); 
  }
}

static void
composited_changed (
  GtkWidget *widget,
  gpointer user_data)
{
  GdkScreen           *screen;
  GdkVisual           *visual;

  screen = gdk_screen_get_default();
  visual = gdk_screen_get_rgba_visual(screen);
  if (visual != NULL && gdk_screen_is_composited(screen))
      gtk_widget_set_visual(widget, visual);
}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget           *window;
  GtkWidget           *grid;
  GtkWidget           *label;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Simple Clock");
  gtk_window_set_default_size (GTK_WINDOW (window), 10, 10);
  gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
  gtk_window_set_skip_pager_hint (GTK_WINDOW (window), TRUE);
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (window), TRUE);
  gtk_widget_set_app_paintable (window, TRUE);
  composited_changed (window, NULL);
  if (center == TRUE)
      gtk_window_set_position(GTK_WINDOW(window),
                              GTK_WIN_POS_CENTER_ALWAYS);
  if (above == TRUE) {
      gtk_window_set_keep_above (GTK_WINDOW(window), TRUE);
  }
  else {
      gtk_window_set_keep_below (GTK_WINDOW(window), TRUE);
  }
  if (stick == TRUE)
      gtk_window_stick (GTK_WINDOW(window));
  grid = gtk_grid_new ();
  gtk_grid_set_column_homogeneous (GTK_GRID (grid),
                                TRUE);
  gtk_grid_set_row_homogeneous (GTK_GRID (grid),
                                FALSE);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 10);

  label = gtk_label_new (NULL);
  g_timeout_add (1000, on_timeout, label);
  gtk_widget_set_halign (label, GTK_ALIGN_CENTER);

  gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
  gtk_container_add (GTK_CONTAINER (window), grid);
  gtk_container_set_border_width (GTK_CONTAINER (window), 8);

  g_signal_connect (G_OBJECT(window), "destroy",
                    G_CALLBACK (destroy_handler), app);
  g_signal_connect (G_OBJECT (window), "key-press-event",
                    G_CALLBACK (key_handler), app);
  g_signal_connect (G_OBJECT (window), "button-press-event",
                    G_CALLBACK (button_handler), app);
  g_signal_connect (G_OBJECT (window), "size-allocate",
                    G_CALLBACK (geometry_hints), NULL);
  g_signal_connect (G_OBJECT (window), "draw",
                    G_CALLBACK (draw_handler), NULL);
  g_signal_connect (G_OBJECT (window), "draw",
                    G_CALLBACK (draw_handler), NULL);
  g_signal_connect (G_OBJECT (window), "composited-changed",
                    G_CALLBACK (composited_changed), NULL);
  gtk_widget_show_all (window);

  if ((posx != 0) || (posy != 0))
     gtk_window_move (GTK_WINDOW (window), posx, posy);
}

static int
get_options (int argc,
             char *argv[])
{
  static
    GOptionEntry option_entries[] = {
    { "bgcolor",       0, 0, G_OPTION_ARG_STRING,  &bgcolor,
       "Specify window background color, black, #000, rgb(r,g,b), rgba(r,g,b,a)", "COLOR" },
    { "border",  0, 0, G_OPTION_ARG_INT,   &border,
       "Draw window border, same as bgcolor", "COLOR" },
    { "border-color",  0, 0, G_OPTION_ARG_STRING,   &border_color,
       "Set border color", "COLOR" },
    { "center",  0, 0, G_OPTION_ARG_NONE,   &center,
       "Place window at the center of the screen", NULL },
    { "color",       0, 0, G_OPTION_ARG_STRING,  &color,
       "Specify color of the label, white, #FFFFFF", "COLOR" },
    { "date",        0, 0, G_OPTION_ARG_STRING,  &date,
       "Specify display time, e.g. %a %b %d/%m/%Y %H:%M:%S but not 'now", "STRING" },
    { "font",        0, 0, G_OPTION_ARG_STRING,  &font,
       "Specify font to use", "FONT" },
    { "keep-above",  0, 0, G_OPTION_ARG_NONE,   &above,
       "Keep window above, default is to keep window below", NULL },
    { "lock",  0, 0, G_OPTION_ARG_NONE,   &lock,
       "Lock position", NULL },
    { "opacity",  0, 0, G_OPTION_ARG_INT,   &opacity,
       "Set window opacity, compositing must be enabled first", "INT" },
    { "posx",        0, 0, G_OPTION_ARG_INT,    &posx,
       "Specify X position to use", "INT" },
    { "posy",        0, 0, G_OPTION_ARG_INT,   &posy,
       "Specify Y position to use", "INT" },
    { "stick",  0, 0, G_OPTION_ARG_NONE,   &stick,
       "Show window on all desktops", NULL },
    { NULL }
  };
              
  GOptionContext *option_context;
  GError *error = NULL;

#if (!GLIB_CHECK_VERSION (2, 36, 0))
  g_type_init ();
#endif

  option_context = g_option_context_new (NULL);
  g_option_context_add_main_entries (option_context,
                                     option_entries,
                                     NULL);
  if (g_option_context_parse (option_context,
                              &argc,
                              &argv,
                              &error) == FALSE) {
    g_printerr ("%s\n", error->message);
    g_error_free (error);
    return 1;
  }
  if (bgcolor != NULL) {
     if (gdk_rgba_parse (&color_bg, bgcolor) == FALSE) {
         g_printerr ("Unknown color: %s\n", bgcolor);
         return 1;
     }
  }
  if (border_color != NULL) {
      if (gdk_rgba_parse (&color_border, border_color) == FALSE) {
          g_printerr ("Unknown color: %s\n", border_color);
          return 1;
      }
  }
  if (opacity < 0 || opacity > 100) {
      g_printerr ("Opacity must be between 0 and 100: %d\n", opacity);
      return 1;
  }
  if (color == NULL)
      color = "red";
  if (date == NULL)
      date = "%r";
  if (font == NULL)
      font = "Sans Bold 20";
  g_option_context_free (option_context);

  return 0;
}

int
main (int argc,
      char **argv)
{
  int status;
  GtkApplication *app;
  gboolean opts;

  opts = get_options (argc, argv);

  if (opts == 1)
     return 1;

  app = gtk_application_new ("org.gtk.simple_clock",
                             G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

It needs a compositor to be transparent. Like Compton.
Xfce has built in. In setting go to Window Manager Tweaks -> Compositor
As soon as you disable compositing, Sclock is no longer transparent.
Enable it, it's back on.

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
rockedge
Site Admin
Posts: 5856
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2102 times
Been thanked: 2194 times
Contact:

Re: Simple Clock

Post by rockedge »

Very nice! KLV-Airedale is using xfce where the compositor turns transparency on and off but with Bionic64 only sometimes can I get the transparency to work.

Here is the updated version of sClock including the latest added --stick option

Attachments
sClock.sfs
(40 KiB) Downloaded 36 times
sClock.tar.xz
(9.22 KiB) Downloaded 42 times
sClock-1.5_1.x86_64.xbps
(11.63 KiB) Downloaded 27 times
sClock.pet
(9.32 KiB) Downloaded 42 times
User avatar
greengeek
Posts: 1227
Joined: Thu Jul 16, 2020 11:06 pm
Has thanked: 354 times
Been thanked: 148 times

Re: Simple Clock

Post by greengeek »

MochiMoppel wrote: Fri Jun 17, 2022 2:08 am

Date is the problem. Because date is an external command. All external commands piping to yad will cause this problem while Bash builtin commands like echo or printf are OK. Therefore this would also work (in bash 4.2 or newer) and would be more efficient:

Code: Select all

#!/bin/sh
while : ; do
	printf '%(%a %d %b %H:%M %S)T\n'
	sleep 1
done | yad --title=clock --geometry=230x50+420+16 --form --cycle-read --field=": " --no-buttons --undecorated &

Would you expect this to work in Tahr32?

Code: Select all

root# ./mochiclkyad
root# Unable parse command line: Unknown option --cycle-read

I have bash 4.3

User avatar
MochiMoppel
Posts: 1142
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 18 times
Been thanked: 373 times

Re: Simple Clock

Post by MochiMoppel »

greengeek wrote: Fri Jun 24, 2022 7:49 am

Would you expect this to work in Tahr32?

Code: Select all

root# ./mochiclkyad
root# Unable parse command line: Unknown option --cycle-read

Not after reading your error message :mrgreen:
Tahr 6.0.5 uses outdated yad version 0.12.4.

You could try gtkdialog instead:

Code: Select all

#!/bin/sh
echo '<window decorated="false">
<text>
  <variable>vTXT</variable>
  <input>printf "%(%a %d %b %H:%M %S)T"</input>
</text>
<timer>
  <action>refresh:vTXT</action>
</timer>
</window>'|gtkdialog -sG +420+16
User avatar
rcrsn51
Posts: 1249
Joined: Sun Aug 23, 2020 4:26 pm
Been thanked: 291 times

Re: Simple Clock

Post by rcrsn51 »

rockedge wrote: Fri Jun 24, 2022 2:36 am

... Compiled in Bionic64-8, with devx loaded. ...compile command I used:

Code: Select all

gcc sclock.c -o sclock $(pkg-config --cflags --libs gtk+-3.0)

I can confirm this. Provided that your environment has gtk-3, This should compile anywhere.

User avatar
mikewalsh
Moderator
Posts: 5674
Joined: Tue Dec 03, 2019 1:40 pm
Location: King's Lynn, UK
Has thanked: 611 times
Been thanked: 1747 times

Re: Simple Clock

Post by mikewalsh »

@rockedge / @ozsouth / @rcrsn51 :-

I'm inclined to think Bill's right here. I've just had a mooch round /ubuntu/pool, where Canonical keep every package they've ever built for Ubuntu, all the way back to 4.10, "Hoary Hedgehog". Erik's correct; the libgtk3-devel package is the one that contains all the relevant header files.

This, however, is where it gets slightly murky....

------------------------------------------------------------

I want to try & compile this in Quirky64 April 7.0.1, OK? Now; Barry didn't include GTK3 in this when he built it, so since it's approximately Tahrpup-era - and many Tahrpup packages work OOTB here - I "borrowed" the GTK3 stuff from Tahrpup64 6.0.5. Of course, the development package was always a separate download.

Tahrpup used the GTK3 3.10.8 package, OK? Scanning through all the relevant repo sections, the 3.10.8 package has been wiped out of existence! No sign of it anywhere.

The previous 3.8.4 package is all present & correct, as is the subsequent 3.12.2 package.....but Tahr's original OOTB install of GTK3 3.10.8 is no longer in the repos. Now; from the look of things, and judging by the dates, 3.12.2 is from either "Utopic Unicorn" (14.10) OR "Vivid Vervet" (15.04).

(The 'Quirkies' were always Barry's development platform, for trying out novel ideas. Although 'April' seems to have a lot of stuff 'poached' directly from mainstream distros, it also seems to have quite a few unique items, obviously compiled from scratch.....and I couldn't even begin to guess where Barry obtained his sources.)

------------------------------------------------------------------

So; I'm doing a backup of my 'working' Quirky as I type this. I've downloaded all the 3.12.2 packages (bin, common, devel, and the main one; haven't bothered with the debug package, 'cos I can't see me needing that) from /ubuntu/pool, amalgamated everything into an "all-in-one' .pet, and the plan is to slightly update Quirky's GTK3+ to the next version up. Crucially, however, it will have the "headers" - the ".h" files - installed for GTK3.

(Before anyone says it, I'm well aware that an older version of GTK3 may not have all the relevant options anyway, but.....I'm curious to see how far it'll go.)

And THEN I shall have another try at compiling sClock. This may work....and there again, it may not. Wish me luck!

Mike. ;)

Puppy "stuff" ~ MORE Puppy "stuff" ~ ....and MORE! :D
_______________________________________________________

Image

User avatar
rockedge
Site Admin
Posts: 5856
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2102 times
Been thanked: 2194 times
Contact:

Re: Simple Clock

Post by rockedge »

@mikewalsh We have our fingers crossed.......I think as long as the gtk+3-dev (or in Void Linux speak gtk+-devel) is any version 3+ it should work.

But what if you try to compile against gtk+2-dev or similar? I should try this........

Code: Select all

gcc sclock.c -o sClock $(pkg-config --cflags --libs gtk+-2.0)

probably will not due to syntax differences between gtk3 and gtk2

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: Simple Clock

Post by misko_2083 »

mikewalsh wrote: Fri Jun 24, 2022 2:13 pm

Wish me luck!

Good luck :lol:

3.12? Those are old development libraries.
I use 3.24 here.

rockedge wrote: Fri Jun 24, 2022 3:41 pm

@mikewalsh We have our fingers crossed.......I think as long as the gtk+3-dev (or in Void Linux speak gtk+-devel) is any version 3+ it should work.

But what if you try to compile against gtk+2-dev or similar? I should try this........

Code: Select all

gcc sclock.c -o sClock $(pkg-config --cflags --libs gtk+-2.0)

probably will not due to syntax differences between gtk3 and gtk2

No, It wouldn't compile. It would print a lot of errors.

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
rockedge
Site Admin
Posts: 5856
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2102 times
Been thanked: 2194 times
Contact:

Re: Simple Clock

Post by rockedge »

@misko_2083 I didn't think it could.

I am using gtk+3-devel version 3.24.34 as well in KLV and libgtk-3-dev_3.22.30 with Puppy Linux Bionic64-8 successfully for a smooth fast build.

User avatar
greengeek
Posts: 1227
Joined: Thu Jul 16, 2020 11:06 pm
Has thanked: 354 times
Been thanked: 148 times

Re: Simple Clock

Post by greengeek »

MochiMoppel wrote: Fri Jun 24, 2022 8:26 am

You could try gtkdialog instead:

Code: Select all

#!/bin/sh
echo '<window decorated="false">
<text>
  <variable>vTXT</variable>
  <input>printf "%(%a %d %b %H:%M %S)T"</input>
</text>
<timer>
  <action>refresh:vTXT</action>
</timer>
</window>'|gtkdialog -sG +420+16

Yes, thank you. Very nice. Simple and clean.

mochiclock3.png
mochiclock3.png (147.21 KiB) Viewed 1104 times
geo_c
Posts: 2575
Joined: Fri Jul 31, 2020 3:37 am
Has thanked: 1855 times
Been thanked: 729 times

Re: Simple Clock

Post by geo_c »

I played around with @MochiMoppel's gtkdialog script. And it's cool. I'd like to figure out how to increase the size of the font, as I'm guessing it's using the terminal font settings at the moment. You can see the clock down by the Menu start button.

Image

geo_c
Old School Hipster, and Such

User avatar
mikewalsh
Moderator
Posts: 5674
Joined: Tue Dec 03, 2019 1:40 pm
Location: King's Lynn, UK
Has thanked: 611 times
Been thanked: 1747 times

Re: Simple Clock

Post by mikewalsh »

@rockedge / @misko_2083 :-

I've given up on this in Quirky. I tried upgrading to the slightly newer GTK-3.0.....and all my browsers quit working!

Before restoring to original spec, I tried building sclock.c. GTK-3.0 wanted libwayland-client.....which wanted libmirclient.....which wanted protobuf-lite.....which wanted....arrgh! No, no; hell, no. Sorry, but I just couldn't be arsed with that much of a lib chase; in a way, it goes to show just how non-standard these 'Quirkies' were. (Admittedly, I've added a shed-load of stuff to get everything working in its current trim as it is.)

I'm really not that 'into' compiling, I'm afraid. I tend to either use as-is, or to modify, things already built by other folks.

Sorry to let the side down, guys. I'm guessing that since many of you are building/compiling stuff on a regular basis, y'all probably have much of this loaded/installed all the time. Anyways,Fred's original 'GTK yclock' solution works fine in Quirky64 'April', so that'll do for this one. Erik's packages work great in all the other 64-bitzers in the kennels, so I'm satisfied with those, too....

Mike. ;)

Puppy "stuff" ~ MORE Puppy "stuff" ~ ....and MORE! :D
_______________________________________________________

Image

User avatar
MochiMoppel
Posts: 1142
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 18 times
Been thanked: 373 times

Re: Simple Clock

Post by MochiMoppel »

geo_c wrote: Sat Jun 25, 2022 4:12 am

I'd like to figure out how to increase the size of the font, as I'm guessing it's using the terminal font settings at the moment.

The terminal font is different (just compare the number zero)

You seem to use a GTK theme with dark background and green text color, so unless you have made changes to the gtkdialog code the resulting clock uses your theme settings.

To change the fonts, sizes, colors etc. you could use pango markup in the <input> tag, either directly (not for the faint of heart :lol: ) or via a function. Pango allows to create different styles for each part of the clock with a single printf statement:

gtkdiaclock.gif
gtkdiaclock.gif (39.43 KiB) Viewed 1001 times



For a start let's only set the font size to 18 and also make it bold:

Code: Select all

function make_me_pretty {
	printf "<span font='bold 18'>%(%R:%S)T</span>"
};export -f make_me_pretty

echo '<window decorated="false" border-width="0">
<text use-markup="true">
  <variable>vTXT</variable>
  <input>make_me_pretty</input>
</text>
<timer>
  <action>refresh:vTXT</action>
</timer>
</window>'|gtkdialog -sG +420+16
User avatar
fredx181
Posts: 2663
Joined: Tue Dec 03, 2019 1:49 pm
Location: holland
Has thanked: 294 times
Been thanked: 1050 times
Contact:

Re: Simple Clock

Post by fredx181 »

MochiMoppel wrote:

pango markup in the <input> tag, either directly (not for the faint of heart :lol: )

Indeed for me, directly in the <input> tag I couldn't make it work, can you explain a little what the trick should be ?

User avatar
mikewalsh
Moderator
Posts: 5674
Joined: Tue Dec 03, 2019 1:40 pm
Location: King's Lynn, UK
Has thanked: 611 times
Been thanked: 1747 times

Re: Simple Clock

Post by mikewalsh »

@fredx181 / @MochiMoppel :-

fredx181 wrote: Sun Jun 26, 2022 10:00 am
MochiMoppel wrote:

pango markup in the <input> tag, either directly (not for the faint of heart :lol: )

Indeed for me, directly in the <input> tag I couldn't make it work, can you explain a little what the trick should be ?

Yah, I'm curious, too.

I'd like to try and make Fred's early solution - near the start of the thread (which works for me in Quirky64 April):-

viewtopic.php?p=59726#p59726

.....show the seconds in a smaller font size. Much like how Bill Wilson has done the clock in gKrellM:-

Image

FWIW, the string he uses looks like this:-

Code: Select all

%l:%M <span foreground="$A"><small>%S</small></span>

(That $A variable he uses is peculiar to gKrellM, apparently, and is designed to make everything look like whatever theme gKrellM is currently using...)

Because I can, I set gKrellM's clock to a much larger font size.....and that's my desktop clock. But I'd like to try and adapt Fred's GTK yclock solution to show smaller seconds. I've been playing around with it this morning, but where I've tried using pango markup for the seconds, all I get displayed IS the script text!

The modified strftime string I'm currently on with the test script looks like this:-

Code: Select all

while :
do
  date +'%a %d %b %l:%M <span foreground="$FCOL" size="small">%S</span>'
  sleep 0.5
done

.....but it doesn't want to know. Instead of looking as it should (except with smaller seconds, obviously):-

Image

.....it's coming up like this:-

Image

Which proves that I either haven't got my modifications correct, OR this kind of markup editing won't work with the way Fred's written his script..? :?

(I keep telling y'all that I'm nowt but a "bumbler", and this kinda proves it! :lol: )

Mike. ;)

Puppy "stuff" ~ MORE Puppy "stuff" ~ ....and MORE! :D
_______________________________________________________

Image

User avatar
fredx181
Posts: 2663
Joined: Tue Dec 03, 2019 1:49 pm
Location: holland
Has thanked: 294 times
Been thanked: 1050 times
Contact:

Re: Simple Clock

Post by fredx181 »

mikewalsh wrote:

I'd like to try and make Fred's early solution - near the start of the thread (which works for me in Quirky64 April):-

viewtopic.php?p=59726#p59726

.....show the seconds in a smaller font size.

Hi Mike, I don't think it's possible using pango markup with the script approach I did using the yad --form --cycle-read options , so might need a different setup (but I don't know how TBH).

geo_c
Posts: 2575
Joined: Fri Jul 31, 2020 3:37 am
Has thanked: 1855 times
Been thanked: 729 times

Re: Simple Clock

Post by geo_c »

MochiMoppel wrote: Sun Jun 26, 2022 7:21 am

You seem to use a GTK theme with dark background and green text color, so unless you have made changes to the gtkdialog code the resulting clock uses your theme settings.

To change the fonts, sizes, colors etc. you could use pango markup in the <input> tag, either directly (not for the faint of heart :lol: ) or via a function. Pango allows to create different styles for each part of the clock with a single printf statement:

Well the mochiclock2 is very handy. It looks just like my tray clock only bigger, sticky, and can be moved anywhere on the desktop.

Image

geo_c
Old School Hipster, and Such

User avatar
mikewalsh
Moderator
Posts: 5674
Joined: Tue Dec 03, 2019 1:40 pm
Location: King's Lynn, UK
Has thanked: 611 times
Been thanked: 1747 times

Re: Simple Clock

Post by mikewalsh »

fredx181 wrote: Sun Jun 26, 2022 4:46 pm
mikewalsh wrote:

I'd like to try and make Fred's early solution - near the start of the thread (which works for me in Quirky64 April):-

viewtopic.php?p=59726#p59726

.....show the seconds in a smaller font size.

Hi Mike, I don't think it's possible using pango markup with the script approach I did using the yad --form --cycle-read options , so might need a different setup (but I don't know how TBH).

Nah, no worries, mate. If it won't, it won't. Nowt to concern yourself over. :D

You would know better than I.....you've got more experience, and you have a better idea by now what will work, and what won't.

Thanks for what you've done so far!

Mike. ;)

Puppy "stuff" ~ MORE Puppy "stuff" ~ ....and MORE! :D
_______________________________________________________

Image

User avatar
MochiMoppel
Posts: 1142
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 18 times
Been thanked: 373 times

Re: Simple Clock

Post by MochiMoppel »

fredx181 wrote: Sun Jun 26, 2022 10:00 am
MochiMoppel wrote:

pango markup in the <input> tag, either directly (not for the faint of heart :lol: )

Indeed for me, directly in the <input> tag I couldn't make it work, can you explain a little what the trick should be ?

Sure.
Consider this little example:

echo '<text use-markup="true">
<input>printf "<span font='bold 24'>This text is big and bold</span>"</input>
</text>' | gtkdialog -sc

Does not work. Problems are the
1) tag delimiters '<' and' >' which gtkdialog confuses with its own tags
2) apostrophes, since apostrophes are already used to enclose the main code and therefore can't be used again within the code

One way to solve this is to use their hex values. Prinf knows how to translate them:
echo '<text use-markup="true">
<input>printf "\x3Cspan font=\x27bold 24\x27\x3EThis text is big and bold\x3C/span\x3E"</input>
</text>' | gtkdialog -sc

Prinf also understands octal values. I find them easier to read than hex values:
echo '<text use-markup="true">
<input>printf "\074span font=\047bold 24\047\076This text is big and bold\074/span\076"</input>
</text>' | gtkdialog -sc

So why would you go to this trouble when packing it into a function is so much easier? Well, the function needs to be exported, and this is not supported in other shells, e.g. busybox ash. To give you a real life example, here is the ash script used for my multicolor clock. Uses nested <span> tags:
<span fgcolor='#00FC03' bgcolor='#494159' font='bold 20'>%( %H:%M )T<span font='bold 12' fgcolor='pink'>%(%S )T</span></span>

Code: Select all

#!/bin/ash
echo '<window decorated="false" border-width="0">
<text use-markup="true">
  <variable>vTXT</variable>
  <input>printf "\074span fgcolor=\047#00FC03\047 bgcolor=\047#494159\047 font=\047bold 20\047\076%( %H:%M )T\074span font=\047bold 12\047 fgcolor=\047pink\047\076%(%S )T\074/span\076\074/span\076"</input>
</text>
<timer>
  <action>refresh:vTXT</action>
</timer>
</window>'|gtkdialog -sG +420+16
User avatar
fredx181
Posts: 2663
Joined: Tue Dec 03, 2019 1:49 pm
Location: holland
Has thanked: 294 times
Been thanked: 1050 times
Contact:

Re: Simple Clock

Post by fredx181 »

MochiMoppel wrote:

Consider this little example:

echo '<text use-markup="true">
<input>printf "<span font='bold 24'>This text is big and bold</span>"</input>
</text>' | gtkdialog -sc

Does not work. Problems are the
1) tag delimiters '<' and' >' which gtkdialog confuses with its own tags
2) apostrophes, since apostrophes are already used to enclose the main code and therefore can't be used again within the code

One way to solve this is to use their hex values. Prinf knows how to translate them:
...
...
So why would you go to this trouble when packing it into a function is so much easier?
....

Thanks! I'll stay with using a function if possible but good to know what's the cause of my endless trying and failure :roll: to make it work inside the input tag.

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: Simple Clock

Post by misko_2083 »

mikewalsh wrote: Sun Jun 26, 2022 1:52 am

@rockedge / @misko_2083 :-

I've given up on this in Quirky. I tried upgrading to the slightly newer GTK-3.0.....and all my browsers quit working!

Before restoring to original spec, I tried building sclock.c. GTK-3.0 wanted libwayland-client.....which wanted libmirclient.....which wanted protobuf-lite.....which wanted....arrgh! No, no; hell, no. Sorry, but I just couldn't be arsed with that much of a lib chase; in a way, it goes to show just how non-standard these 'Quirkies' were. (Admittedly, I've added a shed-load of stuff to get everything working in its current trim as it is.)

I'm really not that 'into' compiling, I'm afraid. I tend to either use as-is, or to modify, things already built by other folks.

Sorry to let the side down, guys. I'm guessing that since many of you are building/compiling stuff on a regular basis, y'all probably have much of this loaded/installed all the time. Anyways,Fred's original 'GTK yclock' solution works fine in Quirky64 'April', so that'll do for this one. Erik's packages work great in all the other 64-bitzers in the kennels, so I'm satisfied with those, too....

Mike. ;)

Maybe we can bypass Gtk+ altogether Mike. :)
I found this: https://github.com/kumohakasemk9/cairo- ... loginan2.c
Made some changes and now it's drawing a clock on a transparent window.
Just cairo and Xlib.

Code: Select all

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>

/*  gcc file.c -o clockc $(pkg-config --cflags --libs cairo cairo-xlib-xrender x11)*/

void draw(cairo_t *g);
void main() {
	Display *disp = XOpenDisplay(NULL);
	cairo_t *bg;
	cairo_surface_t *ximg,*img;
        cairo_t *g;
	img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,150,20);
	bg = cairo_create(img);

	int s;
	if(disp == NULL) {
		printf("Display open failed.\n");
		return;
	}
	Atom WM_DELETE_WINDOW = XInternAtom(disp,"WM_DELETE_WINDOW",False);
	s = DefaultScreen(disp);
        XVisualInfo vinfo;
        XMatchVisualInfo(disp, DefaultScreen(disp), 32, TrueColor, &vinfo);

        XSetWindowAttributes attr;
        attr.colormap = XCreateColormap(disp, DefaultRootWindow(disp), vinfo.visual, AllocNone);
        attr.border_pixel = 0;
        attr.background_pixel = 0;

	int w =  XCreateWindow(disp, DefaultRootWindow(disp), 0, 0, 150, 20, 0, vinfo.depth, InputOutput, vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr);
	XMapWindow(disp,w);
	XSetWMProtocols(disp,w,&WM_DELETE_WINDOW,1);

	ximg = cairo_xlib_surface_create(disp,w,vinfo.visual,150,20);
	cairo_xlib_surface_set_size(ximg,150,20);
	g = cairo_create(ximg);
	cairo_set_source_surface(g,img,0,0);

	while(1) {
		if(XPending(disp)) {
			XEvent e;
			XNextEvent(disp,&e);
			if(e.type == ClientMessage && e.xclient.data.l[0] == WM_DELETE_WINDOW) {break;}
		} else {
		        draw(g);

		}
	}
        cairo_destroy(g);
	cairo_surface_destroy(ximg);
	cairo_destroy(bg);
	cairo_surface_destroy(img);
	XDestroyWindow(disp,w);
	XCloseDisplay(disp);
}

void draw(cairo_t *g) {
	char buffer[64];
        time_t timer;
        static char *date = "%r";
        struct tm* tm_info;
        time (&timer);
        tm_info = localtime (&timer);
        strftime (buffer, 64, date, tm_info);

        cairo_save (g);
        cairo_set_source_rgba (g,0,0,0,1);
        cairo_set_operator (g, CAIRO_OPERATOR_CLEAR);
        cairo_paint (g);
        cairo_restore (g);
        cairo_set_operator (g, CAIRO_OPERATOR_OVER);
        cairo_save (g);

        cairo_set_source_rgb (g, 0.0, 1.0, 0.0);
	cairo_select_font_face(g,"Ubuntu Mono",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_BOLD);
	cairo_set_font_size(g,20);
        cairo_move_to (g, 0.0, 18.0);
	cairo_show_text(g,buffer);
        cairo_restore (g);
        cairo_paint (g);
        sleep(1);
}

Image
It has a delay when closing the window.
Ideally draw() should have a thread of it's own but could not make it work.
Damn the Xlib.

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: Simple Clock

Post by misko_2083 »

I got more sleep time than usual and I'm finally figuring out x11.

Needed dev libs: libcairo2-dev libx11-dev
I've added a timeout of 1 second instead of sleep.
Left click cycles through date mods and colors (because why not ;) ).
Image
Right click for exit.
What works with xfwm4 for undecorated window are motif wm himts not sure about other wms.
Added net wm state properties to make the window sticky, below, skip taskbar and skip pager.
Alt left click to move.

sclockx.c

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>

/*  gcc sclockx.c -o sclockx $(pkg-config --cflags --libs cairo-xlib-xrender x11)  */

void draw(cairo_t *g, char *date);

int main (int argc, char *argv[]) {
  Display *disp = XOpenDisplay(NULL);
  if(disp == NULL) {
      printf("Display open failed.\n");
      return 1;
  }
  cairo_t *g, *bg;
  cairo_surface_t *ximg,*img;
  int s;

  img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,180,26);
  bg = cairo_create(img);
  s = DefaultScreen(disp);

  XVisualInfo vinfo;
  XMatchVisualInfo(disp, DefaultScreen(disp), 32, TrueColor, &vinfo);

  XSetWindowAttributes attr;
  attr.override_redirect = False;
  attr.event_mask = ExposureMask | KeyPressMask |
                    VisibilityChangeMask | ButtonPressMask;
  attr.colormap = XCreateColormap(disp, DefaultRootWindow(disp), vinfo.visual, AllocNone);
  attr.border_pixel = 0;
  attr.background_pixel = 0;

  int w =  XCreateWindow(disp, DefaultRootWindow(disp), 0, 0, 180, 26, 0,
                         vinfo.depth, InputOutput, vinfo.visual,
                         CWEventMask | CWColormap | CWBorderPixel | CWBackPixel , &attr);
  XStoreName(disp, w, "sclockx");
  XSelectInput(disp, w, 
               ExposureMask | KeyPressMask | ClientMessage | 
               ButtonPressMask | ButtonReleaseMask);
  XSizeHints sh;
  sh.width = sh.min_width = 150;
  sh.height = sh.min_height = 24;
  sh.max_width = 220;
  sh.max_height = 40;
  sh.win_gravity = 0;
  sh.flags = PSize | PMinSize | PMaxSize | PWinGravity;
  XSetWMNormalHints(disp, w, &sh);

  Atom motif_hints;
  long hints[5] = {2, 0, 0, 0, 0};
  motif_hints = XInternAtom(disp, "_MOTIF_WM_HINTS", False);
  XChangeProperty(disp, w, motif_hints, motif_hints, 32, PropModeReplace, (unsigned char *)&hints, 5);

  Atom window_state = XInternAtom(disp, "_NET_WM_STATE", False);
  long wmStateBelow = XInternAtom(disp, "_NET_WM_STATE_BELOW", False);
  long wmStateSticky = XInternAtom(disp, "_NET_WM_STATE_STICKY", False);
  long wmStateSkipTaskbar = XInternAtom(disp, "_NET_WM_STATE_SKIP_TASKBAR", False);
  long wmStateSkipPager = XInternAtom(disp, "_NET_WM_STATE_SKIP_PAGER", False);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeReplace, (unsigned char *) &wmStateBelow, 1);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeAppend, (unsigned char *) &wmStateSticky, 1);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeAppend, (unsigned char *) &wmStateSkipTaskbar, 1);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeAppend, (unsigned char *) &wmStateSkipPager, 1);

  XFlush(disp);
  XMapWindow(disp,w);

  Atom wm_delete_window = XInternAtom(disp,"WM_DELETE_WINDOW",False);
  XSetWMProtocols(disp,w,&wm_delete_window,1);

  ximg = cairo_xlib_surface_create(disp,w,vinfo.visual,180,26);
  cairo_xlib_surface_set_size(ximg,180,26);
  g = cairo_create(ximg);
  cairo_set_source_surface(g,img,0,0);

  int x11_fd;
  fd_set in_fds;
  int nfds = x11_fd + 1;
  struct timeval tv;
  XEvent ev;
  x11_fd = ConnectionNumber(disp);
  static char *date = "%r";
  for(;;) {
      FD_ZERO(&in_fds);
      FD_SET(x11_fd, &in_fds);
      // Set timer to one second
      tv.tv_usec = 0;
      tv.tv_sec = 1;
      // Wait for X Event or a Timer
      int ret;
      if (!XPending(disp))
          ret = select(nfds, &in_fds, NULL, NULL, &tv);
      if (ret == -1 && errno == EINTR)
          continue;
      if (ret == -1)
          goto shutdown;
      if (ret == 0)
          draw(g, date);

      if (XPending(disp)) {
          XNextEvent(disp, &ev);
          if (XFilterEvent(&ev, w))
              continue;
          if (ret > 0) {
              switch (ev.type) {
              case ClientMessage:
              if (ev.xclient.data.l[0] == wm_delete_window) 
                  goto shutdown;
                  case ButtonPress:
                      switch(ev.xbutton.button){
                      case Button1:
                      if (date == "%r")
                          date = "%R:%S";
                      else if (date == "%R:%S")
                          date = "%a %d %b";
                      else if (date == "%a %d %b")
                          date = "      %Y";
                      else
                          date = "%r";
                      continue;
                      case Button3:
                           goto shutdown;
                      }
              default:
                  break;
              }
          }
          else if (ret == 0) 
              draw(g, date);
          else
              printf("An error occured!\n");
      }
  }
  shutdown: printf("Exit\n");
  cairo_destroy(g);
  cairo_surface_destroy(ximg);
  cairo_destroy(bg);
  cairo_surface_destroy(img);
  XDestroyWindow(disp,w);
  XCloseDisplay(disp);
  return 1;
}


void draw(cairo_t *g, char *date) {
  char buffer[64];
  time_t timer;

  struct tm* tm_info;
  time (&timer);
  tm_info = localtime (&timer);
  strftime (buffer, 64, date, tm_info);

  cairo_save (g);
  cairo_set_source_rgba (g,0,0,0,1);
  cairo_set_operator (g, CAIRO_OPERATOR_CLEAR);
  cairo_paint (g);
  cairo_restore (g);
  cairo_set_operator (g, CAIRO_OPERATOR_OVER);
  cairo_save (g);

  if (date == "%r")
      cairo_set_source_rgb (g, 0.0, 1.0, 0.0);
  else if (date == "%R:%S")
      cairo_set_source_rgb (g, 1.0, 0.0, 0.0);
  else if (date == "%a %d %b")
      cairo_set_source_rgb (g, 1.0, 1.0, 1.0);
  else
      cairo_set_source_rgb (g, 0.9, 0.7, 0.0);

  cairo_select_font_face(g,"Sans",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(g,24);
  cairo_move_to (g, 0.0, 20.0);
  cairo_show_text(g,buffer);
  cairo_restore (g);
  cairo_paint (g);
}

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
rockedge
Site Admin
Posts: 5856
Joined: Mon Dec 02, 2019 1:38 am
Location: Connecticut,U.S.A.
Has thanked: 2102 times
Been thanked: 2194 times
Contact:

Re: Simple Clock

Post by rockedge »

I gave it compile run in Bionic64 which built sClockx but it will not run:

Screenshot(18).jpg
Screenshot(18).jpg (27.73 KiB) Viewed 929 times
Screenshot(20).jpg
Screenshot(20).jpg (21.63 KiB) Viewed 928 times
User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: Simple Clock

Post by misko_2083 »

Should be fixed now.

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>

/*  gcc sclockx.c -o sclockx $(pkg-config --cflags --libs cairo-xlib-xrender x11)*/

void draw(cairo_t *g, char *date);

int main (int argc, char *argv[]) {
  Display *disp = XOpenDisplay(NULL);
  if(disp == NULL) {
      printf("Display open failed.\n");
      return 1;
  }
  cairo_t *g, *bg;
  cairo_surface_t *ximg,*img;
  int s;

  img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,180,26);
  bg = cairo_create(img);
  s = DefaultScreen(disp);

  XVisualInfo vinfo;
  const char depths[] = { 32, 24, 8, 4, 2, 1, 0 };
  for (int i = 0; depths[i]; i++) {
      XMatchVisualInfo(disp, s, depths[i], TrueColor, &vinfo);
      if (vinfo.visual)
          break;
  }

  XSetWindowAttributes attr;
  attr.override_redirect = False;
  attr.event_mask = ExposureMask | KeyPressMask |
                    VisibilityChangeMask | ButtonPressMask;
  attr.colormap = XCreateColormap(disp, DefaultRootWindow(disp), vinfo.visual, AllocNone);
  attr.border_pixel = 0;
  attr.background_pixel = 0;

  int w =  XCreateWindow(disp, DefaultRootWindow(disp), 0, 0, 180, 26, 0,
                         vinfo.depth, InputOutput, vinfo.visual,
                         CWEventMask | CWColormap | CWBorderPixel | CWBackPixel , &attr);
  XStoreName(disp, w, "sclockx");
  XSelectInput(disp, w, 
               ExposureMask | KeyPressMask | ClientMessage | 
               ButtonPressMask | ButtonReleaseMask);
  XSizeHints sh;
  sh.width = sh.min_width = 150;
  sh.height = sh.min_height = 24;
  sh.max_width = 220;
  sh.max_height = 40;
  sh.win_gravity = 0;
  sh.flags = PSize | PMinSize | PMaxSize | PWinGravity;
  XSetWMNormalHints(disp, w, &sh);

  Atom motif_hints;
  long hints[5] = {2, 0, 0, 0, 0};
  motif_hints = XInternAtom(disp, "_MOTIF_WM_HINTS", False);
  XChangeProperty(disp, w, motif_hints, motif_hints, 32, PropModeReplace, (unsigned char *)&hints, 5);

  Atom window_state = XInternAtom(disp, "_NET_WM_STATE", False);
  long wmStateBelow = XInternAtom(disp, "_NET_WM_STATE_BELOW", False);
  long wmStateSticky = XInternAtom(disp, "_NET_WM_STATE_STICKY", False);
  long wmStateSkipTaskbar = XInternAtom(disp, "_NET_WM_STATE_SKIP_TASKBAR", False);
  long wmStateSkipPager = XInternAtom(disp, "_NET_WM_STATE_SKIP_PAGER", False);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeReplace, (unsigned char *) &wmStateBelow, 1);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeAppend, (unsigned char *) &wmStateSticky, 1);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeAppend, (unsigned char *) &wmStateSkipTaskbar, 1);
  XChangeProperty(disp, w, window_state, XA_ATOM, 32, PropModeAppend, (unsigned char *) &wmStateSkipPager, 1);

  XFlush(disp);
  XMapWindow(disp,w);

  Atom wm_delete_window = XInternAtom(disp,"WM_DELETE_WINDOW",False);
  XSetWMProtocols(disp,w,&wm_delete_window,1);

  ximg = cairo_xlib_surface_create(disp,w,vinfo.visual,180,26);
  cairo_xlib_surface_set_size(ximg,180,26);
  g = cairo_create(ximg);
  cairo_set_source_surface(g,img,0,0);

  int x11_fd;
  fd_set in_fds;
  int nfds = x11_fd + 1;
  struct timeval tv;
  XEvent ev;
  x11_fd = ConnectionNumber(disp);
  static char *date = "%r";
  for(;;) {
      FD_ZERO(&in_fds);
      FD_SET(x11_fd, &in_fds);
      // Set timer to one second
      tv.tv_usec = 0;
      tv.tv_sec = 1;
      // Wait for X Event or a Timer
      int ret;
      if (!XPending(disp))
          ret = select(nfds, &in_fds, NULL, NULL, &tv);
      if (ret == -1 && errno == EINTR)
          continue;
      if (ret == -1)
          goto shutdown;
      if (ret == 0)
          draw(g, date);

      if (XPending(disp)) {
          XNextEvent(disp, &ev);
          if (XFilterEvent(&ev, w))
              continue;
          if (ret > 0) {
              switch (ev.type) {
              case ClientMessage:
              if (ev.xclient.data.l[0] == wm_delete_window) 
                  goto shutdown;
                  case ButtonPress:
                      switch(ev.xbutton.button){
                      case Button1:
                      if (date == "%r")
                          date = "%R:%S";
                      else if (date == "%R:%S")
                          date = "%a %d %b";
                      else if (date == "%a %d %b")
                          date = "      %Y";
                      else
                          date = "%r";
                      continue;
                      case Button3:
                           goto shutdown;
                      }
              default:
                  break;
              }
          }
          else if (ret == 0) 
              draw(g, date);
          else
              printf("An error occured!\n");
      }
  }
  shutdown: printf("Exit\n");
  cairo_destroy(g);
  cairo_surface_destroy(ximg);
  cairo_destroy(bg);
  cairo_surface_destroy(img);
  XDestroyWindow(disp,w);
  XCloseDisplay(disp);
  return 1;
}

void draw(cairo_t *g, char *date) {
  char buffer[64];
  time_t timer;

  struct tm* tm_info;
  time (&timer);
  tm_info = localtime (&timer);
  strftime (buffer, 64, date, tm_info);

  cairo_save (g);
  cairo_set_source_rgba (g,0,0,0,1);
  cairo_set_operator (g, CAIRO_OPERATOR_CLEAR);
  cairo_paint (g);
  cairo_restore (g);
  cairo_set_operator (g, CAIRO_OPERATOR_OVER);
  cairo_save (g);

  if (date == "%r")
      cairo_set_source_rgb (g, 0.0, 1.0, 0.0);
  else if (date == "%R:%S")
      cairo_set_source_rgb (g, 1.0, 0.0, 0.0);
  else if (date == "%a %d %b")
      cairo_set_source_rgb (g, 1.0, 1.0, 1.0);
  else
      cairo_set_source_rgb (g, 0.9, 0.7, 0.0);

  cairo_select_font_face(g,"Sans",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(g,24);
  cairo_move_to (g, 0.0, 20.0);
  cairo_show_text(g,buffer);
  cairo_restore (g);
  cairo_paint (g);
}

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

Post Reply

Return to “Scripts”