Рейтинг
+34.32
голосов:
10
avatar

Программирование  

Программированиетопик-ссылка Частые ошибки программирования на Bash

Нашел в блоге Владимира Бредникова серию интересных статей по ошибкам при написании Bash-скриптов. Считаю их очень полезными ибо сам неоднократно натыкался на подобное "неадекватное" поведение баша и разбор полетов занимал не один час ценного времени...

ПрограммированиеНаучитесь программировать - онлайн уроки от codecademy.com

Codecademy.com начали переводить и разрабатывать уроки по программированию на русском языке.



О них:

С Codecademy научиться программировать проще простого.
Codecademy предлагает интерактивный и веселый способ обучения, к тому же, можно учиться вместе с друзьями.


>>>Посетить<<<

Программированиетопик-ссылка Книга Windows 8 для С# разработчиков (русский, pdf, 4,72 Мб)

Рассматривается работа с устройствами портативных компьютеров, с графикой, видео, отладка, публикация приложений.

ПрограммированиеЗаинтересует ли обзорная статья(или несколько) по Visual C# 2010 Express(eng)

Проголосовало: 14. Воздержалось: 2

Хочу узнать, многим ли будет интересна статья с описанием интерфейс/ компоненты/ горячие клавиши и т.п. среды программирования Visual C# 2010 Express(eng). Могу написать такую статью, возможно у кого-то будут предложения по этому поводу. Что хотите видеть в статье, или есть идеи как сделать её интересной для читателей - пишите в коменты!

ПрограммированиеРазработка мать его "Ужас"

Привет ребята, все вы меня знаете и помните что из меня прогер как из балерины футболист, поэтому прошу помочь, кто чем сможет



[ Читать дальше... ⇒ ]
  • avatar
  • Lucky
  • 1877
  • 0
  • 20 марта 2012, 08:05
  • 9

ПрограммированиеUnity3D проводит акцию по раздаче бесплатных лицензий

Проект Unity3d объявил доступности бесплатных лицензий под платформы Android и iOS к своему игровому движку. Не путать с DE Unity3d разработанной для Ubuntu компанией Canonical.



Как видно из скриншота, акция будет продолжаться до 8 апреля 2012 года.

Unity это инструмент для разработки игр под Windows, MacOS, Wii, iPhone, iPod, iPad, Android, PS3, XBox 360 а также через веб-плеер Unity, который подключается к браузеру как плагин или Flash. Имеется поддержка как DirectX так и OpenGL. Вещь эта платная и доступна по цене $400 за штуку, однако сейчас идет аукцион невиданной щедрости.

>>>Взять халявную лицензию<<<
  • avatar
  • pashtuun
  • 1778
  • +13
  • 07 марта 2012, 15:07
  • 1

ПрограммированиеТребования и советы для создания расширений в GNOME Shell

Один из разработчиков GNOME Shell опубликовал в своем блоге статью с советами по созданию расширений в GNOME Shell. Очень жаль, что команда не очень хорошо поработала над документацией, из-за чего новые разработчики постоянно натыкаются на одинаковые ошибки, которые представлены в статье.



[ Читать дальше... ⇒ ]
  • avatar
  • pashtuun
  • 1523
  • +13
  • 25 февраля 2012, 10:18
  • 1

ПрограммированиеПосоветуйте книжку по паскалю

Посоветуйте хорошую книжку по паскалю чтобы примеров по больше и задания к каждой главе были

ПрограммированиеМой первый "Hello World" для GTK+ или Си-шная реализация скрипта Grub-Configurator

Представляю Си-шный вариант реализации своей утилиты grub-config на Gtk+
Шапками сходу забрасывать будет некрасиво ибо только начал изучать GTK+ и системные вызовы Linux.
Для компиляции необходимы devel-пакеты gtk+-2.0 и imagemagick, а в роли редактора простенького проекта будет незаменим geany.
Deb-пакет
Исходник:
#include <gtk/gtk.h>
#include <string.h>
#include <stdio.h>
#include <wand/MagickWand.h>
#include <X11/extensions/Xrandr.h>

typedef struct{
  gchar   *filepath;	//wallpaper image file path
  gint     timeout;		//timeout count
  gboolean savedefault;	//savedefault flag
  gboolean recovery;	//recoveri flag
  gboolean memtest;		//memtest flag
  gboolean playsound;	//playsound flag
  gboolean wallpaper;	//wallpaper flag
  gchar   *resolution;	//string-resolution
  gint     x_res;		//x-resolution
  gint     y_res;		//y-resolution
  glong	   lfSize;		//last file size
  gchar	  *t_image_name;//temporary image-file name
  gint	   x_preview;	//width preview image
  gint	   y_preview;	//height preview image
  gchar   *work_file_buf;//file
  gchar   *file_buf;	//	buffers
} grub_config;

const gchar *STRING_1="Обращаю внимание!\n\
Утилита, изменяет файлы конфигурации загрузчика.\
В маловераятном случае но это может привести к потере \
операционной системой возможности нормально загружаться!\
Поэтому как говориться: все делаете на свой страх и риск!\
Начальный конфиг сохраняется в - /etc/default/grub_save\n\
Никакие изменения не вступают в силу вплоть до подтверждения \
выбранных настроек и ввода пароля!";

const gint file_path_len=1024;
const gint FilterCount=4;
const gchar *FileFilters[]={"*.jpg", "*.JPG", "*.png", "*.PNG"};
const gchar *logo_path="/usr/share/icons/hicolor/128x128/apps/grub-config.png"; // Иконка - лого
const gchar *DefaultImagePath="/usr/share/backgrounds"; // Дефолтная папка с обоями
const gchar *def_grub="/etc/default/grub"; // Конфиг Grub
const gchar *boot_img="/boot/grub/boot.jpg"; // Целевой файл обоев
const gchar *default_melody="480 900 2 1000 2 800 2 400 2 600 3"; // Мелодия бипа
const gint win_width=500, win_height=300; // Дефолтные размеры окна
const gint thumb_width=128, thumb_height=64;
const gint default_timeout=3;

//шаблоны поиска-замены-вставки
const gchar *tmpl1  = "GRUB_DEFAULT";
const gchar *tmpl2  = "GRUB_SAVEDEFAULT=true";
const gchar *tmpl3  = "GRUB_TIMEOUT";
const gchar *tmpl4  = "GRUB_DISABLE_LINUX_RECOVERY";
const gchar *tmpl4_1= "GRUB_DISABLE_RECOVERY";
const gchar *tmpl5  = "GRUB_GFXMODE";
const gchar *tmpl6  = "GRUB_BACKGROUND";
const gchar *tmpl7  = "GRUB_INIT_TUNE";
const gchar *tmpl8  = "memtest";

gchar *filepath=NULL, *save_filepath=NULL;
gchar *ScreenResolution=NULL;
GtkWidget *file_button, *color_button, *font_button, *thumb, *chkbx1, *chkbx[5], *button[4], *lebel[7], *spin_button, *resolution;
GtkWindow *main_window=NULL;
GtkFileFilter *GtkFilter=NULL;
GdkPixbuf *PixBuffer=NULL, *PixBuffer_logo=NULL;
GtkEntryBuffer *TextBufferRes=NULL;
grub_config grc;

void MessageBox(const gchar *message){
  GtkWidget *dialog=gtk_message_dialog_new(main_window, \
					GTK_DIALOG_MODAL, \
					GTK_MESSAGE_INFO, \
					GTK_BUTTONS_CLOSE, \
					NULL);
  gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), message);
  gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);
}

void MessError(const gchar *txt, const gchar *fn){
  const gchar *caption="Error!\n";
  GtkWidget *dialog;
  int size=strlen(caption)+strlen(txt)+strlen(fn)+1;
  gchar *buf=malloc(sizeof(gchar)*size);
  sprintf(buf, "Error!\n%s %s", txt, fn);
  dialog=gtk_message_dialog_new(main_window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, NULL);
  gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), buf);
  gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);
  g_free(buf);
}

gboolean InputControl(){
  const gchar *sr=gtk_entry_get_text(GTK_ENTRY(resolution));
  memset(ScreenResolution, 0, 20*sizeof(gchar));
  strcpy(ScreenResolution, sr);

  const int max=9;
  gchar sw[max], sh[max], tmp;
  int i,w=0,h=0,res_x=0,res_y=0;
  for(i=0; i<max; i++) sw[i]=sh[i]=0;
  gboolean res=TRUE;
  for(i=0; i<max; i++){
	  tmp=ScreenResolution[i];
	  if(tmp>='0' && tmp<='9')
		if(res) sw[w++]=tmp;
		else    sh[h++]=tmp;
	  else if (tmp) res=FALSE;
  }
  if(res || w>4 || w<3 || h>4 || h<3) return FALSE;
  w=0; h=0;
  for(i=0; i<max; i++){
  if(sw[i]) {res_x*=10; res_x+=(sw[i]-'0');}
  if(sh[i]) {res_y*=10; res_y+=(sh[i]-'0');}
  }
  grc.x_res=res_x; grc.y_res=res_y;
  strcpy(ScreenResolution, sw); strcat(ScreenResolution, "x"); strcat(ScreenResolution, sh);
  grc.resolution=ScreenResolution;
  gtk_entry_set_text(GTK_ENTRY(resolution), ScreenResolution);
  return TRUE;
}

gchar *FileToBuffers(const gchar *filepath){
  glong lSize, result;
  FILE *pFile=fopen(filepath, "r");
  if (pFile!=NULL){
	fseek (pFile , 0 , SEEK_END);
	lSize = ftell (pFile);
	g_print("opening file name: %s\n",filepath);
	g_print("opening file size: %i\n",(int)lSize);
	rewind (pFile);
	gchar *buffer = g_malloc(sizeof(gchar)*lSize+1);
	if (buffer == NULL) {fclose (pFile); g_free(buffer); return NULL;}
	result = fread (buffer,1,lSize,pFile);
	if (result != lSize) {fclose (pFile); g_free(buffer); return NULL;}
	fclose (pFile);
	grc.lfSize=lSize;
	buffer[lSize]=0;
	return buffer;
  }
  return NULL;
}

void ImageConvert(){ // Обработка изображения
#define ThrowWandException(wand) { char *description; ExceptionType severity; \
  description=MagickGetException(wand,&severity); \
  (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
  description=(char *) MagickRelinquishMemory(description); grc.wallpaper=FALSE; exit(-1);}

  if(!InputControl()) MessError("wrong input screen resolution","");
  MagickBooleanType status;
  MagickWand *magick_wand = NULL;
  DrawingWand *d_wand = NULL;
  PixelWand *p_wand = NULL;
  
  MagickWandGenesis(); /* Read image file */
  magick_wand=NewMagickWand();
  status=MagickReadImage(magick_wand,grc.filepath);
  if (status == MagickFalse) ThrowWandException(magick_wand);

  MagickResetIterator(magick_wand); /* Resize image */
  MagickResizeImage(magick_wand,grc.x_res,grc.y_res,LanczosFilter,1.0);
  /* Write the image then destroy it. */
  status=MagickWriteImages(magick_wand,grc.t_image_name,MagickTrue);
  if (status == MagickFalse) ThrowWandException(magick_wand);
  magick_wand=DestroyMagickWand(magick_wand);
  if(d_wand) d_wand = DestroyDrawingWand(d_wand);
  if(p_wand) p_wand = DestroyPixelWand(p_wand);
  MagickWandTerminus();
}

gboolean my_strcmp(gchar *buf, const gchar *tpl){
  gint i;
  for(i=0; i<strlen(tpl); i++) if(buf[i]!=tpl[i]) return FALSE;
  return TRUE;
}

int f_str(const gchar *tpl){ /* find string */
  gint i, l=strlen(grc.file_buf);

  for(i=0; i<l; i++) if(grc.file_buf[i]==tpl[0] && my_strcmp(grc.file_buf+i, tpl)) return i;
  return 0;
}

int f_str_s(const gchar *tpl){ /*find line content string*/
  int ptr=f_str(tpl);
  if(!ptr) return 0;
  while(grc.file_buf[ptr]!='\n') ptr--;
  return ++ptr;
}

void s_move(gchar *dist, gchar *src, gint len){ // Перенос опред.колич.символов
  gint i;
  for(i=0; i<len; i++) dist[i]=src[i];
}

int next_l(gint ptr){
  while(grc.file_buf[ptr]!='\n')
	if(grc.file_buf[ptr]!='\0') ptr++;
	else {
		grc.file_buf[ptr++]='\n';
		grc.file_buf[ptr]='\0';
		return ptr;
		}
  return ++ptr;
}

gboolean add_str_aft_line(const gchar *tpl, gchar *new){			//добавление строки после найденной по шаблону
  int ptr=f_str_s(tpl);							//ищу строку по шаблону
  if(!ptr) return FALSE;						//выход если строка не найдена
  ptr=next_l(ptr);								//перевожу указатель на след.строку
  s_move(grc.work_file_buf, grc.file_buf, ptr);	//копирую текст до шаблона
  grc.work_file_buf[ptr]='\0';					//завершаю нулем
  strcpy(grc.work_file_buf+ptr, new);			//вставляю новую строку
  if(ptr<strlen(grc.file_buf))				//проверка на конец файла
	strcat(grc.work_file_buf,grc.file_buf+ptr);	//и копирую оставшееся
  strcpy(grc.file_buf, grc.work_file_buf);		//возвращаю результат в основной буфер
  return TRUE;
}

gboolean facs(const gchar *tpl, gchar *new){	//поиск и замена строки
  int ptr=f_str_s(tpl);
  if(!ptr) return FALSE;			//выход если строка не найдена
  s_move(grc.work_file_buf, grc.file_buf, ptr);	//копирую текст до шаблона
  grc.work_file_buf[ptr]='\0';			//завершаю нулем
  strcpy(grc.work_file_buf+ptr, new);		//вставляю новую строку
  ptr=next_l(ptr);				//пареход на следующую строку в источнике
  if(ptr<strlen(grc.file_buf))			//проверка на конец файла
	strcat(grc.work_file_buf,grc.file_buf+ptr);	//и копирую оставшееся
  strcpy(grc.file_buf, grc.work_file_buf);	//возвращаю результат в основной буфер
  return TRUE;
}

gboolean get_line(gchar *buf, const gchar *tpl){//поиск строки содержащей шаблон и копирование её в буфер
  gint ptr=f_str_s(tpl);
  if(!ptr) return FALSE;
  gint dptr=0;
  while(grc.file_buf[ptr]!='\n' && grc.file_buf[ptr]!='\0') buf[dptr++]=grc.file_buf[ptr++];
  buf[dptr]='\0';
  if(!dptr) return FALSE;
  return TRUE;
}

gboolean get_line_parameter_string(gchar *buf, const gchar *tpl){	//поиск строки по шаблону и возврат значения от знака = до первого пробела 
  if(!get_line(buf, tpl)) return FALSE;
  gint ptr;
  for(ptr=0; ptr<strlen(buf); ptr++) if(buf[ptr]=='=') break;
  if(ptr>=strlen(buf)) return FALSE;
  gint dptr=0;
  ptr++;
  while(buf[ptr]!=' ' && buf[ptr]!='\0') buf[dptr++]=buf[ptr++];
  buf[dptr++]='\0';
  return TRUE;
}

gint get_line_parameter_int(gchar *buf, const gchar *tpl){//поиск строки по шаблону и возврат целочисленного значения после символа '='
  if(!get_line_parameter_string(buf, tpl)) return FALSE;
  gint ptr, dig;
  gint res=0, len=strlen(buf);
  for(ptr=0;ptr<len;ptr++){
	dig=buf[ptr]-'0';
	if(dig>9) return 0;
	res=res*10+dig;
	}
  return res;
}

gboolean check_line_on_comment(const gchar *tpl){	//поиск строки по шаблону и проверка на закомментированность
  gint ptr=f_str_s(tpl);							//возвращает FALSE если строки нет или она закоментирована

  if(!ptr) return FALSE;
  while(grc.file_buf[ptr]!='\0' || grc.file_buf[ptr]!='\n'){
	if(grc.file_buf[ptr]==' ') {ptr++; continue;}
	if(grc.file_buf[ptr++]=='#') return FALSE;
	else break;
	}
  return TRUE;
}

void StringRoutine(){ // Обработка файла-конфига
  gchar buf[200];
  if(grc.savedefault){
	sprintf(buf,"%s%s\n",tmpl1,"=saved");	//создаю новую строку
	facs(tmpl1, buf);
	sprintf(buf,"%s\n", tmpl2);			//добавляю,
	if(!facs(tmpl2, buf))					//	если требуется, GRUB_SAVEDEFAULT=true
	  add_str_aft_line(tmpl1, buf);
  }
  else {
	sprintf(buf,"%s%s\n",tmpl1,"=0");		//устанавливаю первоначальное значение
	facs(tmpl1, buf);
	facs(tmpl2, "");
  }

  sprintf(buf,"%s=%i\n", tmpl3, grc.timeout);	//задаю таймаут
  facs(tmpl3, buf);

  *buf='\0';
  if(grc.recovery) strcpy (buf,"#");		//определяюсь с пунктами recovery mode

  if(f_str(tmpl4)){				//поиск и замена ведется по двум шаблонам
	strcat(buf, tmpl4); strcat(buf,"=true\n");// GRUB_DISABLE_LINUX_RECOVERY и GRUB_DISABLE_RECOVERY
	facs(tmpl4, buf);			//потому-шта в разных версиях груба они различаюца
	}
  else  {
	strcat(buf, tmpl4_1); strcat(buf,"=true\n");
	facs(tmpl4_1, buf);
	}

  sprintf(buf,"%s=\"%s\"\n", tmpl7, default_melody);//настраиваю бип
  if(grc.playsound){
	if(!facs(tmpl7, buf)){
		strcat(grc.file_buf, "\n");
		strcat(grc.file_buf, buf);
		}
	}
  else facs(tmpl7, "");

  if(grc.wallpaper){						//обновляю разрешение экрана
	sprintf(buf,"%s=%ix%i\n", tmpl5, grc.x_res, grc.y_res);
	facs (tmpl5, buf);
	sprintf(buf,"%s=%s\n", tmpl6, boot_img);
	if(!facs(tmpl6,buf)){
		strcat(grc.file_buf,"\n");
		strcat(grc.file_buf,buf);			//добавляю в конец GRUB_BACKGROUND=path
		}
	}
  else {
	sprintf(buf,"#%s=640x480\n", tmpl5);
	facs (tmpl5, buf);
	facs(tmpl6,"");
	}
  
  int i=strlen(grc.file_buf);				//удаляю лишние пробелы и перевод строки в конце буфера
  if(grc.file_buf[i-1]){
	i--;
	while(grc.file_buf[i]=='\n' || grc.file_buf[i]==' ') i--;
	grc.file_buf[++i]='\0';
	}
  grc.lfSize=i*sizeof(gchar);
  
  g_print("\n\nСодержимое конфига:\n%s\n\n", grc.file_buf);
}

void MemtestMove(){ //перенос файла memtest86+
// ПОКА ЭТО ПУСТЫШКА. НА ДНЯХ ДОБАВЛЮ
}

static void ApplySettings(){
  const gchar *errprefw="can't writting to file:";
  const gchar *errprefo="missing opening file:";
  
  if( !InputControl()){
	  MessageBox("Error input screen resolution");
	  return;
  }
  /* Контрольно считываю параметры */
  grc.timeout		= gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_button));
  grc.wallpaper		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[0]));
  grc.savedefault	= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[1]));
  grc.recovery		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[2]));
  grc.memtest		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[3]));
  grc.playsound		= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chkbx[4]));
  if(grc.filepath)	grc.wallpaper=TRUE;
  else 			grc.wallpaper=FALSE;

  g_free(grc.file_buf);
  grc.file_buf=FileToBuffers(def_grub);

  if (!grc.file_buf) MessError(errprefo, def_grub);

  gint rnd=87687, len=100; // Буфера и в них имена временных файлов
  gchar *t_img=g_malloc(len);
  gchar *t_wrk=g_malloc(len);
  gchar *t_fsc=g_malloc(len);
  
  grc.work_file_buf=g_malloc(grc.lfSize*2); // Выделяю память для рабочих буферов
  memcpy(grc.work_file_buf, grc.file_buf, grc.lfSize);
  g_free(grc.file_buf);
  grc.file_buf=g_malloc(grc.lfSize*2); // Буфер для нового содержимого конфига
  memcpy(grc.file_buf, grc.work_file_buf, grc.lfSize);
  grc.file_buf[grc.lfSize]=grc.work_file_buf[grc.lfSize]='\0';

  sprintf(t_wrk, "/tmp/wrk_tmp_%i.tmp",rnd);// Имена временных файлов
  sprintf(t_fsc, "/tmp/fsc_tmp_%i.sh",rnd); 
  
  StringRoutine(); // Обработка файла-конфига
  if(grc.wallpaper) ImageConvert(); // Обработка изображения
  MemtestMove();
  
  long lWrite;
  FILE *pFile=fopen(t_wrk, "wb"); // Сбрасываю буфер с новым содержимым во временный файл
  if (pFile) lWrite=fwrite (grc.file_buf , 1 , grc.lfSize, pFile );
  if(pFile && lWrite==grc.lfSize){
	fclose (pFile); pFile=NULL;
	gchar *t_scr=malloc(200*sizeof(gchar)); // Создаю скрипт, чтобы не вызывать gksu по несколько раз
	if(grc.wallpaper) // Если надо скопировать картинку
		 sprintf(t_scr,"#!/bin/sh\nmv %s %s\ncp %s %s_save\nmv %s %s\nchown root:root %s\nupdate-grub",
							grc.t_image_name, boot_img, def_grub, def_grub, t_wrk, def_grub, def_grub);
	else sprintf(t_scr,"#!/bin/sh\ncp %s %s_save\nmv %s %s\nchown root:root %s\nupdate-grub",
							def_grub, def_grub, t_wrk, def_grub, def_grub);
g_print("\n\nТекст скрипта:\n%s\n\n", t_scr);	
	gboolean fl=FALSE;
	glong sSize=strlen(t_scr)*sizeof(gchar), sWrite=0;
	FILE *sFile=fopen(t_fsc, "wb"); // Создаю файл со скриптом
    if (sFile) sWrite=fwrite (t_scr , 1, sSize , sFile );
    if (!sFile || sSize!=sWrite) MessError(errprefw, t_fsc);
	else {
		fclose (sFile); sFile=NULL; fl=TRUE;
		sprintf(t_img,"chmod +x %s", t_fsc);
		system(t_img);
		sprintf(t_img,"gksu %s", t_fsc); // Создаю команду запуска скрипта
		system(t_img); // Выполняю эту команду
		}
	if (sFile) fclose (sFile);
	if (fl) remove (t_fsc); // Удаляю файл со скриптом
	g_free(t_scr); // Освобождаю буфер скрипта
  }
  else {
	MessError(errprefw, t_wrk);
	fclose (pFile);
  }

  g_free(t_img); g_free(t_wrk); g_free(t_fsc);// Возвращаю память куче
}

void UpdatePath(){
  if( ! grc.filepath ) return;
  if(!filepath) filepath=g_malloc((size_t)file_path_len);
  strcpy(filepath, grc.filepath);
  int i, len=strlen(grc.filepath);
  for(i=len; i>0; i--) if (filepath[i]=='/') {
	  filepath[i]='\0'; break;
  }
}

gboolean LoadImagePrewiev(){
//  GError *error;
  PixBuffer=gdk_pixbuf_new_from_file_at_size(grc.filepath, thumb_width, thumb_height, NULL);// &error);
  gtk_image_set_from_pixbuf(GTK_IMAGE(thumb), PixBuffer);
  return TRUE;
}

gboolean ShowURL(GtkAboutDialog *about, const gchar *url, gpointer data){
  gtk_show_uri(NULL, url, 0, NULL);
  return TRUE;
}

void AboutDialog(GtkWidget * widget, gpointer data){
  const gchar* autor_a[]={
	  "Terechov Wladislav\n Conquistador ™\n e-mail: asgrem@gmail.com\nhttp://my.mail.ru/community/win_xp/",
	  NULL};
  const gchar* name_a="About";
  const gchar* prog_a="Grub Configurator";
  const gchar* vers_a="0.1";
  const gchar* copy_a="free software";
//  const gchar* site_a="http://my.mail.ru/community/win_xp/";
  const gchar* coms_a="Configurator of GRand Unified Bootloader";
  GtkAboutDialog *dialog=GTK_ABOUT_DIALOG(gtk_about_dialog_new());
  GdkPixbuf *pict=gdk_pixbuf_new_from_file(logo_path, NULL);

  gtk_about_dialog_set_name(dialog, name_a);
  gtk_about_dialog_set_program_name(dialog, prog_a);
  gtk_about_dialog_set_version(dialog, vers_a);
  gtk_about_dialog_set_copyright(dialog, copy_a);
  gtk_about_dialog_set_comments(dialog, coms_a);
  gtk_about_dialog_set_authors(dialog, autor_a);
  gtk_about_dialog_set_logo(dialog, pict);

  g_signal_connect(G_OBJECT(dialog), "activate-link", G_CALLBACK(ShowURL), NULL);
  
  gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (GTK_WIDGET(dialog));
}

GtkWidget *LabelSet(const gchar *string){
  GtkWidget *label=gtk_label_new(string);
  gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
  gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD); //PANGO_WRAP_CHAR, PANGO_WRAP_WORD_CHAR
  return label;
}

static void AttentionMessage(GtkWidget * widget, gpointer data){
  MessageBox(STRING_1);
}

static void PriviewImage(GtkWidget * widget, gpointer data){
  if(!grc.filepath) return;
  ImageConvert();
  GtkWidget *image = gtk_image_new();
  GdkPixbuf *pb=gdk_pixbuf_new_from_file_at_size(grc.t_image_name, grc.x_preview, grc.y_preview, NULL);// &error);
  gtk_image_set_from_pixbuf(GTK_IMAGE(image), pb);

  GtkWidget *dialog=gtk_dialog_new_with_buttons ("Preview", main_window,
	GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
	NULL);
  GtkWidget *box=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
  gtk_box_pack_start(GTK_BOX(box), image, TRUE, TRUE, 0);
  gtk_widget_show(image);
  gtk_dialog_run(GTK_DIALOG(dialog));
  gtk_widget_destroy (GTK_WIDGET(dialog));
}

static gboolean delete_event(GtkWidget * widget, GdkEvent * event, gpointer data){
  g_print("Delete event occurred\n");
  return FALSE;
}

static void destroy(GtkWidget * widget, gpointer data){
  gtk_main_quit();
}

static void toogle_callback(GtkWidget *togglebutton, gboolean *data){ //обработка сигналов от чек-батонов
  *data=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton));
  gchar *labl = *data ? "Enable" : "Disable";
  gtk_button_set_label(GTK_BUTTON(togglebutton), labl);
  if( togglebutton == chkbx[0] ){								//при изменении состояния кнопки обоев...
	if(*data){
		grc.filepath=save_filepath;
		UpdatePath();
		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_button), filepath);
		if(grc.filepath) LoadImagePrewiev();
		gtk_entry_set_editable(GTK_ENTRY(resolution), TRUE);
		}
	else {
		if(!filepath) {
			filepath=g_malloc((size_t)file_path_len);
			}
		strcpy(filepath, DefaultImagePath);
		grc.filepath=NULL;
		gtk_image_set_from_pixbuf(GTK_IMAGE(thumb), PixBuffer_logo);
		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_button), filepath);
		gtk_entry_set_editable(GTK_ENTRY(resolution), FALSE);
		}
	}	
}

void set_toggle_button_state(GtkWidget *button, gboolean *flag) { // Установка начального состояния тоггл-кнопок
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(button), *flag);
  toogle_callback(button, flag);
}

void file_selected_event(GtkFileChooserButton *fc_button, gpointer user_data) {
  if(grc.filepath)g_free(grc.filepath);
    save_filepath=grc.filepath=gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fc_button));
    grc.wallpaper=TRUE;										//устанавливаю кнопку обоев в "enable"
    set_toggle_button_state(chkbx[0],&grc.wallpaper);
}

void update_parameter(){ //обновление параметров согласно файлу-конфигу grub
  gchar *buf=g_malloc(256);
  get_line_parameter_string(buf, tmpl1);
  if(strcmp(buf,"saved") || f_str(tmpl2))grc.savedefault=TRUE;

  grc.timeout=get_line_parameter_int(buf, tmpl3);

  if(!check_line_on_comment(tmpl4) && !check_line_on_comment(tmpl4_1)) grc.recovery=TRUE;
  gboolean res1=check_line_on_comment(tmpl4);
  gboolean res2=check_line_on_comment(tmpl4_1);
  g_print("%s - %i\n%s - %i", tmpl4, (int)res1, tmpl4_1, (int)res2);

  if(f_str(tmpl6)){
	grc.wallpaper=TRUE;
	if(get_line_parameter_string(buf,tmpl6)){
		save_filepath=grc.filepath=g_malloc(file_path_len);
		strcpy(grc.filepath, buf);
		}}
  if(f_str(tmpl7)) grc.playsound=TRUE;
  
  g_free(buf);
}

int main(int argc, char ** argv){
  GtkWidget * window;
  GtkWidget * box;
  gint i;
  
  gtk_init(&argc, &argv);
  ScreenResolution=g_malloc(20); // Выделяю буфер для строчки с разрешением

  /* Определяю разрешение экрана и превью */
  int nsizes;
  Display *dpy = XOpenDisplay(NULL);
  XRRScreenSize *ss = XRRSizes(dpy, 0, &nsizes);
  grc.x_res=ss->width; grc.y_res=ss->height;
  XCloseDisplay(dpy);
  grc.x_preview = grc.x_res/3*2;
  grc.y_preview = grc.y_res/3*2;

  const gchar *temp_image_name="/tmp/img_tmp_file.jpg";// Имя временного файла-изображения
  grc.t_image_name=g_malloc((strlen(temp_image_name)+1)*sizeof(gchar));
  strcpy(grc.t_image_name, temp_image_name); 

  GtkFilter = gtk_file_filter_new (); // Инициализация файловых фильтров
  gtk_file_filter_set_name(GtkFilter, "Images");
  for(i=0; i<FilterCount; i++) gtk_file_filter_add_pattern (GtkFilter, FileFilters[i]);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  main_window = GTK_WINDOW(window); // Сохраняю идентификатор главного окна глобально для диалогов

  gtk_window_set_default_size (GTK_WINDOW (window), win_width, win_height);
  gtk_window_set_title(GTK_WINDOW(window), "Grub Configurator");
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);

  g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);

  box=gtk_table_new(10, 2, FALSE);
  gtk_container_add(GTK_CONTAINER(window), box);

  grc.file_buf=FileToBuffers(def_grub);
  grc.timeout		= default_timeout;
  grc.wallpaper=grc.savedefault=grc.recovery=grc.memtest=grc.playsound=FALSE;
  update_parameter();

/* лебел - выбор изображения	1 строчка */
  lebel[0]=LabelSet("Background image:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[0], 0, 1, 0, 1);
  gtk_widget_show(lebel[0]);
  // чекбокс background
  chkbx[0]=gtk_toggle_button_new();
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[0], 1, 2, 0, 1);
  g_signal_connect(G_OBJECT(chkbx[0]), "toggled", G_CALLBACK(toogle_callback), &grc.wallpaper);
  gtk_widget_show(chkbx[0]);

/* иконка предпросмотра и кнопка выбора файла	2 строчка */
  thumb = gtk_image_new();
  PixBuffer_logo=PixBuffer=gdk_pixbuf_new_from_file_at_size(logo_path, thumb_width, thumb_height, NULL);// &error);
  if(grc.filepath) LoadImagePrewiev();
  else gtk_image_set_from_pixbuf(GTK_IMAGE(thumb), PixBuffer);
  button[3]=gtk_button_new();
  gtk_button_set_relief(GTK_BUTTON(button[3]), GTK_RELIEF_NONE);
  gtk_button_set_focus_on_click(GTK_BUTTON(button[3]), FALSE);
  gtk_button_set_image(GTK_BUTTON(button[3]), thumb);
  g_signal_connect(G_OBJECT(button[3]), "clicked", G_CALLBACK(PriviewImage), window);
  gtk_table_attach_defaults(GTK_TABLE(box), button[3], 0, 1, 1, 2);
  gtk_widget_show(button[3]);
  
  file_button=gtk_file_chooser_button_new("Select Image File", GTK_FILE_CHOOSER_ACTION_OPEN); //GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
  gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_button), DefaultImagePath);
  gtk_file_chooser_button_set_width_chars(GTK_FILE_CHOOSER_BUTTON (file_button), 15);
  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (file_button), GtkFilter);
  g_signal_connect(G_OBJECT(file_button), "file-set", G_CALLBACK(file_selected_event), NULL);
  gtk_table_attach_defaults(GTK_TABLE(box), file_button, 1, 2, 1, 2);
  gtk_widget_show(file_button);

/* выбор разрешения				3 строчка */
  lebel[1]=LabelSet("Input default screen resolution:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[1], 0, 1, 2, 3);
  gtk_widget_show(lebel[1]);
  gchar res[20];
  sprintf(res,"%ix%i", grc.x_res, grc.y_res);
  TextBufferRes=gtk_entry_buffer_new(res, strlen(res));
  resolution=gtk_entry_new_with_buffer(TextBufferRes);
  gtk_entry_set_max_length(GTK_ENTRY(resolution), 9);
  gtk_entry_set_editable(GTK_ENTRY(resolution), FALSE);
  gtk_table_attach_defaults(GTK_TABLE(box), resolution, 1, 2, 2, 3);
  gtk_widget_show(resolution);
  
/* спин timeout					4 строчка */
  lebel[2]=LabelSet("Grub timeout:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[2], 0, 1, 3, 4);
  gtk_widget_show(lebel[2]);
  spin_button=gtk_spin_button_new_with_range(0,120,1); // Добавляю спинер
  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button), grc.timeout);
  gtk_table_attach_defaults(GTK_TABLE(box), spin_button, 1, 2, 3, 4);
  gtk_widget_show(spin_button);
  
/* чекбокс savedefault			5 строчка */
  lebel[3]=LabelSet("Save last item as default:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[3], 0, 1, 4, 5);
  gtk_widget_show(lebel[3]);
  chkbx[1]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[1], 1, 2, 4, 5);
  g_signal_connect(G_OBJECT(chkbx[1]), "toggled", G_CALLBACK(toogle_callback), &grc.savedefault);
  gtk_widget_show(chkbx[1]);

/* чекбокс recovery mode		6 строчка */
  lebel[4]=LabelSet("Items \"Recovery mode\":");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[4], 0, 1, 5, 6);
  gtk_widget_show(lebel[4]);
  chkbx[2]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[2], 1, 2, 5, 6);
  g_signal_connect(G_OBJECT(chkbx[2]), "toggled", G_CALLBACK(toogle_callback), &grc.recovery);
  gtk_widget_show(chkbx[2]);
  
/* чекбокс memtest86+			7 строчка */
  lebel[5]=LabelSet("Items \"memtest86+\":");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[5], 0, 1, 7, 8);
  gtk_widget_show(lebel[5]);
  chkbx[3]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[3], 1, 2, 7, 8);
  g_signal_connect(G_OBJECT(chkbx[3]), "toggled", G_CALLBACK(toogle_callback), &grc.memtest);
  gtk_widget_show(chkbx[3]);
  
/* чекбокс playsound			8 строчка */
  lebel[6]=LabelSet("Play sound on start:");
  gtk_table_attach_defaults(GTK_TABLE(box), lebel[6], 0, 1, 8, 9);
  gtk_widget_show(lebel[6]);
  chkbx[4]=gtk_toggle_button_new_with_label ("Disable");
  gtk_table_attach_defaults(GTK_TABLE(box), chkbx[4], 1, 2, 8, 9);
  g_signal_connect(G_OBJECT(chkbx[4]), "toggled", G_CALLBACK(toogle_callback), &grc.playsound);
  gtk_widget_show(chkbx[4]);

/* кнопка Read My				9 строчка */
  button[0]=gtk_button_new_with_label("Read my!");
  gtk_table_attach_defaults(GTK_TABLE(box), button[0], 0, 2, 9, 10);
  g_signal_connect(G_OBJECT(button[0]), "clicked", G_CALLBACK(AttentionMessage), &button[0]);
  gtk_widget_show(button[0]);
  gtk_container_set_focus_child(GTK_CONTAINER(box), button[0]);			//устанавливаю фокус на кнопку ReadMy

/* кнопка About					10 строчка */
  button[1]=gtk_button_new_with_label("About");
  gtk_table_attach_defaults(GTK_TABLE(box), button[1], 0, 1, 10, 11);
  g_signal_connect(G_OBJECT(button[1]), "clicked", G_CALLBACK(AboutDialog), &button[1]);
  gtk_widget_show(button[1]);

// кнопка Apply
  button[2]=gtk_button_new_with_label("Apply settings!");
  gtk_table_attach_defaults(GTK_TABLE(box), button[2], 1, 2, 10, 11);
  g_signal_connect(G_OBJECT(button[2]), "clicked", G_CALLBACK(ApplySettings), &button[1]);
  gtk_widget_show(button[2]);
  
  set_toggle_button_state(chkbx[0], &grc.wallpaper); //"нажимаю" кнопки согласно конфига
  set_toggle_button_state(chkbx[1], &grc.savedefault);
  set_toggle_button_state(chkbx[2], &grc.recovery);
  set_toggle_button_state(chkbx[3], &grc.memtest);
  set_toggle_button_state(chkbx[4], &grc.playsound);
 
  gtk_widget_show(box);
  gtk_widget_show(window);
  gtk_main();
  
  g_free(grc.t_image_name);
  if(ScreenResolution) g_free(ScreenResolution);
  if(grc.filepath)  g_free(grc.filepath);
  if(filepath)  g_free(filepath);
  if(save_filepath!=grc.filepath && save_filepath)  g_free(save_filepath);
  return 0;
}
  • avatar
  • terra
  • 2035
  • +35
  • 21 января 2012, 22:11
  • 12